Skip to main content
Glama

Server Details

Search PubMed/Europe PMC, fetch articles and full text (PMC/EPMC/Unpaywall), citations, MeSH terms.

If you are the author of this connector, you can claim ownership with GitHub, an HTTP challenge, or a DNS record. Claimed connector authors can inspect health checks, view analytics, and manage their listing.
Status
Healthy
Last Tested
Transport
Streamable HTTP
URL
Repository
cyanheads/pubmed-mcp-server
GitHub Stars
144
Server Listing
pubmed-mcp-server

Available Tools

11 tools
pubmed_convert_idsPubmed Convert IdsA
Read-only
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idsYesArticle 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).
idTypeYesThe type of IDs being submitted. Required so the API can unambiguously resolve them.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
recordsNoConversion results, one per input ID
totalConvertedNoNumber of IDs successfully converted
totalSubmittedNoNumber of IDs submitted

TDQS

A4.7/5.0
Behavior5/5

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

Given the annotations (readOnlyHint=true, openWorldHint=true), the description adds critical behavioral context: it only resolves PMC-indexed articles, imposes a batch limit, and requires a single ID type. These are non-obvious constraints that affect outcomes and are not derived from the annotations alone. It also names a concrete alternative for unsupported cases, increasing transparency about the tool's boundaries.

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?

The description is concise (two sentences) and front-loads the core purpose before diving into constraints and alternatives. Every clause earns its place: purpose, scope, batch limit, and redirection. No fluff or repetition, making it easy for an agent to parse quickly.

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

Completeness5/5

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

With only two parameters and full schema documentation, the description covers all necessary behavioral context: what the tool does, its limitations (PMC-only, 50 IDs, single type), and when to use an alternative. The presence of an output schema covers return values. Nothing essential is missing for an agent to select and invoke this tool correctly.

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?

The schema already provides 100% coverage with detailed descriptions for both parameters, including examples and the optional 'PMC' prefix note. The description's statement about 'single type' and batch size largely reiterates the schema's maxItems and 'All IDs must be the same type.' While the description does add no harmful ambiguity, it provides minimal additional parameter-level meaning beyond what the schema already encodes.

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?

The description begins with a clear verb-resource pair ('Convert between article identifiers (DOI, PMID, PMCID)') and immediately differentiates the tool from siblings by scoping to PMC-indexed articles. It also specifies batch limits and the single-type rule, making the tool's purpose unambiguous and distinct from sibling tools like pubmed_search_articles.

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

Usage Guidelines5/5

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

The description explicitly states when to use this tool (for PMC-indexed articles) and when not to, naming the alternative: 'for articles not in PMC, use pubmed_search_articles instead.' It also mentions the 50-ID limit and the single-type requirement, providing clear usage context. This goes beyond a basic when-to-use and covers exclusions.

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

pubmed_europepmc_fetchPubmed Europepmc FetchA
Read-only
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
recordsYesRecords to retrieve, each addressed by the `source` and `epmcId` of a `pubmed_europepmc_search` hit. The whole batch resolves in one Europe PMC request.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
noticeNoGuidance when one or more requested records could not be resolved. Absent when every record came back.
recordsNoResolved records, in the order Europe PMC returned them
notFoundNoRequested `source` + `epmcId` pairs Europe PMC returned no record for

TDQS

A4.8/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true. The description adds batch limit (up to 25), confirms the return includes full abstracts, and notes the truncation flag from the sibling search. It doesn't describe the exact response shape or error/side-effect behavior, but for a read-only fetch with annotations covering safety, the added context is valuable and not redundant.

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?

The description packs high-density information (purpose, sibling routing, use-case scope, batch limit, parameter sourcing) into four compact sentences with clear logical flow: what it does → when to use it → constraints. No filler or repetition of schema details beyond what adds value.

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

Completeness5/5

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

The description fully covers when to use this tool over siblings, how to obtain the required parameters (from search hit), the batch limit, and what data it returns. Given readOnly annotations and an output schema, nothing missing that an agent needs to select and invoke it correctly.

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

Parameters5/5

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

Schema provides 100% coverage with descriptions for both parameters. The description goes further by explaining the relationship: epmcId is copied from the search hit, and for MED records it equals the PMID. This directly helps an agent know how to obtain and populate the parameters correctly, which the schema alone doesn't convey.

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?

The description specifies the verb (fetch), resource (Europe PMC records), and key output (full abstracts). It explicitly differentiates from sibling tools by naming the retrieval path for PPR, PAT, and AGR records that pubmed_fetch_articles and pubmed_fetch_fulltext cannot address. This is a precise, non-tautological statement.

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

Usage Guidelines5/5

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

It clearly states when to use this tool: to read full abstracts for records flagged as abstractTruncated by pubmed_europepmc_search, and for preprint/patent/Agricola records lacking PMID/DOI. It also explicitly mentions alternatives (pubmed_fetch_articles, pubmed_fetch_fulltext) and why they'd fail. Explicit when-to-use and when-not guidance.

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

pubmed_fetch_articlesPubmed Fetch ArticlesB
Read-only
Inspect

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

ParametersJSON Schema
NameRequiredDescriptionDefault
pmidsYesPubMed IDs to fetch
includeMeshNoInclude MeSH terms
includeGrantsNoInclude grant information

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
noticeNoOptional guidance when no articles were returned — points to discovery tools. Absent on successful fetches.
articlesNoParsed articles
totalReturnedNoNumber of articles returned
unavailablePmidsNoPMIDs that returned no article data

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, and the description's 'Fetch' is consistent with those hints. The description adds useful context about return fields (abstract, authors, journal, MeSH terms), but it does not disclose behavior for invalid/missing IDs, errors, or rate limits, though the schema caps batch size at 200.

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?

The description is two sentences with zero waste. The core action and input mode are front-loaded, and the second sentence adds value by summarizing the return payload without unnecessary detail.

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?

For a straightforward fetch-by-ID tool, the description together with the full schema, output schema, and read-only annotations covers the essential invocation requirements. The main gap is the absence of explicit routing to sibling tools for search or full-text retrieval, but this does not prevent correct invocation.

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 the schema already documents all three parameters. The description adds marginal value by mentioning MeSH terms, which aligns with includeMesh, but does not explain includeGrants behavior or parameter semantics beyond what the schema provides.

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

Purpose4/5

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

The description states a specific action ('Fetch'), resource ('full article metadata'), and input mode ('by PubMed IDs'), and enumerates key return fields (abstract, authors, journal, MeSH terms). This makes it clear what the tool does and broadly distinguishes it from sibling tools like pubmed_search_articles and pubmed_fetch_fulltext, though it does not explicitly name those alternatives.

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

Usage Guidelines2/5

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

The phrase 'by PubMed IDs' implies a prerequisite, but the description gives no explicit guidance about when to use this tool versus alternatives. It does not direct agents to pubmed_search_articles when IDs are unknown or to pubmed_fetch_fulltext when full text is needed, leaving usage inference to the agent.

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

pubmed_fetch_fulltextPubmed Fetch FulltextA
Read-only
Inspect

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

ParametersJSON Schema
NameRequiredDescriptionDefault
doisNoDOIs 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.
pmidsNoPubMed 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.
pmcidsNoPMC 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.
sectionsNoFilter to specific sections by title, case-insensitive (e.g. ["Introduction", "Methods", "Results", "Discussion"]). Applies to `source=pmc` results only.
maxSectionsNoMaximum top-level body sections. Applies to `source=pmc` results only.
overflowModeNoHow 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.truncate
maxCharactersNoPer-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.
includeReferencesNoInclude reference list. Applies to `source=pmc` results only.
maxCharactersPerSectionNoBudget 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.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
noticeNoOptional guidance for a partial or empty body. A `sections`-filter miss names the requested terms and affected article id(s) and suggests retrying without `sections` or using broader headings. A metadata-only record names the id(s) the chain could retrieve as front matter only and points at `pubmed_fetch_articles` for the abstract. A budgeted response names the characters returned versus carried and points at `truncation`. Absent when none of those applies.
articlesNoFull-text articles
truncatedNoTrue when a character budget shortened at least one returned body. Absent when every returned article carries its full post-filter body. The per-article accounting is in `truncation`.
truncationNoCharacter accounting for full text the budget shortened. Present only when a budget actually removed characters — its absence means every returned article carries its full post-filter body.
unavailableNoPer-identifier explanations for any requested PMIDs, PMCIDs, or DOIs with no returnable full text. `idType` discriminates which branch the id came from.
totalReturnedNoNumber of articles returned

TDQS

A4.3/5.0
Behavior5/5

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

The description adds substantial behavioral context beyond the readOnlyHint/openWorldHint annotations: the multi-source fallback order (PMC → Europe PMC fullTextXML → Unpaywall), the result formats per source (JATS, HTML-as-Markdown, PDF-as-text), and how quality/budget behaviors vary by source. This is exactly the kind of disclosure that helps an agent predict what it will receive and explains the open-world nature of the tool's behavior.

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

Conciseness4/5

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

The description is front-loaded with purpose, then the fallback chain, then input modality. It is long, but every clause earns its place given the genuine complexity of a three-layer fallback system. Dense but well-ordered; minor deduction only because some orchestration detail overlaps with what the per-parameter schema descriptions already state.

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?

For a high-complexity tool with nine parameters and a fallback chain, the description covers the orchestration comprehensively: purpose, source routing per ID type, and result formats. The output schema exists and documents return values, so that burden is offloaded. The only minor gap is environmental prerequisites (UNPAYWALL_EMAIL is mentioned in the schema but not surfaced in the description), which is a small omission for an otherwise complete definition.

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% and the schema's per-parameter descriptions are already rich (covering resolution, fallback, and applicability). The tool description adds orchestration framing — which source each ID type lands on — but no per-parameter detail beyond what the schema already provides. Baseline 3 is appropriate because the schema carries the full burden and the description adds modest framing value.

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?

The first sentence states a specific verb and resource ('Fetch full-text articles from PubMed Central with structured sections and references') and immediately adds a strong differentiator — the transparent fallback chain through Europe PMC and Unpaywall. This clearly distinguishes the tool from siblings like pubmed_fetch_articles and pubmed_europepmc_fetch without needing to open any schema.

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

Usage Guidelines4/5

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

The description gives explicit, actionable guidance on which of the three mutually exclusive ID parameters to provide ('Provide exactly one of pmcids, pmids, or dois') and explains the auto-resolution behavior of each (e.g., DOIs auto-resolve via the ID Converter, preprints fall through to Europe PMC/Unpaywall). The only gap is that it does not state when an agent should prefer a sibling tool (e.g., using pubmed_fetch_articles when only metadata/abstracts are needed), but the input-mode selection guidance is strong.

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

