MCP Goes Stateless: The 2026-07-28 Spec, Explained

The MCP protocol dropped sessions and went stateless on July 28, 2026. What changed, why it matters for production agents, and how to migrate your servers.

TL;DR — MCP 2026-07-28 killed sessions. No more initialize handshake, no more Mcp-Session-Id, no more sticky routing. Every request is self-describing. You can now put MCP servers behind a plain round-robin load balancer. Also: tools can ask follow-up questions mid-call (MRTR), gateways can route on headers without parsing bodies, and list responses are cacheable. SDKs for Python, TypeScript, Go, and C# are already updated.

The Sticky Session Problem Is Dead

I spent two weeks in June debugging an MCP deployment that kept dropping tool calls after pod restarts. The issue was obvious in hindsight: our Kubernetes service was round-robining requests, but MCP required session affinity because of the initialize handshake. Miss the right pod, get a “session not found” error. The workaround was sticky sessions at the ingress layer — ugly, fragile, and it meant one slow pod could bottleneck all requests pinned to it.

On July 28, Anthropic published the new MCP specification and that entire class of problem disappeared. The protocol-level session is gone. Every request carries its own context. Any instance behind a load balancer can handle any request.

This isn’t a minor version bump. It’s the biggest architectural change since MCP launched, and if you’re running MCP servers in production, it changes how you deploy, scale, and think about reliability.

What Actually Changed

MCP official blog announcing the 2026-07-28 specification — stateless protocol core, MRTR, header-based routing The official MCP blog post announcing the 2026-07-28 spec — the biggest protocol revision since launch.

The 2026-07-28 specification introduces six major changes. Here’s what matters for production:

1. Stateless Core (Sessions Removed)

Before:

Client → initialize → Server (get session ID)
Client → tools/call + Mcp-Session-Id → Server (must hit same instance)

After:

Client → tools/call + _meta{clientInfo, protocolVersion} → Server (any instance)

The initialize/initialized exchange is gone. The Mcp-Session-Id header is gone. Each request includes its protocol version and client identity in _meta. If a client wants server capabilities upfront, there’s a new server/discover RPC — but it’s optional, not required.

What this means in practice: MCP servers are now as stateless as a REST API. Deploy behind any load balancer. Scale horizontally. No shared session store needed.

2. Multi Round-Trip Requests (MRTR)

Previously, if a tool needed user confirmation mid-execution, the server had to hold open a bidirectional stream and initiate a reverse request. That required persistent connections and made serverless deployment impossible.

Now: a tool returns resultType: "input_required" with the questions it needs answered. The client collects answers and retries the same call with inputResponses attached. Stateless. Works over plain HTTP POST.

// Server response asking for confirmation:
{
  "resultType": "input_required",
  "inputRequests": [
    {"id": "confirm-1", "type": "confirmation",
     "message": "Delete 47 files matching *.tmp?"}
  ]
}

// Client retries with answer:
{
  "method": "tools/call",
  "params": {
    "name": "cleanup",
    "arguments": {"pattern": "*.tmp"},
    "inputResponses": [
      {"id": "confirm-1", "value": true}
    ]
  }
}

This unlocks interactive tools on serverless infrastructure. No websockets, no long-lived connections.

3. Header-Based Routing

Every Streamable HTTP request now carries:

  • Mcp-Method: the JSON-RPC method (e.g., tools/call)
  • Mcp-Name: the specific tool/resource/prompt name

Gateways, WAFs, and rate limiters can route, authorize, and meter without parsing JSON bodies. For large-scale deployments, this is a significant performance win.

4. Cacheable List Responses

tools/list, prompts/list, resources/list, and resources/read responses now include ttlMs and cacheScope. Clients can cache tool catalogs and avoid re-fetching on every reconnect.

For agents that initialize frequently (serverless functions, short-lived processes), this reduces cold-start latency from tool discovery.

5. Authorization Hardening

  • iss validation per RFC 9207 (closes authorization server mix-up attacks)
  • application_type in DCR (CLI/desktop apps stop getting rejected for localhost redirects)
  • Credentials bound to the issuing authorization server (no cross-server reuse)
  • DCR formally deprecated in favor of Client ID Metadata Documents (CIMD)

6. Tasks as Extension

Tasks moved from experimental to a formal extension (io.modelcontextprotocol/tasks) with poll-based tasks/get and tasks/update. Long-running operations have a standardized lifecycle now.

