---
summary: "Crossref rejections come back as declared reasons with the rejected inputs, works_cursor walks on the journal and funder tools work again, crossref_search_works.fields is limited to the 17 names the summary projects, and blank search inputs read as omitted."
breaking: true
security: false
---

# 0.4.0 — 2026-09-23

**Breaking:** two input classes that previously reached Crossref now fail schema validation with `-32602` (`invalid_arguments`) before any request — a `crossref_search_works.fields` name outside the 17 listed below, and a fractional `rows` or `offset`. Pass one of the listed names (use `crossref_get_work` for any other metadata) and whole-number `rows`/`offset`.

## Added

- **Declared reasons for Crossref's rejections of caller input** ([#9](https://github.com/cyanheads/crossref-mcp-server/issues/9)) — a 400, or a 404 `cursor-invalid`, maps on Crossref's `type` to `unknown_filter` (with `data.suggestion` when Crossref lists the hyphenated key), `sort_cursor_conflict`, `invalid_cursor`, or `invalid_parameter`, each a `ValidationError` carrying `data.rejected` (`{ type, value }` per entry) and a recovery hint. `crossref_search_works` declares all four; the journal and funder tools declare `invalid_cursor` and `invalid_parameter`.
- **Citation locators and ISSN on `crossref_search_works` results** ([#63](https://github.com/cyanheads/crossref-mcp-server/issues/63)) — `volume`, `issue`, `page`, `articleNumber`, and `issn`, projected whenever deposited and rendered in `content[]`.

## Changed

- **`crossref_search_works.fields` accepts only the 17 select names the summary projects** ([#63](https://github.com/cyanheads/crossref-mcp-server/issues/63)) — `DOI`, `title`, `type`, `author`, `published`, `published-print`, `published-online`, `container-title`, `publisher`, `is-referenced-by-count`, `score`, `abstract`, `volume`, `issue`, `page`, `article-number`, `ISSN`. Any other name now fails with `invalid_arguments` before the request, where a name like `license` was fetched and silently dropped and a miscased `doi` came back as a Crossref 400.
- **`rows` on the three search tools and `offset` on `crossref_search_works` are integers** ([#69](https://github.com/cyanheads/crossref-mcp-server/issues/69)) — a fractional value fails with `invalid_arguments` before the request. Crossref answered a fractional `rows` with an unstructured 400 and silently truncated a fractional `offset`.
- **Blank optional inputs on the three search tools read as omitted** ([#64](https://github.com/cyanheads/crossref-mcp-server/issues/64)) — a blank or whitespace-only query term or `filter` value is dropped, and `sort`, `order`, `issn`, and `funder_doi` accept `""`. A page left with no search criterion carries a `notice` saying it is an unfiltered listing.
- **Open-access guidance points at `license.url`** with a Creative Commons license URL instead of `directory:DOAJ`, which Crossref accepts and then answers with HTTP 500.

## Fixed

- **`works_cursor` walks on `crossref_search_journals` and `crossref_search_funders`** ([#60](https://github.com/cyanheads/crossref-mcp-server/issues/60)) — the cursor request sent a publication-date sort, which Crossref refuses beside a cursor. A walk now sorts `created` descending (newest registered first); offset pages keep `published` descending.
- **Empty search pages no longer lead `content[]` with an empty text block** ([#61](https://github.com/cyanheads/crossref-mcp-server/issues/61)) — `format()` emits nothing for a page with no records, so the notice explaining the empty page comes first.
- **A `works_offset` past the end of a journal or funder works list carries a `notice`** naming the offset and the works total, and offset notices use the singular for a total of one ([#68](https://github.com/cyanheads/crossref-mcp-server/issues/68)).
- **Crossref's raw response body no longer rides `error.data`** ([#70](https://github.com/cyanheads/crossref-mcp-server/issues/70)) — `httpErrorFromResponse` runs with `captureBody: false`, so a 5xx carries the status and message without the upstream Java stack excerpt.
- **An `issn` filter value Crossref cannot read is refused before the request** as `invalid_parameter` ([#70](https://github.com/cyanheads/crossref-mcp-server/issues/70)), instead of a Crossref 500 retried four times as an outage; any spelling Crossref reads (`0028–0836`, `ISSN 0028-0836`) passes through unchanged.

## Dependencies

- `@types/node` (dev) `^26.6.1` → `^26.6.2`
