Skip to main content
Glama
jxia622

pubmed-clinical-mcp

by jxia622
README.md
# PubMed Clinical MCP

`pubmed-clinical-mcp` is a lightweight Model Context Protocol (MCP) server for clinical biomedical literature retrieval. It gives MCP-compatible clients reusable tools for PubMed/MEDLINE search, article metadata retrieval, PubMed Central full text, full-text availability checks, related articles, clinical query building, PICO extraction, article ranking, and evidence summarization.

This project is designed for clinical evidence support and research workflows. It is **not** a diagnosis system, treatment recommendation system, paywall bypasser, or institutional-library automation tool.

## Why This Exists

Many medical agents need reliable access to public biomedical literature, but PubMed handling often gets mixed into one-off application code. This package separates that capability into a standalone MCP server so tools like Codex, Claude Desktop, Cursor, or other MCP clients can call PubMed-focused tools directly.

## Features

- PubMed/MEDLINE search through NCBI E-utilities.
- PubMed article fetching with title, abstract, authors, journal, year, DOI, PMCID, MeSH terms, publication types, and URL.
- PubMed Central open-access full-text section retrieval when legally available.
- Related PubMed article lookup through NCBI `elink`.
- Unpaywall DOI availability checks for legal open-access links.
- Clinical query builder for natural-language medical questions.
- Article ranking against a clinical question with relevance reasons.
- Rough PICO extraction from abstracts or article passages.
- Citation-backed evidence table and limitations summary.
- Retry/backoff on `429` and transient server failures.
- Optional local JSON cache.
- Tests use local fixtures, so CI does not need live API access.

## Tool List

| Tool | Purpose |
| --- | --- |
| `build_clinical_query` | Convert a natural-language clinical question into a PubMed-ready query. |
| `search_pubmed` | Search PubMed and return PMIDs plus lightweight metadata. |
| `fetch_pubmed_articles` | Fetch detailed PubMed article metadata for PMIDs. |
| `search_and_fetch_pubmed` | Build a query, search, fetch, rank, and return citations in one call. |
| `fetch_pmc_full_text` | Fetch PMC full-text sections when a PMCID is legally available. |
| `check_full_text_availability` | Check PMC and Unpaywall for legal full-text access. |
| `find_related_articles` | Find related PubMed articles using NCBI `elink`. |
| `rank_articles` | Rank article objects against a clinical question. |
| `extract_pico` | Extract rough population/intervention/comparator/outcome fields. |
| `summarize_evidence` | Produce an evidence table, citation-backed findings, and limitations. |

## Install

```bash
git clone https://github.com/jxia622/pubmed-clinical-mcp.git
cd pubmed-clinical-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
```

## Optional Environment Variables

No paid keys are required. For low-volume demos, the server can run without API keys.

```bash
export NCBI_EMAIL="you@example.com"
export NCBI_API_KEY="optional_free_ncbi_key"
export UNPAYWALL_EMAIL="you@example.com"
export PUBMED_MCP_CACHE_PATH=".cache/pubmed_clinical_mcp.json"
```

Notes:

- `NCBI_EMAIL` is recommended for NCBI E-utilities usage.
- `NCBI_API_KEY` is optional and raises NCBI rate limits.
- `UNPAYWALL_EMAIL` is required for Unpaywall checks.
- `PUBMED_MCP_CACHE_PATH` enables a simple local JSON cache.

## Run The MCP Server

```bash
pubmed-clinical-mcp
```

or:

```bash
python -m pubmed_clinical_mcp.server
```

## Example MCP Client Config

```json
{
  "mcpServers": {
    "pubmed-clinical": {
      "command": "python",
      "args": ["-m", "pubmed_clinical_mcp.server"],
      "env": {
        "NCBI_EMAIL": "you@example.com",
        "PUBMED_MCP_CACHE_PATH": ".cache/pubmed_clinical_mcp.json"
      }
    }
  }
}
```

