Skip to main content
Glama
sarathi-aiml

clinical-mcp

by sarathi-aiml

clinical-mcp

An MCP server for clinical workflows: search and summarize synthetic FHIR R4 patient records, pull literature from PubMed, and de-identify free text — all from Claude (or any MCP client).

Built as a reference-quality MCP server: it implements the full spec surface (tools, resources, and prompts — most public servers stop at tools), ships with a test suite that exercises the wire protocol, and runs over stdio or authenticated streamable HTTP.

All patient data is synthetic, generated by Synthea. No real PHI exists anywhere in this project.

Architecture

[Claude / MCP client]
        |  stdio  or  streamable-http (+ bearer auth)
        v
[clinical-mcp  (MCPServer)]
   |-- tools ------ search_patients, get_patient_summary, get_observations,
   |                search_pubmed, get_pubmed_abstract, deidentify_text
   |-- resources -- fhir://patients            (roster)
   |                fhir://patients/{id}       (full record, URI template)
   |-- prompts ---- clinical_summary, literature_review
   |
   +-- FhirStore ----------- in-memory index over Synthea FHIR R4 bundles
   +-- PubMedClient -------- NCBI E-utilities, rate-limited (3/s, 10/s w/ key)
   +-- deidentify() -------- HIPAA Safe Harbor regex redaction

Quick start

pip install clinical-mcp

Claude Desktop / Claude Code config (mcpServers entry):

{
  "clinical": {
    "command": "clinical-mcp",
    "env": { "CLINICAL_MCP_DATA_DIR": "/path/to/fhir/bundles" }
  }
}

From source:

git clone https://github.com/sarathi-aiml/clinical-mcp
cd clinical-mcp
pip install -e ".[dev]"
clinical-mcp                       # stdio, serves the bundled 10-patient sample
pytest                             # 33 tests, no network needed

Then ask Claude things like:

"Find female patients over 50 with hypertension, summarize the first one, and pull the three most recent PubMed papers relevant to her medication list."

Tools

Tool

What it does

search_patients

Filter the roster by name, gender, age range, or diagnosed condition

get_patient_summary

Demographics + conditions, medications, allergies, immunizations

get_observations

Labs and vitals, filterable by FHIR category, name, and date

search_pubmed

PubMed search via NCBI E-utilities (supports field tags like [MeSH])

get_pubmed_abstract

Full abstract for a PMID, section labels preserved

deidentify_text

Safe Harbor redaction: names, dates, SSN/MRN, phone, email, ZIP, ages > 89

Resources expose the same data addressably (fhir://patients/{id}), so clients can attach a full patient record as context without a tool round-trip. Prompts encode the two workflows I use most — chart summarization and patient-grounded literature review — as reusable templates.

HTTP transport with auth

CLINICAL_MCP_API_KEY=$(openssl rand -hex 32) clinical-mcp --transport http --port 8000

Every request must carry Authorization: Bearer <key>; the server refuses to start unauthenticated on HTTP. stdio (the default) needs no key — the transport is the trust boundary.

Data

The repo ships 10 trimmed synthetic patients under data/sample/. For a bigger corpus:

python scripts/fetch_data.py --out data/full            # ~1,100 patients
CLINICAL_MCP_DATA_DIR=data/full clinical-mcp

--trim strips bundles to the resource types the server actually reads (Patient, Condition, MedicationRequest, Observation, AllergyIntolerance, Encounter, Immunization, Procedure, DiagnosticReport, CarePlan) and caps high-volume types.

De-identification: scope and limits

deidentify_text is regex-based Safe Harbor screening: it catches the identifier formats that appear in structured clinical text and additionally redacts every patient name loaded in the store. It is not a certified de-identification pipeline — free-text names without honorifics, misspellings, and rare-context identifiers will get through. For real PHI you want a trained NER pass (e.g. Philter, or an LLM pass with human review) layered on top; this tool is the deterministic first filter, and its per-category counts make audits cheap.

What breaks at 500K documents a week

This server is deliberately sized for its job — a reference implementation over a synthetic corpus. Here is what fails first under production load, and the upgrade path for each:

  1. The in-memory store. Everything loads into RAM at startup; ~10K patients is comfortable, ~100K is not, and startup time grows linearly. First fix: SQLite/DuckDB with indexes on name, birth date, and condition codes behind the same FhirStore interface. Real fix: point the store at an actual FHIR endpoint (HAPI, or a cloud FHIR API) and make the tools thin translation layers over FHIR search parameters.

  2. One patient per bundle. The loader assumes Synthea's layout. Mixed bundles need reference resolution (subject.reference) instead of file-level grouping.

  3. PubMed rate limits. 3 req/s (10 with a key) is fine interactively and useless in batch. At volume you need a local cache keyed by query hash with a TTL, and batch efetch (up to 200 PMIDs per request) instead of per-article calls.

  4. Regex de-identification recall. At 500K documents/week even 99% recall leaks thousands of identifiers. The counts output is designed for exactly this measurement: sample, audit, and gate on measured recall — then put a NER model in the pipeline.

  5. Single-process HTTP. Streamable HTTP under uvicorn on one process serves a team, not a fleet. Horizontal scale needs stateless sessions (the store is read-only, so this is mostly free) behind a load balancer, and per-client rate limiting at the gateway.

Development

pip install -e ".[dev]"
pytest              # protocol-level + unit tests, PubMed mocked
ruff check .

Docker:

docker build -t clinical-mcp .
docker run --rm -i clinical-mcp                                   # stdio
docker run --rm -p 8000:8000 -e CLINICAL_MCP_API_KEY=secret \
  clinical-mcp --transport http --host 0.0.0.0

License

MIT

-
license - not tested
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • MCP Hub: AI service discovery, per-user OAuth, and multi-service workflow orchestration

  • Hosted MCP server exposing US hospital procedure cost data to AI assistants

  • Auditable MCP server for PubMed, Europe PMC, ClinicalTrials.gov, and bioRxiv/medRxiv queries

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sarathi-aiml/clinical-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server