Skip to main content
Glama
cyanheads

pubmed-mcp-server

by cyanheads

Pubmed Search Articles

pubmed_search_articles
Read-only

Search PubMed by query, filters, and date ranges to retrieve PMIDs and optional summaries for research.

Instructions

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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sortNoSort order: relevance (default), pub_date (newest first), author, or journalrelevance
queryYesPubMed search query (supports full NCBI syntax). Must carry a search term: a value that is blank once markup is stripped is rejected rather than sent to PubMed as an empty term.
authorNoFilter by author name (e.g. "Smith J")
offsetNoResult 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.
journalNoFilter by journal name
speciesNoFilter by species
languageNoFilter by language (e.g. "english")
dateRangeNoFilter by date range. The filter is applied only when both `minDate` and `maxDate` are non-empty; either one empty disables the entire date range.
meshTermsNoFilter by MeSH terms. Multiple terms are AND'd — all must match.
maxResultsNoMaximum results to return
hasAbstractNoOnly include articles with abstracts
freeFullTextNoOnly include free full text articles
summaryCountNoFetch brief summaries for top N results (0 = PMIDs only). Above the 50 cap, pass the remaining PMIDs to pubmed_fetch_articles.
publicationTypesNoFilter by publication type (e.g. "Review", "Clinical Trial", "Meta-Analysis"). Multiple values are OR'd — any match qualifies.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
errorNoPresent when the call failed. Absent on success.
pmidsNoPubMed IDs
queryNoOriginal query
noticeNoOptional guidance when the result set does not reflect what was asked for — a field tag PubMed ignored, a phrase it matched nothing for, a dateRange dropped for having one bound, no matches at all, or paging past the end. Absent when nothing applies.
offsetNoResult offset used
searchUrlNoPubMed search URL
summariesNoBrief summaries (empty array when summaryCount is 0)
totalCountNoTotal matching articles
appliedFiltersNoNormalized filter values that were applied to the PubMed query
effectiveQueryNoSanitized query sent to PubMed after applying all active filters

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed9 schema fields changedv2.10.12
    • changedInput schema / properties / query / description
      Previous value: -"PubMed search query (supports full NCBI syntax)"New value: +"PubMed search query (supports full NCBI syntax). Must carry a search term: a value that is blank once markup is stripped is rejected rather than sent to PubMed as an empty term."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `queue_full`: Local NCBI request queue is at capacity. `ncbi_unreachable`: NCBI E-utilities is unreachable after all retry attempts. `ncbi_deadline_exceeded`: Total request deadline expired before NCBI returned a response. `ncbi_invalid_response`: NCBI returned a body that could not be parsed (invalid XML/JSON). `ncbi_resource_not_found`: NCBI returned a structured \"not found\" error for the requested ID(s). Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `queue_full`: Local NCBI request queue is at capacity. `ncbi_unreachable`: NCBI E-utilities is unreachable after all retry attempts. `ncbi_deadline_exceeded`: Total request deadline expired before NCBI returned a response. `ncbi_invalid_response`: NCBI returned a body that could not be parsed (invalid XML/JSON). `ncbi_resource_not_found`: NCBI returned a structured \"not found\" error for the requested ID(s). `blank_query`: The query holds no search term once whitespace, and any markup the tool strips first, are removed — so NCBI would receive a blank term. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "queue_full",
      -  "ncbi_unreachable",
      -  "ncbi_deadline_exceeded",
      -  "ncbi_invalid_response",
      -  "ncbi_resource_not_found"
      -]New value: +[
      +  "queue_full",
      +  "ncbi_unreachable",
      +  "ncbi_deadline_exceeded",
      +  "ncbi_invalid_response",
      +  "ncbi_resource_not_found",
      +  "blank_query"
      +]
    • changedOutput schema / properties / summaries / items / properties / authors / description
      Previous value: -"Formatted author string"New value: +"Formatted author string — the first three of the record's own authors, then \"et al.\". On an NCBI Bookshelf chapter these are the chapter's authors; the book's editors are reported separately in `editors`."
    • addedOutput schema / properties / summaries / items / properties / bookTitle
      Added value: +{
      +  "description": "Title of the book an NCBI Bookshelf record belongs to, e.g. \"GeneReviews(®)\". Present instead of `source` on a book record; absent on a journal article.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / summaries / items / properties / docType
      Added value: +{
      +  "description": "What PubMed classifies this record as: \"chapter\" or \"book\" for an NCBI Bookshelf record, \"citation\" for an ordinary journal article. Absent when PubMed supplies none.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / summaries / items / properties / editors
      Added value: +{
      +  "description": "Editors of the containing book, kept out of `authors` so they cannot displace the record's own authors. Absent on a journal article and on a book that credits no editors.",
      +  "items": {
      +    "description": "One editor, \"Surname Initials\" as ESummary renders it",
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / summaries / items / properties / publisherName
      Added value: +{
      +  "description": "Publisher of the book an NCBI Bookshelf record belongs to. Present only on a book record; absent on a journal article.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / summaries / items / properties / source / description
      Previous value: -"Journal source"New value: +"Journal the article appeared in. Absent on an NCBI Bookshelf record, which has no journal — its venue is in `bookTitle` and `publisherName` instead, and `docType` says which kind of record it is."
  2. Changed6 schema fields changedv2.10.4
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "query",
      +      "offset",
      +      "pmids",
      +      "summaries",
      +      "searchUrl",
      +      "effectiveQuery",
      +      "totalCount",
      +      "appliedFilters"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `queue_full`: Local NCBI request queue is at capacity. `ncbi_unreachable`: NCBI E-utilities is unreachable after all retry attempts. `ncbi_deadline_exceeded`: Total request deadline expired before NCBI returned a response. `ncbi_invalid_response`: NCBI returned a body that could not be parsed (invalid XML/JSON). `ncbi_resource_not_found`: NCBI returned a structured \"not found\" error for the requested ID(s). Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "queue_full",
      +            "ncbi_unreachable",
      +            "ncbi_deadline_exceeded",
      +            "ncbi_invalid_response",
      +            "ncbi_resource_not_found"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "query",
      -  "offset",
      -  "pmids",
      -  "summaries",
      -  "searchUrl",
      -  "effectiveQuery",
      -  "totalCount",
      -  "appliedFilters"
      -]
  3. Changed5 schema fields changedv2.10.2
    • changedInput schema / properties / offset / description
      Previous value: -"Result offset for pagination (0-based)"New value: +"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."
    • changedInput schema / properties / offset / maximum
      Previous value: -9007199254740991New value: +9998
    • changedInput schema / properties / summaryCount / description
      Previous value: -"Fetch brief summaries for top N results (0 = PMIDs only)"New value: +"Fetch brief summaries for top N results (0 = PMIDs only). Above the 50 cap, pass the remaining PMIDs to pubmed_fetch_articles."
    • changedOutput schema / properties / notice / description
      Previous value: -"Optional guidance when results are empty or paging overshot — e.g. how to broaden filters or reset offset. Absent on successful result pages."New value: +"Optional guidance when the result set does not reflect what was asked for — a field tag PubMed ignored, a phrase it matched nothing for, a dateRange dropped for having one bound, no matches at all, or paging past the end. Absent when nothing applies."
    • changedOutput schema / properties / summaries / items / properties / doi / description
      Previous value: -"DOI"New value: +"DOI, cased as NCBI reports it. DOIs are case-insensitive by spec and no case normalization is applied here, so casing can differ from a Europe PMC-sourced `doi` — compare the two case-insensitively."
  4. Changed3 schema fields changedv2.9.4
    • addedOutput schema / properties / totalCount
      Added value: +{
      +  "description": "Total matching articles",
      +  "type": "number"
      +}
    • removedOutput schema / properties / totalFound
      Removed value: -{
      -  "description": "Total matching articles",
      -  "type": "number"
      -}
    • changedOutput schema / required
      Previous value: -[
      -  "query",
      -  "offset",
      -  "pmids",
      -  "summaries",
      -  "searchUrl",
      -  "effectiveQuery",
      -  "totalFound",
      -  "appliedFilters"
      -]New value: +[
      +  "query",
      +  "offset",
      +  "pmids",
      +  "summaries",
      +  "searchUrl",
      +  "effectiveQuery",
      +  "totalCount",
      +  "appliedFilters"
      +]
  5. Changed1 schema field changedv2.7.8
    • changedOutput schema / required
      Previous value: -[
      -  "query",
      -  "effectiveQuery",
      -  "appliedFilters",
      -  "totalFound",
      -  "offset",
      -  "pmids",
      -  "summaries",
      -  "searchUrl"
      -]New value: +[
      +  "query",
      +  "offset",
      +  "pmids",
      +  "summaries",
      +  "searchUrl",
      +  "effectiveQuery",
      +  "totalFound",
      +  "appliedFilters"
      +]
  6. Addedv2.7.6
  7. Removedv2.7.4
  8. Changed30 schema fields changedv2.3.2
    • removedInput schema / additionalProperties
      Removed value: -false
    • addedInput schema / properties / author
      Added value: +{
      +  "description": "Filter by author name (e.g. \"Smith J\")",
      +  "type": "string"
      +}
    • removedInput schema / properties / dateRange / additionalProperties
      Removed value: -false
    • changedInput schema / properties / dateRange / description
      Previous value: -"Defines an optional date range for the search."New value: +"Filter by date range"
    • changedInput schema / properties / dateRange / properties / dateType / description
      Previous value: -"The type of date to filter by: 'pdat' (Publication Date), 'mdat' (Modification Date), 'edat' (Entrez Date). Default is 'pdat'."New value: +"Date type: pdat (publication), mdat (modification), edat (entrez)"
    • changedInput schema / properties / dateRange / properties / maxDate / description
      Previous value: -"The end date for the search range (YYYY, YYYY/MM, or YYYY/MM/DD)."New value: +"End date (YYYY/MM/DD, YYYY/MM, or YYYY)"
    • removedInput schema / properties / dateRange / properties / maxDate / pattern
      Removed value: -"^\\d{4}(\\/\\d{2}(\\/\\d{2})?)?$"
    • changedInput schema / properties / dateRange / properties / minDate / description
      Previous value: -"The start date for the search range (YYYY, YYYY/MM, or YYYY/MM/DD)."New value: +"Start date (YYYY/MM/DD, YYYY/MM, or YYYY)"
    • removedInput schema / properties / dateRange / properties / minDate / pattern
      Removed value: -"^\\d{4}(\\/\\d{2}(\\/\\d{2})?)?$"
    • addedInput schema / properties / dateRange / required
      Added value: +[
      +  "minDate",
      +  "maxDate"
      +]
    • removedInput schema / properties / fetchBriefSummaries
      Removed value: -{
      -  "default": 0,
      -  "description": "Number of top PMIDs for which to fetch brief summaries using ESummary. Set to 0 to disable. Max 50. Default 0.",
      -  "maximum": 50,
      -  "minimum": 0,
      -  "type": "integer"
      -}
    • removedInput schema / properties / filterByPublicationTypes
      Removed value: -{
      -  "description": "An array of publication types to filter by (e.g., [\"Review\", \"Clinical Trial\"]).",
      -  "items": {
      -    "type": "string"
      -  },
      -  "type": "array"
      -}
    • addedInput schema / properties / freeFullText
      Added value: +{
      +  "description": "Only include free full text articles",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / hasAbstract
      Added value: +{
      +  "description": "Only include articles with abstracts",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / journal
      Added value: +{
      +  "description": "Filter by journal name",
      +  "type": "string"
      +}
    • addedInput schema / properties / language
      Added value: +{
      +  "description": "Filter by language (e.g. \"english\")",
      +  "type": "string"
      +}
    • changedInput schema / properties / maxResults / description
      Previous value: -"Maximum number of articles to retrieve. Corresponds to ESearch's 'retmax' parameter. Default is 20, max is 1000."New value: +"Maximum results to return"
    • removedInput schema / properties / maxResults / exclusiveMinimum
      Removed value: -0
    • addedInput schema / properties / maxResults / minimum
      Added value: +1
    • addedInput schema / properties / meshTerms
      Added value: +{
      +  "description": "Filter by MeSH terms",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / offset
      Added value: +{
      +  "default": 0,
      +  "description": "Result offset for pagination (0-based)",
      +  "maximum": 9007199254740991,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedInput schema / properties / publicationTypes
      Added value: +{
      +  "description": "Filter by publication type (e.g. \"Review\", \"Clinical Trial\", \"Meta-Analysis\")",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / query
      Added value: +{
      +  "description": "PubMed search query (supports full NCBI syntax)",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • removedInput schema / properties / queryTerm
      Removed value: -{
      -  "description": "The primary keyword or phrase to search for in PubMed. Must be at least 3 characters long.",
      -  "minLength": 3,
      -  "type": "string"
      -}
    • addedInput schema / properties / sort
      Added value: +{
      +  "default": "relevance",
      +  "description": "Sort order: relevance (default), pub_date (newest first), author, or journal",
      +  "enum": [
      +    "relevance",
      +    "pub_date",
      +    "author",
      +    "journal"
      +  ],
      +  "type": "string"
      +}
    • removedInput schema / properties / sortBy
      Removed value: -{
      -  "default": "relevance",
      -  "description": "Sorting criteria for results. Options: 'relevance' (default), 'pub_date', 'author', 'journal_name'.",
      -  "enum": [
      -    "relevance",
      -    "pub_date",
      -    "author",
      -    "journal_name"
      -  ],
      -  "type": "string"
      -}
    • addedInput schema / properties / species
      Added value: +{
      +  "description": "Filter by species",
      +  "enum": [
      +    "humans",
      +    "animals"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / summaryCount
      Added value: +{
      +  "default": 0,
      +  "description": "Fetch brief summaries for top N results (0 = PMIDs only)",
      +  "maximum": 50,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "queryTerm"
      -]New value: +[
      +  "query"
      +]
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "offset": {
      +      "description": "Result offset used",
      +      "type": "number"
      +    },
      +    "pmids": {
      +      "description": "PubMed IDs",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "query": {
      +      "description": "Original query",
      +      "type": "string"
      +    },
      +    "searchUrl": {
      +      "description": "PubMed search URL",
      +      "type": "string"
      +    },
      +    "summaries": {
      +      "description": "Brief summaries (empty array when summaryCount is 0)",
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "authors": {
      +            "description": "Formatted author string",
      +            "type": "string"
      +          },
      +          "doi": {
      +            "description": "DOI",
      +            "type": "string"
      +          },
      +          "pmcId": {
      +            "description": "PMC ID",
      +            "type": "string"
      +          },
      +          "pmcUrl": {
      +            "description": "PMC URL",
      +            "type": "string"
      +          },
      +          "pmid": {
      +            "description": "PubMed ID",
      +            "type": "string"
      +          },
      +          "pubDate": {
      +            "description": "Publication date",
      +            "type": "string"
      +          },
      +          "pubmedUrl": {
      +            "description": "PubMed URL",
      +            "type": "string"
      +          },
      +          "source": {
      +            "description": "Journal source",
      +            "type": "string"
      +          },
      +          "title": {
      +            "description": "Article title",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "pmid"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "totalFound": {
      +      "description": "Total matching articles",
      +      "type": "number"
      +    }
      +  },
      +  "required": [
      +    "query",
      +    "totalFound",
      +    "offset",
      +    "pmids",
      +    "summaries",
      +    "searchUrl"
      +  ],
      +  "type": "object"
      +}
  9. First observedv1.0.0

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover readOnlyHint and openWorldHint, so the safety profile is handled. The description adds real behavioral context: return format (PMIDs + optional summaries), pagination via offset for large sets, and the general shape of results. It doesn't mention rate limits or the 9999-record PubMed cap (that lives in the schema), but as a read-only search this is solid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the core action and resource, then capabilities. Zero filler; every clause carries information (filters, return shape, pagination).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 14 params with full schema coverage, an output schema, and annotations, the description is appropriately scoped. It explains return shape and pagination. Missing: explicit routing to sibling tools (europepmc_search, fetch_articles handoff) for a tool whose ecosystem has many near-neighbors, which is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description adds marginal value by summarizing filter categories (field-specific: author, journal, MeSH; common: language, species, free full text) and pagination, but every parameter is already fully documented in the schema, so it doesn't add beyond what's structured.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Search PubMed") and enumerates the capabilities: full query syntax, filters, date ranges, and return shape (PMIDs with optional summaries). It clearly distinguishes itself from siblings like pubmed_fetch_articles and pubmed_europepmc_search by positioning as the primary PubMed search entry point.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implied usage is clear for a search tool, but there's no explicit when-not guidance or routing to siblings (e.g., europepmc_search vs pubmed_search_articles, or the summaryCount→fetch_articles handoff beyond the schema's own note). The description omits any alternative-selection guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.