MCP FHIR Server
Provides read/write access to any FHIR-compliant healthcare API with built-in validation, supporting resource management, search operations, and granular permissions through natural language.
README
MCP FHIR Server
A generic MCP server providing read/write access to any FHIR-compliant API with built-in validation.
This server works with any FHIR server, not just Zus Health. For Zus-specific features (like getting UPIDs), see the Zus Extensions section below.
Features
Core FHIR Features
- FHIR resource validation using consolidated FHIR schemas
- Create and update resources (POST/PUT)
- Read resources by type and ID
- Search resources with query parameters
- Granular permissions via environment configuration
- Bearer token authentication
- Custom HTTP headers for multi-tenant or vendor-specific requirements
- Detailed error messages for debugging and LLM-based correction
Zus Health Extensions (Optional)
- Zus UPID lookup - Get Universal Patient IDs from Zus FHIR servers
- Intelligent name matching - Find best patient match when multiple results exist
- Builder ID support - Multi-tenant access via
Zus-Accountheader
Installation
Prerequisites
- Python 3.13+
- uv (recommended) or pip
Setup
# Clone the repository
git clone <repository-url>
cd mcp-fhir
# Install dependencies (production only)
uv sync
# For development (includes test tools, linter, etc.)
uv sync --extra dev
# Or with pip
pip install -e .
Note: The make commands will automatically install development dependencies when needed, so you can also just run make test directly after cloning.
Configuration
Environment File
The server can load environment variables from a file using the --env-file command line flag:
# Load environment variables from a specific file
uv run fastmcp run server.py --env-file /path/to/your/.env
# Or for development
uv run fastmcp dev server.py --env-file /path/to/your/.env
If no --env-file flag is provided, the server will use system environment variables only.
Create a .env file:
cp .env.example .env
Environment Variables
| Variable | Default | Description |
|---|---|---|
FHIR_BASE_URL |
http://localhost:8080/fhir |
FHIR server base URL |
FHIR_ALLOW_READ |
true |
Enable GET operations |
FHIR_ALLOW_WRITE |
true |
Enable POST/PUT/PATCH/DELETE operations |
FHIR_AUTH_TOKEN |
(empty) | Bearer token for authentication |
FHIR_ALLOWED_METHODS |
(empty) | Comma-separated HTTP methods (overrides READ/WRITE) |
Permission Model
Option 1: Simple Read/Write (default)
FHIR_ALLOW_READ=true # Enables GET
FHIR_ALLOW_WRITE=true # Enables POST, PUT, PATCH, DELETE
Option 2: Granular Methods (takes precedence)
FHIR_ALLOWED_METHODS=GET,POST # Only read and create
Examples:
GET- Read-onlyPOST,PUT- Create and update only (no reads)GET,POST- Read and create (no updates)GET,POST,PUT- Full access
Running
Development
# Using make (recommended)
make dev
# Or directly
uv run fastmcp dev server.py
Production
# Using make (recommended)
make run
# Or directly
uv run fastmcp run server.py
Claude Desktop Integration
Edit your Claude Desktop config file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"fhir": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/mcp-fhir",
"run",
"fastmcp",
"run",
"server.py",
"--env-file",
"/absolute/path/to/mcp-fhir/.env"
]
}
}
}
Alternative: You can also set environment variables directly in the config:
{
"mcpServers": {
"fhir": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/mcp-fhir",
"run",
"fastmcp",
"run",
"server.py"
],
"env": {
"FHIR_BASE_URL": "https://your-fhir-server.com/fhir",
"FHIR_ALLOW_READ": "true",
"FHIR_ALLOW_WRITE": "true",
"FHIR_AUTH_TOKEN": "your-token-here"
}
}
}
}
Restart Claude Desktop after editing.
Tools
Core FHIR Tools
These tools work with any FHIR-compliant server:
write_fhir_resource
Create or update a FHIR resource.
Parameters:
resource(object): FHIR resource JSONcustom_headers(object, optional): Custom HTTP headers for the request- For Zus servers:
{"Zus-Account": "builder-id"}for multi-tenant access - For other servers: Any vendor-specific headers your FHIR server requires
- For Zus servers:
Behavior:
- Validates resource against FHIR schema
- Uses POST if no
idfield (create), PUT ifidexists (update) - Returns validation errors for correction if invalid
- Returns server response on success (if
FHIR_ALLOW_READ=true)
Example:
{
"resourceType": "Patient",
"name": [{"family": "Smith", "given": ["John"]}],
"gender": "male"
}
Note: If validation schema fails to load, validation is skipped (server-side validation still applies).
read_fhir_resource
Read a resource by type and ID.
Parameters:
resource_type(string): e.g., "Patient", "Observation"resource_id(string): Resource IDcustom_headers(object, optional): Custom HTTP headers for the request
Returns: JSON resource or error message
search_fhir_resources
Search resources with query parameters.
Parameters:
resource_type(string): Resource type to searchsearch_params(object, optional): Query parameters- Example:
{"name": "Smith", "gender": "female"}
- Example:
custom_headers(object, optional): Custom HTTP headers for the request
Returns: FHIR Bundle with matching resources
get_fhir_config
View current configuration.
Returns: Configuration summary including base URL, permissions, and allowed methods.
Zus Health Extensions
These tools are specific to Zus Health FHIR servers and will not work with other FHIR implementations.
get_patient_zus_upid
Get the Zus UPID (Universal Patient ID) for a Patient resource from Zus FHIR server.
Parameters:
first_name(string): Patient's first namelast_name(string): Patient's last namebuilder_id(string, optional): Zus builder ID to filter the search
Behavior:
- Searches for Patient resources using
nameparameter (concatenated first and last name) - Optionally filters by Zus
builderIDparameter if provided - Extracts Zus UPID from Patient's identifiers with system
https://zusapi.com/fhir/identifier/universal-id - When multiple patients are found, uses intelligent name matching to find the best match
- Returns the Zus UPID value or appropriate error message
Example usage:
get_patient_zus_upid("John", "Smith")
get_patient_zus_upid("John", "Smith", "builder-123")
Response formats:
- Single patient found:
Zus UPID: zus-upid-12345 - Multiple patients with good name match:
Zus UPID: zus-upid-12345 (Best match: John Smith)+ other matches if any - Multiple patients with no clear match: Lists all found patients with their Zus UPIDs
- No patients found:
Error: No Patient found with name 'John Smith' - No Zus UPID:
Error: No Zus UPID found for Patient(s) with name 'John Smith'
Name Matching Logic:
- Exact name matches get highest priority (score 1.0)
- Partial matches (e.g., "John" matching "Johnny") get medium priority (score 0.7 for given name)
- Family name matches are weighted more heavily than given name matches
- Partial matches are permissive: shorter names can match longer ones (e.g., "John" matches "Johnny")
- If the best match has a score ≥ 0.5, it's returned as the primary result
- Other decent matches (score ≥ 0.3) are listed as alternatives
Technical Details
HTTP Headers
All requests include:
Content-Type: application/fhir+json
Accept: application/fhir+json
Authorization: Bearer {token} (if FHIR_AUTH_TOKEN set)
Custom Headers:
You can provide additional custom headers via the custom_headers parameter in any tool. This is useful for:
- Multi-tenant systems (e.g., Zus's
Zus-Accountheader) - Vendor-specific authentication or routing headers
- Any other FHIR server-specific requirements
Example (Zus):
{"Zus-Account": "builder-123"}
Timeouts
All requests timeout after 30 seconds.
Error Handling
The server returns detailed errors for:
| Code | Description |
|---|---|
| 400 | Invalid request/validation error |
| 401 | Authentication failed |
| 403 | Insufficient permissions |
| 404 | Resource or endpoint not found |
| 422 | Business rule violation |
| Timeout | Connection timeout (30s) |
Errors include full server response when available for debugging.
Validation
Resources are validated using the fhir-validator library before submission:
- Checks FHIR spec compliance
- Validates required fields and data types
- Verifies resource structure
If validation schema loading fails at startup, a warning is logged and validation is bypassed (server-side validation still occurs).
Development
Testing
# Run tests (automatically installs dev dependencies if needed)
make test
# With coverage
make test-cov
# Watch mode
make test-watch
Or directly:
uv run pytest
uv run pytest --cov=. --cov-report=term-missing
Note: All make commands automatically install development dependencies when needed, so new developers can simply run make test after cloning the repository.
Code Quality
make lint # Run linter (automatically installs dev dependencies)
make format # Format code (automatically installs dev dependencies)
make check # Lint + format check (automatically installs dev dependencies)
Project Structure
mcp-fhir/
├── server.py # Generic MCP FHIR server implementation
├── zus_extensions.py # Zus Health-specific tools (optional)
├── fhir_validator.py # FHIR validation logic
├── pyproject.toml # Dependencies
├── .env.example # Example configuration
└── tests/ # Test suite
Architecture
The server is designed with modularity in mind:
- server.py: Contains generic FHIR operations that work with any FHIR server
- zus_extensions.py: Contains Zus Health-specific functionality (UPID lookup, etc.)
- Generic tools accept
custom_headersfor flexibility with different FHIR vendors - Zus tools use
builder_idfor Zus-specific multi-tenancy
This separation allows you to:
- Use the generic tools with any FHIR server
- Add your own vendor-specific extensions by following the zus_extensions.py pattern
- Keep the core FHIR functionality clean and standards-compliant
License
[Add license information]
Contributing
[Add contribution guidelines]
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。