MCP Goes Stateless: What the 2026-07-28 Spec Changes and How to Migrate

The Model Context Protocol’s stateful session model forced load balancers to parse full JSON-RPC bodies for routing, pinned traffic via sticky sessions that blocked auto-scaling, required backend storage for simple ephemeral tools, and created ambiguous session scope across distributed systems — four pain points the official 2025-12-19 transports post identified as the core motivation for the stateless rewrite (Exploring the Future of MCP Transports).

If you’ve ever run a remote MCP server behind a load balancer, you’ve probably hit the wall: sticky sessions that don’t scale, JSON-body parsing just to route a request, and a shared session store that becomes the single point of failure. The 2026-07-28 specification didn’t just patch these problems — it tore out the stateful core entirely. For more infrastructure patterns, see our MCP server testing guide and the AI agent infrastructure arena.

Why MCP Had to Go Stateless

The stateful session model that shipped with MCP’s November 2024 launch created four production bottlenecks: load balancers had to parse full JSON-RPC bodies to route, sticky sessions pinned clients to single instances and blocked auto-scaling, simple ephemeral tools still needed backend storage across turns, and session scope was ambiguous across distributed systems (Exploring the Future of MCP Transports).

The 2026 roadmap was explicit: “stateful sessions fight with load balancers,” and the working group committed to no new official transports this cycle — only STDIO and Streamable HTTP (2026 MCP Roadmap). What follows is the full spec breakdown, the migration path, and the deprecation calendar you need to plan against.

What the 2026-07-28 Spec Actually Changed

The MCP 2026-07-28 specification — the largest revision since the protocol’s November 2024 launch, published July 28, 2026 after a 10-week validation window that began with the May 21 release candidate (Release Candidate Post) — removes the initialize handshake and Mcp-Session-Id, introduces Multi Round-Trip Requests, mandates Mcp-Method/Mcp-Name routing headers, adds cacheable tool catalogs with ttlMs/cacheScope, documents W3C Trace Context propagation, formalizes an Extensions framework, hardens OAuth 2.1, and deprecates Roots, Sampling, Logging, and the HTTP+SSE transport (Release Announcement · Changelog).

The Wire — Before and After HTTP Examples

In the 2026-07-28 spec, every HTTP request carries protocol version, client identity, and capabilities in the _meta object instead of relying on a one-time initialize handshake, while the new required Mcp-Method and Mcp-Name headers let load balancers route without parsing JSON bodies — the Mcp-Session-Id header is removed entirely so any request can land on any instance (Changelog · Streamable HTTP Transport).

Before (2025-11-25):

POST /mcp HTTP/1.1
Content-Type: application/json
Mcp-Session-Id: abc123

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{}}}

After (2026-07-28):

POST /mcp HTTP/1.1
Content-Type: application/json
Mcp-Method: tools/call
Mcp-Name: search

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search","arguments":{"query":"MCP stateless"}},"_meta":{"protocolVersion":"2026-07-28","clientId":"my-client","capabilities":{"tools":{}}}}

Multi Round-Trip Requests (MRTR)

Multi Round-Trip Requests (MRTR, SEP-2322) replace the removed server-initiated elicitation/create, sampling/createMessage, and roots/list RPCs: the server returns resultType: "input_required" with inputRequests, and the client retries the original call with answers in inputResponses — all results now carry a required resultType of either "complete" or "input_required", and server-initiated requests may only be issued while the server is actively processing a client request (MRTR Pattern · Changelog).

{
  "jsonrpc": "2.0",
  "id": 42,
  "result": {
    "resultType": "input_required",
    "inputRequests": [
      {
        "id": "confirm_cost",
        "type": "boolean",
        "prompt": "This operation will cost $5. Proceed?"
      }
    ]
  }
}

The client then retries with inputResponses in _meta, making the interaction fully stateless and visible to the model.

Headers, Caching, and Tracing

