sharp-on-fhir-mcp
A clean-room SHARP-on-MCP compliant FHIR R4 MCP server that enables AI agents to interact with any FHIR R4 endpoint using SHARP context headers, without server-side OAuth. It provides clinical tools, lab results, imaging, and interactive MCP-UI dashboards.
README
Featherless
<img width="2124" height="1344" alt="image (4)" src="https://github.com/user-attachments/assets/55dc0b64-8ba3-4c69-b193-59c60287068d" />
A clean-room SHARP-on-MCP compliant FHIR R4 MCP server with interactive MCP-UI clinical dashboards.
Built for the Prompt Opinion "Build the Future of Healthcare AI" Hackathon โ a vendor-neutral MCP server that any SMART-on-FHIR app, agent, or LLM host can
plug into without server-side OAuth, API keys, or proprietary auth flows.
Why SHARP?
The SHARP (Standardised Healthcare Agent Remote Protocol) spec describes a headers-based context model for MCP servers in healthcare:
| Header | Purpose |
|---|---|
X-FHIR-Server-URL |
Base URL of the patient's FHIR R4 endpoint |
X-FHIR-Access-Token |
Bearer token already minted by the agent host |
X-Patient-ID |
Optional default Patient resource id |
Per SHARP ยง3.2, the MCP server never runs an OAuth dance itself. The agent host (e.g. a SMART-on-FHIR launch container) obtains the token and forwards it on every call. This means a single deployment of this server works against Epic, Cerner, MEDITECH, athenahealth, eClinicalWorks, ConnectEHR, HAPI, or any other FHIR R4 endpoint โ there's nothing vendor-specific.
The server advertises capabilities.experimental.fhir_context_required = true
on every initialise response so SHARP-aware clients know to forward those
headers automatically.
What's included
๐ฉบ Clinical FHIR tools
fhir_get_capability_statementโ discover the connected FHIR serverfhir_get_patient,fhir_search,fhir_read,fhir_patient_everythingโ generic R4 accessclinical_search_patients,clinical_get_patient_summaryclinical_get_appointments,clinical_get_encountersclinical_get_problems,clinical_get_medications,clinical_get_allergies,clinical_get_immunizationsclinical_get_health_recordโ one-shot consolidated recordclinical_get_contextโ full visit context (demographics + allergies + meds + problems + labs + vitals + encounters + alerts) in parallel
๐ฌ Labs, vitals & imaging
lab_get_results,lab_get_vital_signs,lab_get_diagnostic_reportsimaging_get_documentsโ DocumentReference search
๐ง Optional persistent clinical memory (mem0)
Backed by mem0 (Apache-2.0). mem0 is
embedded as a Python library โ no separate service or database. Memory
state persists in a Docker volume (mem0_data).
mem0 is text-only at the storage layer, but is well-suited to clinical
narrative use (encounters, alerts, notes, transcripts). For non-text
inputs (radiology films, audio dictation, video clips), the agent host
should pre-process โ caption images via a VLM, transcribe audio with
Whisper, summarise video โ and persist the resulting text via
memory_store_note. This keeps memory cleanly searchable and lets each
host pick the right model per modality.
Available when OPENAI_API_KEY (or OPENAI_API_BASE for an OpenAI-compat
provider) is set, and MEM0_DISABLED is not 1:
memory_store_encounterโ visit summary with diagnoses, plan, complaintmemory_store_alertโ persistent clinical flag (allergy, drug interaction, โฆ)memory_store_noteโ free-text note (use for VLM/Whisper outputs)memory_search_historyโ semantic search scoped to current patientmemory_get_patient_historyโ list memories for the patientmemory_deleteโ remove a single memory by idmemory_reset_patientโ wipe all memories for one patient (irreversible)
๐ MCP-UI visualisations
visualize_lab_trendโ Chart.js line chart of one lab over timevisualize_vitalsโ multi-chart vitals dashboardvisualize_patient_dashboardโ full HTML clinical page (demographics, alerts, allergies, meds, problems, labs, encounters, immunisations + Chart.js trends)
All visual tools return MCP-UI ui:// resources that the host renders in its inspector pane.
Quickstart
1. Install
git clone https://github.com/your-org/sharp-fhir-mcp.git
cd sharp-fhir-mcp
pip install -e .
2. Run the server
sharp-fhir-mcp # http (streamable) on 0.0.0.0:8000
sharp-fhir-mcp --port 9000 # custom port
SHARP_STRICT_CONTEXT=1 sharp-fhir-mcp # reject calls missing FHIR headers
The MCP endpoint is http://localhost:8000/mcp.
For the full stack (FHIR MCP server + embedded mem0 memory) use the
one-shot bring-up script โ it handles the broken-docker-symlink case
(common after migrating off OrbStack), seeds .env if missing, optionally
prunes build cache, and starts the stack detached:
./scripts/start.sh # build + start, detached
./scripts/start.sh --no-memory # disable mem0 (memory_* tools omitted)
./scripts/start.sh --logs # follow logs after start
./scripts/start.sh --prune --build # free disk + rebuild from scratch
./scripts/start.sh --down # tear down + remove memory volume
Or run compose directly:
cp .env.example .env # set OPENAI_API_KEY (or OPENAI_API_BASE)
docker compose up --build -d
Note:
localhosthere refers to localhost of the machine where you are running the server. To access it remotely, deploy the server (see below) or port-forward to your local instance.
3. Connect from any SHARP-aware MCP client
Send these headers on every JSON-RPC request:
X-FHIR-Server-URL: https://hapi.fhir.org/baseR4
X-FHIR-Access-Token: <bearer token from your SMART launch>
X-Patient-ID: 12345 # optional
4. Try a public sandbox without writing a SMART app
The HAPI public FHIR R4 sandbox is read-only and does not require auth โ useful for kicking the tires:
curl -X POST http://localhost:8000/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'X-FHIR-Server-URL: https://hapi.fhir.org/baseR4' \
-H 'X-FHIR-Access-Token: anonymous' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Deployment
Vercel (Python serverless)
This server runs as a stateless Streamable-HTTP endpoint, which works on Vercel out of the box. You can re-use an existing Next.js MCP scaffold by either:
-
Adding the Python ASGI handler โ drop the
appStarlette instance intoapi/index.py:# api/index.py from sharp_fhir_mcp.server import app # noqa: F401plus a minimal
vercel.json:{ "builds": [{"src": "api/index.py", "use": "@vercel/python"}], "routes": [{"src": "/(.*)", "dest": "api/index.py"}] } -
Or running it as a sidecar behind your existing Vercel front-end and reverse-proxying
/mcpto a longer-lived host (Fly.io, Railway, Render).
The server respects the Vercel-injected PORT environment variable.
Local development
cp .env.example .env # set FHIR_SERVER_URL etc. for fallbacks
sharp-fhir-mcp # http://localhost:8000/mcp
Docker / docker-compose
A single-service stack: the FHIR MCP server runs in one container and embeds mem0 as a library.
cp .env.example .env
# Set OPENAI_API_KEY (or OPENAI_API_BASE for an OpenAI-compat provider:
# OpenRouter, Ollama OpenAI-mode, vLLM, LM Studio, Together).
docker compose up --build
- MCP endpoint:
http://localhost:8000/mcp - Persistent memory volume:
mem0_data(mounted at/datain container)
Local LLM + embeddings (no OpenAI calls)
Point both the LLM and embedder at a local Ollama:
OPENAI_API_BASE=http://host.docker.internal:11434/v1
MEM0_LLM_PROVIDER=ollama
MEM0_LLM_MODEL=llama3.1
MEM0_EMBED_PROVIDER=ollama
MEM0_EMBED_MODEL=nomic-embed-text
Disabling memory
Pass MEM0_DISABLED=1 (or ./scripts/start.sh --no-memory) to skip mem0
entirely. The FHIR/clinical/lab/visualisation tools still work; only the
memory_* tools are omitted.
Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MCP Client / Agent / LLM host (Claude, Cursor, custom) โ
โ โข Knows the patient's FHIR endpoint + access token โ
โ โข Sends X-FHIR-Server-URL, X-FHIR-Access-Token headers โ
โโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Streamable HTTP (SHARP-on-MCP)
POST /mcp + JSON-RPC + SHARP headers
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ featherless-mcp <img width="2124" height="1344" alt="image (10)" src="https://github.com/user-attachments/assets/81e48473-20b9-41ac-a485-8e1116bb7ffc" />
โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ SharpContextMiddleware โ โ
โ โ โข Parses X-FHIR-Server-URL / X-FHIR-Access-Token โ โ
โ โ โข Stores in ContextVar for the request scope โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ FastMCP tool registry โ โ
โ โ โโ fhir_* (generic R4 search/read) โ โ
โ โ โโ clinical_* (patient/encounter/medication/โฆ) โ โ
โ โ โโ lab_* / imaging_*(observations, reports, docs) โ โ
โ โ โโ memory_* (optional, embedded mem0) โ โ
โ โ โโ visualize_* (MCP-UI Chart.js dashboards) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Vendor-neutral FHIR R4 client (httpx, async) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ
FHIR R4 server (Epic / Cerner / HAPI / โฆ)
See CLAUDE.md for detailed module-by-module notes and the
SHARP compliance check-list.
SHARP compliance check-list
| Requirement | Status |
|---|---|
| Streamable-HTTP transport (stdio not in scope) | โ |
Read FHIR endpoint from X-FHIR-Server-URL header |
โ |
Read bearer token from X-FHIR-Access-Token header |
โ |
Optional X-Patient-ID header for default patient context |
โ |
Advertise capabilities.experimental.fhir_context_required |
โ |
| No server-side OAuth / token storage | โ |
| Vendor-neutral FHIR R4 client | โ |
Structured fhir_context_required errors when headers absent |
โ |
Optional strict context enforcement (SHARP_STRICT_CONTEXT=1) |
โ |
License
MIT โ see LICENSE.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.