pubmed_format_citationsPubmed Format CitationsA
Read-only
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pmidsYesPubMed IDs to cite
formatNoCitation format(s) to generate — single style as a string or multiple as an array. Allowed values: apa, mla, bibtex, ris, vancouver.apa

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
noticeNoOptional guidance when no citations were produced — points to discovery tools. Absent when at least one citation was produced.
citationsNoCitations per article
totalFormattedNoNumber of PMIDs successfully formatted
totalSubmittedNoNumber of PMIDs submitted for citation formatting
unavailablePmidsNoRequested PMIDs that did not return article metadata

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, indicating the tool is a safe, read-only operation. The description adds context beyond the annotations by specifying the output is 'formatted citations' and that it accepts both single and multiple formats. However, it does not disclose details like how invalid PMIDs are handled or how multiple formats are returned (e.g., as an object keyed by format). Given that annotations cover the safety profile, the description does contribute additional behavioral context, warranting a 4.

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?

The description is concise and front-loaded: it starts with the core action and resource, then immediately lists the supported formats, and explains the input flexibility in the second sentence. There is no fluff, and every sentence contributes to agent understanding. The tool name and formal title are clear, and the description avoids redundancy with the schema. This is exemplary conciseness and structure.

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?

The description, combined with the rich input schema and the presence of an output schema, provides sufficient information for an agent to use the tool correctly. The context signals indicate low complexity: only 2 parameters, single required, no nested objects, and full schema coverage. The description clarifies the only ambiguity (string vs. array for format) and lists all allowed values. The output schema likely covers return structure, so nothing critical is missing. However, it does not mention potential errors or behavior for invalid PMIDs, which could be a minor gap for a complete understanding.

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

Parameters4/5

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

The input schema provides exhaustive descriptions for both parameters (pmids and format), covering 100% of the schema. The description reinforces the parameter semantics by stating that a single format can be a string or an array, which aligns with the schema's anyOf definition. While the schema already explains the parameter types and allowed values, the description adds clarity on how to combine the two parameters (e.g., 'for multiple formats, pass an array'). This adds marginal value over the schema, so a 4 is appropriate.

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?

The description clearly states the tool's purpose: 'Get formatted citations for PubMed articles in one or more formats.' It specifies a concrete verb ('get'), a resource ('formatted citations for PubMed articles'), and enumerates the exact supported formats (apa, mla, bibtex, ris, vancouver). This allows an agent to differentiate it from sibling tools that fetch articles, search, or convert IDs, as none of those involve citation formatting.

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

Usage Guidelines4/5

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

The description provides clear usage direction by specifying the input variations: 'Pass a single format as a string or multiple as an array.' It also implicitly indicates when to use this tool (when formatted citations are needed) and when not (e.g., when raw article data is needed, use pubmed_fetch_articles). However, there is no explicit exclusion or comparison to sibling tools, but the context is sufficient for an agent to infer the appropriate use case.

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

pubmed_lookup_citationPubmed Lookup CitationA
Read-only
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
citationsYesCitations to look up. More fields = better match accuracy.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
resultsNoMatch results, one per input citation
totalMatchedNoNumber of citations with PMID matches
totalWarningsNoNumber of matched citations that carry at least one warning
totalSubmittedNoNumber of citations submitted

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: it explains the deterministic ECitMatch primary-key behavior, the field requirements for a match, and how field completeness affects accuracy.

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?

Two dense sentences with no filler. The purpose is front-loaded, followed immediately by usage context, reliability comparison, and critical constraints. Every clause adds information.

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

Completeness5/5

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

The description covers when to use the tool, how matching works, required fields, and accuracy trade-offs. An output schema exists, so return-value documentation is not the description's burden. Nothing essential for correct invocation is missing.

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

Parameters4/5

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

Schema coverage is 100%, so the schema already documents all parameters. The description adds meaningful semantics beyond the schema by explaining that more fields improve match accuracy and that journal+volume+page are the primary keys, which helps the agent construct effective citations.

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?

The description opens with a specific verb and resource: 'Look up PubMed IDs from partial bibliographic citations.' It also distinguishes itself from free-text search by emphasizing deterministic citation matching for structured references, which clearly separates it from sibling tools like pubmed_search_articles.

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

Usage Guidelines5/5

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

It explicitly states when to use this tool ('when you have a reference... and need the PMID') and contrasts it with free-text search. It also gives concrete exclusion guidance: author-only or volume-only inputs guarantee no match, and each citation must include at least journal or year.

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

pubmed_lookup_meshPubmed Lookup MeshA
Read-only
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesMeSH descriptor name or free-text term to look up
offsetNoResult 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.
maxResultsNoMaximum results
includeDetailsNoFetch full MeSH records (scope notes, tree numbers, entry terms)

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
queryNoOriginal search query
noticeNoOptional guidance when no descriptors matched or the offset overshot the result set — suggests spell-check, free-text search, or resetting the offset. Absent on successful result pages.
offsetNoResult offset this page was read from
resultsNoMatching MeSH records
nextOffsetNoOffset to request for the next page. Omitted when this is the last page, so its absence is the end-of-results signal.
totalCountNoTotal MeSH descriptors matching the query upstream, before the maxResults cap

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already mark it read-only and open-world; the description adds useful behavioral detail by disclosing the returned record fields and the offset-based pagination mechanism for paging past maxResults. It does not contradict the annotations.

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?

A single sentence that front-loads the purpose, then states the output contents and pagination behavior. There is no filler or repetition of schema details.

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

Completeness5/5

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

For a read-only search tool with a full output schema and well-documented parameters, the description covers the essential behavior: what is returned and how pagination works. Nothing needed for correct invocation is missing.

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 the schema already documents all four parameters. The description adds some context about return contents and pagination, but it does not materially expand parameter meaning beyond the schema.

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?

The description names a specific resource (MeSH controlled vocabulary) and a clear action (search and explore), and specifies the return contents (descriptor records with tree numbers, scope notes, entry terms). This distinguishes it from the sibling PubMed article/citation tools, none of which target MeSH.

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?

The description implies the tool is for MeSH vocabulary lookups, which gives an agent a clear context, but it does not explicitly state when to prefer this over sibling tools or mention exclusions. There is no direct comparison to alternatives like pubmed_search_articles.

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

pubmed_search_articlesPubmed Search ArticlesA
Read-only
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
sortNoSort order: relevance (default), pub_date (newest first), author, or journalrelevance
queryYesPubMed search query (supports full NCBI syntax)
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

ParametersJSON Schema
NameRequiredDescription
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

TDQS

A4.3/5.0
Behavior4/5

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

Annotations include readOnlyHint=true and openWorldHint=true. The description adds behavioral context: it mentions PubMed's limit of 9999 records (offset cap at 9998) and the note about summarizing with a cap of 50, directing to pubmed_fetch_articles for remaining PMIDs. It also clarifies date range behavior (only applied when both minDate and maxDate are non-empty) which is in the schema but the description sets expectations. These are useful beyond annotations. Not a contradiction.

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

Conciseness4/5

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

The description is a single paragraph that is relatively concise given the tool's complexity (14 parameters). It front-loads the main purpose and return type, then lists key capabilities. It doesn't repeat schema details, so it's efficient. Could be slightly more structured (e.g., bullet points) but overall good.

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?

The tool is complex with 14 parameters, but the schema covers all parameter details and the output schema exists. The description adds important context about pagination limits, summarization limits, and the hint to use another tool. It does not explain the output schema, but that is not required when output schema is provided. Overall, complete for an agent to call it correctly.

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

Parameters4/5

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

Schema description coverage is 100%, so parameters are well-documented in the schema. The description adds a few semantic details beyond the schema: it explicitly mentions that offset is 0-based and that PubMed serves at most 9999 records, and that summaryCount above 50 requires passing PMIDs to a sibling. These are minor clarifications, but since the schema already covers parameters, a high score is appropriate. The description doesn't fully compensate for anything missing, but adds a little value.

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?

The description states a specific verb ('Search') and resource ('PubMed') with explicit scope: 'full query syntax, filters, and date ranges'. It also indicates return type ('PMIDs and optional brief summaries') and supports pagination. This clearly distinguishes it from siblings like pubmed_fetch_articles or pubmed_convert_ids.

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

Usage Guidelines4/5

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

The description clearly states what the tool does, including filters and pagination, but does not explicitly mention when not to use it or direct to alternatives. It implies usage for searching PubMed, and mentions 'pagination via offset' which is a usage pattern. However, it doesn't name specific sibling tools or conditions for when to choose them instead (e.g., when to use pubmed_fetch_articles for full text). Thus, it's clear context but lacks explicit exclusions.

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

pubmed_spell_checkPubmed Spell CheckB
Read-only
Inspect

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

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesPubMed search query to spell-check

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
originalNoOriginal query
correctedNoCorrected query (same as original if no suggestion)
hasSuggestionNoWhether NCBI suggested a correction

TDQS

B3.4/5.0
Behavior3/5

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

The readOnlyHint annotation covers the readonly nature, so the description doesn't need to repeat that. However, the description is thin on what the

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?

Two sentences, no redundancy, and the second sentence adds the use case. Efficient and clear without wasted words.

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

Completeness3/5

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

For a single-parameter tool with a readOnlyHint, it is reasonably complete. However, it omits the output format (e.g., does it return a single suggested query or a list of alternatives?) and any mention of error behavior for invalid queries. The description is adequate for a simple tool but lacks depth expected from a tool targeting refined usage.

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

Parameters4/5

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

