OMOPHub MCP Server

Medical vocabularies for AI agents.
Search, map, and navigate 11M+ OMOP concepts: SNOMED CT, ICD-10, RxNorm, LOINC, and more. Directly from Claude, Cursor, VS Code, or any MCP-compatible client.

npm version Codecov npm downloads License TypeScript MCP Compatible

Quick Start · Tools · Examples · Docs · Website

--- ## Why OMOPHub MCP? Working with medical vocabularies today means downloading multi-gigabyte CSV files, loading them into a local database, and writing SQL to find what you need. Every time. **OMOPHub MCP Server gives your AI assistant instant access to the entire OHDSI ATHENA vocabulary**. No database setup, no CSV wrangling, no context switching. Just ask. ``` You: "Map ICD-10 code E11.9 to SNOMED" Claude: Found it - E11.9 (Type 2 diabetes mellitus without complications) maps to SNOMED concept 201826 (Type 2 diabetes mellitus) via standard 'Maps to' relationship. ``` **Use cases:** - **Concept lookup** - Find OMOP concept IDs for clinical terms in seconds - **Cross-vocabulary mapping** - Map between ICD-10, SNOMED, RxNorm, LOINC, and 120+ vocabularies - **Hierarchy navigation** - Explore ancestors and descendants for phenotype definitions - **Concept set building** - Let your AI agent assemble complete concept sets for cohort definitions - **Code validation** - Verify medical codes and check their standard mappings --- ## Quick Start ### 1. Get an API Key Sign up at [omophub.com](https://omophub.com) → create an API key in your [dashboard](https://dashboard.omophub.com/api-keys). ### 2. Add to Your AI Client
Claude Desktop Open Claude Desktop settings > "Developer" tab > "Edit Config". Add to `claude_desktop_config.json`: ```json { "mcpServers": { "omophub": { "command": "npx", "args": ["-y", "@omophub/omophub-mcp"], "env": { "OMOPHUB_API_KEY": "oh_your_key_here" } } } } ```
Claude Code ```bash claude mcp add omophub -- npx -y @omophub/omophub-mcp # Then set OMOPHUB_API_KEY in your environment ```
Cursor Open the command palette and choose "Cursor Settings" > "MCP" > "Add new global MCP server". Add to `.cursor/mcp.json`: ```json { "mcpServers": { "omophub": { "command": "npx", "args": ["-y", "@omophub/omophub-mcp"], "env": { "OMOPHUB_API_KEY": "oh_your_key_here" } } } } ```
VS Code Add to `.vscode/mcp.json`: ```json { "servers": { "omophub": { "command": "npx", "args": ["-y", "@omophub/omophub-mcp"], "env": { "OMOPHUB_API_KEY": "oh_your_key_here" } } } } ```
Streamable HTTP (Remote / Hosted) Run the MCP server as an HTTP service that clients connect to via URL: ```bash # Start HTTP server on port 3100 npx -y @omophub/omophub-mcp --transport=http --port=3100 --api-key=oh_your_key_here # MCP endpoint: http://localhost:3100/mcp # Health check: http://localhost:3100/health ``` Connect MCP clients to `/` or `/mcp`. Useful for centralized deployments where multiple AI agents share one server instance.
Hosted (mcp.omophub.com) Connect directly to the OMOPHub-hosted MCP server - no installation required. Each client authenticates with their own API key via the `Authorization` header: **Claude Code:** ```bash claude mcp add omophub --transport http \ -H "Authorization: Bearer oh_your_key_here" \ https://mcp.omophub.com ``` **VS Code** (`.vscode/mcp.json`): ```json { "servers": { "omophub": { "type": "http", "url": "https://mcp.omophub.com", "headers": { "Authorization": "Bearer oh_your_key_here" } } } } ``` **Cursor / Windsurf:** ```json { "mcpServers": { "omophub": { "url": "https://mcp.omophub.com", "headers": { "Authorization": "Bearer oh_your_key_here" } } } } ``` > **Note:** Claude Desktop's Custom Connectors UI only supports OAuth and cannot send custom headers. Use the [npx setup](#claude-desktop) instead.
Docker ```bash # HTTP mode (default in Docker) - serves MCP on port 3100 docker run -e OMOPHUB_API_KEY=oh_your_key_here -p 3100:3100 omophub/omophub-mcp # Stdio mode (for piping) docker run -i -e OMOPHUB_API_KEY=oh_your_key_here omophub/omophub-mcp --transport=stdio ```
### 3. Start Asking > "What's the OMOP concept ID for type 2 diabetes?" > "Map ICD-10 code E11.9 to SNOMED" > "Show me all descendants of Diabetes mellitus in SNOMED" --- ## Available Tools | Tool | What it does | | :--- | :--- | | `search_concepts` | Search for medical concepts by name or clinical term across all vocabularies | | `get_concept` | Get detailed info about a specific OMOP concept by `concept_id` | | `get_concept_by_code` | Look up a concept using a vocabulary-specific code (e.g., ICD-10 `E11.9`) | | `map_concept` | Map a concept to equivalent concepts in other vocabularies (paginated — see note below) | | `get_hierarchy` | Navigate concept hierarchy - ancestors, descendants, or both | | `list_vocabularies` | List available medical vocabularies with statistics | | `semantic_search` | Search using natural language with neural embeddings (understands clinical meaning) | | `find_similar_concepts` | Find concepts similar to a reference concept, name, or description | | `explore_concept` | Get concept details, hierarchy, and cross-vocabulary mappings in one call | | `fhir_resolve` | Resolve a FHIR coded value (incl. administrative codes via the HL7 FHIR-to-OMOP IG ConceptMaps) to its OMOP standard concept and CDM target table | | `fhir_resolve_codeable_concept` | Resolve a FHIR CodeableConcept — best match by OHDSI vocabulary preference, honoring `userSelected` | ### Resources | URI | Description | | :--- | :--- | | `omophub://vocabularies` | Full vocabulary catalog with statistics | | `omophub://vocabularies/{vocabulary_id}` | Details for a specific vocabulary | ### Prompts | Prompt | Description | | :--- | :--- | | `phenotype-concept-set` | Guided workflow to build a concept set for a clinical phenotype | | `code-lookup` | Look up and validate a medical code with mappings and hierarchy | --- ## Example Prompts **Find a concept →** `search_concepts` > "Search for metformin in RxNorm" **Cross-vocabulary mapping →** `map_concept` > "I have SNOMED concept 201826 - what's the ICD-10 code?" **Build a concept set →** `search_concepts` → `get_hierarchy` → `map_concept` > "Help me build a concept set for Type 2 diabetes including all descendants" > **Completeness matters here.** `map_concept` returns one page at a time > (`page_size` 1-200, default 100). A widely-used drug ingredient can have well over > a thousand NDC mappings, so a single call is a sample, not the answer. Check > `has_more` in the response and keep incrementing `page` until it is `false` — > otherwise the concept set looks complete while silently missing codes. > > Use `find_similar_concepts` for exploration, not for this: it is ranked embedding > similarity, so it has no notion of set membership and cannot be exhaustive no > matter how large `page_size` is. **Validate a code →** `get_concept_by_code` → `map_concept` > "Is ICD-10 code E11.9 valid? What does it map to in SNOMED?" **Semantic search →** `semantic_search` > "Find concepts related to 'heart attack'" **Explore a concept →** `explore_concept` > "Give me everything about SNOMED concept 201826" **FHIR-to-OMOP resolution →** `fhir_resolve` > "Resolve FHIR SNOMED code 44054006 to OMOP — what table does it go in?" **CodeableConcept →** `fhir_resolve_codeable_concept` > "This CodeableConcept has both SNOMED 44054006 and ICD-10 E11.9 — which should I use for OMOP?" **Find similar →** `find_similar_concepts` > "What concepts are similar to 'Type 2 diabetes mellitus'?" --- ## Configuration ### Environment Variables | Variable | Required | Description | | :--- | :---: | :--- | | `OMOPHUB_API_KEY` | ✅ | Your OMOPHub API key | | `OMOPHUB_BASE_URL` | | Custom API base URL (default: `https://api.omophub.com/v1`) | | `OMOPHUB_LOG_LEVEL` | | `debug` · `info` · `warn` · `error` (default: `info`) | | `OMOPHUB_ANALYTICS_OPTOUT` | | Set to `true` to disable analytics headers | | `OMOPHUB_USER_AGENT_SUFFIX` | | Optional deployment identifier appended to `omophub-mcp/` (default: none) | | `MCP_TRANSPORT` | | `stdio` (default) or `http` | | `MCP_PORT` | | HTTP server port (default: `3100`, only used with `http` transport) | | `HEALTH_PORT` | | Port for standalone health endpoint in stdio mode (default: disabled) | ### CLI Arguments ```bash # Stdio mode (default) npx @omophub/omophub-mcp --api-key=oh_your_key --base-url=https://custom.api.com/v1 # HTTP mode npx @omophub/omophub-mcp --transport=http --port=3100 --api-key=oh_your_key # Stdio mode with standalone health endpoint npx @omophub/omophub-mcp --api-key=oh_your_key --health-port=8080 ``` ### Health Endpoint (Docker / Kubernetes) In **HTTP mode**, the health endpoint is available at `/health` on the same port as the MCP endpoint: ```bash npx @omophub/omophub-mcp --transport=http --port=3100 --api-key=oh_your_key curl http://localhost:3100/health # → {"status":"ok","version":"1.5.0","uptime_seconds":42} ``` In **stdio mode**, use `--health-port` for a standalone health endpoint: ```bash HEALTH_PORT=8080 OMOPHUB_API_KEY=oh_your_key npx @omophub/omophub-mcp curl http://localhost:8080/health ``` The Docker image defaults to HTTP mode on port 3100 with health checks built in. --- ## Development ```bash git clone https://github.com/OMOPHub/omophub-mcp.git cd omophub-mcp npm install npm run build npm test ``` Run locally: ```bash OMOPHUB_API_KEY=oh_your_key npx tsx src/index.ts ``` --- ## Troubleshooting | Error | Solution | | :--- | :--- | | `API key required` | Set `OMOPHUB_API_KEY` in your environment or MCP config | | `Authentication failed` | API key may be invalid or expired - [generate a new one](https://dashboard.omophub.com/api-keys) | | `Rate limit exceeded` | Automatic retries are built in. For higher limits, [upgrade your plan](https://dashboard.omophub.com/billing) | | Tools not appearing | Restart your AI client, verify `npx @omophub/omophub-mcp` runs without errors, check config path | --- ## Links - [Documentation](https://docs.omophub.com) - [Get an API Key](https://dashboard.omophub.com/api-keys) - [Python SDK](https://github.com/OMOPHub/omophub-python) - [Community & Support](https://github.com/OMOPHub/omophub-mcp/issues) --- ## License MIT - see [LICENSE](LICENSE)