pubmed-mcp-server

v2.10.2

Search PubMed, fetch articles, generate citations, explore MeSH terms, and discover related research.

pubmed.caseyjhand.com/mcp
claude mcp add --transport http pubmed-mcp-server https://pubmed.caseyjhand.com/mcp
codex mcp add pubmed-mcp-server --url https://pubmed.caseyjhand.com/mcp
{
  "mcpServers": {
    "pubmed-mcp-server": {
      "url": "https://pubmed.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http pubmed-mcp-server https://pubmed.caseyjhand.com/mcp
{
  "mcpServers": {
    "pubmed-mcp-server": {
      "command": "bunx",
      "args": [
        "mcp-remote",
        "https://pubmed.caseyjhand.com/mcp"
      ],
      "env": {
        "NCBI_API_KEY": "your-ncbi-api-key",
        "NCBI_ADMIN_EMAIL": "you@example.com",
        "UNPAYWALL_EMAIL": "you@example.com"
      }
    }
  }
}
{
  "mcpServers": {
    "pubmed-mcp-server": {
      "type": "http",
      "url": "https://pubmed.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://pubmed.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

11

pubmed_search_articles

open-world

Search 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 result sets.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "pubmed_search_articles",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "PubMed search query (supports full NCBI syntax)"
    },
    "maxResults": {
      "default": 20,
      "description": "Maximum results to return",
      "type": "integer",
      "minimum": 1,
      "maximum": 1000
    },
    "offset": {
      "default": 0,
      "description": "Result offset for pagination (0-based). PubMed serves at most the first 9999 records of a result set, so this caps at 9998; narrow the query or add filters to reach anything beyond it.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9998
    },
    "sort": {
      "default": "relevance",
      "description": "Sort order: relevance (default), pub_date (newest first), author, or journal",
      "type": "string",
      "enum": [
        "relevance",
        "pub_date",
        "author",
        "journal"
      ]
    },
    "dateRange": {
      "description": "Filter by date range. The filter is applied only when both `minDate` and `maxDate` are non-empty; either one empty disables the entire date range.",
      "type": "object",
      "properties": {
        "minDate": {
          "type": "string",
          "pattern": "^$|^\\d{4}([/\\-.]\\d{1,2}([/\\-.]\\d{1,2})?)?$",
          "description": "Start date (YYYY/MM/DD, YYYY/MM, or YYYY); empty string disables this bound"
        },
        "maxDate": {
          "type": "string",
          "pattern": "^$|^\\d{4}([/\\-.]\\d{1,2}([/\\-.]\\d{1,2})?)?$",
          "description": "End date (YYYY/MM/DD, YYYY/MM, or YYYY); empty string disables this bound"
        },
        "dateType": {
          "default": "pdat",
          "description": "Date type: pdat (publication), mdat (modification), edat (entrez)",
          "type": "string",
          "enum": [
            "pdat",
            "mdat",
            "edat"
          ]
        }
      },
      "required": [
        "minDate",
        "maxDate",
        "dateType"
      ],
      "additionalProperties": false
    },
    "publicationTypes": {
      "description": "Filter by publication type (e.g. \"Review\", \"Clinical Trial\", \"Meta-Analysis\"). Multiple values are OR'd — any match qualifies.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "author": {
      "description": "Filter by author name (e.g. \"Smith J\")",
      "type": "string"
    },
    "journal": {
      "description": "Filter by journal name",
      "type": "string"
    },
    "meshTerms": {
      "description": "Filter by MeSH terms. Multiple terms are AND'd — all must match.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "language": {
      "description": "Filter by language (e.g. \"english\")",
      "type": "string"
    },
    "hasAbstract": {
      "description": "Only include articles with abstracts",
      "type": "boolean"
    },
    "freeFullText": {
      "description": "Only include free full text articles",
      "type": "boolean"
    },
    "species": {
      "description": "Filter by species",
      "type": "string",
      "enum": [
        "humans",
        "animals"
      ]
    },
    "summaryCount": {
      "default": 0,
      "description": "Fetch brief summaries for top N results (0 = PMIDs only). Above the 50 cap, pass the remaining PMIDs to pubmed_fetch_articles.",
      "type": "integer",
      "minimum": 0,
      "maximum": 50
    }
  },
  "required": [
    "query",
    "maxResults",
    "offset",
    "sort",
    "summaryCount"
  ],
  "additionalProperties": false
}
view source ↗

pubmed_fetch_articles

open-world

Fetch full article metadata by PubMed IDs. Returns detailed article information including abstract, authors, journal, MeSH terms.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "pubmed_fetch_articles",
    "arguments": {
      "pmids": "<pmids>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "pmids": {
      "minItems": 1,
      "maxItems": 200,
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^\\d+$"
      },
      "description": "PubMed IDs to fetch"
    },
    "includeMesh": {
      "default": true,
      "description": "Include MeSH terms",
      "type": "boolean"
    },
    "includeGrants": {
      "default": false,
      "description": "Include grant information",
      "type": "boolean"
    }
  },
  "required": [
    "pmids",
    "includeMesh",
    "includeGrants"
  ],
  "additionalProperties": false
}
view source ↗

