Medical reasoning API for AI agents. Converts clinical input into structured risk signals.
Website: https://medmcp.vercel.app
npm install @medmcp/sdkRun locally before a release or large change:
# Core build + analyze tests (risk-mapper unit + symptom-engine contract w/ seeded DB)
npm ci && npm run build && npm run test:analyze
# TypeScript SDK
cd sdk && npm ci && npm test
# Python SDK
cd sdk-python && python -m unittest discover -s tests -p "test_*.py"CI runs the same checks on push and pull requests to main (see .github/workflows/ci.yml).
Medical content (src/data/seed-*, symptom rules in src/analyze/, clinical MCP tooling): required review workflow and checklist — docs/medical-review.md. Risk heuristic policy (symptom tiers): docs/risk-classification-draft.md (mirror of risk-mapper intent; PRs that change rules still need medical: approved).
Usage policy — EN (canonical): docs/policy.md. HR summary (landing copy): docs/policy-hr.md. Playbook za Lovable / footer: docs/landing-lovable.md.
Data / logging / GDPR (developer summary): docs/gdpr.md.
Release notes: see CHANGELOG.md. Before a tagged release, update that file and bump version in the root package.json (and SDK package versions when you publish them).
Agent / HTTP clients: every /v1/* response includes X-MedMCP-Schema-Version, X-MedMCP-Release, and optional X-MedMCP-Git-Revision / X-MedMCP-Data-Revision (see GET /v1/schema → agent_tooling). CORS exposes these headers to browsers.
MedMCP is the deterministic medical reasoning layer for AI agents — structured clinical risk signals, drug interactions, and differential diagnosis without prompt drift or hallucination.
Scribe / documentation: Feed patient notes into your agent and route on risk_level: critical — MedMCP handles the medical reasoning, you own the UX.
Intake / triage: Replace ad-hoc symptom parsing with a shared output contract — same input always returns the same structured risk signal, regardless of which model powers your agent.
Clinical copilot: Give your copilot deterministic answers on drug interactions and differentials — no prompting, no fine-tuning, no medical knowledge base to maintain.
Not a diagnosis tool. Not a consumer product. Infrastructure.
npm install @medmcp/sdkimport { MedMCP } from '@medmcp/sdk';
const client = new MedMCP({
apiKey: 'mk_your_key_here',
timeoutMs: 10_000, // optional
maxRetries: 2, // optional, retries 429/5xx
retryDelayMs: 250 // optional
});
const result = await client.analyze('chest pain for 2 hours');
const lab = await client.labGet('troponin');
const categories = await client.labCategories();
await client.waitlistJoin('user@example.com');
console.log(result.risk_level); // "high"
console.log(result.interpretation); // "1 symptom(s) identified: chest pain. Top differential: pulmonary embolism..."
console.log(lab.lab_value.reference_range);
console.log(categories.categories);pip install medmcpfrom medmcp import MedMCP
client = MedMCP(
api_key="mk_your_key_here",
timeout_ms=10_000,
max_retries=2,
retry_delay_ms=250,
)
result = client.analyze("chest pain for 2 hours")
lab = client.lab_get("troponin")
all_labs = client.lab_list("cardiac")
client.waitlist_join("user@example.com")
print(result.risk_level) # "high"
print(result.interpretation) # "1 symptom(s) identified: chest pain. Top differential: pulmonary embolism..."
print(lab["lab_value"].reference_range)
print(all_labs["count"])curl -X POST https://core-production-389e.up.railway.app/v1/analyze \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"type":"symptom","data":{"text":"chest pain for 2 hours"}}'Response:
{
"risk_level": "high",
"confidence": 1,
"entities": [
{ "type": "symptom", "value": "chest pain" },
{ "type": "diagnosis", "value": "pulmonary embolism", "metadata": { "match_score": 1, "icd11_code": "BB41" } }
],
"source_type": "symptom",
"interpretation": "1 symptom(s) identified: chest pain. Top differential: pulmonary embolism (match score: 1).",
"signals": [
{ "type": "risk_driver", "label": "chest pain", "detail": "high-risk symptom" },
{ "type": "differential", "label": "pulmonary embolism", "detail": "match_score: 1" },
{ "type": "symptom_match", "label": "chest pain" }
]
}Integration time: under 5 minutes.
Zero-dependency scripts (curl-free, same API): see examples/README.md (Node + Python).
analyze(text: string)health()schema()labGet(name: string)labList(category?: string)labCategories()waitlistJoin(email: string)waitlistList()
Config options:
apiKey(required)baseUrl(optional)timeoutMs(optional)maxRetries(optional; retries429and5xx)retryDelayMs(optional)
analyze(text: str)health()schema()lab_get(name: str)lab_list(category: str | None = None)lab_categories()waitlist_join(email: str)waitlist_list()
Constructor kwargs (optional, defaults match TypeScript SDK): timeout_ms, max_retries (retries 429 / 5xx), retry_delay_ms. On socket timeout after retries, raises RuntimeError with the same message shape as the TS client.
Converts clinical input into a structured risk signal.
Request
{
"type": "symptom",
"data": {
"text": "shortness of breath and racing heart"
}
}| Field | Type | Description |
|---|---|---|
type |
"symptom" |
Input type. Only symptom supported in v1. |
data.text |
string |
Free-text clinical description. |
Response schema (stable across all versions)
{
"risk_level": "low | medium | high | critical",
"confidence": 0.0,
"entities": [],
"signals": [],
"source_type": "symptom | lab | vitals | medication",
"interpretation": "string"
}| Field | Description |
|---|---|
risk_level |
Deterministic risk classification based on clinical red-flag criteria. |
confidence |
Fraction of extracted symptoms matched by at least one differential (0–1). |
entities |
Recognized symptoms, top differential diagnoses, ICD-11 codes. |
signals |
Structured breakdown: risk_driver, differential, symptom_match entries for agent routing. |
source_type |
Mirrors the input type. |
interpretation |
Short structured reasoning for agent consumption. |
No auth required.
{
"status": "ok",
"version": "1.0.0",
"timestamp": "...",
"release": "0.1.0",
"data_revision": "(optional — set MEDDATA_DATA_REVISION)",
"git_revision": "(optional — set MEDDATA_GIT_REVISION or Railway auto)"
}version: public HTTP API compatibilityrelease: semver of@medmcp/corepackage at build/deploydata_revision: your opaque tag for seed/rules (recommended for reproducibility)
Request timing is logged as [http] METHOD path status ms for /v1/* except GET /v1/health (set LOG_HTTP_HEALTH=1 to include health pings).
Look up reference ranges, critical values, and clinical interpretation for laboratory tests. Auth required.
Query parameters
| Parameter | Description |
|---|---|
name |
Lab test name or abbreviation (e.g. sodium, Na+, Hb, troponin, CRP) |
action |
list — returns all available tests; categories — returns category list |
category |
Filter by category when listing: electrolytes, renal, metabolic, cardiac, inflammatory, haematology |
# Look up a specific test
curl "https://core-production-389e.up.railway.app/v1/lab?name=troponin" \
-H "X-API-Key: YOUR_API_KEY"
# List all lab tests in a category
curl "https://core-production-389e.up.railway.app/v1/lab?action=list&category=electrolytes" \
-H "X-API-Key: YOUR_API_KEY"Response (single test):
{
"lab_value": {
"name": "troponin I",
"abbreviation": "hs-TnI",
"unit": "ng/L",
"reference_range": "<14 (99th percentile, hs-TnI)",
"critical_high": "52 ng/L",
"category": "cardiac",
"interpretation": "...",
"clinical_notes": "..."
}
}Returns full input/output JSON schema. Auth required.
All endpoints (except /v1/health) require an API key:
X-API-Key: mk_your_key_here
Risk classification is rule-based, not LLM-based. Deterministic by design.
| Level | Criteria |
|---|---|
critical |
Red-flag symptom present: syncope, altered consciousness, haemoptysis |
high |
High-risk symptom present: chest pain, dyspnoea, tachycardia, palpitations |
medium |
≥2 symptoms matched with at least one differential |
low |
Single mild symptom or no recognized symptoms |
git clone https://github.com/medmcp-dev/core
cd core
npm install
npm run setup # build + seed database
npm run start:http # starts on port 3000Set MEDDATA_API_KEY in your environment to use a fixed key instead of auto-generated.
For Claude Desktop, Cursor, and other MCP hosts: run the same server as npm start (stdio transport). It reads the local seeded SQLite from this repo (not the Railway HTTP API).
1. Build and seed once
git clone https://github.com/medmcp-dev/core.git
cd core
npm ci
npm run setup # build + seed meddata.db at repo root2. Configure the host
- Claude Desktop merges MCP servers into
claude_desktop_config.json:- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
- macOS:
- Cursor: Project MCP file
.cursor/mcp.json, or Settings → MCP (global). Format is the samemcpServersobject.
Use absolute paths to dist/index.js or set "cwd" to the repo root and pass "args": ["dist/index.js"].
Minimal example (replace the path with your clone):
{
"mcpServers": {
"medmcp": {
"command": "node",
"args": ["C:/dev/core/dist/index.js"]
}
}
}Same layout with cwd (often easier on Windows):
{
"mcpServers": {
"medmcp": {
"command": "node",
"args": ["dist/index.js"],
"cwd": "C:/dev/core",
"env": {
"DB_PATH": "C:/dev/core/meddata.db"
}
}
}
}DB_PATH is optional if the default database at the repo root is fine. Drop env entirely unless you keep the DB elsewhere.
Copy-paste template (placeholders): examples/mcp-claude-desktop.snippet.json.
3. Verify
npm start(Should block on stdio; stop with Ctrl+C — the desktop app launches it for you.)
MCP tools: get_medical_concept, get_drug_info, get_drug_interactions, get_icd11_code, get_differential_diagnosis, get_lab_value
HTTP vs MCP: Symptom analysis with
risk_level/signalsis onPOST /v1/analyze(SDK or curl). The MCP server exposes the clinical lookup tools above; wire HTTP separately if your agent needs analyze.
Repo discoverability (maintainers): GitHub topics help developers find the server — e.g. mcp, mcp-server, model-context-protocol, medical-ai, clinical-decision-support, healthcare, typescript, sqlite.
| Phase | Status |
|---|---|
Symptom → risk signal (POST /v1/analyze) |
✅ v1 |
Lab result interpretation (GET /v1/lab) |
✅ v1 |
| Vitals processing | Planned |
| Medication context | Planned |
JS SDK (@medmcp/sdk) |
✅ v1 |
Python SDK (medmcp) |
✅ v1 |
Deeper capability roadmap (MCP surfaces, future tools): docs/roadmap-mcp-capabilities.md.
cd sdk
npm test
npm run build
npm version patch
npm publishcd sdk-python
python -m unittest discover -s tests -p "test_*.py"
python -m build
python -m twine upload dist/*Notes:
- Bump versions together when SDK surfaces change.
- Tag release in git after successful npm/PyPI publish.
- Keep README examples aligned with both SDK clients.
MedMCP provides structured reference signals for AI agents and developers. It is not a substitute for clinical judgment, current prescribing guidelines, or peer-reviewed literature. Always verify critical clinical decisions against authoritative sources.