Skip to content

Back to the catalog

The 2026-07-28 MCP Specification: Stateless Core, MRTR, Header-Based Routing
blog.modelcontextprotocol.ioarticle

The 2026-07-28 MCP Specification: Stateless Core, MRTR, Header-Based Routing

The official MCP maintainers announce the 2026-07-28 spec revision, which converts MCP from a bidirectional stateful protocol into a stateless request/response protocol: sessions and initialize/initialized are retired, requests self-describe via _meta with an optional server/discover RPC, and Mcp-Method/Mcp-Name headers let gateways route and authorize without parsing JSON bodies. It also introduces Multi Round-Trip Requests (MRTR) to replace held-open streams for sampling/elicitation, cache hints (ttlMs, cacheScope) on list/read responses, formalizes an extensions framework (Tasks, MCP Apps, Enterprise Managed Authorization), and hardens authorization with RFC 9207 issuer validation and a shift from Dynamic Client Registration to Client ID Metadata Documents. TypeScript, Python, Go, and C# SDKs (Tier 1) ship updated support, with Rust in beta and a 12-month deprecation window for Roots, Sampling, Logging, and legacy HTTP+SSE transport.

TL;DR MCP's 2026-07-28 spec makes the protocol stateless, adds MRTR for server-to-client requests, header-based routing, cacheable list results, and OAuth hardening.
Also seen from another angle🛡️ Security →
Document

What it claims

The 2026-07-28 MCP spec turns MCP from a bidirectional stateful protocol into a request/response stateless one, plus a batch of related changes: MRTR for server→client requests, mandatory routing headers, cacheable list results, authorization hardening, a formal extensions framework, and a deprecation policy. Tier 1 SDKs (TypeScript, Python, Go, C#) ship updated; Rust supports it in beta. Context: ~half a billion SDK downloads/month, TS and Python each past 1 billion total.

How it works

Stateless core. The initialize/initialized handshake and the Mcp-Session-Id header are retired (SEP-2575, SEP-2567). Every request is self-describing, carrying its protocol version, client identity, and capabilities in _meta. A new optional server/discover RPC fetches capabilities up front. Any request can land on any instance behind a plain round-robin load balancer with no shared storage. If you need cross-call state, mint an explicit handle from a tool and have the model pass it back as an argument — not transport-hidden session state.

MRTR (SEP-2322) replaces the server-initiated elicitation/create, sampling/createMessage, and roots/list that needed a held-open stream. The server returns resultType: "input_required" with the requests it needs; the client retries the original call with answers in inputResponses.

Header routing (SEP-2243). Streamable HTTP requests must now include Mcp-Method and Mcp-Name, so gateways/WAFs/rate limiters route and meter without parsing JSON bodies.

Caching (SEP-2549). tools/list, prompts/list, resources/list, resources/read now carry ttlMs and cacheScope.

Breaking changes and deprecations

  • Deprecated (≥12-month offramp, SEP-2577): Roots, Sampling, Logging, and the legacy HTTP+SSE transport. Still work; don't adopt in new code.
  • Dynamic Client Registration formally deprecated in favor of Client ID Metadata Documents (CIMD); DCR works for backward compatibility but will be removed.
  • Tasks moved from experimental core into the io.modelcontextprotocol/tasks extension (SEP-2663), with poll-based tasks/get and new tasks/update; change notifications move to a single opt-in subscriptions/listen stream.
  • A formal deprecation policy now guarantees a twelve-month minimum window.

Authorization hardening

  • Auth servers must return iss per RFC 9207; clients validate before redeeming a code — closes an AS mix-up hole (SEP-2468).
  • Clients set application_type during DCR so localhost redirects for desktop/CLI apps stop being rejected (SEP-837).
  • Credentials bound to the issuer that minted them; no reuse across auth servers (SEP-2352).

How to use it

SDKs implement both server and client APIs for the new version with migration notes for breaking parts; the maintainers flag migration cost "especially for developers that did depend on session identifiers." An example stateless call:

POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
{"jsonrpc":"2.0","id":1,"method":"tools/call",
 "params":{"name":"search","arguments":{"q":"otters"},
 "_meta":{"io.modelcontextprotocol/clientInfo":{"name":"my-app","version":"1.0"}}}}

Limits

This is a blog announcement, not the spec text — actual migration detail lives in the linked SEPs and SDK migration notes. Rust is beta only. Deprecated features (SSE transport, Roots/Sampling/Logging, DCR) keep working for at least twelve months, so the breaking cost is deferred rather than immediate, but new builds should avoid them.

Organisations named here

  • David Soria Parra
  • Den Delimarsky
  • Model Context Protocol
  • RFC 9207

Technologies named here

  • MCP TypeScript SDK
  • MCP Python SDK
  • MCP Go SDK
  • MCP C# SDK
  • MCP Rust SDK
  • Model Context Protocol

Techniques named here

  • Stateless protocol core
  • Multi Round-Trip Requests
  • Header-based routing
  • Cacheable list results
  • Explicit state handles
  • Client ID Metadata Documents
  • Issuer validation
  • Extensions framework