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.
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)