Skip to main content

MCP Goes Stateless: Inside the 2026-07-28 Specification Release Candidate

· 7 min read
Gergely Sipos
Frontend Architect

The Model Context Protocol specification release candidate (locked May 21, stable July 28, 2026) makes the protocol fully stateless — no handshakes, no session IDs, no sticky routing. Alongside that headline change, it graduates the extensions framework to first-class status, introduces MCP Apps for server-rendered UI, formalizes the Tasks extension for long-running work, adds production-grade observability headers, upgrades to full JSON Schema 2020-12, and hardens OAuth 2.0 authorization through multiple SEPs. Three features — Roots, Sampling, and Logging — are deprecated under a new lifecycle policy with a one-year sunset window.

The Headline: Stateless Core

The 2025-11-25 specification required a stateful handshake before any real work could happen. Clients and servers exchanged an initialize / initialized round-trip, the server issued an Mcp-Session-Id header, and every subsequent request carried that session ID. In production, this meant sticky routing at load balancers, shared session stores across instances, and reconnection logic when sessions expired.

The 2026-07-28 RC removes all of that. Protocol version, client info, and capabilities now travel in a _meta field on every request. Any server instance can handle any request. Plain round-trip load balancing works out of the box.

Before (2025-11-25 — stateful handshake):

// Step 1: Client sends initialize
{ "method": "initialize",
"params": { "protocolVersion": "2025-11-25",
"clientInfo": { "name": "my-client", "version": "1.0" },
"capabilities": { "roots": {} } } }

// Step 2: Server responds with Mcp-Session-Id header
// Step 3: All subsequent requests carry Mcp-Session-Id

After (2026-07-28 — stateless _meta):

// Any request, any time, any server instance
{ "method": "tools/call",
"params": {
"_meta": { "protocolVersion": "2026-07-28",
"clientInfo": { "name": "my-client", "version": "1.0" },
"capabilities": { "extensions": {} } },
"name": "search_docs",
"arguments": { "query": "deploy" } } }

Clients that need to discover what a server supports can call server/discover on demand — no upfront negotiation required.

Breaking Changes

Four changes require migration work:

ChangeImpactMigration
Session/handshake removalinitialize code must be rewrittenPass client info in _meta; use server/discover for capabilities
Tasks extension graduationExperimental Tasks API lifecycle changesNew handle-based pattern: tools/call → handle → tasks/get / tasks/update / tasks/cancel
Error code shift-32002 (missing resource) → -32602 (JSON-RPC Invalid Params)Update error handlers
Server-to-client requestsSSE-based elicitation prompts replacedUse inputRequired result; client re-issues with inputResponses + requestState

The session removal is the most disruptive — every client and server SDK needs changes. The upside is that the new model is dramatically simpler to operate.

Extensions Framework

Extensions graduate from an informal convention to a formally governed system. Every extension is identified by a reverse-DNS ID (com.example.my-ext), negotiated via an extensions map in client/server capabilities, and versioned independently of the core specification. Extensions get their own repositories and a dedicated SEP (Specification Enhancement Proposal) review track.

Why this matters: third-party tool vendors can ship MCP extensions alongside their products. Multiple extension versions can coexist safely within the same client-server pair. The two headline extensions shipping with the RC — MCP Apps and Tasks — demonstrate the pattern.

MCP Apps

MCP Apps let servers ship server-rendered HTML interfaces alongside their tools. The mechanism:

  • Tools declare UI templates ahead of time as part of their schema
  • Hosts prefetch, cache, and security-review templates before rendering
  • Rendered UI communicates back via JSON-RPC — the same protocol used for everything else
  • Every UI action goes through the same audit/consent path as a regular tool call

This is a significant expansion of what MCP servers can do. Instead of returning only structured data for the host to render, a server can now provide its own interactive interface while still operating within the protocol's security model.

Tasks Extension

Long-running work — multi-step data pipelines, code generation, approval workflows — gets a dedicated extension instead of overloading tools/call responses.

The lifecycle is handle-based:

