medical-mcp
# 𩺠Medical MCP Server
> **Bring trusted medical data directly into your AI workflow.** A local server for private, free access to FDA, WHO, PubMed, RxNorm, Semantic Scholar, and Google Scholar. No API keys. No data leaks.
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that brings authoritative medical information into AI coding environments like Cursor and Claude Desktop.
<a href="https://glama.ai/mcp/servers/@JamesANZ/medical-mcp">
<img width="380" height="200" src="https://glama.ai/mcp/servers/@JamesANZ/medical-mcp/badge" alt="medical-mcp MCP server" />
</a>
[](https://archestra.ai/mcp-catalog/jamesanz__medical-mcp)
## Why Use Medical MCP?
- š **Your Data Never Leaves** ā Runs 100% locally; no tracking, no logs, no cloud
- š **No API Keys** ā Works out of the box, zero configuration
- š„ **Authoritative Sources** ā FDA, TGA, Health Canada, EMA, DailyMed, WHO, PubMed, RxNorm, ClinicalTrials.gov
- ā” **Easy Setup** ā One-click install in [Cursor](https://cursor.sh) or simple manual setup
- š¬ **Comprehensive** ā Drug info, health stats, medical literature, clinical guidelines, pediatric sources
- š”ļø **Resilient** ā Circuit breakers, retry with backoff, rate limiting, and automatic fallbacks
- š **Evidence-Graded** ā Results tagged with study type and evidence level (Meta-Analysis ā Case Report). Tags are automatic labels from the title and abstract, not independently checked grades.
- š„ **Health Monitoring** ā Built-in health check tool to diagnose source availability
## What's New in v2.0
- **Resilience Layer** ā Circuit breakers per source, retry with exponential backoff + jitter, per-source token bucket rate limiters
- **Monid web search** ā Scholar, AAP, and PMC HTML go through Monid TinyFish (Tavily-style search/fetch). Semantic Scholar is the no-key fallback
- **Evidence Grading** ā PubMed and multi-database results tagged with study type (Systematic Review, RCT, Cohort, Case Report, etc.) and evidence grade (IāV). These tags are automatic labels from the title and abstract, not independently checked grades.
- **Response Validation** ā Zod schemas validate all upstream API responses, logging warnings on schema drift without breaking
- **NCBI API Key Support** ā Optional `NCBI_API_KEY` env var boosts PubMed from 3 req/sec to 10 req/sec
- **Health Check Tool** ā `health-check` pings all upstream sources and reports latency, circuit breaker states, rate limiter status, and cache health
- **Structured Logging** ā Leveled, structured logging (DEBUG/INFO/WARN/ERROR) with source tracking and timing for every API call
- **Request Timeouts** ā All upstream calls have explicit response/deadline timeouts to prevent hanging
## Quick Start
**Install in Cursor (Recommended):**
[š Install in Cursor](cursor://anysphere.cursor-deeplink/mcp/install?name=medical-mcp&config=eyJtZWRpY2FsLW1jcCI6eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1lZGljYWwtbWNwIl19fQ==)
**Or install manually:**
```bash
npm install -g medical-mcp
# Or from source:
git clone https://github.com/JamesANZ/medical-mcp.git
cd medical-mcp && npm install && npm run build
```
## Features
### š Drug Information
- **`search-drugs`** ā Search FDA, DailyMed, TGA (Australia), Health Canada, and EMA. Filter with `countries` (`US`, `AU`, `CA`, `EU`). Unsupported codes are rejected rather than returned as empty regulatory results.
- **`search-drug-nomenclature`** ā Standardized drug names via RxNorm (`limit` defaults to 25)
- **`search-drug-safety`** ā FDA FAERS adverse events (with report IDs), recalls, and shortages
### š Health Statistics
- **`get-health-statistics`** ā WHO Global Health Observatory data (life expectancy, mortality, disease prevalence)
### š¬ Medical Literature
- **`search-medical-literature`** ā Search 30M+ PubMed articles (with evidence grading). Optional `question` or `rerank` reorders those hits so papers that actually answer the question sit above papers that only share keywords.
- **`rank-search-hits`** ā Same rerank for a list you already have (title + abstract). Retrieval ranking only ā not diagnosis or advice.
- **`get-article-details`** ā Detailed article info by PMID
- **`search-google-scholar`** ā Academic papers via Monid TinyFish (`research_paper`) when `MONID_API_KEY` is set; otherwise Semantic Scholar
- **`search-medical-journals`** ā Top journals (NEJM, JAMA, Lancet, BMJ, Nature Medicine)
### š„ Clinical Tools
- **`search-clinical-guidelines`** ā Practice recommendations from medical organizations
- **`search-clinical-trials`** ā ClinicalTrials.gov
- **`list-sources`** ā Full catalog of registry adapters and dedicated-tool sources (WHO, PubMed, RxNorm, Scholar, AAP), including which MCP tool reaches each. This is not the `search-drugs` five-regulator fanout.
### š¶ Pediatric Sources
- **`search-pediatric-guidelines`** ā AAP policy/clinical reports via PubMed, plus Bright Futures. Off-domain web hits are dropped; labels come from the page, not from which search ran.
- **`search-pediatric-literature`** ā Research from major pediatric journals. Optional `question` / `rerank` like medical literature.
- **`search-pediatric-drugs`** ā Drugs with pediatric labeling, NDC, manufacturer, and DailyMed URL
### š”ļø Reliability & Monitoring
- **`health-check`** ā Ping all upstream sources, report latency/status, circuit breaker states, and cache health
- **`get-cache-stats`** ā View cache statistics (hit rate, memory usage, entry count)
## Installation
### Cursor (One-Click)
Click the install link above or use:
```
cursor://anysphere.cursor-deeplink/mcp/install?name=medical-mcp&config=eyJtZWRpY2FsLW1jcCI6eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1lZGljYWwtbWNwIl19fQ==
```
### Manual Installation
**Requirements:** Node.js 18+ and npm
```bash
git clone https://github.com/JamesANZ/medical-mcp.git
cd medical-mcp
npm install
npm run build
npm start
```
### Claude Desktop
Add to `claude_desktop_config.json`:
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"medical-mcp": {
"command": "node",
"args": ["/absolute/path/to/medical-mcp/build/index.js"],
"env": {
"NCBI_API_KEY": "your_optional_key_here"
}
}
}
}
```
Restart Claude Desktop after configuration.
## Usage Examples
### Search for Drug Information
```json
{
"tool": "search-drugs",
"arguments": { "query": "Tylenol", "limit": 5 }
}
```
### Search Medical Literature (with Evidence Grading)
Results now include evidence tags:
```
1. Efficacy of COVID-19 Treatments: A Meta-Analysis
Evidence: [Systematic Review / Meta-Analysis ⢠tool grade I]
Authors: Smith J, Jones K...
2. Randomized Trial of Remdesivir in Adults
Evidence: [Randomized Controlled Trial ⢠tool grade II]
Authors: Chen L, Wang M...
```
### Run Health Check
```json
{ "tool": "health-check", "arguments": {} }
```
Returns:
```
ā
FDA: healthy (234ms)
ā
PubMed: healthy (156ms)
ā
WHO: healthy (890ms)
ā
RxNorm: healthy (312ms)
ā
ClinicalTrials: healthy (445ms)
ā
SemanticScholar: healthy (189ms)
NCBI API Key: ā
Configured (10 req/sec PubMed)
```
## Architecture
### Resilience Stack
Every API call flows through a three-layer resilience stack:
```
Request ā Rate Limiter ā Circuit Breaker ā Retry (with backoff) ā Upstream API
```
- **Rate Limiter** ā Per-source token bucket prevents exceeding API limits (PubMed: 3/sec without key, 10/sec with; FDA: 4/sec; Google Scholar: 0.2/sec)
- **Circuit Breaker** ā After 3 consecutive failures, the circuit opens for 60s, preventing cascade failures. Transitions: CLOSED ā OPEN ā HALF_OPEN ā CLOSED
- **Retry** ā Exponential backoff with full jitter on transient failures (429, 5xx, network errors). Max 2 retries
### Evidence Grading
PubMed and multi-database results are automatically classified:
| Grade | Study Type | Examples |
| ----- | --------------------------------- | --------------------------------------------- |
| I | Systematic Review / Meta-Analysis | Cochrane reviews, PRISMA studies |
| II | Randomized Controlled Trial | Double-blind placebo-controlled trials |
| III | Cohort / Case-Control Study | Prospective, retrospective, population-based |
| IV | Case Report / Case Series | Clinical case presentations |
| V | Expert Opinion / Editorial | Commentaries, perspectives, narrative reviews |
These tags are automatic labels from the title and abstract, not independently checked grades.
### Automatic Fallback
When `MONID_API_KEY` is set, Scholar/AAP search and PMC HTML fetch go through **Monid TinyFish**. Without a key, Scholar falls back to **Semantic Scholar's API** ā free, well-structured, 100 req/sec, no API key needed.
### Response Validation
All upstream API responses are validated against Zod schemas. If a source changes their API response format, the server logs a warning but continues operating with raw data ā no crashes, just alerts.
## Data Sources
| Source | Coverage | Update Frequency | Resilience |
| ----------------------------------- | ---------------------------------------- | ---------------- | ---------------------------------- |
| **FDA** | US approved drug labels | Real-time | Circuit breaker + retry |
| **DailyMed** | US structured product labels | Daily | Circuit breaker + retry |
| **TGA ARTG** | Australian Register of Therapeutic Goods | Real-time | Circuit breaker + retry |
| **Health Canada DPD** | Canadian marketed/approved drugs | Real-time | Circuit breaker + retry |
| **EMA** | EU centrally authorised medicines | Twice daily JSON | In-memory cache + retry |
| **FDA FAERS / recalls / shortages** | US safety signals | Real-time | Circuit breaker + retry |
| **WHO** | Global health stats (194 countries) | Annual | Circuit breaker + retry |
| **PubMed** | 30M+ medical citations | Daily | Circuit breaker + retry + NCBI key |
| **RxNorm** | Standardized drug nomenclature (US) | Weekly | Circuit breaker + retry |
| **TinyFish via Monid** | Research papers + domain-scoped web | Real-time | Optional `MONID_API_KEY` |
| **Semantic Scholar** | 200M+ papers with citation data | Real-time | Circuit breaker + retry |
| **AAP** | Bright Futures & policy statements | Periodic | Graceful degradation |
| **Pediatric Journals** | Major pediatric journals | Daily | Circuit breaker + retry |
| **ClinicalTrials.gov** | Interventional and observational trials | Real-time | Circuit breaker + retry |
## Configuration
### Environment Variables
**Performance & Reliability:**
| Variable | Default | Description |
| ------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NCBI_API_KEY` | _(none)_ | Free PubMed API key ā 3x throughput. Get one at [NCBI](https://www.ncbi.nlm.nih.gov/account/settings/) |
| `MONID_API_KEY` | _(none)_ | Optional. When set, Scholar/AAP/PMC HTML use Monid's TinyFish search and fetch (Tavily-style web scraper). Get a key at [Monid](https://app.monid.ai/access/api-keys) |
| `TINYFISH_API_KEY` | _(none)_ | Optional fallback if you call TinyFish directly instead of through Monid. |
| `TYPESAFE_API_KEY` | _(none)_ | Optional. Needed to rerank literature hits with JEV (`jev-1.13.0`). Without it, search works as before. Get a key at [TypeSafe](https://typesafe.ai) |
| `LOG_LEVEL` | `INFO` | Logging level: `DEBUG`, `INFO`, `WARN`, `ERROR`, `SILENT` |
**Cache:**
| Variable | Default | Description |
| -------------------------- | --------- | ----------------------------- |
| `CACHE_ENABLED` | `true` | Enable/disable caching |
| `CACHE_MAX_SIZE` | `1000` | Maximum cache entries |
| `CACHE_TTL_FDA` | `86400` | FDA TTL in seconds (24h) |
| `CACHE_TTL_PUBMED` | `3600` | PubMed TTL (1h) |
| `CACHE_TTL_WHO` | `604800` | WHO TTL (7d) |
| `CACHE_TTL_RXNORM` | `2592000` | RxNorm TTL (30d) |
| `CACHE_TTL_GOOGLE_SCHOLAR` | `3600` | Google Scholar TTL (1h) |
| `CACHE_TTL_BRIGHT_FUTURES` | `2592000` | Bright Futures TTL (30d) |
| `CACHE_TTL_AAP_POLICY` | `604800` | AAP Policy TTL (7d) |
| `CACHE_TTL_REGULATORS` | `86400` | TGA/EMA/Health Canada TTL |
| `CACHE_TTL_SAFETY` | `3600` | FAERS/recalls/shortages TTL |
| `CACHE_TTL_TRIALS` | `3600` | Clinical trial search TTL |
| `CACHE_CLEANUP_INTERVAL` | `300000` | Cleanup interval in ms (5min) |
**Deduplication:**
| Variable | Default | Description |
| ---------------------------- | ------- | ----------------------------------------- |
| `DEDUP_ENABLED` | `true` | Enable/disable cross-source deduplication |
| `DEDUP_SIMILARITY_THRESHOLD` | `0.9` | Fuzzy title match threshold (0.0ā1.0) |
| `DEDUP_LOG_REMOVED` | `false` | Log removed duplicates |
**Performance**: Cached responses return in <10ms vs 800ā1500ms for API calls. Expected hit rate: 60%+ for common queries.
## Security & Privacy
- ā
**Localhost-only** ā Server runs locally, no external access
- ā
**No data storage** ā All queries are real-time, nothing saved to disk
- ā
**Process isolation** ā Medical data stays on your machine
- ā
**No API keys required** ā Works without credentials (NCBI and Monid keys are optional)
## Technical Details
**Built with:** Node.js, TypeScript, MCP SDK
**Dependencies:** `@modelcontextprotocol/sdk`, `superagent`, `zod`, `express`, `cors`
**Platforms:** macOS, Windows, Linux
**Source layout:**
```
src/
āāā index.ts # MCP tool definitions
āāā utils.ts # Core API functions + formatters
āāā constants.ts # API URLs, config constants
āāā types.ts # TypeScript types
āāā logger.ts # Structured leveled logging
āāā rank/ # Optional JEV post-retrieval ranker (question vs abstract)
ā āāā policy.ts # Keep / demote / drop ā no HTTP
ā āāā jev-client.ts # TypeSafe System One client (jev-1.13.0)
āāā cache/
ā āāā config.ts # TTL policies, env var support
ā āāā manager.ts # In-memory LRU cache
āāā resilience/
ā āāā index.ts # Composed resilientCall()
ā āāā circuit-breaker.ts # Per-source circuit breaker
ā āāā retry.ts # Exponential backoff + jitter
ā āāā rate-limiter.ts # Token bucket rate limiter
āāā validation/
ā āāā schemas.ts # Zod schemas for API responses
āāā sources/ # Country/source registry + adapters
ā āāā adapters/ # FDA, TGA, Health Canada, EMA, DailyMed, FAERS, trials, TinyFish
ā āāā ...
āāā utils/
āāā deduplication.ts # Cross-source paper dedup
āāā evidence-grading.ts # Study type classification
āāā semantic-scholar.ts # Semantic Scholar API client
```
## Medical Disclaimer
ā ļø **Important**: This tool provides information from authoritative sources but should **not** replace professional medical advice, diagnosis, or treatment. Always consult qualified healthcare professionals for medical decisions.
## Contributing
ā **If this project helps you, please star it on GitHub!** ā
Contributions welcome! Please open an issue or submit a pull request.
## License
MIT License ā see [LICENSE.md](LICENSE.md) for details.
## Support
If you find this project useful, consider supporting it:
**ā” Lightning Network**
```
lnbc1pjhhsqepp5mjgwnvg0z53shm22hfe9us289lnaqkwv8rn2s0rtekg5vvj56xnqdqqcqzzsxqyz5vqsp5gu6vh9hyp94c7t3tkpqrp2r059t4vrw7ps78a4n0a2u52678c7yq9qyyssq7zcferywka50wcy75skjfrdrk930cuyx24rg55cwfuzxs49rc9c53mpz6zug5y2544pt8y9jflnq0ltlha26ed846jh0y7n4gm8jd3qqaautqa
```
**āæ Bitcoin**: [bc1ptzvr93pn959xq4et6sqzpfnkk2args22ewv5u2th4ps7hshfaqrshe0xtp](https://mempool.space/address/bc1ptzvr93pn959xq4et6sqzpfnkk2args22ewv5u2th4ps7hshfaqrshe0xtp)
**Ī Ethereum/EVM**: [0x42ea529282DDE0AA87B42d9E83316eb23FE62c3f](https://etherscan.io/address/0x42ea529282DDE0AA87B42d9E83316eb23FE62c3f)
TDQS
Scored across 11 tools
Multiple tools have overlapping purposes that could cause confusion, such as search-medical-databases, search-medical-journals, search-medical-literature, and search-google-scholar all targeting article/research searches with unclear boundaries. Similarly, search-drug-nomenclature and search-drugs both handle drug searches but from different sources, potentially leading to misselection. The descriptions help somewhat, but the significant overlap reduces clarity.
The naming follows a consistent verb-noun pattern with hyphens (e.g., check-drug-interactions, get-article-details), which is predictable and readable. There are minor deviations, such as some tools using 'get' and others using 'search', but overall the convention is maintained throughout the set, making it easy to understand the tool functions at a glance.
With 11 tools, the count is reasonable and well-scoped for a medical information server, covering drug interactions, drug details, health statistics, clinical guidelines, and various search functionalities. It's slightly on the higher side but not excessive, as each tool appears to serve a distinct purpose within the medical domain, making it manageable for agents to navigate.
The tool set covers key areas like drug information, medical literature, and health statistics, but there are notable gaps. For example, it lacks update or delete operations for any resources, and there's no clear lifecycle management for medical data (e.g., no tools for patient records or treatment plans). While agents can work around this for information retrieval, the surface is incomplete for broader medical workflows.