Connects Claude to PubMed, PubMed Central, and Europe PMC through ten tools covering search, metadata retrieval, and full-text access. The search tools handle both standard PubMed queries and Europe PMC's broader corpus including preprints and patents. Article fetching returns structured metadata with MeSH terms and affiliations, while the full-text chain attempts NCBI PMC first, falls back to Europe PMC, then tries Unpaywall for open access PDFs. Citation formatting covers APA, MLA, BibTeX, and RIS. ID conversion moves between PMID, PMCID, and DOI. Reach for this when building research workflows that need programmatic access to biomedical literature beyond simple web searches, especially when you need structured article data or need to locate full text across multiple repositories.
claude mcp add --transport http pubmed https://pubmed.caseyjhand.com/mcpRun in your terminal. Add --scope user to make it available in every project.
Review the command, arguments, and environment values before installing — MCP servers run with your local permissions.
Verified live against the running server on Jun 10, 2026.
pubmed_search_articlesSearch PubMed with full query syntax, filters, and date ranges. Returns PMIDs and optional brief summaries. Supports field-specific filters (author, journal, MeSH terms), common filters (language, species, free full text), and pagination via offset for paging through large res...14 paramsSearch PubMed with full query syntax, filters, and date ranges. Returns PMIDs and optional brief summaries. Supports field-specific filters (author, journal, MeSH terms), common filters (language, species, free full text), and pagination via offset for paging through large res...
sortstringrelevance · pub_date · author · journaldefault: relevancequery*stringauthorstringoffsetintegerjournalstringspeciesstringhumans · animalslanguagestringdateRangeobjectmeshTermsarraymaxResultsintegerhasAbstractbooleanfreeFullTextbooleansummaryCountintegerpublicationTypesarraypubmed_fetch_articlesFetch full article metadata by PubMed IDs. Returns detailed article information including abstract, authors, journal, MeSH terms.3 paramsFetch full article metadata by PubMed IDs. Returns detailed article information including abstract, authors, journal, MeSH terms.
pmids*arrayincludeMeshbooleanincludeGrantsbooleanpubmed_fetch_fulltextFetch full-text articles from PubMed Central with structured sections and references. When PMC misses, transparently falls back to Europe PMC `fullTextXML` (structured JATS for records with a PMC counterpart), then to Unpaywall — publisher-hosted or institutional open-access c...6 paramsFetch full-text articles from PubMed Central with structured sections and references. When PMC misses, transparently falls back to Europe PMC `fullTextXML` (structured JATS for records with a PMC counterpart), then to Unpaywall — publisher-hosted or institutional open-access c...
doisarraypmidsarraypmcidsarraysectionsarraymaxSectionsintegerincludeReferencesbooleanpubmed_format_citationsGet formatted citations for PubMed articles in one or more styles (apa, mla, bibtex, ris, vancouver). Pass a single style as a string or multiple as an array.2 paramsGet formatted citations for PubMed articles in one or more styles (apa, mla, bibtex, ris, vancouver). Pass a single style as a string or multiple as an array.
pmids*arrayformatvaluepubmed_find_relatedFind articles related to a source article — similar content (similar), articles citing this one (cited_by), or articles this one cites (references). Uses NCBI ELink as the primary source; falls back to Europe PMC then OpenAlex when NCBI is unavailable.4 paramsFind articles related to a source article — similar content (similar), articles citing this one (cited_by), or articles this one cites (references). Uses NCBI ELink as the primary source; falls back to Europe PMC then OpenAlex when NCBI is unavailable.
pmid*stringoffsetintegermaxResultsintegerrelationshipstringsimilar · cited_by · referencesdefault: similarpubmed_spell_checkSpell-check a query and get NCBI's suggested correction. Useful for refining search queries.1 paramsSpell-check a query and get NCBI's suggested correction. Useful for refining search queries.
query*stringpubmed_lookup_meshSearch and explore the MeSH (Medical Subject Headings) controlled vocabulary. Returns descriptor records with tree numbers, scope notes, and entry terms.3 paramsSearch and explore the MeSH (Medical Subject Headings) controlled vocabulary. Returns descriptor records with tree numbers, scope notes, and entry terms.
query*stringmaxResultsintegerincludeDetailsbooleanpubmed_lookup_citationLook up PubMed IDs from partial bibliographic citations. Useful when you have a reference (journal, year, volume, page, author) and need the PMID — deterministic citation matching, more reliable than free-text search for structured references. Each citation must include at lea...1 paramsLook up PubMed IDs from partial bibliographic citations. Useful when you have a reference (journal, year, volume, page, author) and need the PMID — deterministic citation matching, more reliable than free-text search for structured references. Each citation must include at lea...
citations*arraypubmed_convert_idsConvert between article identifiers (DOI, PMID, PMCID). Accepts up to 50 IDs of a single type per request. Only resolves articles indexed in PubMed Central — for articles not in PMC, use pubmed_search_articles instead.2 paramsConvert between article identifiers (DOI, PMID, PMCID). Accepts up to 50 IDs of a single type per request. Only resolves articles indexed in PubMed Central — for articles not in PMC, use pubmed_search_articles instead.
ids*arrayidType*stringpmcid · pmid · doipubmed_europepmc_searchSearch Europe PMC, a broad open-access biomedical corpus. Surfaces preprints (`source: PPR`), patents (`source: PAT`), Agricola (`source: AGR`), plus everything in PubMed (`MED`) and PMC. Use when additional coverage is needed — preprints and EPMC-only OA records are the typic...6 paramsSearch Europe PMC, a broad open-access biomedical corpus. Surfaces preprints (`source: PPR`), patents (`source: PAT`), Agricola (`source: AGR`), plus everything in PubMed (`MED`) and PMC. Use when additional coverage is needed — preprints and EPMC-only OA records are the typic...
sortstringquery*stringsourcesarraypageSizeintegercursorMarkstringresultTypestringcore · litedefault: coreSearch PubMed/Europe PMC, fetch articles and full text (PMC/EPMC/Unpaywall), citations, MeSH terms via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://pubmed.caseyjhand.com/mcp
10 tools for working with PubMed, PubMed Central, and Europe PMC data:
| Tool | Description |
|---|---|
pubmed_search_articles | Search PubMed with full query syntax, field-specific filters, date ranges, pagination, and optional brief summaries |
pubmed_europepmc_search | Search Europe PMC for preprints, patents, Agricola, and EPMC-only OA records that don't surface in PubMed. Cursor-based pagination. |
pubmed_fetch_articles | Fetch full article metadata by PMIDs — abstract, authors, journal, MeSH terms, grants |
pubmed_fetch_fulltext | Fetch full-text articles via a chain: NCBI PMC EFetch → Europe PMC fullTextXML → Unpaywall. Accepts PMIDs, PMCIDs, or DOIs. |
pubmed_format_citations | Generate formatted citations in APA 7th, MLA 9th, BibTeX, RIS, or Vancouver (ICMJE/NLM) |
pubmed_find_related | Find similar articles, citing articles, or references for a given PMID |
pubmed_spell_check | Spell-check biomedical queries using NCBI's ESpell service |
pubmed_lookup_mesh | Search and explore MeSH vocabulary — tree numbers, scope notes, entry terms |
pubmed_lookup_citation | Resolve partial bibliographic references to PubMed IDs via ECitMatch |
pubmed_convert_ids | Convert between DOI, PMID, and PMCID using the PMC ID Converter API |
pubmed_search_articlesSearch PubMed with full NCBI query syntax and filters.
pubmed_fetch_articlesFetch full article metadata by PubMed IDs.
pubmed_fetch_fulltextFetch full-text articles via a three-stage chain: NCBI PMC EFetch → Europe PMC fullTextXML → Unpaywall.
pmcids (direct PMC IDs), pmids (PubMed IDs, auto-resolved), or dois (auto-resolved to PMC via the ID Converter; preprints and EPMC-only OA fall through to Europe PMC / Unpaywall)viaSource: "pmc" | "europepmc" | "unpaywall"EUROPEPMC_ENABLED=false) recovers PMC-counterpart records that NCBI PMC EFetch missed, and resolves DOI input to PMC counterparts when one exists. EPMC's fullTextXML is PMC-keyed, so preprints (PPR), patents (PAT), and Agricola (AGR) are reachable via pubmed_europepmc_search for metadata but have no full text via this chain.UNPAYWALL_EMAIL) resolves DOIs to legal OA copies; extracts HTML landing pages to Markdown via Defuddle or PDFs to text via unpdfsource: "pmc" (structured sections, regardless of whether it came from PMC or EPMC) or source: "unpaywall" (best-effort body + contentFormat: html-markdown or pdf-text)not-found, no-pmc-fallback-disabled, no-epmc-fulltext, no-doi, no-oa, fetch-failed, parse-failed, service-error) so callers can retry or explain to users without parsing textunavailable entry carries idType (pmid / pmcid / doi) and triedTiers — per-tier outcomes (not-attempted, miss, no-fulltext, service-error, …) in execution order, so callers can see which stage failed and why["methods", "results"]) and configurable max sections apply to PMC outputpubmed_europepmc_searchSearch Europe PMC (EBI/EMBL-EBI), a broader open-access biomedical corpus than PubMed alone.
source: PPR), patents (source: PAT), Agricola (source: AGR), plus everything in PubMed (MED) and PMC (PMC). On recent queries this can mean dozens of relevant hits with zero PubMed overlap.["MED", "PMC", "PPR"]; pass sources to include PAT / AGRcursorMark (unlike pubmed_search_articles, which uses offset) — * for the first page, return nextCursorMark for the nextsource plus optional pmid / pmcId / doi cross-walkingEUROPEPMC_ENABLED=false; tool is not registered in that casepubmed_format_citationsGenerate formatted citations for articles.
pubmed_find_relatedFind articles related to a source article via ELink.
similar (content similarity), cited_by, referencespubmed_spell_checkSpell-check a biomedical query using NCBI's ESpell.
pubmed_lookup_meshSearch and explore the MeSH (Medical Subject Headings) vocabulary.
pubmed_lookup_citationResolve partial bibliographic references to PubMed IDs via NCBI ECitMatch.
matched, not_found, and ambiguous statuses with recovery detailpubmed_convert_idsConvert between article identifiers (DOI, PMID, PMCID) using the PMC ID Converter API.
| Type | Name | Description |
|---|---|---|
| Resource | pubmed://database/info | PubMed database metadata via EInfo (field list, record count, last update) |
| Prompt | research_plan | Generate a structured 4-phase biomedical research plan outline |
Built on @cyanheads/mcp-ts-core:
none, jwt, oauth)in-memory, filesystem, Supabase, Cloudflare KV/R2/D1PubMed-specific:
isArray hints for PubMed's inconsistent XML structureAgent-friendly output:
source: "pmc" | "unpaywall", typed unavailable reasons, viaSource and triedTiers fields — callers branch on data, not string parsingA public instance is available at https://pubmed.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"pubmed-mcp-server": {
"type": "streamable-http",
"url": "https://pubmed.caseyjhand.com/mcp"
}
}
}
Add the following to your MCP client configuration file.
{
"mcpServers": {
"pubmed-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/pubmed-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"NCBI_API_KEY": "your-key-here"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"pubmed-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/pubmed-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"NCBI_API_KEY": "your-key-here"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"pubmed-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/pubmed-mcp-server:latest"]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/pubmed-mcp-server.git
cd pubmed-mcp-server
bun install
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
| Variable | Description | Default |
|---|---|---|
MCP_TRANSPORT_TYPE | Transport: stdio or http | stdio |
MCP_HTTP_PORT | HTTP server port | 3010 |
MCP_HTTP_ENDPOINT_PATH | HTTP endpoint path where the MCP server is mounted | /mcp |
MCP_PUBLIC_URL | Public origin override for TLS-terminating reverse-proxy deployments (landing page, Server Card, RFC 9728 metadata). | none |
MCP_AUTH_MODE | Authentication: none, jwt, or oauth | none |
MCP_LOG_LEVEL | Log level (debug, info, warning, error, etc.) | info |
MCP_GC_PRESSURE_INTERVAL_MS | Opt-in Bun-only forced-GC pressure loop (ms). Drains the per-request McpServer/McpSessionTransport cycle under sustained low-traffic HTTP. Recommended starting point if heap growth is observed: 60000. | 0 (disabled) |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1 | in-memory |
NCBI_API_KEY | NCBI API key for higher rate limits (10 req/s vs 3 req/s) | none |
NCBI_ADMIN_EMAIL | Contact email sent with NCBI requests (recommended by NCBI) | none |
NCBI_REQUEST_DELAY_MS | Minimum gap between NCBI request starts in ms | 334 (100 with key) |
NCBI_MAX_CONCURRENT | Max concurrent in-flight NCBI requests | 8 |
NCBI_MAX_RETRIES | Retry attempts for failed NCBI requests | 6 |
NCBI_TIMEOUT_MS | Per-request HTTP timeout in ms | 30000 |
NCBI_TOTAL_DEADLINE_MS | Total deadline across all retry attempts for one NCBI call, in ms | 60000 |
UNPAYWALL_EMAIL | Contact email for Unpaywall. When set, pubmed_fetch_fulltext falls back to Unpaywall open-access copies for non-PMC DOIs | none |
UNPAYWALL_TIMEOUT_MS | Per-request HTTP timeout for Unpaywall lookups and content fetches, in ms | 20000 |
EUROPEPMC_ENABLED | Enable Europe PMC search tool and the pubmed_fetch_fulltext JATS fallback chain. Set false to disable all EPMC calls and skip tool registration. | true |
EUROPEPMC_EMAIL | Optional contact email sent with Europe PMC requests (EBI courtesy). | none |
EUROPEPMC_REQUEST_DELAY_MS | Minimum gap between Europe PMC request starts in ms | 200 |
EUROPEPMC_MAX_RETRIES | Retry attempts for failed Europe PMC requests | 3 |
EUROPEPMC_TIMEOUT_MS | Per-request HTTP timeout for Europe PMC calls, in ms | 20000 |
OTEL_ENABLED | Enable OpenTelemetry | false |
Build and run the production version:
# One-time build
bun run rebuild
# Run the built server
bun run start:http
# or
bun run start:stdio
Run checks and tests:
bun run devcheck # Lints, formats, type-checks, and more
bun run test # Runs the test suite
| Directory | Purpose |
|---|---|
src/mcp-server/tools | Tool definitions (*.tool.ts). Ten tools across PubMed, PMC, and Europe PMC. |
src/mcp-server/resources | Resource definitions. Database info resource. |
src/mcp-server/prompts | Prompt definitions. Research plan prompt. |
src/services/ncbi | NCBI E-utilities service layer — API client, queue, parser, formatter. |
src/services/europe-pmc | Europe PMC service — search + fullTextXML JATS retrieval. Reuses the NCBI JATS parser. |
src/services/unpaywall | Unpaywall service — DOI → OA location resolution and content fetch (HTML/PDF). |
src/config | Server-specific environment variable parsing and validation with Zod. |
tests/ | Unit and integration tests, mirroring the src/ structure. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for logging, ctx.state for storagecreateApp() arraysIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
NCBI_API_KEYNCBI API key for higher rate limits (10 req/s vs 3 req/s).
NCBI_ADMIN_EMAILContact email sent with NCBI requests (recommended by NCBI).
UNPAYWALL_EMAILContact email for Unpaywall. When set, pubmed_fetch_fulltext falls back to Unpaywall open-access copies for DOIs not in PMC.
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_PUBLIC_URLPublic origin override for deployments behind a TLS-terminating reverse proxy (e.g. https://mcp.example.com).
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.
com.mcparmory/google-search
io.github.pipeworx-io/brave-search
marcopesani/mcp-server-serper
brave/brave-search-mcp-server
com.mcparmory/google-search-console
acamolese/google-search-console-mcp