The 2026-07-28 spec mandates Mcp-Method and Mcp-Name headers on every Streamable HTTP request (SEP-2243) so gateways and WAFs route without JSON parsing, adds ttlMs and cacheScope ("public"/"private") to tools/list, prompts/list, and resources/list results (SEP-2549) for client-side caching, and documents W3C Trace Context propagation via traceparent/tracestate/baggage in _meta (SEP-414) for end-to-end distributed tracing (Release Announcement · Changelog).

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [...],
    "ttlMs": 300000,
    "cacheScope": "public"
  }
}

Servers are also encouraged to return tools in deterministic order to improve prompt-cache hit rates across clients (Changelog).

Extensions Become First-Class

The 2026-07-28 spec introduces a formal Extensions framework (SEP-2133) with reverse-DNS identifiers, an extensions map negotiated during capability exchange, dedicated ext-* repositories with delegated maintainers, versioning independent of the core spec, and a new Extensions Track in the SEP process — making extensions first-class citizens rather than ad-hoc additions (Release Candidate Post · Extensions Overview).

Tasks Extension

Tasks graduate from experimental core to the io.modelcontextprotocol/tasks extension (SEP-2663), introducing poll-based tasks/get, a new tasks/update RPC for client-to-server input, tasks/cancel, removal of tasks/list, and server-directed creation where a server answers tools/call with a task handle when work should run asynchronously (Changelog · Tasks Overview).

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "task_created",
    "taskId": "task_abc123",
    "status": "pending"
  }
}

The client then polls tasks/get with the handle until completion.

MCP Apps

MCP Apps (SEP-1865) let servers ship interactive HTML UIs rendered in sandboxed iframes within the host application, with tools declaring UI templates ahead of time so hosts can prefetch, cache, and security-review them — user interactions in the iframe route back to the server over the same JSON-RPC base protocol (MCP Apps Post · Apps Overview).

Authorization Hardening

