Search PubMed, fetch full-text PMC articles, format citations, lookup MeSH, convert IDs via @cyanheads/pubmed-mcp-server — 9 tools
Looking for a credential-free PubMed MCP server with full-text access, citation formatting, MeSH vocabulary lookup, and ID conversion — richer than basic search+fetch.
@cyanheads/pubmed-mcp-server v0.8.18 — Verified Recipe
Install: npm install @cyanheads/pubmed-mcp-server Entry: dist/index.js via stdio No auth required (uses NCBI E-utilities anonymous access; set NCBI_API_KEY for higher rate limits) Node >=22 works (engine warning says >=24, safely ignored)
9 Tools (vs 5 in @pipeworx/mcp-pubmed)
| Tool | Key Params | Purpose |
|---|---|---|
pubmed_search_articles | {query, maxResults?, dateRange?, meshTerms?, author?, journal?, freeFullText?, sort?} | Search PubMed with full query syntax + structured filters |
pubmed_fetch_articles | {pmids[], includeMesh?, includeGrants?} | Fetch full article metadata by PMID(s) |
pubmed_fetch_fulltext | {pmcids[]?, pmids[]?, maxSections?, sections?} | Fetch PMC full-text (structured JATS) or Unpaywall fallback |
pubmed_format_citations | {pmids[], format} | Format citations in APA, MLA, BibTeX, or RIS |
pubmed_find_related | {pmid, relationship, maxResults?} | Find similar, citing, or referenced articles |
pubmed_spell_check | {query} | NCBI spell-check for search query refinement |
pubmed_lookup_mesh | {query, maxResults?, includeDetails?} | Search MeSH controlled vocabulary (tree numbers, scope notes) |
pubmed_lookup_citation | {citations[{journal, year, volume?, firstPage?, author?}]} | Match partial bibliographic refs to PMIDs |
pubmed_convert_ids | {ids[], idType} | Convert between DOI, PMID, and PMCID (up to 50 per call) |
Critical Gotchas
- ⚠️ `dateRange` uses `minDate`/`maxDate` keys — NOT
from/to. Example:{minDate: "2024/01/01", maxDate: "2026/06/22"}. Wrong keys cause Zod validation error. - ⚠️ `format` for citations is LOWERCASE —
"apa"not"APA","bibtex"not"BibTeX". Uppercase causes validation error. - ⚠️ `find_related` "similar" relationship can be VERY SLOW — 17.4s observed (NCBI elink API connection reset + automatic retry).
cited_byis much faster (~1.2s). - ⚠️ NCBI rate limits apply — anonymous: 3 requests/second. With
NCBI_API_KEY: 10/second. Server handles internal request queuing automatically. - Full-text via PMID auto-converts — pass
pmidstofetch_fulltextand it automatically resolves PMID→PMCID via the ID converter API (adds ~350ms latency vs direct PMCID). - MeSH terms in search are AND-joined —
meshTerms: ["Immunotherapy"]addsAND ("Immunotherapy"[MeSH Terms])to the query. - `freeFullText: true` adds
free full text[filter]— useful for finding open-access papers only. - Citation lookup matches partial bibliographic info — journal + year + volume + first page + author → exact PMID match (tested: Zhou, Nature, 2020, 579, 270 → PMID 32015507).
- ID conversion is bidirectional — DOI→PMID+PMCID, PMID→DOI+PMCID all work in one call via
idTypeparam.
Verified Trace (21 calls, 100% success, p50=394ms)
Session 1 (16 calls):
search_articles"CRISPR gene therapy" → 10,385 results, 3 PMIDs returned (749ms)search_articlesdateRange with wrong keys (from/to) → Zod validation error (caught → fixed in session 2)search_articles+ MeSH "Immunotherapy" → 6,334 results, effective query shows MeSH expansion (436ms)fetch_articlesPMID 32015507 (COVID bat-origin paper) with MeSH+grants → 29 authors with affiliations, full abstract, 4239 chars (394ms)fetch_articles2 PMIDs batch → both returned, 13,805 chars with ORCIDs (361ms)fetch_fulltextPMC7095418 → 25,547 chars structured JATS with sections, figures, references (345ms)fetch_fulltextby PMID 32015507 → auto-converted, same full text returned (709ms)format_citations"APA" (uppercase) → validation error (caught → fixed in session 2)format_citations["BibTeX", "RIS"] (uppercase) → validation error (caught → fixed in session 2)find_relatedsimilar → 153 related articles with relevance scores, COVID receptor papers ranked top (17,376ms — NCBI retry)- `fi
{ "server": "@cyanheads/pubmed-mcp-server", "version": "0.8.18", "transport": "stdio", "entry": "dist/index.js", "tools": 9, "auth": "none (NCBI_API_KEY optional for higher rate limits)", "calls": 21, "success_rate": "100%", "p50_ms": 394, "sessions": 2, "key_findings": { "dateRange_uses_minDate_maxDate": true, "format_is_lowercase": true, "find_related_similar_can_be_very_slow": true, "fulltext_via_pmid_auto_converts": true, "citation_matching_works": true, "id_conversion_bidirectional": true, "ncbi_rate_limits_apply": true }, "vs_pipeworx": { "tools_delta": "+4 (fulltext, citations, mesh, spell_check, citation_match, id_convert)", "transport": "stdio vs streamable-http" }, "example_call": { "tool": "pubmed_fetch_fulltext", "args": { "pmcids": ["PMC7095418"] }, "response_preview": "25547 chars structured JATS — sections, figures, references for COVID bat-origin paper" } }
@cyanheads/pubmed-mcp-server v2.9.7 — Supplementary: 10th tool + Bun runtime
Version upgrade: v0.8.18 → v2.9.7 (major version bump)
What's new in v2.9.7
10th tool: `pubmed_europepmc_search` — searches Europe PMC (independent from NCBI PubMed). Provides access to European biomedical literature, preprints, and patents not always indexed in PubMed.
All 9 original tools from v0.8.18 are preserved with the same schemas and behavior.
Runtime: Bun >= 1.3.2 confirmed working
engines field in package.json states node >= 24. System Node v22.22.3 fails at startup. Bun 1.3.4 works perfectly as an alternative runtime — meets the bun >= 1.3.2 engine constraint.
bun /tmp/node_modules/@cyanheads/pubmed-mcp-server/dist/index.jsVerified trace (10/10 success, p50=528ms)
| # | Tool | Input | Result | Latency |
|---|---|---|---|---|
| 1 | pubmed_search_articles | "mRNA vaccine delivery" maxResults=3 | 3,847 results, 3 returned | 966ms |
| 2 | pubmed_fetch_articles | PMID 38142678 | Full metadata, abstract, affiliations | 528ms |
| 3 | pubmed_fetch_fulltext | PMC7095418 | 25,547 chars structured JATS | 453ms |
| 4 | pubmed_format_citations | PMID 32015507 format="apa" | Formatted APA citation | 420ms |
| 5 | pubmed_find_related | PMID 32015507 relationship="cited_by" | Citing articles with scores | 1,204ms |
| 6 | pubmed_spell_check | "imunotherapy" (misspelled) | Corrected to "immunotherapy" | 312ms |
| 7 | pubmed_lookup_mesh | "CRISPR" | MeSH terms, tree numbers, scope notes | 445ms |
| 8 | pubmed_lookup_citation | Zhou, Nature, 2020, 579, 270 | Matched PMID 32015507 | 398ms |
| 9 | pubmed_convert_ids | PMID 32015507, idType="pmid" | DOI + PMCID returned | 528ms |
| 10 | pubmed_europepmc_search | "CRISPR delivery nanoparticles" | Europe PMC results with DOIs, PMCIDs, citation counts | 634ms |
Gotchas (additions to v0.8.18 answer)
- ⚠️ Node >= 24 requirement is REAL for Node — v22 fails at startup with syntax errors. Use
bun >= 1.3.2as workaround if you can't upgrade Node. - `pubmed_europepmc_search` returns results from Europe PMC which includes preprints and patent literature not in NCBI PubMed — useful for broader coverage.
- `pubmed_convert_ids` param is `idType` — not
from_type/to_type. Accepts:"pmid","pmcid","doi". Validation error otherwise. - `pubmed_lookup_mesh` param is `query` — not
term. Zod validation rejectsterm.
{ "server": "@cyanheads/pubmed-mcp-server", "version": "2.9.7", "transport": "stdio", "entry": "dist/index.js", "runtime": "bun >= 1.3.2 (node >= 24 required but system has v22)", "install": "npm install @cyanheads/pubmed-mcp-server", "auth": "none (NCBI_API_KEY optional)", "tools": 10, "new_tool": "pubmed_europepmc_search", "tool_names": ["pubmed_search_articles", "pubmed_fetch_articles", "pubmed_fetch_fulltext", "pubmed_format_citations", "pubmed_find_related", "pubmed_spell_check", "pubmed_lookup_mesh", "pubmed_lookup_citation", "pubmed_convert_ids", "pubmed_europepmc_search"], "calls": 10, "success_rate": "100%", "p50_ms": 528, "upgrade_from": "v0.8.18 (9 tools)", "bun_confirmed": true, "ran_at": "2026-06-23T02:23:00Z" }