MLog
Back to posts
Tech#MCP#AI Agent#Protocol

MCP 2026-07-28: Going Stateless

Published: Jul 14, 2026Reading time: 8 min

MCP's largest revision yet drops the initialize handshake and session IDs for a stateless core. Here's what changes, why it matters, and three migration mistakes to avoid.

MCP 2026-07-28: Going Stateless

I run an MCP server on Kubernetes. Two replicas. Round-robin load balancer in front. Pretty standard setup.

Except MCP 2025-11-25 uses sessions. Client sends initialize, server replies with Mcp-Session-Id, every subsequent request must echo that ID. The server holds session state in memory. When a request lands on the wrong replica — no session there — it fails.

So I had to add sticky sessions. A shared session store. Deep packet inspection for routing. The ops complexity dwarfed the actual business logic.

This isn't just my problem. SEP-1442, opened September 2025 by Jonathan Hefner, Mark Roth, Shaun Smith, Harvey Tuch, and Kurtis Van Gent, stated it plainly: "a simple stateless load balancer cannot be used, as it would route a client's requests to different backend servers."

On July 28, 2026, MCP ships its largest revision yet, and this problem finally goes away. And it fixes a lot more than just that.

What's changing

The RC locked on May 21. Twenty-plus SEPs across five pillars:

Pillar Core change
Stateless core No initialize handshake, no Mcp-Session-Id. Every request is self-contained
Operability layer Mcp-Method/Mcp-Name routing headers, ttlMs caching, W3C Trace Context
Extensions MCP Apps (sandboxed iframe UI) + Tasks + extension framework
Auth hardening 6 SEPs aligning with OAuth 2.1 / OIDC, mandatory iss validation
Deprecation policy Roots / Sampling / Logging deprecated, 12-month removal window

Stateless core

This is the big one — and the biggest breaking change.

In the old model, every session began with initialize from client to server, initialized back, and an Mcp-Session-Id header echoed on every subsequent request. The server held session state in memory. Session lost, server restarted, routed to wrong replica — everything broke.

In 2026-07-28, that whole dance is gone. Every request carries its own protocol version, client identity, and capabilities inside the _meta object. Server capability discovery moves to a new server/discover method — stateless, cacheable, no shared state.

Server-initiated requests also get redesigned. The old model relied on long-lived SSE streams. The new model uses Multi Round-Trip Requests (SEP-2322): the server returns InputRequiredResult with an inputRequests array and an opaque requestState. The client gathers inputs, re-issues the call with inputResponses and the same requestState. The protocol never holds a connection.

{
  "resultType": "input_required",
  "inputRequests": {
    "confirm": {
      "type": "elicitation",
      "message": "Delete these 3 files?",
      "schema": { "type": "boolean" }
    }
  },
  "requestState": "1a2b3c4d5e6f7g8h9i0j..."
}

The real-world consequence: a remote MCP server that previously needed sticky sessions, a shared session store, and deep packet inspection can now run behind a plain round-robin load balancer.

This is the right call. HTTP has worked this way for two decades — application-layer state (cookies, tokens, opaque handles) on a stateless wire is the pattern that scales. MCP co-creator David Soria Parra told ShiftMag in April that "2026 will be about making sure it's ready to help people productionize agentic systems." This release is the technical answer to that statement.

Operability: headers, caching, tracing

Three SEPs that make MCP traffic look like ordinary HTTP API traffic from a routing and observability standpoint. None are glamorous; all remove real production pain.

Routing headers (SEP-2243): Mcp-Method (e.g., tools/call) and Mcp-Name are now required on every Streamable HTTP request. Gateways route on headers without parsing JSON-RPC bodies. At the AAIF MCP Dev Summit in April 2026, Kong, Docker, Solo.io, and Uber's internal platform were all doing the same thing — reverse-engineering tool names from request bodies. That ends on July 28. I think this is the most underrated change in the entire release.

Caching metadata (SEP-2549): tools/list, resources/list, and similar responses now carry ttlMs and cacheScope fields modeled on HTTP Cache-Control. Clients get standardized caching; servers get standardized invalidation.

Distributed tracing (SEP-414): W3C Trace Context propagation with fixed traceparent, tracestate, and baggage keys. OpenTelemetry collectors see MCP traffic end-to-end with zero glue code.

A routable MCP request after 2026-07-28:

