---
summary: "Free-text output normalized (JATS markup, entities), funder deprecation notices, dead countryCode field removed"
breaking: false
security: false
---

# 0.3.4 — 2026-08-09

## Added

- **`crossref_search_funders`** projects `replacedBy`/`replaces` on funder records and emits a `notice` naming the successor registry ID when a returned funder is deprecated by the Funder Registry. The replacement is never followed automatically. [#46](https://github.com/cyanheads/crossref-mcp-server/issues/46)
- **`crossref_search_journals`** emits a `notice` when `include_works` is requested and the matched journal has no registered ISSN, instead of silently skipping the works lookup. [#45](https://github.com/cyanheads/crossref-mcp-server/issues/45)

## Changed

- **`normalizeText()`/`normalizeMarkupText()`** in `crossref-service.ts` now cover every human-readable string projected out of a Crossref record. `normalizeMarkupText()` strips inline JATS markup (tag-aware — `<sub>`/`<sup>` join tight, other tags become word boundaries) before the entity-decode-and-whitespace-collapse baseline; whitespace collapse now handles any run, not just runs of two or more, fixing embedded newlines splitting Markdown headings. Reference entries (`crossref_get_references`) stay on the baseline pass only — angle brackets there are ambiguous (Miller indices, DOI fragments, bracketed URLs) and a strip pass risks deleting real content. [#44](https://github.com/cyanheads/crossref-mcp-server/issues/44)
- **`crossref_get_member`** `primaryName`, `names[]`, `location`, and **`crossref_get_prefix`** `ownerName` now run through `normalizeText()`. `get-member`'s primary-name dedupe now compares normalized values, so an alternate name that only differed from the primary by HTML escaping no longer passes through. [#48](https://github.com/cyanheads/crossref-mcp-server/issues/48)
- **`crossref_search_journals`** `RawCrossrefJournal['ISSN-L']` is typed `string | null` to match the upstream payload, and the projection guard is `!= null` — a `null` ISSN-L was previously written into the string-typed `issnL` output field.

## Removed

- **`crossref_search_funders`** drops the `countryCode` output field and `RawCrossrefFunder['country-code']` — Crossref never sends a `country-code` key on `/funders`. [#47](https://github.com/cyanheads/crossref-mcp-server/issues/47)

## Fixed

- **`crossref_search_funders`** `notice` enrichment now accumulates multiple caveats (e.g. a deprecated match on a page that also stops at the offset ceiling) into one string instead of the second silently overwriting the first.

277 tests pass; `bun run devcheck` clean.

## Dependencies

- `@biomejs/biome` (dev) `^2.5.6` → `^2.5.7`
