npm package: @medscrub/mcp
Description: MCP server for MedScrub PHI de-identification
Author: MedScrub
Latest version: 0.1.15

# MedScrub MCP Server

Model Context Protocol (MCP) server for MedScrub PHI de-identification. Enables Claude Code, Cline, and other MCP clients to safely de-identify healthcare data during AI-assisted development.

![MedScrub in Action](https://medscrub.dev/mcp-screenshot.png)
*MedScrub de-identifying a FHIR Patient resource in Claude Desktop - 100% accuracy on structured healthcare data*

## 🏥 What is MedScrub?

MedScrub is a HIPAA-compliant PHI (Protected Health Information) de-identification service that enables healthcare organizations to safely use AI/LLM services while maintaining patient privacy.

## 🚀 Quick Start

### Prerequisites

- **Node.js**: 18+ required for MCP server
- **Claude Desktop**: For using with Claude Code

**Choose your deployment:**
- **Option A**: Hosted API (Recommended for hackathons/demos) ✨
- **Option B**: Demo API with Synthea FHIR (Perfect for testing with realistic data)
- **Option C**: Local Docker (Full control, no external dependencies)

> **💡 Pro Tip:** Use `npx` to always get the latest version automatically - no manual installation or updates needed!

---

## 🎯 Demo with Synthea FHIR (Recommended for Testing)

**Perfect for:** Testing MedScrub with realistic patient data from the Synthea FHIR MCP

### What You Get
- Access to 117 synthetic patients with complete medical histories
- 99.9% de-identification accuracy on FHIR structured data
- Real-world healthcare AI workflow demonstration
- Perfect for hackathons and demos

### Setup Guide

**See the complete guide:** [/DEMO.md](./DEMO.md)

**Quick configuration for dual MCP setup:**

Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):

```json
{
  "mcpServers": {
    "synthea-fhir": {
      "command": "npx",
      "args": ["-y", "supergateway", "--sse",
               "https://synthea-mcp-1095016408887.us-central1.run.app/sse"]
    },
    "medscrub": {
      "command": "npx",
      "args": ["-y", "@medscrub/mcp"],
      "env": {
        "MEDSCRUB_API_URL": "https://stage.api.medscrub.dev",
        "MEDSCRUB_API_KEY": "msk_test_demo0000000000000000000000000000"
      }
    }
  }
}
```

> **✨ Using `npx`:** Always downloads the latest version automatically - no installation or manual updates needed!

**See also:** [Demo Commands](../../claude-notes/Demo_Commands.md) for 40+ copy-paste examples

---

## Option A: Hosted API (api.medscrub.dev)

**Perfect for:**
- Hackathon participants
- Quick testing and demos
- No Docker setup required

### Step 1: Get Your JWT Token