pubmed_fetch_fulltext

open-world

Fetch 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 copies as HTML-as-Markdown or PDF-as-text. Provide exactly one of `pmcids` (PMC IDs directly), `pmids` (PubMed IDs, auto-resolved), or `dois` (DOIs, auto-resolved to PMC via the ID Converter; preprints and EPMC-only OA fall through to the Europe PMC and Unpaywall layers).

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "pubmed_fetch_fulltext",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "pmcids": {
      "description": "PMC IDs to fetch (e.g. [\"PMC9575052\"]). Provide exactly one of `pmcids`, `pmids`, or `dois`. PMC IDs with no retrievable full text fall through to Europe PMC, then to Unpaywall on the DOI the chain resolves for them.",
      "minItems": 1,
      "maxItems": 10,
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^(?:PMC)?\\d+$"
      }
    },
    "pmids": {
      "description": "PubMed IDs. Provide exactly one of `pmcids`, `pmids`, or `dois`. Articles in PMC are returned as structured JATS; articles not in PMC fall through to Europe PMC (when EPMC has a `fullTextXML`), then to Unpaywall when `UNPAYWALL_EMAIL` is set and a DOI is available.",
      "minItems": 1,
      "maxItems": 10,
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^\\d+$"
      }
    },
    "dois": {
      "description": "DOIs to resolve (e.g. [\"10.21203/rs.3.rs-9010375/v1\"]). Provide exactly one of `pmcids`, `pmids`, or `dois`. Resolved to a PMCID via the PMC ID Converter and returned as structured JATS when the article is in PMC; DOIs with no PMC counterpart (preprints, EPMC-only OA) fall through to Europe PMC, then Unpaywall, when those layers are enabled.",
      "minItems": 1,
      "maxItems": 10,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 3
      }
    },
    "includeReferences": {
      "default": false,
      "description": "Include reference list. Applies to `source=pmc` results only.",
      "type": "boolean"
    },
    "maxSections": {
      "description": "Maximum top-level body sections. Applies to `source=pmc` results only.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    },
    "sections": {
      "description": "Filter to specific sections by title, case-insensitive (e.g. [\"Introduction\", \"Methods\", \"Results\", \"Discussion\"]). Applies to `source=pmc` results only.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "maxCharacters": {
      "description": "Per-article budget for body text, in characters. Counts `source=pmc` section and subsection text, or the `source=unpaywall` `content` body; titles, abstracts, identifiers, and references are never counted or shortened. Applied after `sections`, `maxSections`, and `includeReferences`, so semantic filtering is unaffected. The response-wide ceiling is this value times the number of articles returned. Omit for the full body.",
      "type": "integer",
      "minimum": 1,
      "maximum": 1000000
    },
    "maxCharactersPerSection": {
      "description": "Budget for a single top-level body section, in characters, counting the section text plus its subsections. Combine with `maxCharacters` to cap both one section and the article; the tighter of the two wins. Applies to `source=pmc` results only.",
      "type": "integer",
      "minimum": 1,
      "maximum": 1000000
    },
    "overflowMode": {
      "default": "truncate",
      "description": "How to spend `maxCharacters` across an article that exceeds it. truncate: fill sections in document order, so early sections stay whole and sections past the budget are dropped (counted in `truncation.omittedSections`). outline: split the budget evenly so every section keeps its heading, and an excerpt as far as the budget reaches — use it to survey what an article contains before requesting specific `sections`. Ignored when no budget is set, and identical for `source=unpaywall` bodies, which have no headings to preserve.",
      "type": "string",
      "enum": [
        "truncate",
        "outline"
      ]
    }
  },
  "required": [
    "includeReferences",
    "overflowMode"
  ],
  "additionalProperties": false
}
view source ↗

