A Model Context Protocol (MCP) server for interacting with FHIR APIs, specifically designed for Oracle Millennium Platform APIs. This server provides comprehensive tools for accessing various FHIR resources including Patient records, Clinical data, and Administrative information.
- OAuth2 Authentication: Secure API access using bearer token authentication
- Comprehensive FHIR Resources: Support for 10+ FHIR resource types
- Patient Search: Multiple search capabilities (name, identifier, birthdate, phone, email, address)
- Clinical Data: Access to allergies, conditions, procedures, observations, and immunizations
- Medications & Diagnostics: Retrieve medication requests and diagnostic reports
- Appointments & Encounters: Manage patient appointments and clinical encounters
- Asynchronous Operations: Efficient async/await implementation for better performance
- Patient - Demographics and patient information
- AllergyIntolerance - Patient allergy and intolerance records
- Condition - Medical conditions and diagnoses
- Procedure - Medical procedures performed
- Encounter - Patient encounters and visits
- DiagnosticReport - Diagnostic reports and results
- Observation - Clinical observations (vital signs, lab results)
- Immunization - Immunization records
- MedicationRequest - Medication prescriptions and requests
- Appointment - Scheduled appointments
- Python 3.13 or higher
uvpackage manager (recommended) orpip
- Clone the repository:
git clone <repository-url>
cd fhir-mcp-server- Install dependencies using
uv:
uv syncOr using pip:
pip install -e .- Configure environment variables:
Create a .env file in the project directory and set your FHIR server details:
FHIR_BASE_URL=https://your-fhir-server.com/r4
OAUTH_BEARER_TOKEN=your_oauth2_bearer_tokenThe .env file should contain:
FHIR_CLIENT_ID: Your OAuth2 client ID from the FHIR server providerFHIR_CLIENT_SECRET: Your OAuth2 client secret from the FHIR server providerFHIR_BASE_URL: The base URL of your FHIR R4 server endpointFHIR_TENANT_ID: (Optional) Your tenant ID, defaults to Oracle Cerner sandboxFHIR_SCOPE: (Optional) OAuth2 scopes, defaults to all supported resourcesFHIR_REQUEST_TIMEOUT: (Optional) Request timeout in seconds, default is 60
| Variable | Description | Required | Default |
|---|---|---|---|
FHIR_CLIENT_ID |
OAuth2 client ID for authentication | Yes | None |
FHIR_CLIENT_SECRET |
OAuth2 client secret for authentication | Yes | None |
FHIR_BASE_URL |
Base URL of the FHIR server | No | https://fhir-ehr.cerner.com/r4 |
FHIR_TENANT_ID |
Tenant ID for your FHIR server instance | No | ec2458f2-1e24-41c8-b71b-0e701af7583d |
FHIR_TOKEN_ENDPOINT |
OAuth2 token endpoint URL | No | Auto-generated from tenant ID |
FHIR_SCOPE |
OAuth2 scopes (space-separated) | No | All supported resources |
FHIR_REQUEST_TIMEOUT |
Request timeout in seconds | No | 60.0 |
This server uses OAuth 2.0 Client Credentials flow for system-to-system authentication, following Oracle Cerner's SMART Backend Services specification.
Before using this server, you must register your application with Oracle Cerner to obtain client credentials:
-
Create a CernerCare Account
- Sign up at Oracle Cerner Code Console
- Complete the account registration process
-
Register Your Application
- Log in to the Code Console
- Navigate to "My Applications" and click "Register New Application"
- Choose application type:
- System - For backend services and automated systems
- Confidential - For applications that can securely store credentials
- Provide application details:
- Application name
- Description
- Redirect URIs (not required for client credentials flow)
- Complete the registration process
-
Obtain Credentials
- After registration, you'll receive:
- Client ID - Your application's unique identifier
- Client Secret - Managed through Cerner Central system accounts
- Store these credentials securely
- After registration, you'll receive:
-
Configure FHIR Scopes
Note: Scope format varies based on type of token requested. Below scopes format are for
SMART V2 Token:Request the following system-level scopes for your application (SMART v1 format):
system/Patient.rs- Read access to patient resourcessystem/Observation.rs- Read access to observation resourcessystem/Condition.rs- Read access to condition resourcessystem/Procedure.rs- Read access to procedure resourcessystem/Encounter.rs- Read access to encounter resourcessystem/DiagnosticReport.rs- Read access to diagnostic reportssystem/AllergyIntolerance.rs- Read access to allergy informationsystem/Immunization.rs- Read access to immunization recordssystem/MedicationRequest.rs- Read access to medication requestssystem/Appointment.rs- Read access to appointments
The server automatically manages OAuth 2.0 tokens using Oracle Cerner's token endpoint:
https://authorization.cerner.com/tenants/{TENANT_ID}/hosts/fhir-ehr.cerner.com/protocols/oauth2/profiles/smart-v1/token
Default tenant ID: ec2458f2-1e24-41c8-b71b-0e701af7583d (Oracle Cerner Sandbox)
The server automatically:
- Requests access tokens using client credentials on first API call
- Caches tokens until expiry
- Refreshes tokens automatically when needed (with 5-minute buffer before expiry)
- Handles token errors gracefully
For more information about Oracle Cerner's authorization framework:
Run the MCP server using:
python fhir-mcp-server.pyOr if using uv:
uv run python fhir-mcp-server.pyAdd the following configuration to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"fhir": {
"command": "uv",
"args": [
"run",
"--with",
"fastmcp",
"fastmcp",
"run",
"/absolute/path/to/fhir-mcp-server/fhir-mcp-server.py"
],
"env": {
"FHIR_CLIENT_ID": "your_client_id",
"FHIR_CLIENT_SECRET": "your_client_secret",
"FHIR_BASE_URL": "https://fhir-ehr.cerner.com/r4",
"FHIR_TENANT_ID": "your_tenant_id"
}
}
}
}Important: Replace /absolute/path/to/fhir-mcp-server/fhir-mcp-server.py with the actual full path to the script!
Add the same configuration to Cursor's MCP settings. See QUICKSTART.md for detailed Cursor-specific instructions including:
- Where to find Cursor's MCP configuration
- UI-based setup options
- Cursor-specific troubleshooting
get_patient_by_id- Retrieve a patient by IDsearch_patients_by_name- Search patients by given/family namesearch_patients_by_identifier- Search by identifier (MRN, SSN, etc.)search_patients_by_birthdate- Search by birth datesearch_patients_by_phone- Search by phone numbersearch_patients_by_email- Search by email addresssearch_patients_by_address- Search by address components
get_allergy_by_id/get_patient_allergies- Allergy informationget_condition_by_id/get_patient_conditions- Medical conditionsget_procedure_by_id/get_patient_procedures- Proceduresget_observation_by_id/get_patient_observations- Observationsget_patient_vital_signs- Vital signs specificallyget_patient_lab_results- Laboratory resultsget_immunization_by_id/get_patient_immunizations- Immunizations
get_diagnostic_report_by_id/get_patient_diagnostic_reports- Diagnostic reportsget_medication_request_by_id/get_patient_medication_requests- Medications
get_encounter_by_id/get_patient_encounters- Patient encountersget_appointment_by_id/get_patient_appointments- Appointmentssearch_appointments_by_date- Search appointments by date
get_fhir_capability_statement- Get FHIR server capabilities
# Search for patients by name
result = await search_patients_by_name(
given_name="John",
family_name="Doe"
)# Get patient's conditions
conditions = await get_patient_conditions(
patient_id="12345",
clinical_status="active"
)
# Get patient's allergies
allergies = await get_patient_allergies(
patient_id="12345"
)
# Get patient's vital signs
vitals = await get_patient_vital_signs(
patient_id="12345",
date="2024-01-01"
)# Get upcoming appointments for a patient
appointments = await get_patient_appointments(
patient_id="12345",
status="booked",
date="ge2024-01-01" # Greater than or equal to date
)This server implements tools based on the following Oracle Millennium Platform API documentation:
- Patient API
- AllergyIntolerance API
- Condition API
- Procedure API
- Encounter API
- DiagnosticReport API
- Observation API
- Immunization API
- MedicationRequest API
- Appointment API
This server follows the FHIR R4 specification for resource structures and search parameters.
The server will raise HTTP exceptions for:
- Authentication failures (401 Unauthorized)
- Missing resources (404 Not Found)
- Server errors (500 Internal Server Error)
- Invalid requests (400 Bad Request)
All exceptions include detailed error messages from the FHIR server response.
Problem: Claude Desktop shows ModuleNotFoundError when trying to load the MCP server.
Solution: Make sure you've installed dependencies first:
cd /Users/sdesani/Work/fhir-mcp-server
uv syncYour Claude Desktop config should use the fastmcp run pattern:
{
"command": "uv",
"args": [
"run",
"--with",
"fastmcp",
"fastmcp",
"run",
"/absolute/path/to/fhir-mcp-server/fhir-mcp-server.py"
]
}This uses uv run --with fastmcp to dynamically install FastMCP, then runs your script which will use the installed dependencies from your project's .venv.
Server not appearing in Claude Desktop:
- Restart Claude Desktop after updating the config
- Check for JSON syntax errors in
claude_desktop_config.json - Verify the file path is absolute (starts with
/)
401 Unauthorized errors:
- Verify your OAuth token is valid and not expired
- Check the token has the correct scopes/permissions
Timeout errors:
- Increase
FHIR_REQUEST_TIMEOUTin your.envfile or Claude Desktop config - Default is 60 seconds, try 120 or higher for slow servers
-
Credential Management:
- Never commit your
.envfile or credentials to version control - Store
FHIR_CLIENT_IDandFHIR_CLIENT_SECRETsecurely - Use environment variables or secure credential management systems
- Rotate credentials regularly according to your organization's security policies
- Never commit your
-
OAuth 2.0 Security:
- The server uses OAuth 2.0 Client Credentials flow for secure system-to-system authentication
- Tokens are automatically cached and refreshed
- Follow the Application Registration steps to obtain valid credentials
-
HTTPS Only: Always use HTTPS endpoints for production FHIR servers
-
Scope Management:
- Request only the minimum required scopes for your application
- Review and update scopes as your application requirements change
- See Application Registration for available scopes
-
PHI Protection:
- Be mindful that FHIR resources contain Protected Health Information (PHI)
- Ensure compliance with healthcare data privacy regulations (HIPAA, GDPR, etc.)
- Implement appropriate access controls and audit logging
- Follow your organization's data handling policies
-
SMART Compliance:
- This server follows the SMART Backend Services specification
- Ensures secure healthcare application integration
fhir-mcp-server/
├── fhir-mcp-server.py # MCP server implementation
├── pyproject.toml # Project dependencies and metadata
├── .env # Your local configuration (not committed)
├── .gitignore # Git ignore rules
├── README.md # This file
├── QUICKSTART.md # Quick start guide
└── EXAMPLES.md # Usage examples
To add support for additional FHIR resources:
- Add a new tool function decorated with
@mcp.tool() - Use the
make_fhir_request()helper function - Follow the existing pattern for parameters and return types
- Update this README with the new tool information
Test the server by running it and connecting through an MCP client like Cursor or using the MCP Inspector tool.
[Add your license information here]
Contributions are welcome! Please feel free to submit a Pull Request.
For issues related to:
- FHIR Server: Contact your FHIR server administrator
- Oracle Millennium Platform: Refer to Oracle documentation
- This MCP Server: Open an issue in this repository
- QUICKSTART.md - Quick start guide with setup instructions for Claude Desktop and Cursor
- EXAMPLES.md - Comprehensive usage examples
- Built with FastMCP
- Implements FHIR R4 standard
- Designed for Oracle Millennium Platform APIs