---
summary: "Framework ^0.13.6 → ^0.13.12: tool error results now end with a request ID, the Docker image installs dependencies in a build-platform deps stage, and server.json launches with npx."
breaking: false
security: false
---

# 0.5.21 — 2026-10-05

## Changed

- **Tool error results end with a request ID**: `content[]` closes with `request <id>` and `structuredContent.error.data.requestId` carries the same id. Tool error results only. (`cyanheads/mcp-ts-core#576`, 0.13.10)
- **Declared `recovery` hints are filled by the framework**: `hn_get_thread`, `hn_get_user`, and `hn_search_content` no longer forward `ctx.recoveryFor(...)` at their `ctx.fail` sites. The hints callers receive are unchanged. (`cyanheads/mcp-ts-core#579`, 0.13.10)
- **Argument rejections log at `notice`** instead of `error`; log-side only. (`cyanheads/mcp-ts-core#567`, 0.13.10)
- **Malformed arguments are repaired before validation**: a JSON-stringified object, or an integer sent for a string field, is decoded and re-validated. (`cyanheads/mcp-ts-core#479`, `#487`, 0.13.9)
- **MCP SDK `@modelcontextprotocol/server` 2.0.0 → 2.2.0**: a 2026-07-28 POST without `MCP-Protocol-Version` is refused `400` / `-32020`, and a JSON-RPC batch over 100 messages is refused (0.13.9, 0.13.11).
- **`ctx.log` messages mirrored to the client honor `MCP_LOG_LEVEL`** and mask sensitive fields. (`cyanheads/mcp-ts-core#621`, `#630`, 0.13.11)
- **Fetch error messages and log records name an upstream URL by origin** (`https://host/…`). (`cyanheads/mcp-ts-core#626`, 0.13.12)
- **Every call logs under a framework-generated `requestId`**; the client's JSON-RPC id moves to `jsonRpcId`. (`cyanheads/mcp-ts-core#584`, 0.13.12)
- **Server stack traces and request context no longer appear in error `data`.** (`cyanheads/mcp-ts-core#519`, 0.13.7; `cyanheads/mcp-ts-core#548`, 0.13.8)
- **Docker image installs production dependencies in a `deps` stage** that runs on the build platform and cross-installs for the target, with `scripts/install-otel.ts` adding the OpenTelemetry packages and `scripts/prune-musl-packages.ts` removing musl-only native bindings. The production stage copies `node_modules` from it; base images move to Bun 1.4.2, and `MCP_FORCE_CONSOLE_LOGGING` leaves the image environment.
- **`server.json` launches with npx**: both npm entries set `runtimeHint: "npx"` and drop `packageArguments`; the HTTP entry sets `MCP_TRANSPORT_TYPE` to `http`.
- **Ignore rules cover every env file**: `.gitignore` ignores `.env*` except `.env.example`, `.env.template`, and `.env.sample`; `.dockerignore` excludes `.env*` and the `.mcpregistry_*` token files; `.mcpbignore` excludes `docs/idea.md` and `logs/`. `package.json` `files` excludes `dist/*.mcpb` from the npm tarball.
- **`.env.example` lists optional variables** (commented out): `MCP_REQUEST_STATE_KEY`, `LOG_TOOL_FAILURE_PAYLOADS`, `LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES`, and the per-signal `OTEL_EXPORTER_OTLP_*_ENDPOINT` overrides.
- **CodeQL runs one job per language** (`actions`, `javascript-typescript`), each uploading under `/language:<language>`.
- **Tooling scripts synced**: `lint:packaging` checks the Dockerfile build platform and the `server.json` launch shape, `lint:mcp` fails on a definition that does not import or a `server.json` that does not parse, `release:github` gains `--check`, and `devcheck`'s TODO scan and tracked-secrets globs are corrected.
- **Docs**: `CLAUDE.md` / `AGENTS.md` describe the framework's recovery fill and request IDs, `README.md` lists the `MCP_HTTP_HOST` default as `127.0.0.1`, and `framework-skills/` is synced to 0.13.12.

## Dependencies

- `@cyanheads/mcp-ts-core` ^0.13.6 → ^0.13.12
- Dev: `@biomejs/biome` ^2.5.14 → ^2.5.15
- Dev: `@socketsecurity/bun-security-scanner` ^1.1.2 → ^1.1.3
- Dev: `@types/node` ^26.6.2 → ^26.6.4
- Dev: `@vitest/coverage-istanbul` ^5.0.1 → ^5.0.3
- Dev: `ignore` ^7.0.9 → ^7.0.11
- Dev: `tsc-alias` ^1.9.5 → ^1.9.7
- Dev: `vitest` ^5.0.1 → ^5.0.3
- `packageManager` bun@1.4.0 → bun@1.4.2
