by wso2
Expose any FHIR Server or API as a Model Context Protocol (MCP) server, enabling seamless integration with AI/LLM tools and healthcare applications.
FHIR MCP Server provides a bridge between standard FHIR APIs and the Model Context Protocol, allowing developers and AI tools to query, read, create, update, and delete clinical resources using MCP transports (stdio, SSE, or streamable HTTP). It abstracts authentication, response filtering, and transport details so that downstream tools can focus on the clinical data they need.
Installation
uvx fhir-mcp-serveruv pip sync requirements.txt, then run uv run fhir-mcp-server.wso2/fhir-mcp-server:latest or build locally, then start with docker run --env-file .env -p 8000:8000 fhir-mcp-server.docker-compose.yml to spin up both a HAPI FHIR server and the MCP server together.Configuration
FHIR_SERVER_BASE_URL (required). Optional variables include FHIR_SERVER_CLIENT_ID, FHIR_SERVER_CLIENT_SECRET, FHIR_SERVER_SCOPES, FHIR_SERVER_DISABLE_AUTHORIZATION, FHIR_MCP_HOST, FHIR_MCP_PORT, etc.--transport flag (stdio, sse, streamable-http). Default is streamable-http.--log-level.Running
uv run fhir-mcp-server --transport streamable-http --log-level DEBUG
Clients (VS Code, Claude Desktop, MCP Inspector) can connect using the appropriate URL (http://localhost:8000/mcp for HTTP, /sse for SSE, or stdio command).
search, read, create, update, delete, get_capabilities, get_user).search or read tools to obtain specific clinical facts.Q: Which FHIR servers are supported? A: Any server that implements the FHIR REST API, including public HAPI servers, Epic sandbox, or self‑hosted installations.
Q: How do I disable authentication?
A: Set the environment variable FHIR_SERVER_DISABLE_AUTHORIZATION=True before starting the server.
Q: What transport should I choose?
A: Use streamable-http for typical HTTP client libraries, sse for event‑driven clients, or stdio when embedding the server in a CLI pipeline.
Q: Can I run the server without Docker?
A: Yes, the PyPI package runs directly with Python 3.8+ and uvx or a virtual environment.
Q: How are response sizes reduced?
A: Provide response_filter_fhirpaths in tool calls; the server applies the FHIRPath expressions and returns only the selected elements.
Q: Where are the tool definitions documented?
A: The README lists each tool (search, read, create, update, delete, get_capabilities, get_user) with required and optional parameters.
The FHIR MCP Server is a Model Context Protocol (MCP) server that provides seamless integration with FHIR APIs. Designed for developers, integrators, and healthcare innovators, this server acts as a bridge between modern AI/LLM tools and healthcare data, making it easy to search, retrieve, and analyze clinical information.
This video showcases the MCP server's functionality when connected to a public HAPI FHIR server. This example showcases direct interaction with an open FHIR server that does not require an authorization flow.
https://github.com/user-attachments/assets/cc6ac87e-8329-4da4-a090-2d76564a3abf
This video showcases the MCP server's capabilities within the Epic EHR ecosystem. It demonstrates the complete OAuth 2.0 Authorization Code Grant flow.
https://github.com/user-attachments/assets/96b433f1-3e53-4564-8466-65ab48d521de
MCP-compatible transport: Serves FHIR via stdio, SSE, or streamable HTTP
SMART-on-FHIR based authentication support: Securely authenticate with FHIR servers and clients
Response Filtering using FHIRPath: Filter resources and bundles returned by read and search operations using custom FHIRPath expressions to retrieve only the fields needed for the task, reducing payload sizes.
Tool integration: Integratable with any MCP client such as VS Code, Claude Desktop, and MCP Inspector
You can use the FHIR MCP Server by installing our Python package, or by cloning this repository.
Configure Environment Variables:
To run the server, you must set FHIR_SERVER_BASE_URL.
FHIR_SERVER_BASE_URL, FHIR_SERVER_CLIENT_ID, FHIR_SERVER_CLIENT_SECRET, and FHIR_SERVER_SCOPES. Authorization is enabled by default.FHIR_SERVER_DISABLE_AUTHORIZATION to True.By default, the MCP server runs on http://localhost:8000, and you can customize the host and port using FHIR_MCP_HOST and FHIR_MCP_PORT.
You can set these by exporting them as environment variables like below or by creating a .env file (referencing .env.example).
export FHIR_SERVER_BASE_URL=""
export FHIR_SERVER_CLIENT_ID=""
export FHIR_SERVER_CLIENT_SECRET=""
export FHIR_SERVER_SCOPES=""
export FHIR_MCP_HOST="localhost"
export FHIR_MCP_PORT="8000"
Install the PyPI package and run the server
uvx fhir-mcp-server
Clone the repository:
git clone <repository_url>
cd <repository_directory>
Create a virtual environment and install dependencies:
uv venv
source .venv/bin/activate
uv pip sync requirements.txt
Or with pip:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Configure Environment Variables: Copy the example file and customize if needed:
cp .env.example .env
Run the server:
uv run fhir-mcp-server
You can run the MCP server using Docker for a consistent, isolated environment.
Note on Authorization: When running the MCP server locally via Docker or Docker Compose, authorization should be disabled by setting the environment variable,
FHIR_SERVER_DISABLE_AUTHORIZATION=True. This would be fixed in the future releases.
Build the Docker Image or pull the docker image from the container registry:
docker build -t fhir-mcp-server .
docker pull wso2/fhir-mcp-server:latest
Configure Environment Variables
Copy the example environment file and edit as needed:
cp .env.example .env
# Edit .env to set your FHIR server, client credentials, etc.
Alternatively, you can pass environment variables directly with -e flags or use Docker secrets for sensitive values. See the Configuration section for details on available environment variables.
Run the Container
docker run --env-file .env -p 8000:8000 fhir-mcp-server
This will start the server and expose it on port 8000. Adjust the port mapping as needed.
For a quick setup that includes both the FHIR MCP server and a HAPI FHIR server (with PostgreSQL), use the provided docker-compose.yml. This sets up an instant development environment for testing FHIR operations.
Prerequisites:
Run the Stack:
docker-compose up -d
This command will:
FHIR_SERVER_BASE_URL set to http://hapi-r4-postgresql:8080/fhir.Access the Services:
docker-compose down.Configure Additional Environment Variables:
If you need to customize OAuth or other settings, adjust the env variables in the docker-compose.yml. The compose file sets basic configuration; refer to the Configuration section for full options.
The FHIR MCP Server is designed for seamless integration with various MCP clients.
Add the following JSON block to your MCP configuration file in VS Code (> V1.104). You can do this by pressing Ctrl + Shift + P and typing MCP: Open User Configuration.
"servers": {
"fhir": {
"type": "http",
"url": "http://localhost:8000/mcp",
}
}
"servers": {
"fhir": {
"command": "uv",
"args": [
"--directory",
"/path/to/fhir-mcp-server",
"run",
"fhir-mcp-server",
"--transport",
"stdio"
],
"env": {
"FHIR_SERVER_ACCESS_TOKEN": "Your FHIR Access Token"
}
}
}
"servers": {
"fhir": {
"type": "sse",
"url": "http://localhost:8000/sse",
}
}
Add the following JSON block to your Claude Desktop settings to connect to your local MCP server.
{
"mcpServers": {
"fhir": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://localhost:8000/mcp"
]
}
}
}
{
"mcpServers": {
"fhir": {
"command": "uv",
"args": [
"--directory",
"/path/to/fhir-mcp-server",
"run",
"fhir-mcp-server",
"--transport",
"stdio"
],
"env": {
"FHIR_SERVER_ACCESS_TOKEN": "Your FHIR Access Token"
}
}
}
}
{
"mcpServers": {
"fhir": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://localhost:8000/sse"
]
}
}
}
Follow these steps to get the MCP Inspector up and running:
Open a terminal and run the following command:
npx -y @modelcontextprotocol/inspector
In the MCP Inspector interface:
Streamable HTTPhttp://localhost:8000/mcpSTDIOuv--directory /path/to/fhir-mcp-server run fhir-mcp-server --transport stdioSSEhttp://localhost:8000/sseMake sure your MCP server is already running and listening on the above endpoint.
Once connected, MCP Inspector will allow you to visualize tool invocations, inspect request/response payloads, and debug your tool implementations easily.
You can customize the behavior of the MCP server using the following command-line flags:
--transport
--log-level
--help
Sample Usages:
uv run fhir-mcp-server --transport streamable-http --log-level DEBUG
uv run fhir-mcp-server --help
MCP Server Configurations:
FHIR_MCP_HOST: The hostname or IP address the MCP server should bind to (e.g., localhost for local-only access, or 0.0.0.0 for all interfaces).FHIR_MCP_PORT: The port on which the MCP server will listen for incoming client requests (e.g., 8000).FHIR_MCP_SERVER_URL: If set, this value will be used as the server's base URL instead of generating it from host and port. Useful for custom URL configurations or when behind a proxy.FHIR_MCP_REQUEST_TIMEOUT: Timeout duration in seconds for requests from the MCP server to the FHIR server (default: 30).MCP Server OAuth2 with FHIR server Configuration (MCP Client ↔ MCP Server): These variables configure the MCP client's secure connection to the MCP server, using the OAuth2 authorization code grant flow with a FHIR server.
FHIR_SERVER_CLIENT_ID: The OAuth2 client ID used to authorize MCP clients with the FHIR server.FHIR_SERVER_DISABLE_AUTHORIZATION: If set to True, disables authorization checks on the MCP server, allowing connections to publicly accessible FHIR servers.FHIR_SERVER_CLIENT_SECRET: The client secret corresponding to the FHIR client ID. Used during token exchange.FHIR_SERVER_BASE_URL: The base URL of the FHIR server (e.g., https://hapi.fhir.org/baseR4). This is used to generate tool URIs and to route FHIR requests.FHIR_SERVER_SCOPES: A space-separated list of OAuth2 scopes to request from the FHIR authorization server (e.g., user/Patient.read user/Observation.read). Add fhirUser openid to enable retrieval of user context for the get_user tool. If these two scopes are not configured, the get_user tool returns an empty result because the ID token lacks the user's FHIR resource reference.FHIR_SERVER_ACCESS_TOKEN: The access token to use for authenticating requests to the FHIR server. If this variable is set, the server will bypass the OAuth2 authorization flow and use this token directly for all requests.get_capabilities: Retrieves metadata about a specified FHIR resource type, including its supported search parameters and custom operations.
type: The FHIR resource type name (e.g., "Patient", "Observation", "Encounter")search: Executes a standard FHIR search interaction on a given resource type, returning a bundle or list of matching resources.
type: The FHIR resource type name (e.g., "MedicationRequest", "Condition", "Procedure").searchParam: A mapping of FHIR search parameter names to their desired values (e.g., {"family":"Simpson","birthdate":"1956-05-12"}).response_filter_fhirpaths: (Optional) An array of FHIRPath expressions (e.g., ["Patient.name", "Patient.birthDate", "Bundle.link.where(relation='next').url"]) to apply to the resources in the response bundle.read: Performs a FHIR "read" interaction to retrieve a single resource instance by its type and resource ID, optionally refining the response with search parameters or custom operations.
type: The FHIR resource type name (e.g., "DiagnosticReport", "AllergyIntolerance", "Immunization").id: The logical ID of a specific FHIR resource instance.searchParam: A mapping of FHIR search parameter names to their desired values (e.g., {"device-name":"glucometer"}).operation: The name of a custom FHIR operation or extended query defined for the resource (e.g., "$everything").response_filter_fhirpaths: (Optional) An array of FHIRPath expressions (e.g., ["Patient.name", "Observation.valueQuantity"]) to filter the returned single resource (or entries when using custom operations like $everything).create: Executes a FHIR "create" interaction to persist a new resource of the specified type.
type: The FHIR resource type name (e.g., "Device", "CarePlan", "Goal").payload: A JSON object representing the full FHIR resource body to be created.searchParam: A mapping of FHIR search parameter names to their desired values (e.g., {"address-city":"Boston"}).operation: The name of a custom FHIR operation or extended query defined for the resource (e.g., "$evaluate").update: Performs a FHIR "update" interaction by replacing an existing resource instance's content with the provided payload.
type: The FHIR resource type name (e.g., "Location", "Organization", "Coverage").id: The logical ID of a specific FHIR resource instance.payload: The complete JSON representation of the FHIR resource, containing all required elements and any optional data.searchParam: A mapping of FHIR search parameter names to their desired values (e.g., {"patient":"Patient/54321","relationship":"father"}).operation: The name of a custom FHIR operation or extended query defined for the resource (e.g., "$lastn").delete: Execute a FHIR "delete" interaction on a specific resource instance.
type: The FHIR resource type name (e.g., "ServiceRequest", "Appointment", "HealthcareService").id: The logical ID of a specific FHIR resource instance.searchParam: A mapping of FHIR search parameter names to their desired values (e.g., {"category":"laboratory","issued:"2025-05-01"}).operation: The name of a custom FHIR operation or extended query defined for the resource (e.g., "$expand").get_user: Retrieves the currently authenticated user's FHIR resource (for example the linked Patient resource) and returns a concise profile containing available demographic fields such as id, name, and birthDate.
To run tests and contribute to development, install the test dependencies:
Using pip:
# Install project in development mode with test dependencies
pip install -e '.[test]'
# Or install from requirements file
pip install -r requirements-dev.txt
Using uv:
# Install development dependencies
uv sync --dev
The project includes a comprehensive test suite covering all major functionality:
# Simple test runner
python run_tests.py
# Or direct pytest usage
PYTHONPATH=src python -m pytest tests/ -v --cov=src/fhir_mcp_server
Using pytest:
pytest tests/
This will discover and run all tests in the tests/ directory.
Test Features:
The test suite includes:
Coverage reports are generated in htmlcov/index.html for detailed analysis.
Please log in to share your review and rating for this MCP.
Explore related MCPs that share similar capabilities and solve comparable challenges
by modelcontextprotocol
A Model Context Protocol server for Git repository interaction and automation.
by zed-industries
A high‑performance, multiplayer code editor designed for speed and collaboration.
by modelcontextprotocol
Model Context Protocol Servers
by modelcontextprotocol
A Model Context Protocol server that provides time and timezone conversion capabilities.
by cline
An autonomous coding assistant that can create and edit files, execute terminal commands, and interact with a browser directly from your IDE, operating step‑by‑step with explicit user permission.
by upstash
Provides up-to-date, version‑specific library documentation and code examples directly inside LLM prompts, eliminating outdated information and hallucinated APIs.
by daytonaio
Provides a secure, elastic infrastructure that creates isolated sandboxes for running AI‑generated code with sub‑90 ms startup, unlimited persistence, and OCI/Docker compatibility.
by continuedev
Enables faster shipping of code by integrating continuous AI agents across IDEs, terminals, and CI pipelines, offering chat, edit, autocomplete, and customizable agent workflows.
by github
Connects AI tools directly to GitHub, enabling natural‑language interactions for repository browsing, issue and pull‑request management, CI/CD monitoring, code‑security analysis, and team collaboration.