---
summary: "Fix format()/structuredContent parity across 6 tools via new format-parity linter; sync scripts and skills from mcp-ts-core 0.5.3"
breaking: false
---

# 2.3.4 — 2026-04-21

### Fixed

- **`format()` / `structuredContent` parity across 6 tools** — Adopted the framework's new `format-parity` lint rule (mcp-ts-core 0.5.2), which walks every output schema with sentinel values and verifies each leaf is rendered in `content[].text`. Caught 18 real divergences where fields were declared in `output` but silently dropped by `format()` — invisible to `content[]`-only clients (Claude Desktop, VS Code Copilot, Cursor). Fixes:
  - **`clinicaltrials_find_eligible`** — `searchCriteria` (conditions, location, age, sex) and `noMatchHints` now render unconditionally, not only when the match set is empty.
  - **`clinicaltrials_search_studies`** — Same: `searchCriteria` + `noMatchHints` render when present regardless of result count.
  - **`clinicaltrials_get_study_count`** — `noMatchHints` renders whenever present, not only on `totalCount === 0`.
  - **`clinicaltrials_get_field_definitions`** — Renders both `sourceType` and `type` (previously only `sourceType ?? type`); renders `path` even when `resolvedPath` is set; labels nested children section with `children (N):` so the record's dynamic keys are covered by the permissive key-name match.
  - **`clinicaltrials_get_study_record`** — Header now reads `# Study NCTxxxxx: <title>`, providing the `study` keyword required for the top-level record's permissive match.
  - **`clinicaltrials_get_field_values`** — Header renders `piece — field (type[, N unique values])`; `trueCount`/`falseCount` no longer gated on `stat.type === 'BOOLEAN'` literal check (synthetic linter input uses sentinel strings); dropped `.toLocaleString()` on counts (comma-formatted numbers broke strict sentinel substring match).
- **`AGENTS.md` drift from `CLAUDE.md`** — `AGENTS.md` version header was stale at 2.3.1. Synced to current version; framework 0.5.3's new `Docs Sync` devcheck step will prevent recurrence.

### Added

- **`scripts/check-docs-sync.ts`** — New scaffold script (from mcp-ts-core 0.5.3) that fails devcheck when `CLAUDE.md` and `AGENTS.md` diverge. Wired into `bun run devcheck` as the `Docs Sync` step.
- **`lint-mcp` now validates `server.json`** — Updated `scripts/lint-mcp.ts` reads `server.json` + `package.json` at project root and passes them to `validateDefinitions()` for cross-version sanity checks (framework 0.5.3).

### Changed

- **Scaffold scripts resynced from framework** — `scripts/devcheck.ts` and `scripts/lint-mcp.ts` updated to match the 0.5.3 template. Adopted improved `bun audit` error classification (detects registry connection failures vs. true vulnerabilities).
- **Test assertions** — Updated `get-field-values.tool.test.ts` (3 assertions) and `get-study.tool.test.ts` (4 assertions) to match the new `format()` output shape.

### Dependencies

- Upgraded `@cyanheads/mcp-ts-core` from `^0.5.0` to `^0.5.3`. Brings: `format-parity` linter rule, `Docs Sync` devcheck step, `server.json`/`package.json` linter cross-validation, and skill version bumps.
- Bumped `@cloudflare/workers-types` patch version.

### Chores

- **Skill sync** — Synced 6 updated skills from the package (`add-tool` 1.4→1.6, `api-config` 1.1→1.2, `design-mcp-server` 2.3→2.4, `field-test` 1.1→1.2, `polish-docs-meta` 1.3→1.4, `setup` 1.2→1.3). Propagated to `.claude/skills/`.