The 2026-07-28 spec hardens OAuth 2.1 authorization by requiring clients to validate the iss parameter per RFC 9207 before redeeming an authorization code (SEP-2468), binding client credentials to the issuing auth server with no cross-issuer reuse (SEP-2352), and deprecating Dynamic Client Registration in favor of Client ID Metadata Documents (CIMD, PR #2858) (Release Announcement · Authorization Docs).

Clients must now set application_type during registration to prevent auth servers from rejecting localhost redirects for desktop/CLI apps, and scope accumulation on step-up authentication is explicitly supported. These changes close real-world authorization-server mix-up vulnerabilities in the OAuth flow (SDK Betas Post · Authorization Docs).

Deprecations and the 12-Month Feature Lifecycle

The 2026-07-28 spec deprecates Roots, Sampling, Logging, the HTTP+SSE transport, and includeContext values "thisServer"/"allServers" — all remain functional for at least 12 months under the new feature lifecycle policy (SEP-2596) that mandates an Active → Deprecated → Removed progression with a minimum twelve-month deprecation window (Release Announcement · Feature Lifecycle · Deprecated Registry).

Standards Track SEPs can’t reach Final status without a matching scenario in the conformance suite (SEP-2484), and the SDK tier system scores official SDKs against it — so deprecated features carry real migration pressure from the ecosystem, not just the spec committee.

Migration Guide: From 2025-11-25 to 2026-07-28

Migrating from MCP 2025-11-25 to 2026-07-28 requires upgrading to SDK v2: in Python, FastMCP is renamed MCPServer with camelCase→snake_case field changes, httpx/httpx-sse replaced by httpx2, and a v2 server that answers both protocol revisions from one endpoint; in TypeScript, the monolithic @modelcontextprotocol/sdk splits into focused @modelcontextprotocol/server and @modelcontextprotocol/client packages with ESM-only output and Standard Schema tool definitions (Python Migration Guide · SDK Betas Post).

Python SDK v2 — FastMCP → MCPServer Walkthrough

Python SDK v2 renames FastMCP to MCPServer, converts all camelCase fields to snake_case, replaces McpError with MCPError, changes resource URIs from AnyUrl to str, removes streamablehttp_client, swaps httpx/httpx-sse for httpx2, and defaults the Client to mode='auto' which probes server/discover and falls back to initialize on older servers — a v2 Python server answers both protocol revisions from one endpoint (Python Migration Guide · SDK Betas Post).

# Before (v1)
from fastmcp import FastMCP
mcp = FastMCP("my-server")

@mcp.tool()
def search(query: str) -> str:
    return f"Results for {query}"

# After (v2)
from mcp.server import MCPServer
mcp = MCPServer("my-server")

@mcp.tool()
def search(query: str) -> str:
    return f"Results for {query}"

TypeScript SDK v2 — Split Packages and Standard Schema

TypeScript SDK v2 splits the monolithic @modelcontextprotocol/sdk into focused packages — @modelcontextprotocol/server, @modelcontextprotocol/client, and platform-specific adapters for Node, Express, Hono, and Fastify — goes ESM-only with Node 20+/Bun/Deno support, and adopts Standard Schema for tool definitions supporting Zod v4, Valibot, and ArkType (SDK Betas Post · TS SDK v2 Docs).

import { Server } from '@modelcontextprotocol/server';
import { z } from 'zod';

const server = new Server(
  { name: 'my-server', version: '1.0.0' },
  { capabilities: { tools: {} } }
);

server.addTool(
  'search',
  z.object({ query: z.string() }),
  async ({ query }) => ({
    content: [{ type: 'text', text: `Results for ${query}` }]
  })
);

Backward-Compatibility Matrix

A v2 Python server answers both 2025-11-25 and 2026-07-28 protocol revisions from one endpoint, while TypeScript and Go servers opt into 2026-07-28 on the wire explicitly (e.g., Go’s StreamableHTTPOptions.Stateless = true); new clients speaking 2026-07-28 automatically fall back to the initialize handshake against older servers, ensuring a non-breaking upgrade path (SDK Betas Post).

Language v2 Server Supports Both Revisions? Explicit Opt-In Required?
Python Yes (automatic) No
TypeScript Yes (automatic) No
Go Yes Yes (Stateless = true)
C# Yes Yes

Ecosystem Day-Zero Support

AWS, Cloudflare, and Supabase announced day-zero support for the 2026-07-28 spec: AWS’s Swami Sivasubramanian stated that Bedrock AgentCore lets teams “deploy MCP servers on standard, scalable infrastructure without managing sessions,” Cloudflare’s Brendan Irvine-Broque confirmed the Agents SDK supports the spec “from day zero” for Workers deployments, and Supabase’s Inian Parameshwaran noted that MRTR enables mid-call user confirmation because “Supabase MCP runs statelessly” (Release Announcement).

Figma, Google Cloud, Microsoft Foundry, Netlify, Xero, FastMCP 4.0, and Runlayer also announced compatibility updates, confirming that the stateless rewrite is already being adopted across the full MCP ecosystem (Release Announcement). For more on infrastructure patterns, check out the NiteAgent AI agent infrastructure arena.

FAQ

Q1: Is the 2026-07-28 spec a breaking change? Yes — the initialize handshake, Mcp-Session-Id header, and server-initiated RPCs like elicitation/create are removed. However, SDK v2 servers (Python, TypeScript, Go) can serve both 2025-11-25 and 2026-07-28 clients from one endpoint, and new clients automatically fall back to the old handshake against older servers (SDK Betas Post).

Q2: Do I have to migrate now? No — the 2025-11-25 protocol remains supported. The new feature lifecycle policy (SEP-2596) guarantees a minimum 12-month deprecation window for all deprecated features, including the HTTP+SSE transport, Roots, Sampling, and Logging (Feature Lifecycle). Plan migration this quarter; execute within 12 months.

Q3: What replaces sessions for stateful interactions? The explicit-handle pattern: servers mint handles (e.g., basket_id) from tools, and the model passes them back as ordinary arguments — state becomes visible to the model instead of hidden in transport metadata. Multi Round-Trip Requests (MRTR) handle mid-call user input (RC Post).

Q4: Is STDIO transport affected? No — STDIO is unchanged. The stateless rewrite targets Streamable HTTP. The 2026 roadmap committed to no new official transports this cycle, keeping only STDIO and Streamable HTTP (2026 MCP Roadmap).

Q5: What happens to Sampling? Sampling is deprecated (SEP-2577) and will work for at least 12 months. Its functionality is replaced by Multi Round-Trip Requests (MRTR), where the server returns resultType: "input_required" and the client provides the needed input on retry (Changelog · MRTR Pattern).

Q6: When is Dynamic Client Registration (DCR) removed? DCR is deprecated in favor of Client ID Metadata Documents (CIMD, PR #2858) in the 2026-07-28 spec. Under the 12-month feature lifecycle policy, DCR will remain functional until at least July 2027 (Changelog · Authorization Docs).

Comparison Table: 2025-11-25 vs 2026-07-28

Row Column A: 2025-11-25 Column B: 2026-07-28 Source(s)
Connection lifecycle initialize/initialized handshake + Mcp-Session-Id header; protocol-level session Handshake removed; protocol version, client identity, capabilities in _meta; optional server/discover RPC Changelog
Server→client requests Held-open streams: elicitation/create, sampling/createMessage, roots/list MRTR: server returns resultType: "input_required" with inputRequests; client retries with inputResponses MRTR Pattern · Changelog
Routing Load balancers must parse full JSON-RPC bodies Mcp-Method and Mcp-Name required headers; custom per-tool headers via x-mcp-header Release Announcement · Changelog
Caching No cache directives; listChanged hints only ttlMs + cacheScope ("public"/"private") on list/read results; deterministic tool ordering Changelog
Change notifications HTTP GET endpoint + resources/subscribe Single opt-in subscriptions/listen stream; SSE resumability removed Changelog
Tracing Not specified W3C Trace Context in _meta (traceparent, tracestate, baggage) — SEP-414 RC Post · Changelog
Authorization Basic OAuth 2.1; Dynamic Client Registration RFC 9207 iss validation (SEP-2468); client credentials bound to issuer (SEP-2352); DCR deprecated in favor of CIMD Release Announcement · Authorization Docs
Extensions Ad-hoc, experimental Formal framework (SEP-2133): reverse-DNS IDs, extensions map, own repos, Extensions Track RC Post · Extensions Overview
Deprecated features Roots, Sampling, Logging deprecated (SEP-2577); HTTP+SSE transport deprecated; 12-month window Release Announcement · Deprecated Registry

Python SDK v2 Breaking-Change Cheat Sheet

v1 Symbol v2 Symbol Fix / Notes Source
FastMCP MCPServer Rename import and class references Python Migration Guide
camelCase fields snake_case Rename all field accesses Python Migration Guide
McpError MCPError Rename exception class Python Migration Guide
AnyUrl resource URIs str Update type annotations Python Migration Guide
streamablehttp_client Removed Use Client with mode='auto' Python Migration Guide
httpx / httpx-sse httpx2 Update dependency and imports Python Migration Guide
Lowlevel decorators on_* constructor params Refactor handler registration Python Migration Guide

The Bottom Line

The stateless rewrite in MCP 2026-07-28 is the single most impactful change since the protocol’s launch — it converts MCP from a sticky-session protocol into an ordinary HTTP workload that any cloud provider can scale. SDK v2 migration is non-optional this quarter for production servers, but backward compatibility is built into the v2 servers themselves, and the 12-month deprecation window gives teams a clear runway. If your infrastructure currently depends on session affinity, JSON-body routing, or server-initiated elicitation calls, the time to plan is now.

How This Guide Was Built

This guide is based on official documentation, pricing pages, and community reports — we did not run the tool hands-on. Every claim traces to the official MCP specification (2026-07-28), the official MCP blog, or the official SDK migration guides listed below. No third-party blogs, aggregators, or AI-generated summaries were used as sources. All 19 unique source URLs referenced were curl-verified HTTP 200 on August 26, 2026.

For more infrastructure patterns, see our MCP server testing guide and the AI agent infrastructure arena.

← Back to all posts