pubmed_format_citations

open-world

Get formatted citations for PubMed articles in one or more formats (apa, mla, bibtex, ris, vancouver). Pass a single format as a string or multiple as an array.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "pubmed_format_citations",
    "arguments": {
      "pmids": "<pmids>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "pmids": {
      "minItems": 1,
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^\\d+$"
      },
      "description": "PubMed IDs to cite"
    },
    "format": {
      "default": "apa",
      "description": "Citation format(s) to generate — single style as a string or multiple as an array. Allowed values: apa, mla, bibtex, ris, vancouver.",
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "apa",
            "mla",
            "bibtex",
            "ris",
            "vancouver"
          ],
          "description": "Single citation style. One of: apa, mla, bibtex, ris, vancouver."
        },
        {
          "minItems": 1,
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "apa",
              "mla",
              "bibtex",
              "ris",
              "vancouver"
            ]
          },
          "description": "Multiple citation styles to generate. Each entry: apa, mla, bibtex, ris, or vancouver."
        }
      ]
    }
  },
  "required": [
    "pmids",
    "format"
  ],
  "additionalProperties": false
}
view source ↗

pubmed_spell_check

open-world

Spell-check a query and get NCBI's suggested correction. Useful for refining search queries.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "pubmed_spell_check",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 2,
      "description": "PubMed search query to spell-check"
    }
  },
  "required": [
    "query"
  ],
  "additionalProperties": false
}
view source ↗

pubmed_lookup_mesh

open-world

Search and explore the MeSH (Medical Subject Headings) controlled vocabulary. Returns descriptor records with tree numbers, scope notes, and entry terms, plus pagination via offset for paging past the maxResults cap.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "pubmed_lookup_mesh",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "MeSH descriptor name or free-text term to look up"
    },
    "maxResults": {
      "default": 10,
      "description": "Maximum results",
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    },
    "offset": {
      "default": 0,
      "description": "Result offset for pagination (0-based). Pass the `nextOffset` from the previous response to get the following page; the exact-descriptor match is pinned to the first page only.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "includeDetails": {
      "default": true,
      "description": "Fetch full MeSH records (scope notes, tree numbers, entry terms)",
      "type": "boolean"
    }
  },
  "required": [
    "query",
    "maxResults",
    "offset",
    "includeDetails"
  ],
  "additionalProperties": false
}
view source ↗

pubmed_lookup_citation

open-world

