phenoforge
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@phenoforgeadults with type 2 diabetes and nephropathy"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
phenoforge
Semantic value set assembly for clinical cohort definitions, over MCP.
Status: early prototype. The vocabulary loader, hierarchy expansion, hybrid (BM25 + dense) search, curated OHDSI Phenotype Library matching, an eval harness scoring all of it against curated ground truth, a thin MCP server exposing them all, and a LangGraph agent that decomposes a population description, checks curated first, and pauses for human confirmation before including anything generated — all work end-to-end against a real Athena download. See Roadmap.
Setup
Requires your own OHDSI Athena bulk download — vocabulary content carries its own license terms, so it can't be bundled with this repo.
Create a free account at athena.ohdsi.org.
Under Search, select at least ICD10CM and SNOMED as vocabularies, then click Download. SNOMED is used locally only — to resolve curated-set matching (
find_curated_definition) — and is never shipped or exposed through any tool surface.Unzip the download into
data/athena/(this directory is gitignored — nothing underdata/is ever committed or shipped). It contains OMOP CDM vocabulary tables (CONCEPT.csv,CONCEPT_RELATIONSHIP.csv, etc.) — Athena ships vocabulary content pre-shaped as OMOP, so no separate mapping step is needed.
uv sync
python scripts/load_vocab.py data/athena --output data/vocab.duckdb
phenoforge-mcp # stdio MCP server; add to Claude Desktop's mcpServers config to try itOptional: curated phenotype library
find_curated_definition needs a small local cache of OHDSI Phenotype Library cohort
definitions. Like the Athena download, this content carries its own terms — the OHDSI
PhenotypeLibrary GitHub repo has no confirmed LICENSE file (its R package DESCRIPTION claims
Apache, but that's a manifest claim, not a verified grant for the cohort content itself) — so
it's fetched into a gitignored local directory, never committed to this repo. Without this step,
find_curated_definition still runs and reports why nothing matched.
python scripts/fetch_phenotype_library.py # writes data/phenotype_library/Bundles 8 hand-picked, diabetes/kidney-relevant cohorts (not the full library): Type 2/Type 1/ gestational diabetes, diabetic ketoacidosis, retinopathy, and chronic kidney disease.
Optional: dense (semantic) search
search_concepts fuses lexical and semantic matching when a dense index has been built;
without one, it falls back to lexical-only search automatically.
python scripts/build_index.py # writes data/concept_index.lance; downloads BioLORD-2023 on first runOptional: eval harness
Scores each retrieval method (BM25, dense, hybrid, hierarchy expansion) against the curated demo cohorts as ground truth — hierarchical distance-weighted scoring, set-level coverage, and an over-inclusion penalty (partial credit for near-misses under the same hierarchy parent, not exact-match recall). Requires the phenotype library fetch step above; dense/hybrid scoring also needs the built index.
python scripts/run_eval.py # bm25 + expand_descendants
python scripts/run_eval.py --index data/concept_index.lance # + dense + hybridOptional: the agent
The LangGraph agent decomposes a plain-English population description into seed terms, checks
each against the curated phenotype library first, and pauses on the command line for you to
accept or reject any generated (unverified) candidates before they're included. Requires an
Anthropic API key (decomposition is a real Claude call) and the agent extra.
scripts/run_agent.py loads a local .env automatically (gitignored — never commit real keys),
or export the variable directly.
uv sync --extra agent
echo 'ANTHROPIC_API_KEY=...' > .env # or: export ANTHROPIC_API_KEY=...
python scripts/run_agent.py "adults with type 2 diabetes and diabetic nephropathy"
python scripts/run_agent.py "..." --index data/concept_index.lance # + dense retrieval for generated candidatesInteractive exploration
Both notebooks are exploration only, never pushed to production — reusable logic stays in
src/phenoforge/.
notebooks/explore.ipynbcalls the engine directly (no MCP transport) against your real builtdata/vocab.duckdb.notebooks/evaluate.ipynbruns the eval harness and walks through the metrics with explanatory text, a method-comparison chart, and a sortable per-cohort results table.
uv sync --extra dev
jupyter lab notebooks/explore.ipynbRelated MCP server: medterms-mcp
What it does
Turns a plain-English patient population description into a defensible set of ICD-10-CM codes, where every code carries provenance — whether it came from a peer-reviewed phenotype definition, from hierarchy expansion, or from semantic retrieval that a human should check.
"adults with type 2 diabetes and diabetic nephropathy"
→ decomposes into seed clinical terms
→ checks OHDSI Phenotype Library for a validated definition for each
→ falls back to hybrid retrieval for terms with no curated match,
pausing for human confirmation before including anything generated
→ returns a ConceptSet with per-code provenance and citationsRun it for real: python scripts/run_agent.py "adults with type 2 diabetes and diabetic nephropathy" (see Setup).
Why not an existing terminology server
Several good MCP terminology servers exist. They solve lookup — "what is code X", "map X to Y". This solves set assembly, which is the actual task in cohort definition. It also covers US ICD-10-CM, which the existing servers do not, and uses semantic retrieval rather than proxied keyword search, which fails when a population description and a code description share no vocabulary.
Architecture
Three layers — a retrieval engine, a thin MCP server, and a LangGraph agent. The MCP server and the agent are independent consumers of the same engine.
Roadmap
v0.1 — vocabulary layer. Athena loader, DuckDB schema, hierarchy queries
v0.2 — retrieval. BM25, BioLORD-2023 embeddings, LanceDB index, RRF hybrid scoring
v0.3 — expansion + provenance.
ConceptSetmodel, descendant expansion, and OHDSI PL curated matching (small hand-picked demo set — see Setup)v0.4 — MCP server. stdio transport, four tools (see below), Claude Desktop config
v0.5 — eval harness. Distance-weighted scoring, coverage, over-inclusion penalty; curated demo cohorts as ground truth. Decomposition accuracy deferred to
v0.7(seephenoforge.eval) — nothing decomposes a population description yetv0.7 — LangGraph agent. Decompose → check curated first → generate only for unresolved terms → human confirmation gate on anything generated → assemble. Real interactive CLI (
scripts/run_agent.py)v1.0 — packaging. PyPI, docs, validation and limitations section
Skipped: v0.6 (encoder benchmark — BioLORD vs SapBERT vs MedCPT). The agent was the more
demonstrable deliverable, so v0.7 was built first; the encoder benchmark may return later.
Deferred: literature-derived phenotype algorithms (published tier), RxNorm and LOINC domains
Tools
Tool | Status | Purpose |
| done | Exact ICD-10-CM code → name and metadata |
| done | Seed code → full descendant expansion ( |
| done | Hybrid BM25 + dense search over ICD-10-CM names, RRF-fused ( |
| done | Search the bundled OHDSI Phenotype Library demo set before generating anything ( |
| planned | Why is this code in this set, via which path, with what evidence |
find_curated_definition is the only source of curated provenance today, and only for the 8
bundled demo cohorts. Everything from expand_hierarchy and search_concepts is generated
provenance — ungrounded, structural or lexical/semantic only, and meant to be confirmed by a
human before use in a cohort definition.
License
Apache 2.0. Vocabulary content (ICD-10-CM, SNOMED) carries its own license terms from OHDSI/
Athena, separate from this repo's license — nothing from data/ is redistributed.
Not a clinical decision tool
This produces code sets for research and analytics. It does not make clinical determinations and has not been validated for patient care.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityDmaintenanceA Model Context Protocol server that enables conversational searching of NIH-funded research projects and publications through the NIH RePORTER database.4MIT
- AlicenseAqualityCmaintenanceMedical terminology MCP server — ICD-10, MedDRA, RxNorm, CTCAE for AI agents613MIT
- AlicenseBqualityDmaintenanceMCP server for mapping clinical terminology to OMOP concepts using LLMs, with vocabulary search and batch processing capabilities.240Apache 2.0

snowstorm-mcp-serverofficial
Alicense-qualityBmaintenanceEnables AI assistants to look up, search, validate, navigate hierarchies, and expand value sets for SNOMED CT clinical terminology through the Model Context Protocol.7Apache 2.0
Related MCP Connectors
MCP gateway federating 21 biomedical MCP servers behind one endpoint: gnomAD, ClinVar, HPO, VEP.
Diagnoses, drugs & lab codes: ICD-11, SNOMED, LOINC, RxNorm, MeSH, ATC, CID-10. 37 tools, MIT.
Monarch biomedical knowledge graph — diseases, phenotypes, genes, variants
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/colbyw5/phenoforge'
If you have feedback or need assistance with the MCP directory API, please join our Discord server