crossref-mcp-server
Server Details
Resolve DOIs, search ~188M scholarly works, and fetch references via the Crossref REST API.
- Status
- Healthy
- Uptime
- 99.9% over 43 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- cyanheads/crossref-mcp-server
- GitHub Stars
- 4
- Server Listing
- crossref-mcp-server
TDQS
Scored across 7 tools
Each tool targets a distinct Crossref entity or lookup mode: work, references, prefix, member, funder search, journal search, and work search. The boundary between crossref_get_prefix (prefix to member ID) and crossref_get_member (member ID to full publisher record) is explicitly described as a chained workflow, not an ambiguous overlap. No two tools appear to do the same thing.
All seven tools use the same crossref_ prefix followed by a clear verb_noun pattern: get_member, get_prefix, get_references, get_work, search_funders, search_journals, search_works. The convention is uniform across retrieval and search operations. There are no mixed styles or vague verbs.
Seven tools is well-scoped for a read-only Crossref metadata server, covering the core entity types without unnecessary bloat. Each tool has a clear role and no filler operations are present. This fits comfortably within the appropriate 3-15 range.
The surface covers works, references, journals, funders, prefixes, and members, with both search and direct lookup for most entities. One minor gap is the lack of a name-based member search, since crossref_get_member only accepts a member ID and crossref_get_prefix only maps from a DOI prefix. Agents can work around this in many cases by finding members through works or prefixes, but the direct lookup path is incomplete.
Available Tools
7 toolscrossref_get_memberGet Member by IDARead-onlyIdempotentInspect
Resolves a Crossref member ID to its publisher/organization record: primary name, alternate imprint names, owned DOI prefixes, registered DOI counts, a per-work-type breakdown, and per-category metadata deposit coverage. Members are the organizations that register DOIs with Crossref, so this answers "what does this publisher publish, and how completely do they deposit metadata?" Resolve a DOI prefix (e.g. "10.1038") to its member ID with crossref_get_prefix, then pass that ID here.
| Name | Required | Description | Default |
|---|---|---|---|
| member_id | Yes | Crossref member ID — a positive integer, e.g. 297 (Springer) or 340 (PLOS). Resolve a DOI prefix to a member ID first with crossref_get_prefix. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Crossref member ID |
| error | No | Present when the call failed. Absent on success. |
| names | No | Alternate and imprint names registered under this member |
| counts | No | Registered DOI counts |
| coverage | No | Per-category metadata deposit coverage — each a 0–1 fraction split into current (recent) and backfile (older) DOIs. Signals how completely this publisher deposits references, abstracts, ORCIDs, funders, licenses, and similar metadata. |
| deposits | No | Whether the member deposits any metadata with Crossref |
| location | No | Publisher location (city, region, country) |
| prefixes | No | DOI prefixes owned by this member, e.g. "10.1038" |
| primaryName | No | Primary publisher/organization name |
| worksByType | No | DOI counts broken down by work type (all DOIs), sorted by count descending |
| depositsArticles | No | Whether the member deposits journal-article metadata |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the operation read-only and idempotent, so the bar for additional disclosure is lower. The description adds useful domain context—members are organizations that register DOIs—and spells out the scope of the returned record, including deposit metadata coverage, without contradicting 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences each carry weight: the first defines the action and return contents, the second supplies domain context, and the third provides the chaining workflow. No filler or redundancy is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only tool with an output schema and clear annotations, this description is fully sufficient. It tells the agent what the result means, what questions it answers, and how to obtain the required input via a sibling tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the member_id parameter already includes type, positive integer constraint, examples, and a pointer to crossref_get_prefix. The description reinforces the concept of a member ID but does not add significant parameter-level meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Resolves a Crossref member ID to its publisher/organization record', and enumerates meaningful output categories. It is clearly distinguished from siblings like crossref_get_prefix and the search tools through the member-ID focus.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states the prerequisite workflow: 'Resolve a DOI prefix... with crossref_get_prefix, then pass that ID here.' This gives direct guidance on when to use this tool versus its sibling resolver, leaving no ambiguity about sequencing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crossref_get_prefixGet Prefix OwnerARead-onlyIdempotentInspect
Resolves a DOI prefix — the registrant portion of a DOI, e.g. "10.1038" — to its owning Crossref member: the publisher name and numeric member ID. Answers "who publishes DOIs starting with 10.1038?" The Crossref prefix record carries only these three facts (no counts, coverage, or flags); the returned memberId chains directly into crossref_get_member for the full publisher record.
| Name | Required | Description | Default |
|---|---|---|---|
| prefix | Yes | DOI prefix in the format "10.NNNN" — the registrant portion of a DOI with no "/suffix", e.g. "10.1038" or "10.1371". |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| prefix | No | The DOI prefix that was resolved, e.g. "10.1038" |
| memberId | No | Numeric Crossref member ID that owns this prefix — pass to crossref_get_member for the full publisher record |
| ownerName | No | Name of the member (publisher) that owns this prefix |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only and idempotent. The description goes further by disclosing that the prefix record carries only these three facts with no counts, coverage, or flags, and that the returned memberId chains into another tool. This usefully manages agent expectations about output richness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: the first defines the action and output, the second captures the user question, and the third scopes expectations and links to the sibling tool. No redundant phrases or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has a single well-documented parameter, a clear output schema, and annotations covering safety. The description completes the picture by explaining what the result means, what it does not contain, and how to chain into crossref_get_member. Nothing essential is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents the `prefix` parameter, including the format and the no-suffix requirement. The tool description reinforces this with examples but adds no new semantic information beyond the schema, matching the baseline for high coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('resolves') and resource ('DOI prefix' to 'owning Crossref member'), and names the exact output: publisher name and numeric member ID. It also differentiates itself from the sibling crossref_get_member by explaining this tool only resolves the prefix, not the full member record.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description frames the use case clearly with the question 'who publishes DOIs starting with 10.1038?' and explicitly points to crossref_get_member as the next step for a full publisher record. It does not state explicit negative conditions, but the context makes the appropriate invocation scenario obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crossref_get_referencesGet Reference ListARead-onlyIdempotentInspect
Returns the outgoing reference list for a DOI — the works cited by this paper. Each reference includes the deposited citation string and, where Crossref has resolved it, a DOI you can look up with crossref_get_work. Results are paged: referenceCount is the full deposited total, and when more remain the response carries a nextOffset to pass back as offset. Reference list coverage varies by publisher; many older works and non-participating publishers have no indexed references. Incoming citations — the works that cite this paper — are not available through Crossref; use OpenAlex for that.
| Name | Required | Description | Default |
|---|---|---|---|
| doi | Yes | DOI in the format "10.NNNN/suffix", e.g. "10.1038/nature12373". A resolver-wrapped form — "https://doi.org/10.1038/nature12373", "https://dx.doi.org/…", "doi:10.1038/nature12373" — is accepted and unwrapped. | |
| limit | No | Maximum number of references to return in one page (1–500 per call, default 100). A larger value, up to 100000, returns 500 and says so in notice; nextOffset continues after the references returned. Most works fit in a single page; bibliography records can carry tens of thousands. | |
| offset | No | Zero-based index of the first reference to return. Pass the nextOffset value from the previous response to continue through a long reference list. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The limit that was applied to this page. |
| doi | No | DOI of the citing work |
| error | No | Present when the call failed. Absent on success. |
| shown | No | Number of references returned in this page. |
| notice | No | Coverage guidance when no references are indexed, a range explanation when the requested offset is past the end of the list, or which references this page covers and the offset that reaches the next ones. Leads with the value requested and the cap applied when limit was above its per-call cap. Absent on a page that holds the whole list with limit within its cap. |
| offset | No | Zero-based index of the first returned reference within the deposited list |
| truncated | No | True when references remain beyond this page. Absent when the page is the last. |
| nextOffset | No | Offset to pass in the next call to retrieve the following page. Absent when this page reaches the end of the reference list. |
| references | No | Page of the outgoing reference list |
| referenceCount | No | Total number of references in the deposited list |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, yet the description still adds substantial behavioral context: referenceCount is the full deposited total, nextOffset is passed back as offset, and coverage varies by publisher so older or non-participating works may return nothing. That caveat about empty results is the kind of expectation-setting an agent needs before calling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the purpose, then return shape, then paging, then the coverage caveat and the sibling pointer. No sentence is redundant and nothing is buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not enumerate return fields, yet it still flags the two that drive iteration (referenceCount, nextOffset) and warns that empty reference lists are a coverage artifact rather than an error. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 and the schema already documents all three parameters. The description goes beyond it by explaining the pagination workflow — referenceCount as the deposited total, nextOffset as the continuation token — which clarifies how limit and offset interact across calls rather than just what they are.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Returns the outgoing reference list for a DOI') and immediately disambiguates direction by contrasting with incoming citations. It also names crossref_get_work as the follow-up for resolved DOIs, so an agent can place it among siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use (outgoing references), explicit when-not (incoming citations are not available through Crossref — use OpenAlex), and a named alternative for the resolved DOIs. This is the full when/when-not/alternatives pattern.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crossref_get_workGet Work by DOIARead-onlyIdempotentInspect
Resolves a DOI to its full Crossref metadata record: title, authors, editors, affiliations, abstract (when deposited), journal or container with the volume, issue, pages, and article number that locate the work in it, ISSNs and ISBNs, publication date, type, license, full-text links, and funder acknowledgements. The author list is paged: authorCount is the full deposited total, offset and limit select the page (25 authors by default), and when authors remain the response carries a nextOffset to pass back as offset — large-collaboration papers deposit thousands. Post-publication updates are relayed as Crossref records them: updatedBy names each correction, retraction, expression of concern, or new version issued against this work, with its notice DOI and whether the publisher or Retraction Watch recorded it, and updateTo names the works this record is itself a notice for. An absent updatedBy does not mean the work was never updated — coverage depends on those deposits. relations lists related identifiers, such as a preprint and its published version, grouped by relation type; only the Crossref-registered DOIs among them resolve through crossref_get_work. Outgoing references are reported as a count in referencesCount; the reference entries themselves come from crossref_get_references. The isReferencedByCount field reports the total incoming citation count from Crossref; the citing works themselves are not available through Crossref — use OpenAlex for citation graphs.
| Name | Required | Description | Default |
|---|---|---|---|
| doi | Yes | DOI in the format "10.NNNN/suffix", e.g. "10.1038/nature12373". A resolver-wrapped form — "https://doi.org/10.1038/nature12373", "https://dx.doi.org/…", "doi:10.1038/nature12373" — is accepted and unwrapped. | |
| limit | No | Maximum number of authors to return in one page (1–500 per call, default 25). A larger value, up to 100000, returns 500 and says so in notice; nextOffset continues after the authors returned. Ordinary records fit in a single page; large-collaboration papers in particle physics and genomics deposit thousands. | |
| offset | No | Zero-based index of the first author to return. Pass the nextOffset value from the previous response to continue through a long author list. Only the author list is paged; every other field of the record is returned in full on every page. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The limit that was applied to this page of authors. |
| doi | No | Canonical DOI |
| url | No | DOI resolution URL |
| isbn | No | ISBN(s) as deposited — for a book chapter, those of the containing book. Omitted when the record deposits none. |
| issn | No | ISSN(s) of the containing journal |
| page | No | Page range as deposited, e.g. "357-362" |
| type | No | Work type (e.g. journal-article, book-chapter, posted-content) |
| error | No | Present when the call failed. Absent on success. |
| issue | No | Issue of the container the work appears in |
| links | No | Registered full-text links |
| shown | No | Number of authors returned in this page. |
| title | No | Work title |
| notice | No | When updatedBy is present, the update types Crossref records for this work with the source of each, and where the notice is read. Then, when limit was above its per-call cap, the value requested and the cap applied. Then which authors this page covers and the offset that reaches the next ones, or an explanation when the requested offset is past the end of the author list. All share this one string when more than one applies. Absent when the page holds the whole author list, no update is recorded, and limit was within its cap. |
| offset | No | Zero-based index of the first returned author within the deposited list. Omitted alongside authors when the record deposits no author field. |
| volume | No | Volume of the container the work appears in |
| authors | No | Page of the author and contributor list, bounded by limit. Omitted when the record deposits no author field at all. |
| editors | No | Editors of the work, or of the book or proceedings containing it, in the entry shape authors use. Returned whole — never paged by offset and limit, and never counted in authorCount. Omitted when the record deposits none. |
| funders | No | Funding acknowledgements |
| subject | No | Subject classification terms |
| abstract | No | Abstract when deposited by the publisher. Many records lack abstracts. Publishers deposit it as JATS XML, so this is the text of that deposit with markup removed and character references decoded; numeric JATS superscripts retain caret notation (10^{16}, GeV^2), a link keeps its tag only where its href holds an address the text it wraps does not already carry, and each formula appears once — MathML as the TeX annotation it carries, otherwise written out linearly (x_i, A^{−1}, √(m), (a+b)/c), and TeX deposited beside MathML in whichever notation comes first. |
| language | No | Language code (ISO 639) |
| licenses | No | License terms |
| subtitle | No | Subtitle when present |
| updateTo | No | Works this record is an update notice for, in the entry shape updatedBy uses and in deposited order. Omitted when the record is not registered as a notice. |
| published | No | Publication date — the first of published, published-print, published-online, and issued that names one. A component Crossref records as unknown is omitted, and so is every component below it. |
| publisher | No | Publisher name |
| relations | No | Related identifiers — preprints and published versions, other versions, reviews, supplements, parts — grouped by relation type, identifier type, and asserting party, groups in Crossref's order and ids in deposited order. Returned whole. Omitted when the record deposits none. |
| truncated | No | True when authors remain beyond this page. Absent when the page is the last. |
| updatedBy | No | Update notices Crossref records against this work — corrections, errata, retractions, expressions of concern, withdrawals, new versions — in deposited order. Entries are never merged: the same notice DOI can appear once per source, typed differently by each. Omitted when none is recorded, which does not mean the work was never updated: coverage depends on publisher and Retraction Watch deposits. |
| nextOffset | No | Offset to pass in the next call to retrieve the following page of authors. Absent when this page reaches the end of the author list. |
| authorCount | No | Total number of authors in the deposited list, before offset and limit were applied. Omitted alongside authors when the record deposits no author field. |
| articleNumber | No | Article number, deposited by journals that number articles instead of paging them |
| containerTitle | No | Journal, book, or proceedings name containing this work |
| referencesCount | No | Number of outgoing references (works cited by this paper) |
| isReferencedByCount | No | Incoming citation count from Crossref — the count of works citing this DOI |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnly and idempotent; the description goes well beyond them, disclosing that the author list is paged with a 25 default, a 100k ceiling collapsing to 500 with a notice, a nextOffset continuation token, and that every non-author field is returned in full on every page. It also warns that an absent updatedBy is not proof of no updates, that only Crossref-registered DOIs in relations resolve, and that isReferencedByCount is a total with no citing list available.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and scoping constraint are front-loaded, and every later sentence maps to a distinct response field or caveat. It is dense — the opening sentence is a long comma-chained enumeration — and some field lists (ISSNs/ISBNs, license, funder acknowledgements) could be compressed, but nothing is redundant padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still supplies the interpretive context an agent needs: paging protocol, the meaning and limits of update/relations data, and which fields are counts rather than payloads. For a read-only lookup with three parameters, nothing consequential is left unspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3; the description earns above that by explaining the offset/limit interaction in terms of authorCount and nextOffset rather than restating the schema, and by motivating the range (thousands of authors in particle physics and genomics). It adds the continuation protocol the schema alone does not express.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause states a specific verb and resource — 'Resolves a DOI to its full Crossref metadata record' — then enumerates the resolved fields (title, authors, container, ISSNs, dates, license, funders). It explicitly separates itself from crossref_get_references (counts vs. entries) and from OpenAlex (citation graphs), so an agent can place it among the siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear positive guidance: call it with a DOI to get the full record, and it names the alternatives for the sub-resources it does not return (references via crossref_get_references, citing works via OpenAlex). It stops short of stating when to prefer crossref_search_works (i.e., when you have no DOI yet), but the exclusions for the adjacent cases are explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crossref_search_fundersSearch FundersARead-onlyInspect
Finds funders registered in the Crossref Funder Registry by name or funder DOI. Provide funder_doi for an exact single-funder lookup — the full DOI ("10.13039/100000001"), the bare registry ID ("100000001"), or either behind a doi: or https://doi.org/ prefix — or query for name-based search. Name-query results page with offset — the nextOffset enrichment carries the value for the following page, up to offset + rows = 100000. Set include_works to true to also return a page of the most recent works funded by the matched funder; that list pages two ways, in two orders. works_offset is the simple one: newest published first, capped ten times lower at works_offset + rows = 10000. works_cursor has no ceiling and reaches the whole funded-works list, newest registered first — ordered by the date each DOI was registered with Crossref, since Crossref does not walk a publication-date sort by cursor: pass works_cursor="*" on the first call, then chain the nextWorksCursor token from each response. The two cannot be combined, and a cursor walk always starts at the most recently registered work — it cannot resume from an offset. This list also counts works funded by the funder's registry descendants, which a crossref_search_works filter on {"funder": "10.13039/"} does not. Returns funder name, registry ID, country, and alternate names. The Funder Registry supersedes entries, and a deprecated one answers to the same names as its successor while carrying only a fraction of its works: such a record carries replacedBy with the superseding registry ID and the response carries a notice naming it. The replacement is never followed automatically — re-run with funder_doi set to that ID to get the current entry.
| Name | Required | Description | Default |
|---|---|---|---|
| rows | No | Maximum funders to return for name queries, or works when include_works is true (1–100 per call, default 10). A larger value, up to 1000, returns 100 and says so in notice; nextOffset and nextWorksOffset continue after the records returned. | |
| query | No | Funder name search query, e.g. "National Science Foundation" or "Wellcome Trust" | |
| offset | No | Zero-based offset into the name-query funder list. Pass the nextOffset value from the previous response to continue. Ignored when funder_doi is set, which resolves exactly one record. | |
| funder_doi | No | Funder DOI for exact lookup — the full DOI "10.13039/100000001" (NSF) or the bare registry ID "100000001". Supersedes query when provided. | |
| works_cursor | No | Cursor token for deep paging of the funded-works list when include_works is true. Pass "*" to start the walk at the most recently registered work, then pass the nextWorksCursor value from each response. A walk runs by the date each DOI was registered with Crossref, newest first, not by publication date — Crossref does not walk a publication-date sort by cursor. Has no offset ceiling and cannot be combined with works_offset. | |
| works_offset | No | Zero-based offset into the funded-works list when include_works is true. Pass the nextWorksOffset value from the previous response to continue. Capped at works_offset + rows = 10000; use works_cursor to read the whole list. Cannot be combined with works_cursor. | |
| include_works | No | When true, also return a page of works funded by the matched funder. Requires an unambiguous funder — pass funder_doi when a name query matches more than one. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Guidance on a page that needs a caveat: a query nothing matched, an offset or works_offset past the end of a list that did match, a page that stops at one of the route offset ceilings with records still unretrieved (naming the offset and smaller rows that reach the last records below the ceiling, when any remain), a returned funder that the Funder Registry has deprecated in favor of another entry, a query or funder_doi supplied blank with nothing else to search by, so the page lists every funder unfiltered, or a rows value above its per-call cap, naming the value requested and the cap applied. Absent otherwise. A page needing more than one caveat carries them all in this one string. |
| funders | No | Matching funder records |
| nextOffset | No | Value to pass as offset on the next call for the following page of funders. Absent when this page ends the matches or the next page would breach the 100000-record offset ceiling. |
| fundedWorks | No | Page of works funded by the matched funder, newest first — by publication date on an offset page, by Crossref registration date on a works_cursor page. Only present when include_works is true. |
| funderCount | No | Number of funder records returned in this page |
| fundersTotal | No | Total funder records matching the query in Crossref |
| nextWorksCursor | No | Value to pass as works_cursor on the next call for the following page of funded works. Present only on a page requested with works_cursor, and absent once the walk reaches the end of the works list. |
| nextWorksOffset | No | Value to pass as works_offset on the next call for the following page of funded works. Absent when this page ends the works list, the next page would breach the 10000-record offset ceiling, or the page was requested with works_cursor. |
| fundedWorksTotal | No | Total count of funded works for the matched funder, when include_works is true |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/openWorld annotations, it discloses pagination ceilings (offset + rows = 100000 for funders, 10000 for works), cursor ordering semantics, the fact that cursor walks cannot resume from an offset, descendant-funder inclusion, and the replacedBy/notice behavior for deprecated registry entries. These are material behavioral traits not recoverable from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded, but the description is a dense single paragraph with repeated cursor-ordering caveats and overlapping explanations of the two works-paging modes. It is appropriately comprehensive for the complexity but would benefit from bullets or trimming of repeated caveats.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still supplies enough context for correct invocation: exact-lookup formats, paging limits, cursor chaining, include_works ambiguity requirements, and deprecated-entry handling. Nothing material for safe, correct calling is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds useful interpretation: accepted funder_doi formats, that query is superseded by funder_doi, the nextOffset/nextWorksCursor chaining convention, and that works_cursor='*' starts the walk. Some of this duplicates schema text, which keeps it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Finds funders registered in the Crossref Funder Registry') and explicitly distinguishes lookup by funder DOI from name search. It also contrasts its funded-works behavior with the sibling crossref_search_works filter, so the tool is identifiable without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to use funder_doi versus query, how to page name results with nextOffset, when to use works_offset versus works_cursor, that the two cannot be combined, and that deprecated entries must be re-run manually with the replacement ID. This is explicit when/when-not guidance with alternatives named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crossref_search_journalsSearch JournalsARead-onlyInspect
Finds Crossref journal records by ISSN or title query. Provide issn for an exact single-journal lookup, or query for title-based search returning up to rows results. Title-query results page with offset — the nextOffset enrichment carries the value for the following page, up to offset + rows = 100000. Set include_works to true to also return a page of the matched journal's most recent works; that list pages two ways, in two orders. works_offset is the simple one: newest published first, capped ten times lower at works_offset + rows = 10000. works_cursor has no ceiling and reaches the whole works list, newest registered first — ordered by the date each DOI was registered with Crossref, since Crossref does not walk a publication-date sort by cursor: pass works_cursor="*" on the first call, then chain the nextWorksCursor token from each response. The two cannot be combined, and a cursor walk always starts at the most recently registered work — it cannot resume from an offset. Returns journal metadata: title, publisher, ISSNs with their print or electronic form, subject areas, DOI counts (total, current, backfile), and per-category metadata deposit coverage — how completely the journal deposits abstracts, references, ORCIDs, funders, licenses, and similar metadata. An issn lookup also returns DOI counts by issued year.
| Name | Required | Description | Default |
|---|---|---|---|
| issn | No | ISSN for exact single-journal lookup (print or electronic, with or without hyphen). Example: "1234-5678". | |
| rows | No | Maximum number of journals to return for title queries, or works when include_works is true (1–100 per call, default 10). A larger value, up to 1000, returns 100 and says so in notice; nextOffset and nextWorksOffset continue after the records returned. | |
| query | No | Journal title search query, e.g. "Nature" or "Journal of Machine Learning Research" | |
| offset | No | Zero-based offset into the title-query journal list. Pass the nextOffset value from the previous response to continue. Ignored when issn is set, which resolves exactly one record. | |
| works_cursor | No | Cursor token for deep paging of the journal works list when include_works is true. Pass "*" to start the walk at the most recently registered work, then pass the nextWorksCursor value from each response. A walk runs by the date each DOI was registered with Crossref, newest first, not by publication date — Crossref does not walk a publication-date sort by cursor. Has no offset ceiling and cannot be combined with works_offset. | |
| works_offset | No | Zero-based offset into the journal works list when include_works is true. Pass the nextWorksOffset value from the previous response to continue. Capped at works_offset + rows = 10000; use works_cursor to read the whole list. Cannot be combined with works_cursor. | |
| include_works | No | When true, also return a page of the journal's most recent works — newest published first on an offset page, newest registered first on a works_cursor walk. Requires an unambiguous journal — pass issn when a title query matches more than one. A journal with no ISSN registered has no addressable works list; the works lookup is then skipped and the notice enrichment says so. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Guidance on a page that needs a caveat: a query nothing matched, an offset or works_offset past the end of a list that did match, a page that stops at one of the route offset ceilings with records still unretrieved (naming the offset and smaller rows that reach the last records below the ceiling, when any remain), an include_works request that was skipped because the matched journal has no registered ISSN to address its works list by, a query or issn supplied blank with nothing else to search by, so the page lists every journal unfiltered, or a rows value above its per-call cap, naming the value requested and the cap applied. Absent otherwise. A page needing more than one caveat carries them all in this one string. |
| journals | No | Matching journal records |
| nextOffset | No | Value to pass as offset on the next call for the following page of journals. Absent when this page ends the matches or the next page would breach the 100000-record offset ceiling. |
| worksTotal | No | Total works count for the journal, when include_works is true |
| recentWorks | No | Page of works from the matched journal, newest first — by publication date on an offset page, by Crossref registration date on a works_cursor page. Requires include_works, and absent even then when the matched journal has no registered ISSN — the works list is addressable by ISSN alone, and the notice enrichment says so. |
| journalCount | No | Number of journal records returned in this page |
| journalsTotal | No | Total journal records matching the query in Crossref |
| nextWorksCursor | No | Value to pass as works_cursor on the next call for the following page of works. Present only on a page requested with works_cursor, and absent once the walk reaches the end of the works list. |
| nextWorksOffset | No | Value to pass as works_offset on the next call for the following page of works. Absent when this page ends the works list, the next page would breach the 10000-record offset ceiling, or the page was requested with works_cursor. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint; the description adds substantial behavioral detail beyond that: pagination ceilings (offset + rows = 100000, works_offset + rows = 10000), cursor walks with no ceiling, the fact that cursor order is DOI registration date, not publication date, and the '*' bootstrap token. It also discloses graceful degradation (a journal with no ISSN registered skips the works lookup and says so in the notice).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with purpose and mode selection before diving into paging mechanics, and every sentence carries operational content. It is dense and unbroken prose without line breaks or grouping of the two independent paging systems, which makes it heavier to parse than the content requires.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers everything an agent needs for this 7-parameter, zero-required-parameter tool: which parameter path to take, paging strategy and limits, failure/skip behavior, and what metadata comes back. An output schema exists, so the return-value summary is redundant but harmless and helpful for tool selection.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3, but the description adds real meaning: the '*' start value for works_cursor, the chaining of nextWorksCursor across calls, the non-combinability of the two works paging modes, and the caveat that a cursor walk cannot resume from an offset. These are semantic constraints that go beyond restating the schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb + resource ('Finds Crossref journal records') and names both lookup modes (ISSN exact lookup vs title query). The resource is clearly distinct from siblings such as crossref_search_works, crossref_get_member, and crossref_get_work, so an agent can route without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear when-to-use guidance for each mode: 'Provide issn for an exact single-journal lookup, or query for title-based search', plus explicit rules that works_cursor and works_offset cannot be combined and that include_works requires an unambiguous journal. It stops short of naming a sibling alternative (e.g., use crossref_search_works to search works directly), so it does not reach the top of the scale.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crossref_search_worksSearch WorksARead-onlyInspect
Searches the Crossref works index (~188M records) by free text and/or structured filters. The generic query matches loosely across all fields; scope precisely with the field-specific parameters queryTitle, queryAuthor, and queryContainerTitle, or resolve a known citation to its DOI with queryBibliographic — all combine with each other and with query. Use the filter parameter for structured filtering (object with hyphen-separated Crossref keys). Sort options: relevance, score, is-referenced-by-count, published, deposited, indexed, created. Each work returns at most authorLimit authors (25 by default) with authorCount reporting the full deposited total, since a single page of large-collaboration papers can carry tens of thousands of author entries; crossref_get_work pages the whole author list for any DOI whose list was cut. Post-publication updates ride each work as Crossref records them: updatedBy names each correction, retraction, expression of concern, or new version issued against it, and updateTo the works it is itself a notice for — an absent updatedBy does not mean the work was never updated. Offset-based paging is capped at ~10K results; use cursor="*" to start cursor-based deep paging, then pass the nextCursor value from each response to continue. A walk with a query term and no sort runs by relevance, one with filters only in Crossref registration order. The walk ends on the page where nextCursor is absent — that page also carries a notice saying the list is exhausted. Cursor and offset cannot be combined.
| Name | Required | Description | Default |
|---|---|---|---|
| rows | No | Number of results to return per page (1–100 per call, default 20). A larger value, up to 1000, returns 100 and says so in notice — on an offset page the notice also names the offset that continues after the records returned. | |
| sort | No | Sort field. Omitted, an offset page with a query term is ranked by relevance, and so is a cursor walk with one (sent as score). The publication-date sorts (published, published-print, published-online) work with offset paging only — Crossref refuses them alongside cursor; every other sort works with either. | |
| order | No | Sort direction (asc or desc). Applies only alongside sort; without one it has no effect. | |
| query | No | Free-text search query, e.g. "CRISPR gene editing" or "climate change adaptation" | |
| cursor | No | Cursor token for deep paging. Pass "*" to start cursor-based paging (required past ~10K results), then pass the nextCursor value from each response until a response omits it, which means the list is exhausted. A walk with a query term runs by relevance unless sort is set; a walk with filters only runs in Crossref registration order. Relevance scores shift slightly between identical requests, so a relevance walk can repeat or skip a record at a page boundary — sort:"created" walks every match without repeats. Cannot be combined with offset, or with a publication-date sort (published, published-print, published-online), which Crossref does not walk by cursor. | |
| fields | No | Fields to return (reduces payload). Names are case-sensitive, and each fills one output field: DOI → doi, title → title, type → type, author → authors and authorCount, published / published-print / published-online → published, container-title → containerTitle, publisher → publisher, is-referenced-by-count → isReferencedByCount, score → score, abstract → abstract, volume → volume, issue → issue, page → page, article-number → articleNumber, ISSN → issn, updated-by → updatedBy, update-to → updateTo. A selected field absent from a work means the record does not deposit it. DOI is always returned whether or not it is listed here, so every result stays resolvable by crossref_get_work, which also returns the fields this list does not cover (license, funder, references, and the rest of the record). | |
| filter | No | Structured filter object using Crossref hyphen-separated keys. All values must be strings. Boolean flag keys (has-abstract, has-references, has-full-text) require string values "true" or "false". Example: {"type":"journal-article","has-abstract":"true","from-pub-date":"2023-01-01"} | |
| offset | No | Zero-based result offset for offset-based paging. Cannot be used with cursor. Capped at ~10K; use cursor for deeper paging. | |
| queryTitle | No | Match against work titles only, e.g. "Array programming with NumPy". | |
| authorLimit | No | Maximum number of authors to return per work (1–500 per call, default 25; a larger value, up to 100000, applies 500 and says so in notice). Ordinary records fit under the default; large-collaboration papers deposit thousands, and a page of them is large enough to exhaust a client context. Each work reports its full deposited total as authorCount — call crossref_get_work with that work doi to page the authors this cap left out. | |
| queryAuthor | No | Match against author names only, e.g. "Charles R. Harris". | |
| queryBibliographic | No | Whole-citation match to resolve a known reference to its DOI. Combine title, author, year, and container into one string, e.g. "Watson Crick molecular structure of nucleic acids Nature 1953". | |
| queryContainerTitle | No | Match against the container title (journal or book name) only, e.g. "Nature". |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The per-work author cap applied to this page. Absent when no list was cut. |
| error | No | Present when the call failed. Absent on success. |
| works | No | Matching works. Empty when nothing matched the query, when an offset runs past the end of the results, or on the page that ends a cursor walk — the notice enrichment says which. |
| notice | No | Guidance on an empty page, naming which of its three causes applies: a query nothing matched, an offset past the end of a list that did match, or a cursor walk that has reached the end of the list. On a page carrying records, present when authorLimit cut at least one work list, naming how many and the route to the rest, or when every query term and filter value was supplied blank, so the page lists the whole index unfiltered. On any page, present when rows or authorLimit was above its per-call cap, naming the value requested and the cap applied — on an offset page with records remaining, also the offset that continues after the records returned, with the smaller rows that still fit when a full page there would pass the ~10K offset ceiling. A page needing more than one caveat carries them all in this one string. |
| returned | No | Number of records returned in this response |
| truncated | No | True when at least one work on this page had its author list cut by authorLimit. Absent when every work on the page carries its full deposited author list. |
| nextCursor | No | Cursor token to pass as cursor on the next call to continue a cursor walk. Present only on a page requested with cursor, and absent once the walk reaches the end of the list. |
| totalResults | No | Total matching records in Crossref |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover readOnly/openWorld, but the description goes far beyond: the ~10K offset cap and cursor walk protocol, the end condition (page with no nextCursor), the incompatibility of cursor with offset and publication-date sorts, the relevance-walk repeat/skip hazard with the sort:"created" workaround, and the truncation of author lists with authorCount as the true total. It also explains that an absent updatedBy does not mean a work was never updated – a genuine non-obvious caveat.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and mode selection are front-loaded, and the dense back half is mostly load-bearing detail about paging. Some of it restates cursor and sort behavior already spelled out in the schema parameter descriptions, which is avoidable repetition in an already long description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter, nested-object, deep-paging search tool this covers everything an agent needs to call it correctly: query modes, filter shape, sort/paging compatibility, payload limiting, and the escape hatch to crossref_get_work. The output schema exists and the description does not waste space explaining return shapes beyond the paging and author-cap semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: the combination semantics ('all combine with each other and with query'), the authorLimit default of 25 versus the deposited total, and the fact that filter keys are hyphen-separated Crossref names. Much of the cursor and sort text duplicates the schema's own parameter descriptions, keeping it out of 5 territory.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource plus scale ('Searches the Crossref works index (~188M records) by free text and/or structured filters'). It then distinguishes the generic query from the field-specific variants queryTitle/queryAuthor/queryContainerTitle and queryBibliographic, so an agent can pick the right mode without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Strong in-mode routing: use queryBibliographic to resolve a known citation to a DOI, field-specific params to scope precisely, filter for structured filtering, and crossref_get_work to page a truncated author list. It does not, however, differentiate itself from adjacent siblings such as crossref_search_journals or crossref_search_funders, so tool-level selection guidance is incomplete.
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.
2 tool updates
- Changed
crossref_get_work3 fields changed- changed
Output schema / properties / abstract / descriptionPrevious value: -"Abstract when deposited by the publisher. Many records lack abstracts. Publishers deposit it as JATS XML, so this is the text of that deposit with markup removed and character references decoded; a link keeps its tag only where its href holds an address the text it wraps does not already carry, and each formula appears once — MathML as the TeX annotation it carries, otherwise written out linearly (x_i, A^{−1}, √(m), (a+b)/c), and TeX deposited beside MathML in whichever notation comes first."New value: +"Abstract when deposited by the publisher. Many records lack abstracts. Publishers deposit it as JATS XML, so this is the text of that deposit with markup removed and character references decoded; numeric JATS superscripts retain caret notation (10^{16}, GeV^2), a link keeps its tag only where its href holds an address the text it wraps does not already carry, and each formula appears once — MathML as the TeX annotation it carries, otherwise written out linearly (x_i, A^{−1}, √(m), (a+b)/c), and TeX deposited beside MathML in whichever notation comes first." - added
Output schema / properties / licenses / items / properties / startAdded value: +{ + "description": "License start date-time as deposited by the publisher", + "type": "string" +} - added
Output schema / properties / links / items / properties / contentVersionAdded value: +{ + "description": "Content version of the linked manuscript as deposited (e.g. vor, am)", + "type": "string" +}
- Changed
crossref_search_works1 field changed- changed
Output schema / properties / works / items / properties / abstract / descriptionPrevious value: -"Abstract when present in the indexed record — the text of the publisher’s JATS deposit, with markup removed and character references decoded; a link keeps its tag only where its href holds an address the text it wraps does not already carry, and each formula appears once — MathML as the TeX annotation it carries, otherwise written out linearly (x_i, A^{−1}, √(m), (a+b)/c), and TeX deposited beside MathML in whichever notation comes first"New value: +"Abstract when present in the indexed record — the text of the publisher’s JATS deposit, with markup removed and character references decoded; numeric JATS superscripts retain caret notation (10^{16}, GeV^2), a link keeps its tag only where its href holds an address the text it wraps does not already carry, and each formula appears once — MathML as the TeX annotation it carries, otherwise written out linearly (x_i, A^{−1}, √(m), (a+b)/c), and TeX deposited beside MathML in whichever notation comes first"
5 tool updates
- Changed
crossref_get_references8 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of references to return in one page (1–500, default 100). Most works fit in a single page; bibliography records can carry tens of thousands."New value: +"Maximum number of references to return in one page (1–500 per call, default 100). A larger value, up to 100000, returns 500 and says so in notice; nextOffset continues after the references returned. Most works fit in a single page; bibliography records can carry tens of thousands." - changed
Input schema / properties / limit / maximumPrevious value: -500New value: +100000 - changed
Output schema / properties / notice / descriptionPrevious value: -"Coverage guidance when no references are indexed, or a range explanation when the requested offset is past the end of the list. Absent on a normal page."New value: +"Coverage guidance when no references are indexed, a range explanation when the requested offset is past the end of the list, or which references this page covers and the offset that reaches the next ones. Leads with the value requested and the cap applied when limit was above its per-call cap. Absent on a page that holds the whole list with limit within its cap." - added
Output schema / properties / references / items / properties / doiAssertedByAdded value: +{ + "description": "Who supplied the DOI: \"publisher\" when the citing work's publisher deposited it, \"crossref\" when Crossref matched the citation to it.", + "type": "string" +} - added
Output schema / properties / references / items / properties / editionAdded value: +{ + "description": "Edition of the cited book, as deposited", + "type": "string" +} - added
Output schema / properties / references / items / properties / issueAdded value: +{ + "description": "Issue", + "type": "string" +} - added
Output schema / properties / references / items / properties / seriesTitleAdded value: +{ + "description": "Title of the series the cited work belongs to, with inline formatting markup removed", + "type": "string" +} - added
Output schema / properties / references / items / properties / volumeTitleAdded value: +{ + "description": "Title of the cited book or proceedings volume, with inline formatting markup removed. The only title on many book and chapter citations.", + "type": "string" +}
- Changed
crossref_get_work3 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of authors to return in one page (1–500, default 25). Ordinary records fit in a single page; large-collaboration papers in particle physics and genomics deposit thousands."New value: +"Maximum number of authors to return in one page (1–500 per call, default 25). A larger value, up to 100000, returns 500 and says so in notice; nextOffset continues after the authors returned. Ordinary records fit in a single page; large-collaboration papers in particle physics and genomics deposit thousands." - changed
Input schema / properties / limit / maximumPrevious value: -500New value: +100000 - changed
Output schema / properties / notice / descriptionPrevious value: -"When updatedBy is present, the update types Crossref records for this work with the source of each, and where the notice is read. Then which authors this page covers and the offset that reaches the next ones, or an explanation when the requested offset is past the end of the author list. Both share this one string when both apply. Absent when the page holds the whole author list and no update is recorded."New value: +"When updatedBy is present, the update types Crossref records for this work with the source of each, and where the notice is read. Then, when limit was above its per-call cap, the value requested and the cap applied. Then which authors this page covers and the offset that reaches the next ones, or an explanation when the requested offset is past the end of the author list. All share this one string when more than one applies. Absent when the page holds the whole author list, no update is recorded, and limit was within its cap."
- Changed
crossref_search_funders3 fields changed- changed
Input schema / properties / rows / descriptionPrevious value: -"Maximum funders to return for name queries, or works when include_works is true (1–100, default 10)"New value: +"Maximum funders to return for name queries, or works when include_works is true (1–100 per call, default 10). A larger value, up to 1000, returns 100 and says so in notice; nextOffset and nextWorksOffset continue after the records returned." - changed
Input schema / properties / rows / maximumPrevious value: -100New value: +1000 - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance on a page that needs a caveat: a query nothing matched, an offset or works_offset past the end of a list that did match, a page that stops at one of the route offset ceilings with records still unretrieved, a returned funder that the Funder Registry has deprecated in favor of another entry, or a query or funder_doi supplied blank with nothing else to search by, so the page lists every funder unfiltered. Absent otherwise. A page needing more than one caveat carries them all in this one string."New value: +"Guidance on a page that needs a caveat: a query nothing matched, an offset or works_offset past the end of a list that did match, a page that stops at one of the route offset ceilings with records still unretrieved (naming the offset and smaller rows that reach the last records below the ceiling, when any remain), a returned funder that the Funder Registry has deprecated in favor of another entry, a query or funder_doi supplied blank with nothing else to search by, so the page lists every funder unfiltered, or a rows value above its per-call cap, naming the value requested and the cap applied. Absent otherwise. A page needing more than one caveat carries them all in this one string."
- Changed
crossref_search_journals9 fields changed- changed
Input schema / properties / rows / descriptionPrevious value: -"Maximum number of journals to return for title queries, or works when include_works is true (1–100, default 10)"New value: +"Maximum number of journals to return for title queries, or works when include_works is true (1–100 per call, default 10). A larger value, up to 1000, returns 100 and says so in notice; nextOffset and nextWorksOffset continue after the records returned." - changed
Input schema / properties / rows / maximumPrevious value: -100New value: +1000 - added
Output schema / properties / journals / items / properties / backfileDoisAdded value: +{ + "description": "DOIs issued before the current window", + "type": "number" +} - added
Output schema / properties / journals / items / properties / coverageAdded value: +{ + "description": "Per-category metadata deposit coverage for this journal — each a 0–1 fraction split into current and backfile DOIs. Signals how completely the journal deposits abstracts, references, ORCIDs, funders, licenses, and similar metadata. A window with no DOIs reports every fraction as 0, so read each fraction beside currentDois and backfileDois.", + "items": { + "additionalProperties": false, + "description": "Metadata deposit coverage for one category", + "properties": { + "backfile": { + "description": "Coverage fraction (0–1) among backfile (older) DOIs", + "type": "number" + }, + "category": { + "description": "Metadata deposit category, e.g. \"references\", \"abstracts\", \"orcids\", \"funders\", \"licenses\", \"affiliations\"", + "type": "string" + }, + "current": { + "description": "Coverage fraction (0–1) among current (recent) DOIs", + "type": "number" + } + }, + "required": [ + "category" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / journals / items / properties / currentDoisAdded value: +{ + "description": "DOIs issued in the current window — this year and the two before it", + "type": "number" +} - added
Output schema / properties / journals / items / properties / doisByYearAdded value: +{ + "description": "Registered DOIs per issued year, ascending by year; a year with no DOIs has no entry. Returned on an issn lookup only — title-query results omit it.", + "items": { + "additionalProperties": false, + "description": "DOI count for one issued year", + "properties": { + "count": { + "description": "DOIs issued that year", + "type": "number" + }, + "year": { + "description": "Issued year", + "type": "number" + } + }, + "required": [ + "year", + "count" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / journals / items / properties / issnL / descriptionPrevious value: -"Linking ISSN (ISSN-L). Absent when the journal has no linking ISSN registered — Crossref reports that as an explicit null rather than an omitted key."New value: +"Linking ISSN (ISSN-L). Crossref journal records do not carry one, so this is normally absent; issnTypes says which ISSN is print and which electronic." - added
Output schema / properties / journals / items / properties / issnTypesAdded value: +{ + "description": "Each ISSN with its form — print or electronic", + "items": { + "additionalProperties": false, + "description": "One ISSN and its form", + "properties": { + "type": { + "description": "ISSN form, e.g. \"print\" or \"electronic\". Absent when Crossref records no form for this ISSN.", + "type": "string" + }, + "value": { + "description": "ISSN", + "type": "string" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance on a page that needs a caveat: a query nothing matched, an offset or works_offset past the end of a list that did match, a page that stops at one of the route offset ceilings with records still unretrieved, an include_works request that was skipped because the matched journal has no registered ISSN to address its works list by, or a query or issn supplied blank with nothing else to search by, so the page lists every journal unfiltered. Absent otherwise. A page needing more than one caveat carries them all in this one string."New value: +"Guidance on a page that needs a caveat: a query nothing matched, an offset or works_offset past the end of a list that did match, a page that stops at one of the route offset ceilings with records still unretrieved (naming the offset and smaller rows that reach the last records below the ceiling, when any remain), an include_works request that was skipped because the matched journal has no registered ISSN to address its works list by, a query or issn supplied blank with nothing else to search by, so the page lists every journal unfiltered, or a rows value above its per-call cap, naming the value requested and the cap applied. Absent otherwise. A page needing more than one caveat carries them all in this one string."
- Changed
crossref_search_works12 fields changed- changed
Input schema / properties / authorLimit / descriptionPrevious value: -"Maximum number of authors to return per work (1–500, default 25). Ordinary records fit under the default; large-collaboration papers deposit thousands, and a page of them is large enough to exhaust a client context. Each work reports its full deposited total as authorCount — call crossref_get_work with that work doi to page the authors this cap left out."New value: +"Maximum number of authors to return per work (1–500 per call, default 25; a larger value, up to 100000, applies 500 and says so in notice). Ordinary records fit under the default; large-collaboration papers deposit thousands, and a page of them is large enough to exhaust a client context. Each work reports its full deposited total as authorCount — call crossref_get_work with that work doi to page the authors this cap left out." - changed
Input schema / properties / authorLimit / maximumPrevious value: -500New value: +100000 - changed
Input schema / properties / cursor / descriptionPrevious value: -"Cursor token for deep paging. Pass \"*\" to start cursor-based paging (required past ~10K results), then pass the nextCursor value from each response until a response omits it, which means the list is exhausted. Cannot be combined with offset, or with a publication-date sort (published, published-print, published-online), which Crossref does not walk by cursor."New value: +"Cursor token for deep paging. Pass \"*\" to start cursor-based paging (required past ~10K results), then pass the nextCursor value from each response until a response omits it, which means the list is exhausted. A walk with a query term runs by relevance unless sort is set; a walk with filters only runs in Crossref registration order. Relevance scores shift slightly between identical requests, so a relevance walk can repeat or skip a record at a page boundary — sort:\"created\" walks every match without repeats. Cannot be combined with offset, or with a publication-date sort (published, published-print, published-online), which Crossref does not walk by cursor." - changed
Input schema / properties / fields / descriptionPrevious value: -"Fields to return (reduces payload). Names are case-sensitive, and each fills one output field: DOI → doi, title → title, type → type, author → authors and authorCount, published / published-print / published-online → published, container-title → containerTitle, publisher → publisher, is-referenced-by-count → isReferencedByCount, score → score, abstract → abstract, volume → volume, issue → issue, page → page, article-number → articleNumber, ISSN → issn. A selected field absent from a work means the record does not deposit it. DOI is always returned whether or not it is listed here, so every result stays resolvable by crossref_get_work, which also returns the fields this list does not cover (license, funder, references, and the rest of the record)."New value: +"Fields to return (reduces payload). Names are case-sensitive, and each fills one output field: DOI → doi, title → title, type → type, author → authors and authorCount, published / published-print / published-online → published, container-title → containerTitle, publisher → publisher, is-referenced-by-count → isReferencedByCount, score → score, abstract → abstract, volume → volume, issue → issue, page → page, article-number → articleNumber, ISSN → issn, updated-by → updatedBy, update-to → updateTo. A selected field absent from a work means the record does not deposit it. DOI is always returned whether or not it is listed here, so every result stays resolvable by crossref_get_work, which also returns the fields this list does not cover (license, funder, references, and the rest of the record)." - changed
Input schema / properties / fields / items / enumPrevious value: -[ - "DOI", - "title", - "type", - "author", - "published", - "published-print", - "published-online", - "container-title", - "publisher", - "is-referenced-by-count", - "score", - "abstract", - "volume", - "issue", - "page", - "article-number", - "ISSN" -]New value: +[ + "DOI", + "title", + "type", + "author", + "published", + "published-print", + "published-online", + "container-title", + "publisher", + "is-referenced-by-count", + "score", + "abstract", + "volume", + "issue", + "page", + "article-number", + "ISSN", + "updated-by", + "update-to" +] - changed
Input schema / properties / order / descriptionPrevious value: -"Sort direction (asc or desc)"New value: +"Sort direction (asc or desc). Applies only alongside sort; without one it has no effect." - changed
Input schema / properties / rows / descriptionPrevious value: -"Number of results to return per page (1–100, default 20)"New value: +"Number of results to return per page (1–100 per call, default 20). A larger value, up to 1000, returns 100 and says so in notice — on an offset page the notice also names the offset that continues after the records returned." - changed
Input schema / properties / rows / maximumPrevious value: -100New value: +1000 - changed
Input schema / properties / sort / descriptionPrevious value: -"Sort field. The publication-date sorts (published, published-print, published-online) work with offset paging only — Crossref refuses them alongside cursor; every other sort works with either."New value: +"Sort field. Omitted, an offset page with a query term is ranked by relevance, and so is a cursor walk with one (sent as score). The publication-date sorts (published, published-print, published-online) work with offset paging only — Crossref refuses them alongside cursor; every other sort works with either." - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance on an empty page, naming which of its three causes applies: a query nothing matched, an offset past the end of a list that did match, or a cursor walk that has reached the end of the list. On a page carrying records, present when authorLimit cut at least one work list, naming how many and the route to the rest, or when every query term and filter value was supplied blank, so the page lists the whole index unfiltered. A page needing more than one caveat carries them all in this one string."New value: +"Guidance on an empty page, naming which of its three causes applies: a query nothing matched, an offset past the end of a list that did match, or a cursor walk that has reached the end of the list. On a page carrying records, present when authorLimit cut at least one work list, naming how many and the route to the rest, or when every query term and filter value was supplied blank, so the page lists the whole index unfiltered. On any page, present when rows or authorLimit was above its per-call cap, naming the value requested and the cap applied — on an offset page with records remaining, also the offset that continues after the records returned, with the smaller rows that still fit when a full page there would pass the ~10K offset ceiling. A page needing more than one caveat carries them all in this one string." - added
Output schema / properties / works / items / properties / updateToAdded value: +{ + "description": "Works this record is an update notice for, in the entry shape updatedBy uses and in deposited order. Omitted when the record is not registered as a notice.", + "items": { + "additionalProperties": false, + "description": "Update link", + "properties": { + "doi": { + "description": "DOI on the other side of the link: the notice, in updatedBy; the updated work, in updateTo. It is this work's own DOI when the update was made to this record in place.", + "type": "string" + }, + "recordId": { + "description": "Retraction Watch record ID. Present only on retraction-watch entries.", + "type": "string" + }, + "source": { + "description": "Who recorded the link: publisher, or retraction-watch for an entry Crossref carries from the Retraction Watch database", + "type": "string" + }, + "type": { + "description": "Crossref update type as deposited: correction, erratum, corrigendum, addendum, retraction, withdrawal, expression_of_concern, new_version, new_edition, or another code", + "type": "string" + }, + "updated": { + "additionalProperties": false, + "description": "Date the update was issued", + "properties": { + "day": { + "description": "Day of month", + "type": "number" + }, + "month": { + "description": "Month (1–12)", + "type": "number" + }, + "year": { + "description": "Year", + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "doi", + "type", + "source" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / works / items / properties / updatedByAdded value: +{ + "description": "Update notices Crossref records against this work — corrections, errata, retractions, expressions of concern, withdrawals, new versions — in deposited order. Entries are never merged: the same notice DOI can appear once per source, typed differently by each. Omitted when none is recorded, which does not mean the work was never updated: coverage depends on publisher and Retraction Watch deposits.", + "items": { + "additionalProperties": false, + "description": "Update link", + "properties": { + "doi": { + "description": "DOI on the other side of the link: the notice, in updatedBy; the updated work, in updateTo. It is this work's own DOI when the update was made to this record in place.", + "type": "string" + }, + "recordId": { + "description": "Retraction Watch record ID. Present only on retraction-watch entries.", + "type": "string" + }, + "source": { + "description": "Who recorded the link: publisher, or retraction-watch for an entry Crossref carries from the Retraction Watch database", + "type": "string" + }, + "type": { + "description": "Crossref update type as deposited: correction, erratum, corrigendum, addendum, retraction, withdrawal, expression_of_concern, new_version, new_edition, or another code", + "type": "string" + }, + "updated": { + "additionalProperties": false, + "description": "Date the update was issued", + "properties": { + "day": { + "description": "Day of month", + "type": "number" + }, + "month": { + "description": "Month (1–12)", + "type": "number" + }, + "year": { + "description": "Year", + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "doi", + "type", + "source" + ], + "type": "object" + }, + "type": "array" +}
2 tool updates
- Changed
crossref_get_work11 fields changed- changed
Output schema / properties / abstract / descriptionPrevious value: -"Abstract when deposited by the publisher. Many records lack abstracts. Publishers deposit it as JATS XML, so this is the text of that deposit with markup removed and character references decoded; a link keeps its tag only where its href holds an address the text it wraps does not already carry, and a formula the deposit encodes more than once — TeX beside MathML — appears once, in the first notation deposited."New value: +"Abstract when deposited by the publisher. Many records lack abstracts. Publishers deposit it as JATS XML, so this is the text of that deposit with markup removed and character references decoded; a link keeps its tag only where its href holds an address the text it wraps does not already carry, and each formula appears once — MathML as the TeX annotation it carries, otherwise written out linearly (x_i, A^{−1}, √(m), (a+b)/c), and TeX deposited beside MathML in whichever notation comes first." - added
Output schema / properties / articleNumberAdded value: +{ + "description": "Article number, deposited by journals that number articles instead of paging them", + "type": "string" +} - added
Output schema / properties / editorsAdded value: +{ + "description": "Editors of the work, or of the book or proceedings containing it, in the entry shape authors use. Returned whole — never paged by offset and limit, and never counted in authorCount. Omitted when the record deposits none.", + "items": { + "additionalProperties": false, + "description": "Author or contributor", + "properties": { + "affiliation": { + "description": "Institutional affiliations", + "items": { + "additionalProperties": false, + "description": "Affiliation", + "properties": { + "name": { + "description": "Affiliation name as deposited. Absent when the publisher asserted the organization by identifier alone, where ror carries it instead.", + "type": "string" + }, + "ror": { + "description": "ROR identifier for the affiliated organization, when the deposit carries one. It is the whole identity of an affiliation deposited without a name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "family": { + "description": "Family (last) name", + "type": "string" + }, + "given": { + "description": "Given (first) name", + "type": "string" + }, + "name": { + "description": "Name when no given/family split is available", + "type": "string" + }, + "orcid": { + "description": "ORCID identifier URI", + "type": "string" + }, + "sequence": { + "description": "Author order role (first, additional)", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / isbnAdded value: +{ + "description": "ISBN(s) as deposited — for a book chapter, those of the containing book. Omitted when the record deposits none.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / issueAdded value: +{ + "description": "Issue of the container the work appears in", + "type": "string" +} - changed
Output schema / properties / notice / descriptionPrevious value: -"Which authors this page covers and the offset that reaches the next ones, or an explanation when the requested offset is past the end of the author list. Absent when the page holds the whole list."New value: +"When updatedBy is present, the update types Crossref records for this work with the source of each, and where the notice is read. Then which authors this page covers and the offset that reaches the next ones, or an explanation when the requested offset is past the end of the author list. Both share this one string when both apply. Absent when the page holds the whole author list and no update is recorded." - added
Output schema / properties / pageAdded value: +{ + "description": "Page range as deposited, e.g. \"357-362\"", + "type": "string" +} - added
Output schema / properties / relationsAdded value: +{ + "description": "Related identifiers — preprints and published versions, other versions, reviews, supplements, parts — grouped by relation type, identifier type, and asserting party, groups in Crossref's order and ids in deposited order. Returned whole. Omitted when the record deposits none.", + "items": { + "additionalProperties": false, + "description": "Related identifiers sharing one relation type, identifier type, and asserting party", + "properties": { + "assertedBy": { + "description": "Whose deposit asserts the relation: subject (this work's depositor) or object (the related record's depositor, whose assertion Crossref shows here inverted)", + "type": "string" + }, + "idType": { + "description": "Identifier scheme of ids: doi, uri, pmid, arxiv, accession, issn, isbn, or other", + "type": "string" + }, + "ids": { + "description": "Related identifiers in deposited order. A DOI resolves through crossref_get_work only when Crossref registered it; one registered with another agency, such as DataCite, returns doi_not_found there.", + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "description": "Relation type as deposited, read from this work toward ids: is-preprint-of, has-preprint, is-version-of, has-version, has-review, is-supplemented-by, references, has-part, and others", + "type": "string" + } + }, + "required": [ + "type", + "idType", + "assertedBy", + "ids" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / updateToAdded value: +{ + "description": "Works this record is an update notice for, in the entry shape updatedBy uses and in deposited order. Omitted when the record is not registered as a notice.", + "items": { + "additionalProperties": false, + "description": "Update link", + "properties": { + "doi": { + "description": "DOI on the other side of the link: the notice, in updatedBy; the updated work, in updateTo. It is this work's own DOI when the update was made to this record in place.", + "type": "string" + }, + "recordId": { + "description": "Retraction Watch record ID. Present only on retraction-watch entries.", + "type": "string" + }, + "source": { + "description": "Who recorded the link: publisher, or retraction-watch for an entry Crossref carries from the Retraction Watch database", + "type": "string" + }, + "type": { + "description": "Crossref update type as deposited: correction, erratum, corrigendum, addendum, retraction, withdrawal, expression_of_concern, new_version, new_edition, or another code", + "type": "string" + }, + "updated": { + "additionalProperties": false, + "description": "Date the update was issued", + "properties": { + "day": { + "description": "Day of month", + "type": "number" + }, + "month": { + "description": "Month (1–12)", + "type": "number" + }, + "year": { + "description": "Year", + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "doi", + "type", + "source" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / updatedByAdded value: +{ + "description": "Update notices Crossref records against this work — corrections, errata, retractions, expressions of concern, withdrawals, new versions — in deposited order. Entries are never merged: the same notice DOI can appear once per source, typed differently by each. Omitted when none is recorded, which does not mean the work was never updated: coverage depends on publisher and Retraction Watch deposits.", + "items": { + "additionalProperties": false, + "description": "Update link", + "properties": { + "doi": { + "description": "DOI on the other side of the link: the notice, in updatedBy; the updated work, in updateTo. It is this work's own DOI when the update was made to this record in place.", + "type": "string" + }, + "recordId": { + "description": "Retraction Watch record ID. Present only on retraction-watch entries.", + "type": "string" + }, + "source": { + "description": "Who recorded the link: publisher, or retraction-watch for an entry Crossref carries from the Retraction Watch database", + "type": "string" + }, + "type": { + "description": "Crossref update type as deposited: correction, erratum, corrigendum, addendum, retraction, withdrawal, expression_of_concern, new_version, new_edition, or another code", + "type": "string" + }, + "updated": { + "additionalProperties": false, + "description": "Date the update was issued", + "properties": { + "day": { + "description": "Day of month", + "type": "number" + }, + "month": { + "description": "Month (1–12)", + "type": "number" + }, + "year": { + "description": "Year", + "type": "number" + } + }, + "type": "object" + } + }, + "required": [ + "doi", + "type", + "source" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / volumeAdded value: +{ + "description": "Volume of the container the work appears in", + "type": "string" +}
- Changed
crossref_search_works1 field changed- changed
Output schema / properties / works / items / properties / abstract / descriptionPrevious value: -"Abstract when present in the indexed record — the text of the publisher’s JATS deposit, with markup removed and character references decoded; a link keeps its tag only where its href holds an address the text it wraps does not already carry, and a formula the deposit encodes more than once appears once, in the first notation deposited"New value: +"Abstract when present in the indexed record — the text of the publisher’s JATS deposit, with markup removed and character references decoded; a link keeps its tag only where its href holds an address the text it wraps does not already carry, and each formula appears once — MathML as the TeX annotation it carries, otherwise written out linearly (x_i, A^{−1}, √(m), (a+b)/c), and TeX deposited beside MathML in whichever notation comes first"
3 tool updates
- Changed
crossref_search_funders9 fields changed- added
Input schema / properties / funder_doi / anyOfAdded value: +[ + { + "const": "", + "type": "string" + }, + { + "description": "Funder registry ID or funder DOI, e.g. \"100000001\"", + "pattern": "^(?:(?:https?:\\/\\/(?:dx\\.)?doi\\.org\\/|doi:)?10\\.13039\\/)?\\d+$", + "type": "string" + } +] - removed
Input schema / properties / funder_doi / patternRemoved value: -"^(?:(?:https?:\\/\\/(?:dx\\.)?doi\\.org\\/|doi:)?10\\.13039\\/)?\\d+$" - removed
Input schema / properties / funder_doi / typeRemoved value: -"string" - changed
Input schema / properties / rows / typePrevious value: -"number"New value: +"integer" - changed
Input schema / properties / works_cursor / descriptionPrevious value: -"Cursor token for deep paging of the funded-works list when include_works is true. Pass \"*\" to start the walk at the newest work, then pass the nextWorksCursor value from each response. Has no offset ceiling and cannot be combined with works_offset. Each token runs about 1500 characters and is returned on both result surfaces, a fixed cost per page — raise rows to spread it across more works on a long walk."New value: +"Cursor token for deep paging of the funded-works list when include_works is true. Pass \"*\" to start the walk at the most recently registered work, then pass the nextWorksCursor value from each response. A walk runs by the date each DOI was registered with Crossref, newest first, not by publication date — Crossref does not walk a publication-date sort by cursor. Has no offset ceiling and cannot be combined with works_offset." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `rate_limited`: Crossref answered HTTP 429 and the limit did not clear inside the retry budget. `upstream_unavailable`: Crossref was unreachable, returned a 5xx status, or served an HTML error page instead of JSON. `malformed_response`: Crossref returned HTTP 200 with a body that is not valid JSON. `request_timeout`: Crossref did not respond within CROSSREF_TIMEOUT_MS, or answered HTTP 408/504. `funder_not_found`: Funder DOI lookup returned 404 — funder is not in the Crossref Funder Registry. `ambiguous_funder`: include_works is true but the name query matched more than one funder, making the target ambiguous. `offset_too_large`: offset + rows exceeds the 100000-record ceiling Crossref allows on funder name search. `works_offset_too_large`: works_offset + rows exceeds the 10000-record ceiling Crossref allows on a funded-works list. `works_cursor_offset_conflict`: include_works is true and works_cursor was supplied alongside a works_offset above zero. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `rate_limited`: Crossref answered HTTP 429 and the limit did not clear inside the retry budget. `upstream_unavailable`: Crossref was unreachable, returned a 5xx status, or served an HTML error page instead of JSON. `malformed_response`: Crossref returned HTTP 200 with a body that is not valid JSON. `request_timeout`: Crossref did not respond within CROSSREF_TIMEOUT_MS, or answered HTTP 408/504. `invalid_cursor`: Crossref did not recognize the cursor token (HTTP 404 cursor-invalid). `invalid_parameter`: Crossref rejected a parameter value (a filter value of the wrong type or form), or answered HTTP 400 with a body that did not parse. `funder_not_found`: Funder DOI lookup returned 404 — funder is not in the Crossref Funder Registry. `ambiguous_funder`: include_works is true but the name query matched more than one funder, making the target ambiguous. `offset_too_large`: offset + rows exceeds the 100000-record ceiling Crossref allows on funder name search. `works_offset_too_large`: works_offset + rows exceeds the 10000-record ceiling Crossref allows on a funded-works list. `works_cursor_offset_conflict`: include_works is true and works_cursor was supplied alongside a works_offset above zero. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "rate_limited", - "upstream_unavailable", - "malformed_response", - "request_timeout", - "funder_not_found", - "ambiguous_funder", - "offset_too_large", - "works_offset_too_large", - "works_cursor_offset_conflict" -]New value: +[ + "rate_limited", + "upstream_unavailable", + "malformed_response", + "request_timeout", + "invalid_cursor", + "invalid_parameter", + "funder_not_found", + "ambiguous_funder", + "offset_too_large", + "works_offset_too_large", + "works_cursor_offset_conflict" +] - changed
Output schema / properties / fundedWorks / descriptionPrevious value: -"Page of works funded by the matched funder, ordered by publication date (newest first). Only present when include_works is true."New value: +"Page of works funded by the matched funder, newest first — by publication date on an offset page, by Crossref registration date on a works_cursor page. Only present when include_works is true." - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance on a page that needs a caveat: a query nothing matched, an offset past the end of a list that did match, a page that stops at one of the route offset ceilings with records still unretrieved, or a returned funder that the Funder Registry has deprecated in favor of another entry. Absent otherwise. A page needing more than one caveat carries them all in this one string."New value: +"Guidance on a page that needs a caveat: a query nothing matched, an offset or works_offset past the end of a list that did match, a page that stops at one of the route offset ceilings with records still unretrieved, a returned funder that the Funder Registry has deprecated in favor of another entry, or a query or funder_doi supplied blank with nothing else to search by, so the page lists every funder unfiltered. Absent otherwise. A page needing more than one caveat carries them all in this one string."
- Changed
crossref_search_journals10 fields changed- changed
Input schema / properties / include_works / descriptionPrevious value: -"When true, also return a page of the journal's most recent works by publication date. Requires an unambiguous journal — pass issn when a title query matches more than one. A journal with no ISSN registered has no addressable works list; the works lookup is then skipped and the notice enrichment says so."New value: +"When true, also return a page of the journal's most recent works — newest published first on an offset page, newest registered first on a works_cursor walk. Requires an unambiguous journal — pass issn when a title query matches more than one. A journal with no ISSN registered has no addressable works list; the works lookup is then skipped and the notice enrichment says so." - added
Input schema / properties / issn / anyOfAdded value: +[ + { + "const": "", + "type": "string" + }, + { + "description": "ISSN, e.g. \"1234-5678\"", + "pattern": "^\\d{4}-?\\d{3}[\\dX]$", + "type": "string" + } +] - removed
Input schema / properties / issn / patternRemoved value: -"^\\d{4}-?\\d{3}[\\dX]$" - removed
Input schema / properties / issn / typeRemoved value: -"string" - changed
Input schema / properties / rows / typePrevious value: -"number"New value: +"integer" - changed
Input schema / properties / works_cursor / descriptionPrevious value: -"Cursor token for deep paging of the journal works list when include_works is true. Pass \"*\" to start the walk at the newest work, then pass the nextWorksCursor value from each response. Has no offset ceiling and cannot be combined with works_offset. Each token runs about 1500 characters and is returned on both result surfaces, a fixed cost per page — raise rows to spread it across more works on a long walk."New value: +"Cursor token for deep paging of the journal works list when include_works is true. Pass \"*\" to start the walk at the most recently registered work, then pass the nextWorksCursor value from each response. A walk runs by the date each DOI was registered with Crossref, newest first, not by publication date — Crossref does not walk a publication-date sort by cursor. Has no offset ceiling and cannot be combined with works_offset." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `rate_limited`: Crossref answered HTTP 429 and the limit did not clear inside the retry budget. `upstream_unavailable`: Crossref was unreachable, returned a 5xx status, or served an HTML error page instead of JSON. `malformed_response`: Crossref returned HTTP 200 with a body that is not valid JSON. `request_timeout`: Crossref did not respond within CROSSREF_TIMEOUT_MS, or answered HTTP 408/504. `issn_not_found`: ISSN lookup returned 404 — ISSN is not registered in Crossref. `ambiguous_journal`: include_works is true but the title query matched more than one journal, making the target ambiguous. `offset_too_large`: offset + rows exceeds the 100000-record ceiling Crossref allows on journal title search. `works_offset_too_large`: works_offset + rows exceeds the 10000-record ceiling Crossref allows on a journal works list. `works_cursor_offset_conflict`: include_works is true and works_cursor was supplied alongside a works_offset above zero. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `rate_limited`: Crossref answered HTTP 429 and the limit did not clear inside the retry budget. `upstream_unavailable`: Crossref was unreachable, returned a 5xx status, or served an HTML error page instead of JSON. `malformed_response`: Crossref returned HTTP 200 with a body that is not valid JSON. `request_timeout`: Crossref did not respond within CROSSREF_TIMEOUT_MS, or answered HTTP 408/504. `invalid_cursor`: Crossref did not recognize the cursor token (HTTP 404 cursor-invalid). `invalid_parameter`: Crossref rejected a parameter value (a filter value of the wrong type or form), or answered HTTP 400 with a body that did not parse. `issn_not_found`: ISSN lookup returned 404 — ISSN is not registered in Crossref. `ambiguous_journal`: include_works is true but the title query matched more than one journal, making the target ambiguous. `offset_too_large`: offset + rows exceeds the 100000-record ceiling Crossref allows on journal title search. `works_offset_too_large`: works_offset + rows exceeds the 10000-record ceiling Crossref allows on a journal works list. `works_cursor_offset_conflict`: include_works is true and works_cursor was supplied alongside a works_offset above zero. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "rate_limited", - "upstream_unavailable", - "malformed_response", - "request_timeout", - "issn_not_found", - "ambiguous_journal", - "offset_too_large", - "works_offset_too_large", - "works_cursor_offset_conflict" -]New value: +[ + "rate_limited", + "upstream_unavailable", + "malformed_response", + "request_timeout", + "invalid_cursor", + "invalid_parameter", + "issn_not_found", + "ambiguous_journal", + "offset_too_large", + "works_offset_too_large", + "works_cursor_offset_conflict" +] - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance on a page that needs a caveat: a query nothing matched, an offset past the end of a list that did match, a page that stops at one of the route offset ceilings with records still unretrieved, or an include_works request that was skipped because the matched journal has no registered ISSN to address its works list by. Absent otherwise."New value: +"Guidance on a page that needs a caveat: a query nothing matched, an offset or works_offset past the end of a list that did match, a page that stops at one of the route offset ceilings with records still unretrieved, an include_works request that was skipped because the matched journal has no registered ISSN to address its works list by, or a query or issn supplied blank with nothing else to search by, so the page lists every journal unfiltered. Absent otherwise. A page needing more than one caveat carries them all in this one string." - changed
Output schema / properties / recentWorks / descriptionPrevious value: -"Page of works from the matched journal, ordered by publication date (newest first). Requires include_works, and absent even then when the matched journal has no registered ISSN — the works list is addressable by ISSN alone, and the notice enrichment says so."New value: +"Page of works from the matched journal, newest first — by publication date on an offset page, by Crossref registration date on a works_cursor page. Requires include_works, and absent even then when the matched journal has no registered ISSN — the works list is addressable by ISSN alone, and the notice enrichment says so."
- Changed
crossref_search_works23 fields changed- changed
Input schema / properties / cursor / descriptionPrevious value: -"Cursor token for deep paging. Pass \"*\" to start cursor-based paging (required past ~10K results), then pass the nextCursor value from each response until a response omits it, which means the list is exhausted. Cannot be combined with offset."New value: +"Cursor token for deep paging. Pass \"*\" to start cursor-based paging (required past ~10K results), then pass the nextCursor value from each response until a response omits it, which means the list is exhausted. Cannot be combined with offset, or with a publication-date sort (published, published-print, published-online), which Crossref does not walk by cursor." - changed
Input schema / properties / fields / descriptionPrevious value: -"Fields to return (reduces payload). Names are case-sensitive. Useful set: DOI, title, author, published, type, is-referenced-by-count, abstract, container-title, publisher, score. DOI is always returned whether or not it is listed here, so every result stays resolvable by crossref_get_work."New value: +"Fields to return (reduces payload). Names are case-sensitive, and each fills one output field: DOI → doi, title → title, type → type, author → authors and authorCount, published / published-print / published-online → published, container-title → containerTitle, publisher → publisher, is-referenced-by-count → isReferencedByCount, score → score, abstract → abstract, volume → volume, issue → issue, page → page, article-number → articleNumber, ISSN → issn. A selected field absent from a work means the record does not deposit it. DOI is always returned whether or not it is listed here, so every result stays resolvable by crossref_get_work, which also returns the fields this list does not cover (license, funder, references, and the rest of the record)." - added
Input schema / properties / fields / items / descriptionAdded value: +"Crossref select name" - added
Input schema / properties / fields / items / enumAdded value: +[ + "DOI", + "title", + "type", + "author", + "published", + "published-print", + "published-online", + "container-title", + "publisher", + "is-referenced-by-count", + "score", + "abstract", + "volume", + "issue", + "page", + "article-number", + "ISSN" +] - changed
Input schema / properties / filter / descriptionPrevious value: -"Structured filter object using Crossref hyphen-separated keys. All values must be strings. Boolean flag keys (has-abstract, has-references, has-full-text) require string values \"true\" or \"false\". Example: {\"type\":\"journal-article\",\"has-abstract\":\"true\",\"from-pub-date\":\"2023-01-01\",\"directory\":\"DOAJ\"}"New value: +"Structured filter object using Crossref hyphen-separated keys. All values must be strings. Boolean flag keys (has-abstract, has-references, has-full-text) require string values \"true\" or \"false\". Example: {\"type\":\"journal-article\",\"has-abstract\":\"true\",\"from-pub-date\":\"2023-01-01\"}" - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - changed
Input schema / properties / offset / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / order / anyOfAdded value: +[ + { + "const": "", + "type": "string" + }, + { + "description": "Sort direction", + "enum": [ + "asc", + "desc" + ], + "type": "string" + } +] - removed
Input schema / properties / order / enumRemoved value: -[ - "asc", - "desc" -] - removed
Input schema / properties / order / typeRemoved value: -"string" - changed
Input schema / properties / rows / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / sort / anyOfAdded value: +[ + { + "const": "", + "type": "string" + }, + { + "description": "Crossref sort field", + "enum": [ + "relevance", + "score", + "is-referenced-by-count", + "published", + "published-print", + "published-online", + "deposited", + "indexed", + "created", + "updated", + "references-count" + ], + "type": "string" + } +] - changed
Input schema / properties / sort / descriptionPrevious value: -"Sort field"New value: +"Sort field. The publication-date sorts (published, published-print, published-online) work with offset paging only — Crossref refuses them alongside cursor; every other sort works with either." - removed
Input schema / properties / sort / enumRemoved value: -[ - "relevance", - "score", - "is-referenced-by-count", - "published", - "published-print", - "published-online", - "deposited", - "indexed", - "created", - "updated", - "references-count" -] - removed
Input schema / properties / sort / typeRemoved value: -"string" - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `rate_limited`: Crossref answered HTTP 429 and the limit did not clear inside the retry budget. `upstream_unavailable`: Crossref was unreachable, returned a 5xx status, or served an HTML error page instead of JSON. `malformed_response`: Crossref returned HTTP 200 with a body that is not valid JSON. `request_timeout`: Crossref did not respond within CROSSREF_TIMEOUT_MS, or answered HTTP 408/504. `cursor_offset_conflict`: Both cursor and offset were supplied in the same request. `offset_too_large`: The requested offset exceeds the ~10K Crossref limit for offset-based paging. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `rate_limited`: Crossref answered HTTP 429 and the limit did not clear inside the retry budget. `upstream_unavailable`: Crossref was unreachable, returned a 5xx status, or served an HTML error page instead of JSON. `malformed_response`: Crossref returned HTTP 200 with a body that is not valid JSON. `request_timeout`: Crossref did not respond within CROSSREF_TIMEOUT_MS, or answered HTTP 408/504. `unknown_filter`: Crossref rejected a filter key it does not recognize (filter-not-available). `sort_cursor_conflict`: A publication-date sort (published, published-print, published-online) was combined with cursor paging, which Crossref refuses. `invalid_cursor`: Crossref did not recognize the cursor token (HTTP 404 cursor-invalid). `invalid_parameter`: Crossref rejected a parameter value (a filter value of the wrong type or form), or answered HTTP 400 with a body that did not parse. `cursor_offset_conflict`: Both cursor and offset were supplied in the same request. `offset_too_large`: The requested offset exceeds the ~10K Crossref limit for offset-based paging. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "rate_limited", - "upstream_unavailable", - "malformed_response", - "request_timeout", - "cursor_offset_conflict", - "offset_too_large" -]New value: +[ + "rate_limited", + "upstream_unavailable", + "malformed_response", + "request_timeout", + "unknown_filter", + "sort_cursor_conflict", + "invalid_cursor", + "invalid_parameter", + "cursor_offset_conflict", + "offset_too_large" +] - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance on an empty page, naming which of its three causes applies: a query nothing matched, an offset past the end of a list that did match, or a cursor walk that has reached the end of the list. On a page carrying records, present only when authorLimit cut at least one work list, naming how many and the route to the rest."New value: +"Guidance on an empty page, naming which of its three causes applies: a query nothing matched, an offset past the end of a list that did match, or a cursor walk that has reached the end of the list. On a page carrying records, present when authorLimit cut at least one work list, naming how many and the route to the rest, or when every query term and filter value was supplied blank, so the page lists the whole index unfiltered. A page needing more than one caveat carries them all in this one string." - added
Output schema / properties / works / items / properties / articleNumberAdded value: +{ + "description": "Article number, deposited by journals that number articles instead of paging them", + "type": "string" +} - added
Output schema / properties / works / items / properties / issnAdded value: +{ + "description": "ISSN(s) of the containing journal", + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / works / items / properties / issueAdded value: +{ + "description": "Issue of the container the work appears in", + "type": "string" +} - added
Output schema / properties / works / items / properties / pageAdded value: +{ + "description": "Page range as deposited, e.g. \"357-362\"", + "type": "string" +} - added
Output schema / properties / works / items / properties / volumeAdded value: +{ + "description": "Volume of the container the work appears in", + "type": "string" +}
7 tool updates
- First observed
crossref_get_member - First observed
crossref_get_prefix - First observed
crossref_get_references - First observed
crossref_get_work - First observed
crossref_search_funders - First observed
crossref_search_journals - First observed
crossref_search_works
Related MCP Connectors
Search 150M+ academic works, journals, and funders via Crossref API.
Crossref MCP — wraps the Crossref REST API (academic papers, free, no auth)
Verify a DOI or find papers via Crossref metadata. $0.005/call via x402.
Search DataCite datasets and software, fetch DOI metadata, trace relations, format citations.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables retrieval of academic literature metadata via DOI or search using the Crossref REST API.2MIT
- AlicenseNot gradedqualityBmaintenanceEnables searching academic papers, journals, and citations via the Crossref API, and resolving DOIs to canonical metadata with authors, references, and citation graphs.252 npmMIT
- AlicenseNot gradedqualityDmaintenanceSearches and retrieves scholarly metadata from the CrossRef REST API, covering over 150 million records across all disciplines, without requiring an API key.MIT
- FlicenseAqualityDmaintenanceEnables searching and retrieving scholarly metadata from Crossref's public REST API, including works, journals, funders, and members, without requiring an API key.101-
Glama MCP Gateway
Add one secure layer between your agents and this server.