Look 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 least journal or year (ECitMatch primary-keys on journal+volume+page; author-only or volume-only inputs guarantee no match); more fields = better match accuracy.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "pubmed_lookup_citation",
    "arguments": {
      "citations": "<citations>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "citations": {
      "minItems": 1,
      "maxItems": 25,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "journal": {
            "description": "Journal title or ISO abbreviation (e.g., \"proc natl acad sci u s a\")",
            "type": "string"
          },
          "year": {
            "description": "Publication year (e.g., \"1991\")",
            "type": "string"
          },
          "volume": {
            "description": "Volume number",
            "type": "string"
          },
          "firstPage": {
            "description": "First page number",
            "type": "string"
          },
          "authorName": {
            "description": "Author name, typically \"lastname initials\" (e.g., \"mann bj\")",
            "type": "string"
          },
          "key": {
            "description": "Arbitrary label to track this citation in results. Auto-assigned if omitted.",
            "type": "string"
          }
        },
        "additionalProperties": false,
        "description": "Citation to match against PubMed. Must include at least journal or year — ECitMatch primary-keys on journal+volume+page, so author-only or volume-only inputs guarantee no match."
      },
      "description": "Citations to look up. More fields = better match accuracy."
    }
  },
  "required": [
    "citations"
  ],
  "additionalProperties": false
}
view source ↗

pubmed_convert_ids

open-world

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

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "pubmed_convert_ids",
    "arguments": {
      "ids": "<ids>",
      "idType": "<idType>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "ids": {
      "minItems": 1,
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "description": "Article identifiers to convert. All IDs must be the same type. DOIs: \"10.1093/nar/gks1195\", PMIDs: \"23193287\", PMCIDs: \"PMC3531190\" (the \"PMC\" prefix is optional — bare digits like \"3531190\" are also accepted)."
    },
    "idType": {
      "type": "string",
      "enum": [
        "pmcid",
        "pmid",
        "doi"
      ],
      "description": "The type of IDs being submitted. Required so the API can unambiguously resolve them."
    }
  },
  "required": [
    "ids",
    "idType"
  ],
  "additionalProperties": false
}
view source ↗

pubmed_europepmc_fetch

open-world

Fetch complete Europe PMC records — including the full, untruncated abstract — for records addressed by `source` plus `epmcId`. Pairs with `pubmed_europepmc_search`, which returns bounded `abstractSnippet` values and flags cut ones with `abstractTruncated: true`; pass those hits' `source` and `epmcId` here to read the whole abstract. This is the retrieval path for preprint (`PPR`), patent (`PAT`), and Agricola (`AGR`) records, which frequently carry no PMID and no DOI, so `pubmed_fetch_articles` and `pubmed_fetch_fulltext` cannot address them. Up to 25 records per call.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "pubmed_europepmc_fetch",
    "arguments": {
      "records": "<records>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "records": {
      "minItems": 1,
      "maxItems": 25,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "MED",
              "PMC",
              "PPR",
              "PAT",
              "AGR"
            ],
            "description": "Europe PMC source corpus — `MED` (PubMed), `PMC` (PubMed Central), `PPR` (preprint), `PAT` (patent), `AGR` (Agricola). Copy it from the search hit's `source`. `PMC` paired with a PMCID resolves whether or not the article is also indexed in PubMed, and a PubMed-indexed one comes back as its canonical `MED` record carrying that PMCID in `pmcId`."
          },
          "epmcId": {
            "type": "string",
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$",
            "description": "Europe PMC's own record id within that source. Copy it from the search hit's `epmcId` — for `MED` records this is the PMID; for the other sources it is an EPMC-native accession."
          }
        },
        "required": [
          "source",
          "epmcId"
        ],
        "additionalProperties": false,
        "description": "One record address: the Europe PMC source corpus plus its id within that corpus"
      },
      "description": "Records to retrieve, each addressed by the `source` and `epmcId` of a `pubmed_europepmc_search` hit. The whole batch resolves in one Europe PMC request."
    }
  },
  "required": [
    "records"
  ],
  "additionalProperties": false
}
view source ↗

Resources

1

PubMed database metadata including field list, last update date, and record count.

uri pubmed://database/info mime application/json

Prompts

1

Generate a structured research plan outline for a biomedical research project.

  • titlerequired — Project title
  • goalrequired — Primary research goal
  • keywordsrequired — Research keywords (comma-separated)
  • organism — Target organism
  • includeAgentPrompts — Include inline guidance blocks under each phase with execution-time hints ("true" or "false"; omitted = "false")