ADR-0002 — Target MCP 2026-07-28 exclusively
- Status: Accepted
- Date: 2026-08-04
Context
The SDK currently speaks 2024-11-05: an initialize handshake, a
notifications/initialized sink, tools/list, tools/call. The current spec revision
is 2026-07-28, the largest break since MCP launched. Relevant to a stdio server:
- The
initialize/notifications/initializedhandshake is removed. Protocol version and client capabilities ride on every request inparams._meta["io.modelcontextprotocol/protocolVersion"]and…/clientCapabilities. server/discoveris a MUST: it advertises supported versions, capabilities and identity, and doubles as the stdio backward-compatibility probe.- Every result carries
resultType("complete"or"input_required"). - List results are
CacheableResults:ttlMsandcacheScopeare required. - Servers never initiate JSON-RPC requests; sampling/elicitation/roots become MRTR
InputRequiredResults. - Error codes were repartitioned:
-32000..-32019implementation-defined,-32020..-32099spec-reserved (HeaderMismatch-32020,MissingRequiredClientCapability-32021,UnsupportedProtocolVersion-32022).
Two shapes were on the table: dual-era (support both handshakes) or latest-only.
Decision
Implement 2026-07-28 and nothing else. No initialize, no
notifications/initialized, no legacy fallback path in the core. A request whose
_meta protocol version is not 2026-07-28 is rejected with
UnsupportedProtocolVersionError (-32022) listing what we support.
Consequences
Good
- The core stays small enough to read in one sitting. Dual-era support would mean two
result builders (with and without
resultType/ttlMs), two dispatch tables, and a state flag recording which era the peer is in — state that a stateless protocol was specifically redesigned to remove. - Statelessness maps exactly onto a bash read loop. There is no session to keep, so there is no session bug to have.
- Being early on a spec whose whole point is “no handshake, no session” is the position worth holding for an SDK whose selling point is that it is 300 lines of shell.
Bad / accepted
- Clients that predate 2026-07-28 cannot talk to this server, including editors
still on
2025-06-18/2025-11-25. This is the real cost and it is deliberate: the version lives inassets/*_config.json, so a user who needs a legacy client today edits data, not code — but the core will still reject legacy requests, so a genuine legacy client needs a shim, not a config edit. - The spec is young; details may move. Mitigated by
ADR-0003: conformance is asserted against the
official published
schema.json, so drift shows up as a failing test rather than as a silent incompatibility.
Alternatives considered
- Dual-era support behind
MCP_LEGACY_COMPAT=1— rejected as the default shape, but it is the natural extension point if real users show up on old clients: it is additive (a second dispatch branch), and nothing in this decision forecloses it. - Stay on 2025-11-25 until clients catch up — rejected: it keeps the session and handshake machinery that is the worst fit for a shell, in exchange for compatibility the demo server does not currently need.