---
summary: "Fixes gutenberg_search_books/browse_popular/get_book content[] and error-recovery gaps (full subject lists, out-of-range pages, truncation metadata, not_found hints); adopts mcp-ts-core ^0.10.14 with a Socket supply-chain scanner and clears 9 transitive advisories (hono, vite, js-yaml, esbuild) via bun audit."
breaking: false
security: false
---

# 0.1.5 — 2026-07-11

## Changed

- **Supply-chain install guard** — `bunfig.toml` gains `minimumReleaseAge = 259200` (3-day hold on freshly published versions, excluding `@cyanheads/mcp-ts-core` via `minimumReleaseAgeExcludes` for same-day framework adoption) and `[install.security] scanner = "@socketsecurity/bun-security-scanner"`; `trustedDependencies` in `package.json`/`bun.lock` allowlists the scanner's postinstall.
- **Dockerfile** — `oven/bun:1.3` → `oven/bun:1.3.14` pinned across both stages; `bun install` steps gain `--ignore-scripts` and a BuildKit cache mount (`--mount=type=cache,target=/root/.bun/install/cache`).
- **`scripts/devcheck.ts`** Outdated gate — a row held back by `minimumReleaseAge` (bun marks Update equal to Current with a `*`) is no longer reported as drift; a genuine update still fails the gate.
- **`scripts/lint-mcp.ts`** — only spreads `packageJson` into the lint report when present.
- **Package metadata** — `package.json` `author` → `Casey Hand <casey@caseyjhand.com> (https://caseyjhand.com)`; description reworded action-first across `package.json`, `manifest.json`, and both plugin manifests; `manifest.json` gains an explicit `license` field; LICENSE copyright year → 2026.
- **`.gitattributes`, `.github/FUNDING.yml`, `.github/SECURITY.md`** added — LF normalization plus binary/linguist-generated rules, funding links, and a disclosure policy (private report via the GitHub Security tab or casey@caseyjhand.com).
- **Skills** — vendored skill set synced to mcp-ts-core's current release (12 files, incl. `git-wrapup` 1.7, `design-mcp-server` 2.20, `api-linter` 1.8, `api-workers` 1.6, `api-canvas` 1.9); `changelog/template.md` clarifies that `security:` flags only this project's own source fixes, not dependency/transitive CVE bumps.

## Fixed

- **`gutenberg_search_books` — full subject lists in `content[]`**: `format()` rendered only the first three subject headings with a trailing ellipsis even though `structuredContent` carried all of them; it now renders the complete list so `content[]`-only clients see the same data. ([#3](https://github.com/cyanheads/gutenberg-mcp-server/issues/3))
- **`gutenberg_search_books` — out-of-range pages return `page_out_of_range`, not a raw 404**: a page past the last page of results previously leaked Gutendex's raw upstream fetch error. `GutendexService` now keys off the exact `{"detail":"Invalid page."}` response body to translate that specific 404 into a `page_out_of_range` reason; the tool re-throws it as a `ValidationError` with a recovery hint (divide `totalCount` by 32 to find the last page). Other 404s (a genuinely missing resource) still bubble unchanged. ([#6](https://github.com/cyanheads/gutenberg-mcp-server/issues/6))
- **`gutenberg_browse_popular` — truncation metadata reaches `content[]`**: the `enrichment` block's `truncated`/`shown`/`cap`/`truncationCeiling` fields were visible in `structuredContent` but absent from the formatted text. A new `enrichmentTrailer` renders each field as readable prose, including a `gutenberg_search_books` retrieval pointer (same language/topic filters, `sort="popular"`, successive pages) for paging through the full result set. ([#4](https://github.com/cyanheads/gutenberg-mcp-server/issues/4))
- **`gutenberg_get_book` — `not_found` recovery hint reaches the client**: a missing book ID returned the declared `not_found` reason but dropped the recovery guidance on both surfaces. The handler now re-throws through `ctx.fail('not_found', ...)` so the hint reaches `content[]` text and `structuredContent.error.data.recovery.hint`. ([#5](https://github.com/cyanheads/gutenberg-mcp-server/issues/5))

## Dependencies

- `@cyanheads/mcp-ts-core` `^0.10.9` → `^0.10.14`
- `typescript` `^5.9.3` → `^6.0.3` — forced by the framework's es2025 `tsconfig.base.json`
- `bun` (`packageManager`) `1.3.11` → `1.3.14`
- Added `@socketsecurity/bun-security-scanner` `^1.1.2` — the `bunfig.toml install.security` scanner (see Changed)
- `hono` (transitive) `<4.12.25` → `4.12.28` — clears 5 advisories: 1 high ([GHSA-88fw-hqm2-52qc](https://github.com/advisories/GHSA-88fw-hqm2-52qc), CORS middleware reflects any Origin with credentials on the wildcard default) and 4 moderate ([GHSA-wwfh-h76j-fc44](https://github.com/advisories/GHSA-wwfh-h76j-fc44) `serve-static` Windows path traversal, [GHSA-j6c9-x7qj-28xf](https://github.com/advisories/GHSA-j6c9-x7qj-28xf) + [GHSA-wgpf-jwqj-8h8p](https://github.com/advisories/GHSA-wgpf-jwqj-8h8p) Lambda/Lambda@Edge header handling, [GHSA-rv63-4mwf-qqc2](https://github.com/advisories/GHSA-rv63-4mwf-qqc2) Lambda body-limit bypass)
- `vite` (transitive, dev) `<=8.0.15` → `8.1.3` — clears [GHSA-fx2h-pf6j-xcff](https://github.com/advisories/GHSA-fx2h-pf6j-xcff) (high, `server.fs.deny` bypass on Windows) and [GHSA-v6wh-96g9-6wx3](https://github.com/advisories/GHSA-v6wh-96g9-6wx3) (moderate, `launch-editor` NTLMv2 hash disclosure)
- `js-yaml` (transitive) `<3.15.0` → `3.15.0` — clears [GHSA-h67p-54hq-rp68](https://github.com/advisories/GHSA-h67p-54hq-rp68) (moderate, quadratic-complexity DoS via merge-key aliases)
- `esbuild` (transitive, dev) `>=0.27.3 <0.28.1` — no longer resolved in the tree; clears [GHSA-g7r4-m6w7-qqqr](https://github.com/advisories/GHSA-g7r4-m6w7-qqqr) (low, dev-server arbitrary file read on Windows)
- `bun audit`: 9 vulnerabilities (2 high, 6 moderate, 1 low) → 0
