---
summary: "Adopts mcp-ts-core 0.12.3 and the MCP SDK v2 wire it brings — HTTP endpoints serve protocol revision 2026-07-28 alongside the 2025 era, tool arguments are strict, and the advertised outputSchema declares the error envelope."
breaking: false
security: false
---

# 0.3.1 — 2026-08-24

A framework upgrade. Nothing under `src/` changed; everything below arrives through `@cyanheads/mcp-ts-core` `^0.12.3` or the config and docs around it.

## Added

- **`AGENTS.md`** — the agent protocol, for harnesses that read that filename rather than `CLAUDE.md`.
- **`.github/CONTRIBUTING.md` and `.github/CODE_OF_CONDUCT.md`** — how to file, and how to tell a bug in this server from one in `mcp-ts-core`.

## Changed

- **Every HTTP endpoint serves protocol revision `2026-07-28` alongside the 2025 era**, and advertised JSON Schema is 2020-12 rather than draft-07 — a strict 2020-12 client no longer rejects a tool before dispatching it.
- **Tool arguments are strict.** An argument key none of the nine `worldbank_*` tools declares is rejected by name instead of silently stripped. Root level only; nested objects still strip.
- **The advertised `outputSchema` declares the error envelope.** A client that validates `structuredContent` without checking `isError` no longer rejects this server's error results with `-32602`.
- **`resources/subscribe` is advertised and backed** for `worldbank://indicator/{indicatorId}` and `worldbank://country/{countryCode}`.
- **Server log output reaches the client** as `notifications/message`, gated by the client's `logging/setLevel`.
- **An upstream request deadline bounds the whole exchange**, not just the response headers — a World Bank response that stalls mid-body aborts on the same timeout.
- **`MCP_SESSION_MODE=stateless` is set outright in `.env.example`**, documented in the README config table, and unchanged in the Docker image. This server holds no per-session state; the framework's `auto` default otherwise resolves to `stateful`.
- **`MCP_HTTP_RESUMABILITY`, `MCP_HTTP_RESUMABILITY_MAX_EVENTS`, and `MCP_HTTP_RESUMABILITY_TTL_MS` documented in `.env.example`** — SSE replay on a dropped stateful stream, inert while serving stateless.
- **`skills/`, `changelog/template.md`, and the `scripts/lint-mcp.ts`, `scripts/lint-packaging.ts`, `scripts/tree.ts` helpers re-synced from the framework package** — the definition linter drops the removed task surface, and `lint:packaging` checks the bundle for `@modelcontextprotocol/server`.

## Fixed

- **Tool input-validation failures read as flat `path: message` sentences**, not a serialized `ZodIssue[]` blob behind an `MCP error -32602:` prefix.
- **An unknown or disabled tool rejects with `-32602`** rather than resolving an `isError` result.
- **A POST carrying a non-JSON `Content-Type` answers `415`**, not a `-32700` parse error.
- **`bun run tree` honors directory-only `.gitignore` patterns**, so an ignored directory stays out of `docs/tree.md`.

## Dependencies

- `@cyanheads/mcp-ts-core` `^0.11.1` → `^0.12.3` (swaps `@modelcontextprotocol/sdk` `^1.30.0` for `@modelcontextprotocol/server` `^2.0.0`; no source change needed here — no direct SDK imports, no `ctx.elicit` call, no task tools, no output field named `error`)
- `@biomejs/biome` `^2.5.7` → `^2.5.10`
- `@types/node` `^26.1.2` → `^26.2.0`
- `tsc-alias` `^1.9.1` → `^1.9.2`
- `vitest` `^4.1.10` → `^4.1.11`
- `packageManager` `bun@1.3.14` → `bun@1.4.0`, matching the `Dockerfile`'s `oven/bun` build and `-slim` production stages
- The Docker production install and the OpenTelemetry add pass `--omit=peer`
