get_capabilitiesLABSCO SUMMARY
Full read and write against FHIR, with a filter that keeps bundles readable.
Most FHIR integrations stall on the same two things: the payloads are enormous and the authorization dance is specific to each vendor. This one answers both — FHIRPath expressions travel with the request so a search can return two fields instead of a bundle, and the SMART-on-FHIR path is demonstrated end to end against the Epic sandbox rather than described. Note that create, update and delete are in the tool list: the scopes you grant are what decides whether an assistant can write to a chart, so scope the client narrowly before you point it at anything real.
What it is
An MCP server from WSO2 that sits between an assistant and a FHIR API server. It speaks stdio, SSE or streamable HTTP, authenticates against the FHIR server using SMART-on-FHIR, and covers the standard interactions — capability discovery, search, read, create, update and delete — for any resource type the server supports. The README demonstrates it against both a public HAPI FHIR server with no authorization and the Epic sandbox with the full OAuth 2.0 authorization code flow.
What you get
get_capabilities— what a resource type supports: its search parameters and custom operationssearch— a standard FHIR search on a resource type, returning the matching bundleread— one resource instance by type and id, optionally narrowed with search parameters or a custom operation such as$everythingcreate— persist a new resource from a JSON payloadupdate— replace an existing instance's content with a complete payloaddelete— remove a specific resource instanceget_user— the authenticated user's own FHIR resource, returned as a short profile with fields such asid,nameandbirthDate- Response filtering with FHIRPath:
searchandreadacceptresponse_filter_fhirpaths, so a request can come back asPatient.nameandPatient.birthDateinstead of whole resources
Requirements
Python 3.8+, uv, and a reachable FHIR API server. FHIR_SERVER_BASE_URL is the one variable you must set. Authorization is on by default and expects FHIR_SERVER_CLIENT_ID, FHIR_SERVER_CLIENT_SECRET and FHIR_SERVER_SCOPES; against a public server such as HAPI you instead set FHIR_SERVER_DISABLE_AUTHORIZATION to True, which is also what the README asks for when running locally through Docker or Docker Compose. FHIR_SERVER_ACCESS_TOKEN bypasses the OAuth flow with a token you already hold — the README limits that to local stdio use and warns against it once the server is reachable over a network. Transport defaults to streamable-http on FHIR_MCP_HOST and FHIR_MCP_PORT, out of the box localhost and 8000, and --transport switches to stdio or sse. Package fhir-mcp-server (0.10.0) on PyPI, run with uvx, from source, or as a container. Apache 2.0.
Setup effort
One command plus credentials — uvx fhir-mcp-server, then supply credentials
USE CASES
Answering a clinical question over a live FHIR server
Search the resource type, then pull the one instance that matters — filtered down to the handful of fields the question needs.
Finding out what a FHIR server actually supports
Ask for a resource type's capabilities and get its search parameters and custom operations back, instead of guessing from the spec.
Pulling a whole patient record in one call
Run read with the $everything operation and a FHIRPath list, so the compilation comes back trimmed rather than as a full bundle.
Prototyping against a sandbox before touching production data
Point the base URL at a public HAPI server with authorization disabled, then switch to the Epic sandbox with client id, secret and scopes when the flow works.
Getting the signed-in user's own record
Add fhirUser openid to the requested scopes — without them the id token carries no reference to the user's FHIR resource and this returns an empty result.
7 tools
Listed in project docs. Your client may show a different list.
searchreadcreateupdatedeleteget_userBEFORE YOU INSTALL
What to know first
Tools you get
7 tools named in the project's documentation.
Requires
- uvx on PATH
- Python 3.8+
- A reachable FHIR API server
- FHIR_SERVER_BASE_URL in your environment
- FHIR_SERVER_CLIENT_ID, FHIR_SERVER_CLIENT_SECRET and FHIR_SERVER_SCOPES in your environment — authorization is on by default; for a public FHIR server set FHIR_SERVER_DISABLE_AUTHORIZATION=True instead
INSTALLATION
Connect your client
Server setup
uvx fhir-mcp-serverMCP Clients
VS Code
{
"servers": {
"fhir": {
"type": "http",
"url": "http://localhost:8000/mcp"
}
}
}This connects to a server you start yourself: run uvx fhir-mcp-server with FHIR_SERVER_BASE_URL and the authorization variables set; it listens on http://localhost:8000.
The configurations on this page connect to a server you start yourself, so they do not set FHIR_SERVER_BASE_URL, FHIR_SERVER_CLIENT_ID, FHIR_SERVER_CLIENT_SECRET or FHIR_SERVER_SCOPES: the project documents supplying them with export lines or a .env file before running uvx fhir-mcp-server.
Claude Desktop
Set FHIR_SERVER_BASE_URL and the authorization variables under Requirements (export them, or put them in a .env file), then start the server — it listens on http://localhost:8000:
uvx fhir-mcp-serverThen add this to claude_desktop_config.json; it reaches the running server through mcp-remote:
{
"mcpServers": {
"fhir": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://localhost:8000/mcp"
]
}
}
}The configurations on this page connect to a server you start yourself, so they do not set FHIR_SERVER_BASE_URL, FHIR_SERVER_CLIENT_ID, FHIR_SERVER_CLIENT_SECRET or FHIR_SERVER_SCOPES: the project documents supplying them with export lines or a .env file before running uvx fhir-mcp-server.
MCP Inspector
npx -y @modelcontextprotocol/inspectorThe configurations on this page connect to a server you start yourself, so they do not set FHIR_SERVER_BASE_URL, FHIR_SERVER_CLIENT_ID, FHIR_SERVER_CLIENT_SECRET or FHIR_SERVER_SCOPES: the project documents supplying them with export lines or a .env file before running uvx fhir-mcp-server.