Skip to main content
Glama

crossref-mcp-server

Search Journals

crossref_search_journals
Read-only

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.

Input Schema

NameRequiredDescriptionDefault
issnNoISSN for exact single-journal lookup (print or electronic, with or without hyphen). Example: "1234-5678".
rowsNoMaximum 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.
queryNoJournal title search query, e.g. "Nature" or "Journal of Machine Learning Research"
offsetNoZero-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_cursorNoCursor 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_offsetNoZero-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_worksNoWhen 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

NameRequiredDescriptionDefault
errorNoPresent when the call failed. Absent on success.
noticeNoGuidance 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.
journalsNoMatching journal records
nextOffsetNoValue 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.
worksTotalNoTotal works count for the journal, when include_works is true
recentWorksNoPage 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.
journalCountNoNumber of journal records returned in this page
journalsTotalNoTotal journal records matching the query in Crossref
nextWorksCursorNoValue 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.
nextWorksOffsetNoValue 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.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed9 schema fields changed
    • changedInput schema / properties / rows / description
      Previous 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."
    • changedInput schema / properties / rows / maximum
      Previous value: -100New value: +1000
    • addedOutput schema / properties / journals / items / properties / backfileDois
      Added value: +{
      +  "description": "DOIs issued before the current window",
      +  "type": "number"
      +}
    • addedOutput schema / properties / journals / items / properties / coverage
      Added 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"
      +}
    • addedOutput schema / properties / journals / items / properties / currentDois
      Added value: +{
      +  "description": "DOIs issued in the current window — this year and the two before it",
      +  "type": "number"
      +}
    • addedOutput schema / properties / journals / items / properties / doisByYear
      Added 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"
      +}
    • changedOutput schema / properties / journals / items / properties / issnL / description
      Previous 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."
    • addedOutput schema / properties / journals / items / properties / issnTypes
      Added 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"
      +}
    • changedOutput schema / properties / notice / description
      Previous 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."
  2. Changed10 schema fields changed
    • changedInput schema / properties / include_works / description
      Previous 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."
    • addedInput schema / properties / issn / anyOf
      Added value: +[
      +  {
      +    "const": "",
      +    "type": "string"
      +  },
      +  {
      +    "description": "ISSN, e.g. \"1234-5678\"",
      +    "pattern": "^\\d{4}-?\\d{3}[\\dX]$",
      +    "type": "string"
      +  }
      +]
    • removedInput schema / properties / issn / pattern
      Removed value: -"^\\d{4}-?\\d{3}[\\dX]$"
    • removedInput schema / properties / issn / type
      Removed value: -"string"
    • changedInput schema / properties / rows / type
      Previous value: -"number"New value: +"integer"
    • changedInput schema / properties / works_cursor / description
      Previous 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."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous 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."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous 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"
      +]
    • changedOutput schema / properties / notice / description
      Previous 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."
    • changedOutput schema / properties / recentWorks / description
      Previous 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."
  3. First observed

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.