tools/call  →  returns task handle (instead of immediate result)
tasks/get → poll for status and partial results
tasks/update → send input or state changes to a running task
tasks/cancel → abort a running task

The server decides when a tools/call should return a task handle versus an immediate result. There is no tasks/list method — it can't be scoped safely in the stateless model, and listing all tasks across all clients creates authorization problems.

Operations & Observability

Three features close the gap between "works in development" and "runs in production":

  • RoutableMcp-Method and Mcp-Name HTTP headers let load balancers and API gateways route requests without parsing JSON-RPC bodies. You can send tools/call to a compute-heavy pool and resources/read to a cache-optimized pool.
  • CacheablettlMs and cacheScope fields on list/read results, modeled on HTTP Cache-Control. Clients know how long results stay fresh and whether they're safe to share across users.
  • Traceable — W3C Trace Context headers (traceparent, tracestate, baggage) propagated in _meta. Distributed traces correlate across MCP SDKs, gateways, and backend services in any OpenTelemetry-compatible backend.
┌──────────┐     Mcp-Method: tools/call     ┌──────────────┐
│ Client │ ────────────────────────────→ │ Load Balancer │
└──────────┘ Mcp-Name: search_docs └──────┬───────┘
│ route by method
┌─────────┴─────────┐
│ │
┌────▼────┐ ┌────▼────┐
│ Compute │ │ Cache │
│ Pool │ │ Pool │
└─────────┘ └─────────┘

Authorization Hardening

Multiple SEPs align MCP authorization with production OAuth 2.0 / OIDC requirements:

  • Issuer validation — clients must validate the iss parameter on authorization responses (RFC 9207), mitigating mix-up attacks where a malicious server redirects authorization grants to itself.
  • Application type — clients declare application_type during Dynamic Client Registration, preventing desktop/CLI clients from being defaulted to web with inappropriate security assumptions.
  • Credential binding — credentials are bound to the issuing authorization server. Migrating a resource to a different authorization server requires re-registration, not credential reuse.
  • Scope accumulation and .well-known discovery suffix handling are clarified to match real-world deployment patterns.

Full JSON Schema 2020-12

Tool schemas are no longer limited to basic JSON Schema. The inputSchema and outputSchema fields now support oneOf, anyOf, allOf, $ref, and $defs — the full JSON Schema 2020-12 composition vocabulary.

Two constraints keep this safe:

  • Input schemas retain the type: "object" root constraint (tools need named parameters).
  • Output schemas are unrestricted (a tool can return a string, an array, or a complex union).

Implementations must not auto-dereference external $ref URIs (security boundary) and should bound schema depth and validation time to prevent denial-of-service via pathological schemas.

Deprecated Features

Under a new feature lifecycle policy, three features are deprecated with a one-year sunset — removal no earlier than July 28, 2027:

  • Roots — the concept of a server declaring filesystem roots. Replaced by tool parameters, resource URIs, or server configuration. Roots conflated transport-level concerns with application logic.
  • Sampling — the ability for servers to request LLM completions through the client. Replaced by direct integration with LLM provider APIs. Sampling created a confusing reverse dependency where servers needed to know about the client's model.
  • Logging — the structured logging protocol. Replaced by stderr for stdio transports and OpenTelemetry for structured observability. The protocol-level logging duplicated what standard observability tooling already does better.

All three remain functional for at least 12 months. SDK maintainers should add deprecation warnings now and plan migration guides.

Timeline

  • May 21, 2026 — RC locked. The specification text is frozen.
  • July 28, 2026 — Final stable release.

The 10-week validation window between lock and release is for SDK maintainers and client implementers to ship support. Tier 1 SDKs (TypeScript, Python) are expected to have RC-compatible releases within this window. Feedback goes through specification repository issues; implementation questions go to the contributor Discord.

Worth Watching

The stateless redesign is the kind of change that simplifies everything downstream — deployment, scaling, testing, debugging. If you run MCP servers in production or build integrations against the protocol, the RC is worth reading now rather than scrambling at the July release.

For how MCP fits alongside AG-UI and A2A in the protocol stack, see AG-UI: The Missing Protocol Between AI Agents and Your Frontend.