POST /mcp HTTP/1.1
Host: server.example.com
Authorization: Bearer <token>
Mcp-Method: tools/call
Mcp-Name: search_issues
Mcp-Protocol-Version: 2026-07-28
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

{"jsonrpc":"2.0","id":"req-1","method":"tools/call",
 "params":{"name":"search_issues","arguments":{"query":"crash"},
 "_meta":{"clientInfo":{"name":"claude","version":"3.5"}}}}

Extensions: MCP Apps and Tasks

MCP finally gets a real extension system. Extensions use reverse-DNS identifiers (e.g., io.modelcontextprotocol/tasks), live in independent ext-* repositories, negotiate through capability advertisements, and version independently of the core spec. The SEP process now has a formal Extensions Track.

Two extensions ship official on day one:

MCP Apps (SEP-1865): Servers declare HTML interfaces rendered inside sandboxed iframes. Tools declare UI templates in advance so clients can prefetch and security-review them. All user interactions flow through the same JSON-RPC protocol — audit trails and consent flows stay unified. This competes directly with OpenAI's Apps SDK.

Tasks: Migrated from experimental core to an extension, redesigned for the stateless model. Servers return task handles from tools/call responses. Clients drive via tasks/get, tasks/update, tasks/cancel. tasks/list is removed — listing tasks across clients has no well-defined scope without sessions.

2025-11-25 2026-07-28
Status Core (experimental) Extension (official)
Task creation Client-initiated Server-initiated (returned from tools/call)
Task polling tasks/result (blocking) tasks/get (polling)
Task input Re-issue tools/call tasks/update with inputResponses
tasks/list Exists Removed

The extension framework is the second most important change in this release, behind only the stateless core. It's the governance answer to the long tail of feature requests — rich UIs, durable jobs, agent handoff — that don't belong in a wire specification. The lesson from the Language Server Protocol that inspired MCP: the spec stays useful only if its evolution surface is bounded.

Auth hardening

Six SEPs fixing OAuth 2.1 / OIDC deployment sharp edges.

The critical one is SEP-2468: clients must validate the iss parameter on every authorization response per RFC 9207 to prevent mix-up attacks — where one authorization server's response replays against another. These attacks have been weaponized in the wild since 2016. MCP servers are protected resources, and MCP clients inherit the same threat model. The exploitation cost is low because the attack surface is small. Every client should ship this by August.

The rest: application_type declaration during Dynamic Client Registration, credential-to-issuer binding, refresh token scope semantics clarified, scope accumulation during step-up authentication defined, and .well-known discovery suffix stabilized.

Deprecation policy

Roots, Sampling, and Logging are deprecated, not removed. The new lifecycle policy (SEP-2577 + SEP-2596) guarantees a minimum 12 months between deprecation and removal. Calling roots/list on July 29 still works.

Deprecated Why Migration target
Roots Incompatible with stateless design Tool parameters (inputSchema), resource URIs
Sampling Clear responsibility boundary Client-side LLM provider API integration
Logging Industry-standard tools preferred stdio: stderr; structured: OpenTelemetry

This matters more than what got deprecated. The community history shows that removing things informally generates months of thrash. Writing the rules down turns deprecation into routine operations.

Three migration mistakes to avoid

Storing session state in the server process. Porting a stateful server without rethinking persistence. The new contract expects you to externalize anything you cared about per-session — basket ID, browser ID, workflow handle — into an opaque handle the client passes back.

Ignoring routing headers. Mcp-Method and Mcp-Name are required, not optional. Gateways validating Streamable HTTP traffic will reject requests missing them. Regenerate your client SDK if it's old.

Misunderstanding requestState. It's opaque to the client — don't try to parse it. But it's not a secret. The server signs or encrypts whatever needs to survive a round-trip. Don't use it for authorization.

The verdict

This release is bigger than "bug fixes and features." It redefines MCP's operational premise — from "needs a stateful connection" to "runs on stateless HTTP."

For solo developers, this is architectural leveling. What previously required sticky sessions, shared stores, and deep packet inspection now runs on a plain load balancer with stateless replicas. One person can field what used to require a small team.

For platform and gateway vendors, routing headers make MCP traffic indistinguishable from normal APIs at the routing layer. This is a necessary step toward ecosystem infrastructure.

MCP's 2026 roadmap committed to four areas: transport scalability, agent communication, governance maturation, and enterprise readiness. The RC covers all four. SDKs have a 10-week verification window, and Tier 1 SDKs are expected to ship within it. My advice: migrate early. Don't wait until the deadline.