sharp-fhir-mcp
A clean-room SHARP-on-MCP compliant FHIR R4MCP server with interactive MCP-UI clinical dashboards.
Built for the Prompt Opinion "Build the Future of Healthcare AI" Hackathon โ avendor-neutral MCP server that any SMART-on-FHIR app, agent, or LLM host canplug into without server-side OAuth, API keys, or proprietary auth flows.
Why SHARP?
The SHARP (Standardised HealthcareAgent Remote Protocol) spec describes a headers-based context model for MCPservers 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 agenthost (e.g. a SMART-on-FHIR launch container) obtains the token and forwards iton every call. This means a single deployment of this server works againstEpic, Cerner, MEDITECH, athenahealth, eClinicalWorks, ConnectEHR, HAPI, orany other FHIR R4 endpoint โ there's nothing vendor-specific.
The server advertises capabilities.experimental.fhir_context_required = trueon every initialise response so SHARP-aware clients know to forward thoseheaders 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 memory (SimpleMem)
When SIMPLEMEM_API_URL and SIMPLEMEM_ACCESS_TOKEN are set:
memory_store_encounterโ save a visit summarymemory_store_alertโ flag clinical concerns for next visitmemory_search_historyโ semantic search across past encountersmemory_get_patient_historyโ list all stored memories for the current patient
๐ 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 # streamable-http on 0.0.0.0:8000
sharp-fhir-mcp --port 9000 # custom port
sharp-fhir-mcp --strict-context # 403 on non-handshake without FHIR headers
The MCP endpoint is http://localhost:8000/mcp.
Note:
localhosthere refers to localhost of the machine where you arerunning the server. To access it remotely, deploy the server (see below) orport-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 onVercel out of the box. You can re-use an existingNext.js MCP scaffoldby either:
Adding the Python ASGI handler โ drop the
appStarlette instanceintoapi/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 andreverse-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 (optional)
FROM python:3.12-slim
WORKDIR /app
COPY . .
RUN pip install -e .
EXPOSE 8000
CMD ["sharp-fhir-mcp", "--host", "0.0.0.0", "--port", "8000"]
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
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ sharp-fhir-mcp โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 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 SimpleMem) โ โ
โ โ โโ 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 theSHARP 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 403 enforcement (--strict-context) |
โ |
License
MIT โ see LICENSE.