## Example Tool Calls

### Build a PubMed query

```json
{
  "natural_language_question": "Why might a diabetic foot ulcer be Wagner grade 2 instead of grade 1?",
  "filters": {
    "english_only": true,
    "year_from": 2020
  }
}
```

Example output:

```json
{
  "query": "(\"diabetic foot\"[Title/Abstract] OR \"diabetic foot ulcer\"[Title/Abstract]) AND (Wagner[Title/Abstract] OR classification[Title/Abstract] OR staging[Title/Abstract]) AND english[Language] AND (\"2020\"[Date - Publication] : \"3000\"[Date - Publication])",
  "explanation": [
    "Mapped diabetic foot ulcer + Wagner wording to title/abstract terms for classification and staging."
  ],
  "filters": {
    "english_only": true,
    "year_from": 2020
  }
}
```

### Search and fetch ranked PubMed articles

```json
{
  "clinical_question": "What evidence supports using wound depth in diabetic foot ulcer severity assessment?",
  "filters": {
    "english_only": true
  },
  "max_results": 10
}
```

Returns:

- `query_used`
- `query_explanation`
- `ranked_articles`
- `citations`

### Fetch PMC full text

```json
{
  "pmcid": "PMC9446755"
}
```

Returns parsed sections when the article is available in PubMed Central.

## Architecture

```mermaid
flowchart LR
  Client["MCP client"] --> Server["pubmed-clinical-mcp server"]
  Server --> Query["clinical query builder"]
  Server --> PubMed["NCBI PubMed E-utilities"]
  Server --> PMC["PubMed Central XML"]
  Server --> Unpaywall["Unpaywall API"]
  Server --> Rank["ranking + PICO + summarization helpers"]
  Server --> Cache["optional JSON cache"]
```

Core modules:

```text
src/pubmed_clinical_mcp/
  server.py                 # MCP tool definitions
  sources/pubmed.py         # PubMed esearch, efetch, elink
  sources/pmc.py            # PMC full-text XML parsing
  sources/unpaywall.py      # DOI open-access checks
  clinical/query_builder.py # natural language -> PubMed query
  clinical/ranking.py       # relevance ranking
  clinical/pico.py          # rough PICO extraction
  clinical/summarizer.py    # evidence table + limitations
```

## Development

Tests use fixtures and do not call live APIs:

```bash
PYTHONPATH=src python3 -m unittest discover -s tests
```

Compile check:

```bash
PYTHONPATH=src python3 -m compileall src tests
```

## API And Rate-Limit Notes

- PubMed and PMC use NCBI E-utilities.
- NCBI allows higher request rates when `NCBI_API_KEY` is configured.
- The server includes basic retry/backoff for `429` and transient `5xx` failures.
- The cache is intentionally simple and optional. It is not a vector database.

## Safety And Scope

This server:

- retrieves public biomedical literature metadata and legal open-access text;
- does not diagnose;
- does not prescribe treatment;
- does not bypass paywalls;
- does not scrape publisher websites;
- does not automate university or hospital library login;
- does not store institutional credentials.

Any clinical interpretation should be performed by qualified clinicians using the retrieved sources and appropriate guidelines.

TDQS

A3.5/5.0

Scored across 10 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: building queries, checking availability, extracting PICO, fetching full text, fetching articles, finding related articles, ranking, searching (with and without full pipeline), and summarizing. No ambiguity.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (e.g., build_clinical_query, fetch_pubmed_articles, summarize_evidence). No deviations or mixed conventions.

Tool Count5/5

10 tools is well-scoped for a clinical PubMed assistant. Each tool serves a distinct step in the research workflow without unnecessary overlap or missing critical functionality.

Completeness5/5

The tool set covers the full clinical evidence retrieval workflow: natural language query conversion, search, article fetch, full text retrieval, PICO extraction, ranking, summarization, and related article discovery. No obvious gaps.

Maintenance

ActivityStale
ResponsivenessNo issues