Migration: What You Need to Do

If you maintain an MCP server:

Nothing breaks today. The SDKs handle backward compatibility:

  • Python v2 servers answer both protocol versions from one endpoint
  • TypeScript v2 serves 2026-07-28 only when you explicitly configure it
  • Old clients using initialize still work against new servers (SDK handles the fallback)

To opt in to stateless mode:

Python:

pip install "mcp[cli]==2.0.0b1"
from mcp.server import MCPServer

mcp = MCPServer("my-tool")

@mcp.tool()
def search(query: str) -> str:
    """Search the knowledge base."""
    return do_search(query)

TypeScript:

npm install @modelcontextprotocol/server@beta

If your server kept state in the session: Replace it with explicit handles. Mint a handle from one tool, pass it as an argument to subsequent calls. The model can see it and thread it between tools — more reliable than hidden session state.

If you maintain an MCP client:

  • Probe server/discover first. If it responds, the server speaks 2026-07-28
  • If not, fall back to initialize. SDKs do this automatically
  • Start reading Mcp-Method and Mcp-Name headers for routing
  • Implement inputRequests handling for MRTR support

If you run MCP servers in production:

  • Remove sticky session configuration. You don’t need it anymore
  • Remove shared session stores (Redis, etc.) if they existed only for MCP session tracking
  • Add header-based routing at your gateway layer for Mcp-Method/Mcp-Name
  • Enable response caching for tools/list based on ttlMs

The Ecosystem Response

The numbers tell the story of MCP’s adoption:

  • SDK downloads: ~500 million/month across all languages
  • Python + TypeScript: both crossed 1 billion total downloads
  • Specification contributors: 384
  • GitHub stars (spec repo): 8.9K

Major hosts are already updating:

HostStatus
Claude DesktopShipping with 2026-07-28 support
Claude CodeUpdated
CursorIn progress
KiroIn progress
WindsurfIn progress

SandBase’s Store has 1,900+ MCP servers listed. As these servers upgrade to the new spec, the entire ecosystem gets stateless scaling for free.

What This Means for Agent Architecture

The stateless shift changes how you design agent systems:

Before 2026-07-28:

  • Agent runtime needed to manage MCP sessions
  • Tool servers needed sticky load balancing
  • Serverless deployment was awkward (cold starts killed sessions)
  • Horizontal scaling required shared session stores

After 2026-07-28:

  • Tool servers are stateless microservices
  • Standard HTTP load balancing works
  • Serverless-friendly (each request is independent)
  • Scale-to-zero is practical
  • Gateway routing without body parsing

For teams building on MCP server infrastructure, this is the biggest deployment simplification since MCP launched.

Limitations to Note

Scope of what I’ve tested: I’ve migrated two internal MCP servers (a search tool and a code analysis tool) to the Python v2 beta. Both worked cleanly behind plain Kubernetes services. But:

  • Beta SDKs aren’t production-ready yet. Public APIs may still change before stable release
  • MRTR is powerful but new. Client support is still rolling out. Don’t depend on it for critical user flows yet
  • Auth migration needs care. If you’re using DCR today, the deprecation gives you 12 months, but start planning now
  • Legacy HTTP+SSE transport is deprecated. One year offramp, but new servers should use Streamable HTTP

FAQ

Does this break my existing MCP server?

No. SDKs handle backward compatibility automatically. A new client talking to an old server falls back to initialize. An old client talking to a new server still works because new servers answer the legacy handshake.

Can I use MCP servers on serverless now?

Yes. Each request is independent — no session to maintain between invocations. Cold starts only affect the first request, and tools/list caching means you don’t re-discover tools every time.

What happened to bidirectional streaming?

Server-initiated requests (elicitation, sampling, roots) are replaced by MRTR — the server returns a response asking for input, and the client retries. No open stream needed. For notifications, there’s subscriptions/listen which is opt-in.

When should I migrate?

The stable SDK releases are coming soon (Python and TypeScript v2 stable). For production workloads, wait for stable. For new projects, start with the beta now — the API shape is nearly final.

How does this affect SandBase MCP servers?

The 1,900+ servers in SandBase’s Store will progressively update to the new spec. The stateless model means SandBase can route tool calls more efficiently — no session affinity needed at the platform layer.