The only parameter, 'query', is fully described in the schema with a clear description (

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

Purpose4/5

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

The description clearly states the tool's function: 'Spell-check a query and get NCBI's suggested correction.' It also adds a use case ('useful for refining search queries') that gives context. The one-parameter tool is well-defined enough to understand its primary purpose without ambiguity.

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

Usage Guidelines2/5

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

Only a vague hint about refining search queries. No guidance on when to invoke it, what types of queries benefit, or how to interpret the result in the context of sibling search tools. An agent would need to infer typical usage from the title and description.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 11 tool updates
    • Changedpubmed_convert_ids6 fields changed
      • 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": [
        +      "records",
        +      "totalConverted",
        +      "totalSubmitted"
        +    ]
        +  },
        +  {
        +    "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: -[
        -  "records",
        -  "totalConverted",
        -  "totalSubmitted"
        -]
    • Changedpubmed_europepmc_fetch6 fields changed
      • 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": [
        +      "records"
        +    ]
        +  },
        +  {
        +    "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: `europepmc_unreachable`: Europe PMC was unreachable after all retry attempts. `europepmc_invalid_response`: Europe PMC returned a body that could not be parsed (invalid JSON or XML). `europepmc_invalid_input`: Europe PMC rejected the request input (empty query, unknown sort field, malformed parameter). `europepmc_disabled`: Europe PMC service is disabled via EUROPEPMC_ENABLED=false. Other values are possible when a failure originates below the handler.",
        +          "examples": [
        +            "europepmc_unreachable",
        +            "europepmc_invalid_response",
        +            "europepmc_invalid_input",
        +            "europepmc_disabled"
        +          ],
        +          "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: -[
        -  "records"
        -]
    • Changedpubmed_europepmc_search6 fields changed
      • 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": [
        +      "hits",
        +      "cursorMark",
        +      "searchUrl",
        +      "query",
        +      "totalCount",
        +      "appliedSources"
        +    ]
        +  },
        +  {
        +    "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: `europepmc_unreachable`: Europe PMC was unreachable after all retry attempts. `europepmc_invalid_response`: Europe PMC returned a body that could not be parsed (invalid JSON or XML). `europepmc_invalid_input`: Europe PMC rejected the request input (empty query, unknown sort field, malformed parameter). `europepmc_disabled`: Europe PMC service is disabled via EUROPEPMC_ENABLED=false. Other values are possible when a failure originates below the handler.",
        +          "examples": [
        +            "europepmc_unreachable",
        +            "europepmc_invalid_response",
        +            "europepmc_invalid_input",
        +            "europepmc_disabled"
        +          ],
        +          "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: -[
        -  "hits",
        -  "cursorMark",
        -  "searchUrl",
        -  "query",
        -  "totalCount",
        -  "appliedSources"
        -]
    • Changedpubmed_fetch_articles6 fields changed
      • 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": [
        +      "articles",
        +      "totalReturned"
        +    ]
        +  },
        +  {
        +    "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). `invalid_efetch_response`: NCBI EFetch returned a payload missing the PubmedArticleSet wrapper. 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",
        +            "invalid_efetch_response"
        +          ],
        +          "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: -[
        -  "articles",
        -  "totalReturned"
        -]
    • Changedpubmed_fetch_fulltext7 fields changed
      • 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": [
        +      "articles",
        +      "totalReturned"
        +    ]
        +  },
        +  {
        +    "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). `unpaywall_unreachable`: Unpaywall was unreachable when resolving a DOI or fetching content. `europepmc_unreachable`: Europe PMC was unreachable after all retry attempts. `europepmc_invalid_response`: Europe PMC returned a body that could not be parsed (invalid JSON or XML). `europepmc_invalid_input`: Europe PMC rejected the request input (empty query, unknown sort field, malformed parameter). 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",
        +            "unpaywall_unreachable",
        +            "europepmc_unreachable",
        +            "europepmc_invalid_response",
        +            "europepmc_invalid_input"
        +          ],
        +          "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"
        +}
      • addedOutput schema / properties / truncated
        Added value: +{
        +  "description": "True when a character budget shortened at least one returned body. Absent when every returned article carries its full post-filter body. The per-article accounting is in `truncation`.",
        +  "type": "boolean"
        +}
      • removedOutput schema / required
        Removed value: -[
        -  "articles",
        -  "totalReturned"
        -]
    • Changedpubmed_find_related6 fields changed
      • 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": [
        +      "sourcePmid",
        +      "relationship",
        +      "offset",
        +      "articles",
        +      "totalCount",
        +      "source"
        +    ]
        +  },
        +  {
        +    "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). `europepmc_unreachable`: Europe PMC was unreachable after all retry attempts. `europepmc_invalid_response`: Europe PMC returned a body that could not be parsed (invalid JSON or XML). `europepmc_invalid_input`: Europe PMC rejected the request input (empty query, unknown sort field, malformed parameter). `openalex_unreachable`: OpenAlex was unreachable after all retry attempts. `openalex_invalid_response`: OpenAlex returned a body that could not be parsed (invalid JSON). 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",
        +            "europepmc_unreachable",
        +            "europepmc_invalid_response",
        +            "europepmc_invalid_input",
        +            "openalex_unreachable",
        +            "openalex_invalid_response"
        +          ],
        +          "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: -[
        -  "sourcePmid",
        -  "relationship",
        -  "offset",
        -  "articles",
        -  "totalCount",
        -  "source"
        -]
    • Changedpubmed_format_citations6 fields changed
      • 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": [
        +      "citations",
        +      "totalSubmitted",
        +      "totalFormatted"
        +    ]
        +  },
        +  {
        +    "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: -[
        -  "citations",
        -  "totalSubmitted",
        -  "totalFormatted"
        -]
    • Changedpubmed_lookup_citation6 fields changed
      • 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": [
        +      "results",
        +      "totalMatched",
        +      "totalSubmitted",
        +      "totalWarnings"
        +    ]
        +  },
        +  {
        +    "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: -[
        -  "results",
        -  "totalMatched",
        -  "totalSubmitted",
        -  "totalWarnings"
        -]
    • Changedpubmed_lookup_mesh6 fields changed
      • 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",
        +      "results",
        +      "totalCount"
        +    ]
        +  },
        +  {
        +    "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",
        -  "results",
        -  "totalCount"
        -]
    • Changedpubmed_search_articles6 fields changed
      • 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"
        -]
    • Changedpubmed_spell_check6 fields changed
      • 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": [
        +      "original",
        +      "corrected",
        +      "hasSuggestion"
        +    ]
        +  },
        +  {
        +    "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: -[
        -  "original",
        -  "corrected",
        -  "hasSuggestion"
        -]
  2. 6 tool updates
    • Changedpubmed_convert_ids1 field changed
      • changedOutput schema / properties / records / items / properties / doi / description
        Previous value: -"Digital Object Identifier; absent if no DOI is on record"New value: +"Digital Object Identifier, cased as the PMC ID Converter reports it; absent if no DOI is on record. 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."
    • Changedpubmed_europepmc_fetch3 fields changed
      • changedInput schema / properties / records / items / properties / source / description
        Previous value: -"Europe PMC source corpus — `MED` (PubMed), `PMC` (PubMed Central), `PPR` (preprint), `PAT` (patent), `AGR` (Agricola). Copy it from the search hit's `source`."New value: +"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`."
      • changedOutput schema / properties / notFound / items / properties / source / description
        Previous value: -"Europe PMC source corpus — `MED` (PubMed), `PMC` (PubMed Central), `PPR` (preprint), `PAT` (patent), `AGR` (Agricola). Copy it from the search hit's `source`."New value: +"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`."
      • changedOutput schema / properties / records / items / properties / doi / description
        Previous value: -"DOI when present"New value: +"DOI when present, cased as Europe PMC reports it. DOIs are case-insensitive by spec and no case normalization is applied here, so the same DOI can arrive in a different case from `pubmed_fetch_articles` (Europe PMC `10.1056/nejmoa2212948`, NCBI `10.1056/NEJMoa2212948`) — a byte-for-byte comparison across the two reports a false mismatch."
    • Changedpubmed_europepmc_search1 field changed
      • changedOutput schema / properties / hits / items / properties / doi / description
        Previous value: -"DOI when present"New value: +"DOI when present, cased as Europe PMC reports it. DOIs are case-insensitive by spec and no case normalization is applied here, so the same DOI can arrive in a different case from `pubmed_fetch_articles` (Europe PMC `10.1056/nejmoa2212948`, NCBI `10.1056/NEJMoa2212948`) — a byte-for-byte comparison across the two reports a false mismatch."
    • Changedpubmed_fetch_articles1 field changed
      • changedOutput schema / properties / articles / items / properties / doi / description
        Previous value: -"DOI"New value: +"DOI, cased as NCBI reports it (usually the publisher's mixed case). DOIs are case-insensitive by spec and no case normalization is applied here, so the same DOI can arrive in a different case from `pubmed_europepmc_search` and `pubmed_europepmc_fetch` (NCBI `10.1056/NEJMoa2212948`, Europe PMC `10.1056/nejmoa2212948`) — a byte-for-byte comparison across the two reports a false mismatch."
    • Changedpubmed_fetch_fulltext1 field changed
      • changedOutput schema / properties / articles / items / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "description": "Structured JATS full-text article. `viaSource` records whether the JATS came from NCBI PMC or Europe PMC.",
        -    "properties": {
        -      "abstract": {
        -        "description": "Abstract",
        -        "type": "string"
        -      },
        -      "affiliations": {
        -        "description": "Author affiliations",
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      },
        -      "articleType": {
        -        "description": "Article type",
        -        "type": "string"
        -      },
        -      "authors": {
        -        "description": "Authors",
        -        "items": {
        -          "additionalProperties": false,
        -          "description": "Author entry",
        -          "properties": {
        -            "collectiveName": {
        -              "description": "Group name",
        -              "type": "string"
        -            },
        -            "givenNames": {
        -              "description": "Given names",
        -              "type": "string"
        -            },
        -            "lastName": {
        -              "description": "Last name",
        -              "type": "string"
        -            }
        -          },
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "doi": {
        -        "description": "DOI",
        -        "type": "string"
        -      },
        -      "epmcId": {
        -        "description": "Europe PMC record id — present when `viaSource` is `europepmc`",
        -        "type": "string"
        -      },
        -      "epmcSource": {
        -        "description": "Europe PMC source code when `viaSource` is `europepmc`. Common values: `MED` (PubMed-derived), `PMC` (PMC counterpart), `PPR` (preprint), `PAT` (patent), `AGR` (Agricola), plus less common codes (`CTX`, `CBA`, `ETH`, `HIR`). Treat as opaque — EPMC may introduce new codes.",
        -        "type": "string"
        -      },
        -      "journal": {
        -        "additionalProperties": false,
        -        "description": "Journal information",
        -        "properties": {
        -          "issn": {
        -            "description": "ISSN",
        -            "type": "string"
        -          },
        -          "issue": {
        -            "description": "Issue number",
        -            "type": "string"
        -          },
        -          "pages": {
        -            "description": "Page range",
        -            "type": "string"
        -          },
        -          "title": {
        -            "description": "Journal title",
        -            "type": "string"
        -          },
        -          "volume": {
        -            "description": "Volume number",
        -            "type": "string"
        -          }
        -        },
        -        "type": "object"
        -      },
        -      "keywords": {
        -        "description": "Keywords",
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      },
        -      "pmcId": {
        -        "description": "PMC ID — present for NCBI PMC records and Europe PMC entries that have a PMC counterpart. Absent for EPMC-only records like preprints; use `epmcId` in that case.",
        -        "type": "string"
        -      },
        -      "pmcUrl": {
        -        "description": "PMC URL — derived from `pmcId` when present",
        -        "type": "string"
        -      },
        -      "pmid": {
        -        "description": "PubMed ID",
        -        "type": "string"
        -      },
        -      "publicationDate": {
        -        "additionalProperties": false,
        -        "description": "Publication date",
        -        "properties": {
        -          "day": {
        -            "description": "Publication day",
        -            "type": "string"
        -          },
        -          "month": {
        -            "description": "Publication month",
        -            "type": "string"
        -          },
        -          "year": {
        -            "description": "Publication year",
        -            "type": "string"
        -          }
        -        },
        -        "type": "object"
        -      },
        -      "pubmedUrl": {
        -        "description": "PubMed URL",
        -        "type": "string"
        -      },
        -      "references": {
        -        "description": "Reference list",
        -        "items": {
        -          "additionalProperties": false,
        -          "description": "Reference entry",
        -          "properties": {
        -            "citation": {
        -              "description": "Citation text",
        -              "type": "string"
        -            },
        -            "id": {
        -              "description": "Reference ID",
        -              "type": "string"
        -            },
        -            "label": {
        -              "description": "Reference label",
        -              "type": "string"
        -            }
        -          },
        -          "required": [
        -            "citation"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "sections": {
        -        "description": "Article body sections",
        -        "items": {
        -          "additionalProperties": false,
        -          "description": "Article body section",
        -          "properties": {
        -            "label": {
        -              "description": "Section label",
        -              "type": "string"
        -            },
        -            "subsections": {
        -              "description": "Nested subsections",
        -              "items": {
        -                "additionalProperties": false,
        -                "description": "Article subsection",
        -                "properties": {
        -                  "label": {
        -                    "description": "Subsection label",
        -                    "type": "string"
        -                  },
        -                  "text": {
        -                    "description": "Subsection body text",
        -                    "type": "string"
        -                  },
        -                  "title": {
        -                    "description": "Subsection heading",
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "text"
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "text": {
        -              "description": "Section body text",
        -              "type": "string"
        -            },
        -            "title": {
        -              "description": "Section heading",
        -              "type": "string"
        -            }
        -          },
        -          "required": [
        -            "text"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "source": {
        -        "const": "pmc",
        -        "description": "Structured JATS — same DTD whether sourced from NCBI PMC or Europe PMC",
        -        "type": "string"
        -      },
        -      "title": {
        -        "description": "Article title",
        -        "type": "string"
        -      },
        -      "viaSource": {
        -        "description": "Which layer produced the JATS: `pmc` for NCBI PMC EFetch (db=pmc), `europepmc` for Europe PMC `fullTextXML`. Both paths return the same JATS shape; the discriminator records origin for observability and license attribution.",
        -        "enum": [
        -          "pmc",
        -          "europepmc"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "source",
        -      "viaSource",
        -      "sections"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "description": "Best-effort full text from an open-access copy",
        -    "properties": {
        -      "content": {
        -        "description": "Full article text — Markdown or plain text per `contentFormat`",
        -        "type": "string"
        -      },
        -      "contentFormat": {
        -        "description": "How `content` was extracted. html-markdown: Defuddle extracted Markdown from an HTML landing page; light section structure may survive but is not guaranteed. pdf-text: unpdf extracted plain text from a PDF; no section, reference, or heading structure.",
        -        "enum": [
        -          "html-markdown",
        -          "pdf-text"
        -        ],
        -        "type": "string"
        -      },
        -      "doi": {
        -        "description": "DOI used to locate the open-access copy",
        -        "type": "string"
        -      },
        -      "hostType": {
        -        "description": "`publisher` or `repository` — where the OA copy is hosted",
        -        "type": "string"
        -      },
        -      "license": {
        -        "description": "License identifier from Unpaywall (e.g. cc-by, cc0)",
        -        "type": "string"
        -      },
        -      "pmcId": {
        -        "description": "PMC ID this article was requested under, in `PMC<digits>` form — present for `pmcids` input, absent for `pmids` and `dois` input. Ties the article back to the requested identifier, which `unavailable[]` keys on for the ids that found nothing.",
        -        "type": "string"
        -      },
        -      "pmid": {
        -        "description": "PubMed ID when input was `pmids`; absent for `pmcids` and `dois` input",
        -        "type": "string"
        -      },
        -      "pubmedUrl": {
        -        "description": "PubMed URL — present when `pmid` is set",
        -        "type": "string"
        -      },
        -      "source": {
        -        "const": "unpaywall",
        -        "description": "Content fetched from an open-access copy indexed by Unpaywall. Best-effort — structural fidelity depends on `contentFormat`.",
        -        "type": "string"
        -      },
        -      "sourceUrl": {
        -        "description": "URL the content was fetched from",
        -        "type": "string"
        -      },
        -      "title": {
        -        "description": "Detected article title when present",
        -        "type": "string"
        -      },
        -      "totalPages": {
        -        "description": "Page count reported by the PDF extractor; absent for HTML",
        -        "type": "number"
        -      },
        -      "version": {
        -        "description": "OA version: submittedVersion | acceptedVersion | publishedVersion",
        -        "type": "string"
        -      },
        -      "viaSource": {
        -        "const": "unpaywall",
        -        "description": "Layer that produced this article. Constant `unpaywall` for this branch.",
        -        "type": "string"
        -      },
        -      "wordCount": {
        -        "description": "Approximate word count reported by the HTML extractor; absent for PDFs",
        -        "type": "number"
        -      }
        -    },
        -    "required": [
        -      "source",
        -      "viaSource",
        -      "contentFormat",
        -      "doi",
        -      "sourceUrl",
        -      "content"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "Structured JATS full-text article. `viaSource` records whether the JATS came from NCBI PMC or Europe PMC.",
        +    "properties": {
        +      "abstract": {
        +        "description": "Abstract",
        +        "type": "string"
        +      },
        +      "affiliations": {
        +        "description": "Author affiliations",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "articleType": {
        +        "description": "Article type",
        +        "type": "string"
        +      },
        +      "authors": {
        +        "description": "Authors",
        +        "items": {
        +          "additionalProperties": false,
        +          "description": "Author entry",
        +          "properties": {
        +            "collectiveName": {
        +              "description": "Group name",
        +              "type": "string"
        +            },
        +            "givenNames": {
        +              "description": "Given names",
        +              "type": "string"
        +            },
        +            "lastName": {
        +              "description": "Last name",
        +              "type": "string"
        +            }
        +          },
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "doi": {
        +        "description": "DOI, cased as the tier that served this record reports it (NCBI PMC, Europe PMC, or Unpaywall). DOIs are case-insensitive by spec and no case normalization is applied here, so casing can differ between tiers and from other tools — compare case-insensitively.",
        +        "type": "string"
        +      },
        +      "epmcId": {
        +        "description": "Europe PMC record id — present when `viaSource` is `europepmc`",
        +        "type": "string"
        +      },
        +      "epmcSource": {
        +        "description": "Europe PMC source code when `viaSource` is `europepmc`. Common values: `MED` (PubMed-derived), `PMC` (PMC counterpart), `PPR` (preprint), `PAT` (patent), `AGR` (Agricola), plus less common codes (`CTX`, `CBA`, `ETH`, `HIR`). Treat as opaque — EPMC may introduce new codes.",
        +        "type": "string"
        +      },
        +      "journal": {
        +        "additionalProperties": false,
        +        "description": "Journal information",
        +        "properties": {
        +          "issn": {
        +            "description": "ISSN",
        +            "type": "string"
        +          },
        +          "issue": {
        +            "description": "Issue number",
        +            "type": "string"
        +          },
        +          "pages": {
        +            "description": "Page range",
        +            "type": "string"
        +          },
        +          "title": {
        +            "description": "Journal title",
        +            "type": "string"
        +          },
        +          "volume": {
        +            "description": "Volume number",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "keywords": {
        +        "description": "Keywords",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "pmcId": {
        +        "description": "PMC ID — present for NCBI PMC records and Europe PMC entries that have a PMC counterpart. Absent for EPMC-only records like preprints; use `epmcId` in that case.",
        +        "type": "string"
        +      },
        +      "pmcUrl": {
        +        "description": "PMC URL — derived from `pmcId` when present",
        +        "type": "string"
        +      },
        +      "pmid": {
        +        "description": "PubMed ID",
        +        "type": "string"
        +      },
        +      "publicationDate": {
        +        "additionalProperties": false,
        +        "description": "Publication date",
        +        "properties": {
        +          "day": {
        +            "description": "Publication day",
        +            "type": "string"
        +          },
        +          "month": {
        +            "description": "Publication month",
        +            "type": "string"
        +          },
        +          "year": {
        +            "description": "Publication year",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "pubmedUrl": {
        +        "description": "PubMed URL",
        +        "type": "string"
        +      },
        +      "references": {
        +        "description": "Reference list",
        +        "items": {
        +          "additionalProperties": false,
        +          "description": "Reference entry",
        +          "properties": {
        +            "citation": {
        +              "description": "Citation text",
        +              "type": "string"
        +            },
        +            "id": {
        +              "description": "Reference ID",
        +              "type": "string"
        +            },
        +            "label": {
        +              "description": "Reference label",
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "citation"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "sections": {
        +        "description": "Article body sections",
        +        "items": {
        +          "additionalProperties": false,
        +          "description": "Article body section",
        +          "properties": {
        +            "label": {
        +              "description": "Section label",
        +              "type": "string"
        +            },
        +            "subsections": {
        +              "description": "Nested subsections",
        +              "items": {
        +                "additionalProperties": false,
        +                "description": "Article subsection",
        +                "properties": {
        +                  "label": {
        +                    "description": "Subsection label",
        +                    "type": "string"
        +                  },
        +                  "text": {
        +                    "description": "Subsection body text",
        +                    "type": "string"
        +                  },
        +                  "title": {
        +                    "description": "Subsection heading",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "text"
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "text": {
        +              "description": "Section body text",
        +              "type": "string"
        +            },
        +            "title": {
        +              "description": "Section heading",
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "text"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "source": {
        +        "const": "pmc",
        +        "description": "Structured JATS — same DTD whether sourced from NCBI PMC or Europe PMC",
        +        "type": "string"
        +      },
        +      "title": {
        +        "description": "Article title",
        +        "type": "string"
        +      },
        +      "viaSource": {
        +        "description": "Which layer produced the JATS: `pmc` for NCBI PMC EFetch (db=pmc), `europepmc` for Europe PMC `fullTextXML`. Both paths return the same JATS shape; the discriminator records origin for observability and license attribution.",
        +        "enum": [
        +          "pmc",
        +          "europepmc"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "viaSource",
        +      "sections"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "Best-effort full text from an open-access copy",
        +    "properties": {
        +      "content": {
        +        "description": "Full article text — Markdown or plain text per `contentFormat`",
        +        "type": "string"
        +      },
        +      "contentFormat": {
        +        "description": "How `content` was extracted. html-markdown: Defuddle extracted Markdown from an HTML landing page; light section structure may survive but is not guaranteed. pdf-text: unpdf extracted plain text from a PDF; no section, reference, or heading structure.",
        +        "enum": [
        +          "html-markdown",
        +          "pdf-text"
        +        ],
        +        "type": "string"
        +      },
        +      "doi": {
        +        "description": "DOI used to locate the open-access copy",
        +        "type": "string"
        +      },
        +      "hostType": {
        +        "description": "`publisher` or `repository` — where the OA copy is hosted",
        +        "type": "string"
        +      },
        +      "license": {
        +        "description": "License identifier from Unpaywall (e.g. cc-by, cc0)",
        +        "type": "string"
        +      },
        +      "pmcId": {
        +        "description": "PMC ID this article was requested under, in `PMC<digits>` form — present for `pmcids` input, absent for `pmids` and `dois` input. Ties the article back to the requested identifier, which `unavailable[]` keys on for the ids that found nothing.",
        +        "type": "string"
        +      },
        +      "pmid": {
        +        "description": "PubMed ID when input was `pmids`; absent for `pmcids` and `dois` input",
        +        "type": "string"
        +      },
        +      "pubmedUrl": {
        +        "description": "PubMed URL — present when `pmid` is set",
        +        "type": "string"
        +      },
        +      "source": {
        +        "const": "unpaywall",
        +        "description": "Content fetched from an open-access copy indexed by Unpaywall. Best-effort — structural fidelity depends on `contentFormat`.",
        +        "type": "string"
        +      },
        +      "sourceUrl": {
        +        "description": "URL the content was fetched from",
        +        "type": "string"
        +      },
        +      "title": {
        +        "description": "Detected article title when present",
        +        "type": "string"
        +      },
        +      "totalPages": {
        +        "description": "Page count reported by the PDF extractor; absent for HTML",
        +        "type": "number"
        +      },
        +      "version": {
        +        "description": "OA version: submittedVersion | acceptedVersion | publishedVersion",
        +        "type": "string"
        +      },
        +      "viaSource": {
        +        "const": "unpaywall",
        +        "description": "Layer that produced this article. Constant `unpaywall` for this branch.",
        +        "type": "string"
        +      },
        +      "wordCount": {
        +        "description": "Approximate word count reported by the HTML extractor; absent for PDFs",
        +        "type": "number"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "viaSource",
        +      "contentFormat",
        +      "doi",
        +      "sourceUrl",
        +      "content"
        +    ],
        +    "type": "object"
        +  }
        +]
    • Changedpubmed_search_articles5 fields changed
      • 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."
  3. 3 tool updates
    • Addedpubmed_europepmc_fetch
    • Changedpubmed_europepmc_search3 fields changed
      • changedOutput schema / properties / hits / items / properties / abstractSnippet / description
        Previous value: -"First few hundred characters of the abstract as display-ready plain text — JATS/HTML markup stripped and HTML entities decoded — when `resultType: \"core\"` is requested"New value: +"First 400 characters of the abstract as display-ready plain text — JATS/HTML markup stripped and HTML entities decoded — when `resultType: \"core\"` is requested, with a trailing … appended when the abstract was cut. Check `abstractTruncated` before treating it as the whole abstract."
      • addedOutput schema / properties / hits / items / properties / abstractTruncated
        Added value: +{
        +  "description": "Whether `abstractSnippet` was cut short of the full abstract. Retrieve the complete text with `pubmed_europepmc_fetch` using this record’s `source` and `epmcId`. Present whenever `abstractSnippet` is; omitted when Europe PMC carries no abstract.",
        +  "type": "boolean"
        +}
      • changedOutput schema / properties / hits / items / properties / epmcId / description
        Previous value: -"Europe PMC's internal record id; key for `fullTextXML` lookup"New value: +"Europe PMC's internal record id. Pass it with this hit's `source` to `pubmed_europepmc_fetch` for the complete record. Europe PMC's `fullTextXML` is keyed on `pmcId`, not on this id, so records without a PMC counterpart have no full text to fetch."
    • Changedpubmed_fetch_fulltext5 fields changed
      • addedInput schema / properties / maxCharacters
        Added value: +{
        +  "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.",
        +  "maximum": 1000000,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / maxCharactersPerSection
        Added value: +{
        +  "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.",
        +  "maximum": 1000000,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / overflowMode
        Added value: +{
        +  "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.",
        +  "enum": [
        +    "truncate",
        +    "outline"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / properties / notice / description
        Previous value: -"Optional guidance for empty bodies. A `sections`-filter miss names the requested terms and affected article id(s) and suggests retrying without `sections` or using broader headings. A metadata-only record names the id(s) the chain could retrieve as front matter only and points at `pubmed_fetch_articles` for the abstract. Absent when neither case applies."New value: +"Optional guidance for a partial or empty body. A `sections`-filter miss names the requested terms and affected article id(s) and suggests retrying without `sections` or using broader headings. A metadata-only record names the id(s) the chain could retrieve as front matter only and points at `pubmed_fetch_articles` for the abstract. A budgeted response names the characters returned versus carried and points at `truncation`. Absent when none of those applies."
      • addedOutput schema / properties / truncation
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Character accounting for full text the budget shortened. Present only when a budget actually removed characters — its absence means every returned article carries its full post-filter body.",
        +  "properties": {
        +    "articles": {
        +      "description": "Per-article accounting, covering only the articles the budget shortened",
        +      "items": {
        +        "additionalProperties": false,
        +        "description": "Character accounting for one article the budget shortened",
        +        "properties": {
        +          "id": {
        +            "description": "Identifier for the article — PMCID, PMID, DOI, or Europe PMC id, whichever the article carries first",
        +            "type": "string"
        +          },
        +          "originalCharacters": {
        +            "description": "Body characters this article carried before the budget pass",
        +            "type": "number"
        +          },
        +          "returnedCharacters": {
        +            "description": "Body characters this article carries in the response",
        +            "type": "number"
        +          },
        +          "sections": {
        +            "description": "Per-section accounting for `source: pmc` articles, in document order, including sections dropped for budget. Absent for `source: unpaywall`, whose body has no section structure.",
        +            "items": {
        +              "additionalProperties": false,
        +              "description": "Character accounting for one body section of a budgeted article",
        +              "properties": {
        +                "originalCharacters": {
        +                  "description": "Body characters this section carried before the budget pass",
        +                  "type": "number"
        +                },
        +                "returnedCharacters": {
        +                  "description": "Body characters this section carries in the response. Zero means the section was dropped in `truncate` mode, or kept as a heading-only entry in `outline` mode.",
        +                  "type": "number"
        +                },
        +                "title": {
        +                  "description": "Section heading, when the section carries one",
        +                  "type": "string"
        +                },
        +                "truncated": {
        +                  "description": "True when the section returned fewer characters than it originally carried",
        +                  "type": "boolean"
        +                }
        +              },
        +              "required": [
        +                "originalCharacters",
        +                "returnedCharacters",
        +                "truncated"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "source": {
        +            "description": "Which output shape was budgeted: `pmc` budgets body sections and subsections, `unpaywall` budgets the single `content` body",
        +            "enum": [
        +              "pmc",
        +              "unpaywall"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "source",
        +          "originalCharacters",
        +          "returnedCharacters"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "maxCharacters": {
        +      "description": "The `maxCharacters` budget applied, when set",
        +      "type": "number"
        +    },
        +    "maxCharactersPerSection": {
        +      "description": "The `maxCharactersPerSection` budget applied, when set",
        +      "type": "number"
        +    },
        +    "mode": {
        +      "description": "The `overflowMode` that produced these results",
        +      "enum": [
        +        "truncate",
        +        "outline"
        +      ],
        +      "type": "string"
        +    },
        +    "omittedSections": {
        +      "description": "Body sections dropped entirely because an article budget was exhausted before reaching them. Always 0 in `outline` mode, which keeps every heading.",
        +      "type": "number"
        +    },
        +    "originalCharacters": {
        +      "description": "Body characters the shortened articles carried before the budget pass",
        +      "type": "number"
        +    },
        +    "returnedCharacters": {
        +      "description": "Body characters the shortened articles carry in this response",
        +      "type": "number"
        +    }
        +  },
        +  "required": [
        +    "mode",
        +    "originalCharacters",
        +    "returnedCharacters",
        +    "omittedSections",
        +    "articles"
        +  ],
        +  "type": "object"
        +}
  4. 2 tool updates
    • Changedpubmed_europepmc_search1 field changed
      • changedInput schema / properties / query / description
        Previous value: -"Europe PMC search query. Supports field tokens like `AUTH:\"<name>\"`, `JOURNAL:\"<title>\"`, `TITLE:\"<words>\"`, `PUB_YEAR:[2020 TO 2024]`, `DOI:\"...\"`, `EXT_ID:\"<pmid>\" AND SRC:MED`. Free text is matched broadly across abstract/title/keywords."New value: +"Europe PMC search query. Supports field tokens like `AUTH:\"<name>\"`, `JOURNAL:\"<title>\"`, `TITLE:\"<words>\"`, `PUB_YEAR:[2020 TO 2024]`, `DOI:\"...\"`, `EXT_ID:<pmid> AND SRC:MED`, `PMCID:PMC<digits>`. Identifier tokens combined with `AND SRC:` must be unquoted — the quoted form matches nothing. Free text is matched broadly across abstract/title/keywords."
    • Changedpubmed_fetch_fulltext7 fields changed
      • changedInput schema / properties / pmcids / description
        Previous value: -"PMC IDs to fetch (e.g. [\"PMC9575052\"]). Provide exactly one of `pmcids`, `pmids`, or `dois`."New value: +"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."
      • changedOutput schema / properties / articles / items / oneOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "description": "Structured JATS full-text article. `viaSource` records whether the JATS came from NCBI PMC or Europe PMC.",
        -    "properties": {
        -      "abstract": {
        -        "description": "Abstract",
        -        "type": "string"
        -      },
        -      "affiliations": {
        -        "description": "Author affiliations",
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      },
        -      "articleType": {
        -        "description": "Article type",
        -        "type": "string"
        -      },
        -      "authors": {
        -        "description": "Authors",
        -        "items": {
        -          "additionalProperties": false,
        -          "description": "Author entry",
        -          "properties": {
        -            "collectiveName": {
        -              "description": "Group name",
        -              "type": "string"
        -            },
        -            "givenNames": {
        -              "description": "Given names",
        -              "type": "string"
        -            },
        -            "lastName": {
        -              "description": "Last name",
        -              "type": "string"
        -            }
        -          },
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "doi": {
        -        "description": "DOI",
        -        "type": "string"
        -      },
        -      "epmcId": {
        -        "description": "Europe PMC record id — present when `viaSource` is `europepmc`",
        -        "type": "string"
        -      },
        -      "epmcSource": {
        -        "description": "Europe PMC source code when `viaSource` is `europepmc`. Common values: `MED` (PubMed-derived), `PMC` (PMC counterpart), `PPR` (preprint), `PAT` (patent), `AGR` (Agricola), plus less common codes (`CTX`, `CBA`, `ETH`, `HIR`). Treat as opaque — EPMC may introduce new codes.",
        -        "type": "string"
        -      },
        -      "journal": {
        -        "additionalProperties": false,
        -        "description": "Journal information",
        -        "properties": {
        -          "issn": {
        -            "description": "ISSN",
        -            "type": "string"
        -          },
        -          "issue": {
        -            "description": "Issue number",
        -            "type": "string"
        -          },
        -          "pages": {
        -            "description": "Page range",
        -            "type": "string"
        -          },
        -          "title": {
        -            "description": "Journal title",
        -            "type": "string"
        -          },
        -          "volume": {
        -            "description": "Volume number",
        -            "type": "string"
        -          }
        -        },
        -        "type": "object"
        -      },
        -      "keywords": {
        -        "description": "Keywords",
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      },
        -      "pmcId": {
        -        "description": "PMC ID — present for NCBI PMC records and Europe PMC entries that have a PMC counterpart. Absent for EPMC-only records like preprints; use `epmcId` in that case.",
        -        "type": "string"
        -      },
        -      "pmcUrl": {
        -        "description": "PMC URL — derived from `pmcId` when present",
        -        "type": "string"
        -      },
        -      "pmid": {
        -        "description": "PubMed ID",
        -        "type": "string"
        -      },
        -      "publicationDate": {
        -        "additionalProperties": false,
        -        "description": "Publication date",
        -        "properties": {
        -          "day": {
        -            "description": "Publication day",
        -            "type": "string"
        -          },
        -          "month": {
        -            "description": "Publication month",
        -            "type": "string"
        -          },
        -          "year": {
        -            "description": "Publication year",
        -            "type": "string"
        -          }
        -        },
        -        "type": "object"
        -      },
        -      "pubmedUrl": {
        -        "description": "PubMed URL",
        -        "type": "string"
        -      },
        -      "references": {
        -        "description": "Reference list",
        -        "items": {
        -          "additionalProperties": false,
        -          "description": "Reference entry",
        -          "properties": {
        -            "citation": {
        -              "description": "Citation text",
        -              "type": "string"
        -            },
        -            "id": {
        -              "description": "Reference ID",
        -              "type": "string"
        -            },
        -            "label": {
        -              "description": "Reference label",
        -              "type": "string"
        -            }
        -          },
        -          "required": [
        -            "citation"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "sections": {
        -        "description": "Article body sections",
        -        "items": {
        -          "additionalProperties": false,
        -          "description": "Article body section",
        -          "properties": {
        -            "label": {
        -              "description": "Section label",
        -              "type": "string"
        -            },
        -            "subsections": {
        -              "description": "Nested subsections",
        -              "items": {
        -                "additionalProperties": false,
        -                "description": "Article subsection",
        -                "properties": {
        -                  "label": {
        -                    "description": "Subsection label",
        -                    "type": "string"
        -                  },
        -                  "text": {
        -                    "description": "Subsection body text",
        -                    "type": "string"
        -                  },
        -                  "title": {
        -                    "description": "Subsection heading",
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "text"
        -                ],
        -                "type": "object"
        -              },
        -              "type": "array"
        -            },
        -            "text": {
        -              "description": "Section body text",
        -              "type": "string"
        -            },
        -            "title": {
        -              "description": "Section heading",
        -              "type": "string"
        -            }
        -          },
        -          "required": [
        -            "text"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "source": {
        -        "const": "pmc",
        -        "description": "Structured JATS — same DTD whether sourced from NCBI PMC or Europe PMC",
        -        "type": "string"
        -      },
        -      "title": {
        -        "description": "Article title",
        -        "type": "string"
        -      },
        -      "viaSource": {
        -        "description": "Which layer produced the JATS: `pmc` for NCBI PMC EFetch (db=pmc), `europepmc` for Europe PMC `fullTextXML`. Both paths return the same JATS shape; the discriminator records origin for observability and license attribution.",
        -        "enum": [
        -          "pmc",
        -          "europepmc"
        -        ],
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "source",
        -      "viaSource",
        -      "sections"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "description": "Best-effort full text from an open-access copy",
        -    "properties": {
        -      "content": {
        -        "description": "Full article text — Markdown or plain text per `contentFormat`",
        -        "type": "string"
        -      },
        -      "contentFormat": {
        -        "description": "How `content` was extracted. html-markdown: Defuddle extracted Markdown from an HTML landing page; light section structure may survive but is not guaranteed. pdf-text: unpdf extracted plain text from a PDF; no section, reference, or heading structure.",
        -        "enum": [
        -          "html-markdown",
        -          "pdf-text"
        -        ],
        -        "type": "string"
        -      },
        -      "doi": {
        -        "description": "DOI used to locate the open-access copy",
        -        "type": "string"
        -      },
        -      "hostType": {
        -        "description": "`publisher` or `repository` — where the OA copy is hosted",
        -        "type": "string"
        -      },
        -      "license": {
        -        "description": "License identifier from Unpaywall (e.g. cc-by, cc0)",
        -        "type": "string"
        -      },
        -      "pmid": {
        -        "description": "PubMed ID when input was `pmids`; absent for `dois` input",
        -        "type": "string"
        -      },
        -      "pubmedUrl": {
        -        "description": "PubMed URL — present when `pmid` is set",
        -        "type": "string"
        -      },
        -      "source": {
        -        "const": "unpaywall",
        -        "description": "Content fetched from an open-access copy indexed by Unpaywall. Best-effort — structural fidelity depends on `contentFormat`.",
        -        "type": "string"
        -      },
        -      "sourceUrl": {
        -        "description": "URL the content was fetched from",
        -        "type": "string"
        -      },
        -      "title": {
        -        "description": "Detected article title when present",
        -        "type": "string"
        -      },
        -      "totalPages": {
        -        "description": "Page count reported by the PDF extractor; absent for HTML",
        -        "type": "number"
        -      },
        -      "version": {
        -        "description": "OA version: submittedVersion | acceptedVersion | publishedVersion",
        -        "type": "string"
        -      },
        -      "viaSource": {
        -        "const": "unpaywall",
        -        "description": "Layer that produced this article. Constant `unpaywall` for this branch.",
        -        "type": "string"
        -      },
        -      "wordCount": {
        -        "description": "Approximate word count reported by the HTML extractor; absent for PDFs",
        -        "type": "number"
        -      }
        -    },
        -    "required": [
        -      "source",
        -      "viaSource",
        -      "contentFormat",
        -      "doi",
        -      "sourceUrl",
        -      "content"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "Structured JATS full-text article. `viaSource` records whether the JATS came from NCBI PMC or Europe PMC.",
        +    "properties": {
        +      "abstract": {
        +        "description": "Abstract",
        +        "type": "string"
        +      },
        +      "affiliations": {
        +        "description": "Author affiliations",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "articleType": {
        +        "description": "Article type",
        +        "type": "string"
        +      },
        +      "authors": {
        +        "description": "Authors",
        +        "items": {
        +          "additionalProperties": false,
        +          "description": "Author entry",
        +          "properties": {
        +            "collectiveName": {
        +              "description": "Group name",
        +              "type": "string"
        +            },
        +            "givenNames": {
        +              "description": "Given names",
        +              "type": "string"
        +            },
        +            "lastName": {
        +              "description": "Last name",
        +              "type": "string"
        +            }
        +          },
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "doi": {
        +        "description": "DOI",
        +        "type": "string"
        +      },
        +      "epmcId": {
        +        "description": "Europe PMC record id — present when `viaSource` is `europepmc`",
        +        "type": "string"
        +      },
        +      "epmcSource": {
        +        "description": "Europe PMC source code when `viaSource` is `europepmc`. Common values: `MED` (PubMed-derived), `PMC` (PMC counterpart), `PPR` (preprint), `PAT` (patent), `AGR` (Agricola), plus less common codes (`CTX`, `CBA`, `ETH`, `HIR`). Treat as opaque — EPMC may introduce new codes.",
        +        "type": "string"
        +      },
        +      "journal": {
        +        "additionalProperties": false,
        +        "description": "Journal information",
        +        "properties": {
        +          "issn": {
        +            "description": "ISSN",
        +            "type": "string"
        +          },
        +          "issue": {
        +            "description": "Issue number",
        +            "type": "string"
        +          },
        +          "pages": {
        +            "description": "Page range",
        +            "type": "string"
        +          },
        +          "title": {
        +            "description": "Journal title",
        +            "type": "string"
        +          },
        +          "volume": {
        +            "description": "Volume number",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "keywords": {
        +        "description": "Keywords",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "pmcId": {
        +        "description": "PMC ID — present for NCBI PMC records and Europe PMC entries that have a PMC counterpart. Absent for EPMC-only records like preprints; use `epmcId` in that case.",
        +        "type": "string"
        +      },
        +      "pmcUrl": {
        +        "description": "PMC URL — derived from `pmcId` when present",
        +        "type": "string"
        +      },
        +      "pmid": {
        +        "description": "PubMed ID",
        +        "type": "string"
        +      },
        +      "publicationDate": {
        +        "additionalProperties": false,
        +        "description": "Publication date",
        +        "properties": {
        +          "day": {
        +            "description": "Publication day",
        +            "type": "string"
        +          },
        +          "month": {
        +            "description": "Publication month",
        +            "type": "string"
        +          },
        +          "year": {
        +            "description": "Publication year",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "pubmedUrl": {
        +        "description": "PubMed URL",
        +        "type": "string"
        +      },
        +      "references": {
        +        "description": "Reference list",
        +        "items": {
        +          "additionalProperties": false,
        +          "description": "Reference entry",
        +          "properties": {
        +            "citation": {
        +              "description": "Citation text",
        +              "type": "string"
        +            },
        +            "id": {
        +              "description": "Reference ID",
        +              "type": "string"
        +            },
        +            "label": {
        +              "description": "Reference label",
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "citation"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "sections": {
        +        "description": "Article body sections",
        +        "items": {
        +          "additionalProperties": false,
        +          "description": "Article body section",
        +          "properties": {
        +            "label": {
        +              "description": "Section label",
        +              "type": "string"
        +            },
        +            "subsections": {
        +              "description": "Nested subsections",
        +              "items": {
        +                "additionalProperties": false,
        +                "description": "Article subsection",
        +                "properties": {
        +                  "label": {
        +                    "description": "Subsection label",
        +                    "type": "string"
        +                  },
        +                  "text": {
        +                    "description": "Subsection body text",
        +                    "type": "string"
        +                  },
        +                  "title": {
        +                    "description": "Subsection heading",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "text"
        +                ],
        +                "type": "object"
        +              },
        +              "type": "array"
        +            },
        +            "text": {
        +              "description": "Section body text",
        +              "type": "string"
        +            },
        +            "title": {
        +              "description": "Section heading",
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "text"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "source": {
        +        "const": "pmc",
        +        "description": "Structured JATS — same DTD whether sourced from NCBI PMC or Europe PMC",
        +        "type": "string"
        +      },
        +      "title": {
        +        "description": "Article title",
        +        "type": "string"
        +      },
        +      "viaSource": {
        +        "description": "Which layer produced the JATS: `pmc` for NCBI PMC EFetch (db=pmc), `europepmc` for Europe PMC `fullTextXML`. Both paths return the same JATS shape; the discriminator records origin for observability and license attribution.",
        +        "enum": [
        +          "pmc",
        +          "europepmc"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "viaSource",
        +      "sections"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "Best-effort full text from an open-access copy",
        +    "properties": {
        +      "content": {
        +        "description": "Full article text — Markdown or plain text per `contentFormat`",
        +        "type": "string"
        +      },
        +      "contentFormat": {
        +        "description": "How `content` was extracted. html-markdown: Defuddle extracted Markdown from an HTML landing page; light section structure may survive but is not guaranteed. pdf-text: unpdf extracted plain text from a PDF; no section, reference, or heading structure.",
        +        "enum": [
        +          "html-markdown",
        +          "pdf-text"
        +        ],
        +        "type": "string"
        +      },
        +      "doi": {
        +        "description": "DOI used to locate the open-access copy",
        +        "type": "string"
        +      },
        +      "hostType": {
        +        "description": "`publisher` or `repository` — where the OA copy is hosted",
        +        "type": "string"
        +      },
        +      "license": {
        +        "description": "License identifier from Unpaywall (e.g. cc-by, cc0)",
        +        "type": "string"
        +      },
        +      "pmcId": {
        +        "description": "PMC ID this article was requested under, in `PMC<digits>` form — present for `pmcids` input, absent for `pmids` and `dois` input. Ties the article back to the requested identifier, which `unavailable[]` keys on for the ids that found nothing.",
        +        "type": "string"
        +      },
        +      "pmid": {
        +        "description": "PubMed ID when input was `pmids`; absent for `pmcids` and `dois` input",
        +        "type": "string"
        +      },
        +      "pubmedUrl": {
        +        "description": "PubMed URL — present when `pmid` is set",
        +        "type": "string"
        +      },
        +      "source": {
        +        "const": "unpaywall",
        +        "description": "Content fetched from an open-access copy indexed by Unpaywall. Best-effort — structural fidelity depends on `contentFormat`.",
        +        "type": "string"
        +      },
        +      "sourceUrl": {
        +        "description": "URL the content was fetched from",
        +        "type": "string"
        +      },
        +      "title": {
        +        "description": "Detected article title when present",
        +        "type": "string"
        +      },
        +      "totalPages": {
        +        "description": "Page count reported by the PDF extractor; absent for HTML",
        +        "type": "number"
        +      },
        +      "version": {
        +        "description": "OA version: submittedVersion | acceptedVersion | publishedVersion",
        +        "type": "string"
        +      },
        +      "viaSource": {
        +        "const": "unpaywall",
        +        "description": "Layer that produced this article. Constant `unpaywall` for this branch.",
        +        "type": "string"
        +      },
        +      "wordCount": {
        +        "description": "Approximate word count reported by the HTML extractor; absent for PDFs",
        +        "type": "number"
        +      }
        +    },
        +    "required": [
        +      "source",
        +      "viaSource",
        +      "contentFormat",
        +      "doi",
        +      "sourceUrl",
        +      "content"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedOutput schema / properties / notice / description
        Previous value: -"Optional guidance when a `sections` filter removed every body section — names the requested section terms and the affected article id(s), and suggests retrying without `sections` or using broader headings. Absent when no section filter was applied or sections matched."New value: +"Optional guidance for empty bodies. A `sections`-filter miss names the requested terms and affected article id(s) and suggests retrying without `sections` or using broader headings. A metadata-only record names the id(s) the chain could retrieve as front matter only and points at `pubmed_fetch_articles` for the abstract. Absent when neither case applies."
      • changedOutput schema / properties / unavailable / items / properties / reason / description
        Previous value: -"Why no full text was returned. not-found: upstream returned no record for this ID. no-pmc-fallback-disabled: every tier was skipped (`triedTiers` is all `not-attempted`) — typically because EPMC (`EUROPEPMC_ENABLED`) and Unpaywall (`UNPAYWALL_EMAIL`) are not configured. no-epmc-fulltext: EPMC indexed the record but publishes no fullTextXML. no-doi: no DOI to query Unpaywall. no-oa: Unpaywall has no OA copy. fetch-failed: download failed. parse-failed: extraction empty. service-error: upstream server failure (threw, timed out, or returned malformed data)."New value: +"Why no full text was returned. not-found: upstream returned no record for this ID. no-pmc-fallback-disabled: every tier was skipped (`triedTiers` is all `not-attempted`) — typically because EPMC (`EUROPEPMC_ENABLED`) and Unpaywall (`UNPAYWALL_EMAIL`) are not configured. no-epmc-fulltext: EPMC indexed the record but publishes no fullTextXML. no-body: the record was retrieved but carries front matter and abstract only, with no body sections — use `pubmed_fetch_articles` for the metadata. no-doi: no DOI to query Unpaywall. no-oa: Unpaywall has no OA copy. fetch-failed: download failed. parse-failed: extraction empty. service-error: upstream server failure (threw, timed out, or returned malformed data)."
      • changedOutput schema / properties / unavailable / items / properties / reason / enum
        Previous value: -[
        -  "not-found",
        -  "no-pmc-fallback-disabled",
        -  "no-epmc-fulltext",
        -  "no-doi",
        -  "no-oa",
        -  "fetch-failed",
        -  "parse-failed",
        -  "service-error"
        -]New value: +[
        +  "not-found",
        +  "no-pmc-fallback-disabled",
        +  "no-epmc-fulltext",
        +  "no-body",
        +  "no-doi",
        +  "no-oa",
        +  "fetch-failed",
        +  "parse-failed",
        +  "service-error"
        +]
      • changedOutput schema / properties / unavailable / items / properties / triedTiers / items / properties / outcome / description
        Previous value: -"Per-tier outcome. not-attempted: tier was skipped. miss: tier returned no record. no-fulltext: EPMC indexed the record but publishes no fullTextXML. no-doi: no DOI to query Unpaywall. no-oa: Unpaywall reports no open-access copy. fetch-failed: OA copy download failed. parse-failed: extraction produced empty content. service-error: tier service threw."New value: +"Per-tier outcome. not-attempted: tier was skipped. miss: tier returned no record. no-fulltext: EPMC indexed the record but publishes no fullTextXML. no-body: the tier returned a record with front matter and abstract but no body sections, so the chain continued. no-doi: no DOI to query Unpaywall. no-oa: Unpaywall reports no open-access copy. fetch-failed: OA copy download failed. parse-failed: extraction produced empty content. service-error: tier service threw."
      • changedOutput schema / properties / unavailable / items / properties / triedTiers / items / properties / outcome / enum
        Previous value: -[
        -  "not-attempted",
        -  "miss",
        -  "no-fulltext",
        -  "no-doi",
        -  "no-oa",
        -  "fetch-failed",
        -  "parse-failed",
        -  "service-error"
        -]New value: +[
        +  "not-attempted",
        +  "miss",
        +  "no-fulltext",
        +  "no-body",
        +  "no-doi",
        +  "no-oa",
        +  "fetch-failed",
        +  "parse-failed",
        +  "service-error"
        +]
  5. 1 tool update
    • Changedpubmed_lookup_mesh6 fields changed
      • addedInput schema / properties / offset
        Added value: +{
        +  "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.",
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / nextOffset
        Added value: +{
        +  "description": "Offset to request for the next page. Omitted when this is the last page, so its absence is the end-of-results signal.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / notice / description
        Previous value: -"Optional guidance when no descriptors matched — suggests spell-check or free-text search. Absent on successful results."New value: +"Optional guidance when no descriptors matched or the offset overshot the result set — suggests spell-check, free-text search, or resetting the offset. Absent on successful result pages."
      • addedOutput schema / properties / offset
        Added value: +{
        +  "description": "Result offset this page was read from",
        +  "type": "number"
        +}
      • changedOutput schema / properties / totalCount / description
        Previous value: -"Total matching MeSH descriptors"New value: +"Total MeSH descriptors matching the query upstream, before the maxResults cap"
      • changedOutput schema / required
        Previous value: -[
        -  "query",
        -  "results",
        -  "totalCount"
        -]New value: +[
        +  "query",
        +  "offset",
        +  "results",
        +  "totalCount"
        +]
  6. 1 tool update
    • Changedpubmed_fetch_fulltext1 field changed
      • addedOutput schema / properties / notice
        Added value: +{
        +  "description": "Optional guidance when a `sections` filter removed every body section — names the requested section terms and the affected article id(s), and suggests retrying without `sections` or using broader headings. Absent when no section filter was applied or sections matched.",
        +  "type": "string"
        +}
  7. 3 tool updates
    • Changedpubmed_convert_ids1 field changed
      • changedInput schema / properties / ids / description
        Previous value: -"Article identifiers to convert. All IDs must be the same type. DOIs: \"10.1093/nar/gks1195\", PMIDs: \"23193287\", PMCIDs: \"PMC3531190\"."New value: +"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)."
    • Changedpubmed_europepmc_search1 field changed
      • changedOutput schema / properties / hits / items / properties / abstractSnippet / description
        Previous value: -"First few hundred characters of the abstract when `resultType: \"core\"` is requested"New value: +"First few hundred characters of the abstract as display-ready plain text — JATS/HTML markup stripped and HTML entities decoded — when `resultType: \"core\"` is requested"
    • Changedpubmed_lookup_mesh1 field changed
      • changedOutput schema / properties / results / items / properties / treeNumbers / description
        Previous value: -"MeSH tree numbers"New value: +"Navigable MeSH tree numbers (e.g. \"D02.078.370.141.450\"). Omitted for supplementary concept records (SCRs), which map to a heading rather than occupying a tree position."
  8. 1 tool update
    • Changedpubmed_lookup_mesh3 fields changed
      • addedOutput schema / properties / results / items / properties / entrezUid
        Added value: +{
        +  "description": "NCBI Entrez UID for this record — the join key for E-utilities (eSummary/eFetch db=mesh).",
        +  "type": "string"
        +}
      • changedOutput schema / properties / results / items / properties / meshId / description
        Previous value: -"MeSH descriptor unique identifier"New value: +"Canonical MeSH DescriptorUI (e.g. \"D003924\") — resolves at the MeSH Browser and NLM linked data. Falls back to the raw Entrez UID when a record is not decodable."
      • changedOutput schema / properties / results / items / required
        Previous value: -[
        -  "meshId",
        -  "name"
        -]New value: +[
        +  "meshId",
        +  "entrezUid",
        +  "name"
        +]
  9. 4 tool updates
    • Changedpubmed_europepmc_search3 fields changed
      • removedOutput schema / properties / hitCount
        Removed value: -{
        -  "description": "Total matching records across all pages",
        -  "type": "number"
        -}
      • addedOutput schema / properties / totalCount
        Added value: +{
        +  "description": "Total matching records across all pages",
        +  "type": "number"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "hits",
        -  "cursorMark",
        -  "searchUrl",
        -  "query",
        -  "hitCount",
        -  "appliedSources"
        -]New value: +[
        +  "hits",
        +  "cursorMark",
        +  "searchUrl",
        +  "query",
        +  "totalCount",
        +  "appliedSources"
        +]
    • Changedpubmed_find_related3 fields changed
      • addedOutput schema / properties / totalCount
        Added value: +{
        +  "description": "Total related articles found before windowing",
        +  "type": "number"
        +}
      • removedOutput schema / properties / totalFound
        Removed value: -{
        -  "description": "Total related articles found before windowing",
        -  "type": "number"
        -}
      • changedOutput schema / required
        Previous value: -[
        -  "sourcePmid",
        -  "relationship",
        -  "offset",
        -  "articles",
        -  "totalFound",
        -  "source"
        -]New value: +[
        +  "sourcePmid",
        +  "relationship",
        +  "offset",
        +  "articles",
        +  "totalCount",
        +  "source"
        +]
    • Changedpubmed_lookup_mesh2 fields changed
      • addedOutput schema / properties / totalCount
        Added value: +{
        +  "description": "Total matching MeSH descriptors",
        +  "type": "number"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "query",
        -  "results"
        -]New value: +[
        +  "query",
        +  "results",
        +  "totalCount"
        +]
    • Changedpubmed_search_articles3 fields changed
      • 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"
        +]
  10. 4 tool updates
    • Changedpubmed_europepmc_search1 field changed
      • changedInput schema / properties / sort / description
        Previous value: -"Optional EPMC sort: `<field> asc|desc`. Documented sortable fields: `P_PDATE_D` (publication date), `CITED` (citation count), `AUTH_FIRST` (first author surname), `PUB_YEAR` (publication year). Examples: `P_PDATE_D desc` (newest first), `CITED desc` (most cited). Omit for relevance ranking. Fields outside the documented set are rejected by EPMC."New value: +"Optional EPMC sort: `<field> asc|desc`. Documented sortable fields: `P_PDATE_D` (publication date), `CITED` (citation count), `AUTH_FIRST` (first author surname), `PUB_YEAR` (publication year). Examples: `P_PDATE_D desc` (newest first), `CITED desc` (most cited). Omit for relevance ranking. Fields outside the documented set are rejected by EPMC. Note: `P_PDATE_D` is ignored for preprint-only (`sources: [\"PPR\"]`) result sets — preprints have no populated publication date, so use `PUB_YEAR` to order preprints by date."
    • Changedpubmed_fetch_articles1 field changed
      • addedOutput schema / properties / notice
        Added value: +{
        +  "description": "Optional guidance when no articles were returned — points to discovery tools. Absent on successful fetches.",
        +  "type": "string"
        +}
    • Changedpubmed_find_related6 fields changed
      • addedInput schema / properties / offset
        Added value: +{
        +  "default": 0,
        +  "description": "Result offset for pagination (0-based); page through results by incrementing by maxResults",
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • changedOutput schema / properties / notice / description
        Previous value: -"Optional guidance when results are empty — e.g. invalid source PMID, or references requested for a non-PMC source. Absent on successful result pages."New value: +"Guidance when results are empty, a fallback provider answered, or offset overshot. Absent on a clean NCBI result page."
      • addedOutput schema / properties / offset
        Added value: +{
        +  "description": "Result offset used",
        +  "type": "number"
        +}
      • addedOutput schema / properties / source
        Added value: +{
        +  "description": "Provider that answered this request",
        +  "enum": [
        +    "ncbi",
        +    "europepmc",
        +    "openalex"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / properties / totalFound / description
        Previous value: -"Total related articles found before truncation"New value: +"Total related articles found before windowing"
      • changedOutput schema / required
        Previous value: -[
        -  "sourcePmid",
        -  "relationship",
        -  "articles",
        -  "totalFound"
        -]New value: +[
        +  "sourcePmid",
        +  "relationship",
        +  "offset",
        +  "articles",
        +  "totalFound",
        +  "source"
        +]
    • Changedpubmed_format_citations3 fields changed
      • changedInput schema / properties / format / anyOf
        Previous value: -[
        -  {
        -    "description": "Single citation style. One of: apa, mla, bibtex, ris.",
        -    "enum": [
        -      "apa",
        -      "mla",
        -      "bibtex",
        -      "ris"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "description": "Multiple citation styles to generate. Each entry: apa, mla, bibtex, or ris.",
        -    "items": {
        -      "enum": [
        -        "apa",
        -        "mla",
        -        "bibtex",
        -        "ris"
        -      ],
        -      "type": "string"
        -    },
        -    "minItems": 1,
        -    "type": "array"
        -  }
        -]New value: +[
        +  {
        +    "description": "Single citation style. One of: apa, mla, bibtex, ris, vancouver.",
        +    "enum": [
        +      "apa",
        +      "mla",
        +      "bibtex",
        +      "ris",
        +      "vancouver"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "description": "Multiple citation styles to generate. Each entry: apa, mla, bibtex, ris, or vancouver.",
        +    "items": {
        +      "enum": [
        +        "apa",
        +        "mla",
        +        "bibtex",
        +        "ris",
        +        "vancouver"
        +      ],
        +      "type": "string"
        +    },
        +    "minItems": 1,
        +    "type": "array"
        +  }
        +]
      • changedInput schema / properties / format / description
        Previous value: -"Citation format(s) to generate — single style as a string or multiple as an array. Allowed values: apa, mla, bibtex, ris."New value: +"Citation format(s) to generate — single style as a string or multiple as an array. Allowed values: apa, mla, bibtex, ris, vancouver."
      • addedOutput schema / properties / notice
        Added value: +{
        +  "description": "Optional guidance when no citations were produced — points to discovery tools. Absent when at least one citation was produced.",
        +  "type": "string"
        +}
  11. 1 tool update
    • Changedpubmed_fetch_fulltext1 field changed
      • changedInput schema / properties / dois / description
        Previous value: -"DOIs to resolve (e.g. [\"10.21203/rs.3.rs-9010375/v1\"]). Provide exactly one of `pmcids`, `pmids`, or `dois`. Covers preprints and EPMC-only OA records that lack PMID/PMCID. Chain: Europe PMC search-by-DOI → fullTextXML → Unpaywall."New value: +"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."
  12. 1 tool update
    • Changedpubmed_lookup_citation1 field changed
      • changedInput schema / properties / citations / items / description
        Previous value: -"Citation to match against PubMed. Must include at least one bibliographic field (journal, year, volume, firstPage, or authorName)."New value: +"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."
  13. 2 tool updates
    • Changedpubmed_europepmc_search1 field changed
      • changedOutput schema / required
        Previous value: -[
        -  "query",
        -  "hits",
        -  "hitCount",
        -  "cursorMark",
        -  "appliedSources",
        -  "searchUrl"
        -]New value: +[
        +  "hits",
        +  "cursorMark",
        +  "searchUrl",
        +  "query",
        +  "hitCount",
        +  "appliedSources"
        +]
    • Changedpubmed_search_articles1 field changed
      • changedOutput schema / required
        Previous value: -[
        -  "query",
        -  "effectiveQuery",
        -  "appliedFilters",
        -  "totalFound",
        -  "offset",
        -  "pmids",
        -  "summaries",
        -  "searchUrl"
        -]New value: +[
        +  "query",
        +  "offset",
        +  "pmids",
        +  "summaries",
        +  "searchUrl",
        +  "effectiveQuery",
        +  "totalFound",
        +  "appliedFilters"
        +]

Frequently Asked Questions

Discussions

No comments yet. Be the first to start the discussion!

Related MCP Connectors

Related MCP Servers

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A4.2/5.0
Disambiguation4/5

The tools constitute a well-designed set targeting distinct workflow steps: searching (pubmed_search_articles, pubmed_europepmc_search), fetching (pubmed_fetch_articles, pubmed_fetch_fulltext, pubmed_europepmc_fetch), ID conversion (pubmed_convert_ids), related articles (pubmed_find_related), citations (pubmed_format_citations, pubmed_lookup_citation), MeSH lookup (pubmed_lookup_mesh), and spelling (pubmed_spell_check). While search and fetch tools in PubMed vs Europe PMC overlap somewhat, the descriptions explicitly differentiate them (local PubMed vs broader Europe PMC with preprints/patents), so ambiguity is minor.

Naming Consistency5/5

All tools follow a consistent `pubmed_` prefix followed by verb_noun pattern: `search_articles`, `fetch_articles`, `lookup_citation`, `format_citations`, `convert_ids`, `find_related`, etc. The verbs are all lowercase snake_case, and the pattern is uniform across the entire set, even for the Europe PMC variants (`pubmed_europepmc_search`, `pubmed_europepmc_fetch`).

Tool Count5/5

11 tools makes for a well-scoped server. Each tool serves a clearly distinct purpose within the biomedical literature retrieval domain: searching, fetching metadata/full-text, ID conversion, citation formatting/lookup, MeSH exploration, related-articles, and spell-check. No tool feels redundant or trivial; the count is appropriate for the domain's complexity.

Completeness5/5

The tool set provides comprehensive coverage of the core PubMed/PMC workflow: search with full query syntax, fetch metadata and full text, convert identifiers across DOI/PMID/PMCID, find related articles, format citations, and explore MeSH vocabulary. Notable gaps like more advanced search history management or batch operations exist but are not essential to the domain's core purpose. The fallback logic (e.g., europepmc_fetch for non-PMC records, fulltext fallback chain) fills potential dead ends.