1. Visit [https://medscrub.dev](https://medscrub.dev)
2. Sign up or log in
3. Navigate to [/demo page](https://medscrub.dev/demo)
4. Copy your JWT token (valid for 24 hours)

### Step 2: Configure Claude Desktop

Add to your Claude Desktop MCP settings:

**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
**Linux:** `~/.config/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "medscrub": {
      "command": "npx",
      "args": ["-y", "@medscrub/mcp"],
      "env": {
        "MEDSCRUB_API_URL": "https://api.medscrub.dev",
        "MEDSCRUB_JWT_TOKEN": "your-jwt-token-from-website"
      }
    }
  }
}
```

> **✨ Using `npx -y @medscrub/mcp`:** Always uses the latest version automatically. No installation or updates needed!

### Step 3: Restart Claude Desktop

Restart Claude Desktop to load the MCP server.

**Rate Limits:** 100 requests per hour per user.

---

## Option B: Local Docker

**Perfect for:**
- Healthcare organizations
- Production use
- Full data control (PHI never leaves your infrastructure)

### Step 1: Start MedScrub Docker API

```bash
# Navigate to proxy directory
cd ../

# Start Docker container (default port 3000)
docker-compose up -d

# Verify it's running
curl http://localhost:3000/health
```

### Step 2: Configure Claude Desktop

```json
{
  "mcpServers": {
    "medscrub": {
      "command": "npx",
      "args": ["-y", "@medscrub/mcp"],
      "env": {
        "MEDSCRUB_API_URL": "http://localhost:3000",
        "MEDSCRUB_API_KEY": "msk_test_demokey123456789012345678901234"
      }
    }
  }
}
```

> **✨ Using `npx`:** Always uses the latest version - no installation required!

### Step 3: Restart Claude Desktop

Restart Claude Desktop to load the MCP server.

**No rate limits** when running locally.

## 🔧 Available Tools

### medscrub__deidentify_text

De-identify text containing PHI.

**Example:**
```
User: Use medscrub__deidentify_text to scrub this clinical note:
"Patient John Doe (SSN: 123-45-6789) visited on 01/15/2023.
Email: john.doe@example.com"
```

**Returns:**
- De-identified text with tokens
- Session ID for re-identification
- List of detected PHI entities
- Confidence scores

### medscrub__reidentify_text

Restore original PHI using session tokens.

**Example:**
```
User: Use medscrub__reidentify_text with sessionId "abc-123" to restore:
"Patient [NAME_xyz] visited on [DATE_abc]"
```

### medscrub__deidentify_fhir

De-identify FHIR R4 resources with multiple output format options.

**Parameters:**
- `resource` (required): FHIR R4 resource or Bundle to de-identify
- `sessionId` (optional): Existing session ID for consistency
- `outputFormat` (optional): Output format - see below

**Output Formats:**

| Format | Description | Best For |
|--------|-------------|----------|
| `json` | Full FHIR resource (default) | Production FHIR systems |
| `json-compact` | Minimal metadata | Smaller payloads |
| `python-dict` | Python dict syntax | Jupyter notebooks, copy/paste |
| `llm-optimized` | Human-readable text | LLM analysis |

**Example (Default JSON):**
```
User: Use medscrub__deidentify_fhir to scrub this Patient resource:
{
  "resourceType": "Patient",
  "name": [{"family": "Doe", "given": ["John"]}],
  "birthDate": "1980-01-15"
}
```

**Example (Python-Dict for Jupyter):**
```
User: Use medscrub__deidentify_fhir with outputFormat="python-dict" to scrub this Patient:
{
  "resourceType": "Patient",
  "name": [{"family": "Smith", "given": ["John"]}],
  "birthDate": "1985-03-15"
}
```

Returns valid Python dict syntax that can be copy/pasted directly into Jupyter notebooks!

**See Also:** [Format Examples Notebook](/examples/jupyter/medscrub_format_examples.ipynb)

### medscrub__reidentify_fhir

Restore original PHI in FHIR resources.

### medscrub__get_session_info

Get information about a de-identification session.

### medscrub__list_phi_types

List all PHI types that MedScrub detects (18 HIPAA Safe Harbor identifiers).

## 📖 Documentation Resources

The MCP server provides built-in documentation:

- `medscrub://docs/quick-start` - Quick start guide
- `medscrub://docs/phi-types` - PHI types reference
- `medscrub://docs/api-reference` - API documentation
- `medscrub://docs/compliance` - HIPAA compliance guide

Access these in Claude Code by asking:
```
User: Read the resource medscrub://docs/quick-start
```

## 📖 Code Examples & Tutorials

### Sample Projects

Comprehensive code examples for integrating MedScrub:

- **[/samples/](../samples/)** - Multi-language samples (Python, JavaScript, TypeScript, Jupyter)
  - Production-ready client libraries
  - Complete examples with error handling
  - Batch processing patterns
  - Real-time API integration

- **[/jupyter-health/](../jupyter-health/)** - Healthcare data science with Jupyter
  - 5 progressive notebooks (beginner to advanced)
  - FHIR R4 coverage (all 10 resource types)
  - AI-assisted analysis with MCP
  - End-to-end clinical research workflow
  - Synthetic sample data (HIPAA-compliant)

### Quick Start Guides

- **Jupyter Notebooks**: [/jupyter-health/README.md](../jupyter-health/README.md)
- **Python**: [/samples/python/README.md](../samples/python/README.md)
- **JavaScript**: [/samples/javascript/README.md](../samples/javascript/README.md)
- **TypeScript**: [/samples/typescript/README.md](../samples/typescript/README.md)

## 💡 Use Cases

### 1. Scrub Clinical Notes for Testing

```
User: I have this clinical note that needs to be de-identified
before I share it with my team. Can you scrub it?

[Clinical note with PHI]
```

Claude Code will use `medscrub__deidentify_text` automatically.

### 2. Generate Test Data

```
User: Generate a de-identified version of this patient data
for my test suite.

[Patient data with PHI]
```

### 3. FHIR Resource De-identification

```
User: I need to de-identify these FHIR Patient resources
before loading them into my test environment.

[FHIR Bundle with PHI]
```

### 4. Safe AI Experimentation

```
User: I want to ask Claude about this clinical case,
but it contains PHI. Can you help?

[Clinical case with PHI]
```

Claude Code will de-identify before processing, then re-identify the response.

## 🔒 Security & Compliance

### Where PHI Lives

- ✅ **Your Machine**: MedScrub Docker API runs locally
- ✅ **In Memory Only**: Session data stored in memory, encrypted
- ✅ **Never External**: PHI never sent to external services
- ✅ **Complete Control**: You control when to de-identify/re-identify

### HIPAA Safe Harbor

MedScrub implements the HIPAA Safe Harbor de-identification method (§164.514(b)(2)), removing all 18 identifier types:

1. Names
2. Geographic subdivisions
3. Dates (except year)
4. Phone/Fax numbers
5. Email addresses
6. SSN, MRN, Account numbers
7. Device/Vehicle identifiers
8. URLs, IP addresses
9. Biometric identifiers
10. Photos
11. And more...

### Best Practices

- ✅ Run MedScrub API locally on trusted infrastructure
- ✅ Use strong API keys
- ✅ Review detected entities before proceeding
- ✅ Delete sessions when done
- ❌ Don't send PHI directly to external AI without de-identifying
- ❌ Don't store session IDs with PHI in same location

## 🛠️ Development

### Build from Source

```bash
cd mcp-server

# Install dependencies
npm install

# Build TypeScript
npm run build

# Run locally
npm start
```

### Project Structure

```
mcp-server/
├── src/
│   ├── index.ts        # MCP server entry point
│   ├── client.ts       # MedScrub API client
│   ├── tools.ts        # Tool implementations
│   └── resources.ts    # Documentation resources
├── dist/               # Compiled JavaScript
├── package.json
├── tsconfig.json
└── README.md
```

## 🐛 Troubleshooting

### MCP Server Not Loading in Claude Desktop

**Problem:** "Tool not found" or MCP server doesn't appear

**Recommended Solution (Use npx):**

1. Update your config to use `npx` (always gets latest version):
   ```json
   {
     "mcpServers": {
       "medscrub": {
         "command": "npx",
         "args": ["-y", "@medscrub/mcp"],
         "env": {
           "MEDSCRUB_API_URL": "https://api.medscrub.dev",
           "MEDSCRUB_JWT_TOKEN": "your-jwt-token"
         }
       }
     }
   }
   ```

2. Verify config file location:
   - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
   - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
   - Linux: `~/.config/Claude/claude_desktop_config.json`

3. Verify JSON syntax is valid (use [jsonlint.com](https://jsonlint.com))

4. Restart Claude Desktop completely

**Alternative Solution (If npx fails):**

If `npx` doesn't work due to npm corruption across multiple Node versions:

1. Install package globally:
   ```bash
   npm install -g @medscrub/mcp
   ```

2. Find your paths:
   ```bash
   # macOS/Linux
   which node
   npm root -g

   # Windows
   where node
   npm root -g
   ```

3. Update config with direct node execution:
   ```json
   {
     "mcpServers": {
       "medscrub": {
         "command": "/path/to/node",
         "args": ["/path/to/global/node_modules/@medscrub/mcp/dist/index.js"],
         "env": {
           "MEDSCRUB_API_URL": "https://api.medscrub.dev",
           "MEDSCRUB_JWT_TOKEN": "your-jwt-token"
         }
       }
     }
   }
   ```

   **Example paths:**
   - **macOS (nvm)**: `/Users/username/.nvm/versions/node/v22.15.0/bin/node` and `/Users/username/.nvm/versions/node/v22.15.0/lib/node_modules/@medscrub/mcp/dist/index.js`
   - **macOS (Homebrew)**: `/opt/homebrew/bin/node` and `/opt/homebrew/lib/node_modules/@medscrub/mcp/dist/index.js`
   - **Windows**: `C:\Program Files\nodejs\node.exe` and `C:\Users\username\AppData\Roaming\npm\node_modules\@medscrub\mcp\dist\index.js`
   - **Linux**: `/usr/bin/node` and `/usr/lib/node_modules/@medscrub/mcp/dist/index.js`

4. Restart Claude Desktop completely

> **Note:** With the direct path method, you'll need to manually update by running `npm install -g @medscrub/mcp` when new versions are released.

### "Cannot connect to MedScrub API"

1. Verify Docker container is running (for local deployment):
   ```bash
   docker ps | grep medscrub
   ```

2. Check API health:
   ```bash
   curl http://localhost:3000/health
   # or for production
   curl https://api.medscrub.dev/health
   ```

3. Verify API_URL in MCP config matches your deployment

### "Invalid JWT signature" / "API Key invalid" / "Unauthorized"

**For hosted API (recommended):**
1. Get a valid JWT token from [medscrub.dev/dashboard/jwt](https://medscrub.dev/dashboard/jwt)
2. JWT tokens expire after 24 hours - generate a new one if expired
3. Use `MEDSCRUB_JWT_TOKEN` (not `MEDSCRUB_API_KEY`) in your config:
   ```json
   {
     "env": {
       "MEDSCRUB_API_URL": "https://api.medscrub.dev",
       "MEDSCRUB_JWT_TOKEN": "your-jwt-token-here"
     }
   }
   ```
4. Make sure you're using **version 0.1.11+** of the MCP server (use `npx` to get latest automatically)

**For API keys (local deployment):**
1. Verify the key format is `msk_live_` or `msk_test_` followed by 32 alphanumeric characters
2. Check `MEDSCRUB_API_KEY` in Claude Desktop config matches your key
3. For local deployment: Check `.env` file has correct `API_KEY`

### "Session not found"

Sessions expire after 24 hours (default). Create a new de-identification to get a fresh session ID.

### npm/npx Errors

**Problem:** "Cannot find module 'node:path'" or npx fails

**Solution:** Use direct node execution with global installation instead of npx (see "Alternative Solution" in MCP Server Not Loading section above)

**Why this happens:** npm can become corrupted across different Node versions, especially when using nvm or multiple Node installations. The direct path method bypasses npx entirely.

## 📚 Additional Resources

- **MedScrub Documentation**: [docs.medscrub.dev](https://docs.medscrub.dev)
- **Docker API README**: [../README.md](../README.md)
- **MCP Protocol**: [modelcontextprotocol.io](https://modelcontextprotocol.io)
- **HIPAA Safe Harbor**: [HHS.gov](https://www.hhs.gov/hipaa/for-professionals/privacy/special-topics/de-identification/index.html)

## 🤝 Contributing

Contributions welcome! Please see main [CONTRIBUTING.md](../../CONTRIBUTING.md).

## 📄 License

MIT License - see [LICENSE](../../LICENSE)

## 🆘 Support

- **Issues**: [GitHub Issues](https://github.com/medscrub/medscrub/issues)
- **Email**: support@medscrub.dev
- **Community**: [Join JupyterCon Healthcare AI Community](https://discord.gg/MKF5V2C3)

---

**Built with ❤️ for Healthcare AI Development**

*Enable safe AI adoption in healthcare workflows*