Preface¶
The Model Context Protocol (MCP) is an open protocol initiated by Anthropic and maintained by the community, enabling AI Agents to connect external tools, data sources, and interactive interfaces in a unified manner. Since its release at the end of 2024, MCP has quickly become the de facto standard for Agent toolchains – the official Tier 1 SDKs (TypeScript, Python, etc.) now see nearly 500 million monthly downloads, with both TypeScript and Python SDKs exceeding one billion cumulative downloads.
On July 28, 2026, the MCP official team formally released the 2026-07-28 version of the specification. This is the largest revision since the protocol’s launch: the core of the protocol has fully shifted from a “bidirectional stateful” model to a request/response stateless model, removing the initialize/initialized handshake and the Mcp-Session-Id session header. Remote MCP Servers can now be horizontally scaled behind load balancers just like regular HTTP services.
This article is based on the MCP official blog and Release Candidate notes, sorting out the core mechanisms of this change, its impact on deployment architecture, and the migration points developers need to pay attention to.
Why Stateless is Necessary¶
In the 2025-11-25 specification, calling a Remote MCP tool via Streamable HTTP required first establishing a session. The client would send initialize, the server would return an Mcp-Session-Id, and every subsequent request had to carry this ID, “pinning” the client to the specific instance that issued the session.
This workflow works fine for single-server deployments, but once you place an MCP Server behind a load balancer for horizontal scaling, problems arise:
1. You must configure sticky sessions (session affinity), otherwise subsequent requests may land on an instance that does not have the session state;
2. Or maintain a shared session store (such as Redis), increasing operational complexity;
3. Gateways often need to deeply parse JSON-RPC request bodies when routing, rate limiting, or authenticating, which incurs performance and implementation costs.
This was one of the most common pain points reported by community developers. The 2026-07-28 specification completed the stateless transformation through six SEPs (Specification Enhancement Proposals), fulfilling the roadmap outlined in the December 2025 The Future of MCP Transports.
Core Change: Self-Describing Every Request¶
Handshake and Session Headers Removed¶
The following two items have been officially retired in the 2026-07-28 release (see SEP-2575, SEP-2567):
- initialize / initialized handshake exchange
- Mcp-Session-Id HTTP header and protocol-level sessions
Protocol version, client identity, client capabilities, and other information are now carried with each request in the _meta field of the JSON-RPC parameters. If a client wants to learn about the server’s capabilities in advance, it can call the newly added server/discover RPC – but this is optional, and tool calls can be initiated directly without doing so.
Request Comparison¶
2025-11-25: Handshake first, then call tools with Session ID
POST /mcp HTTP/1.1
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"initialize",
"params":{"protocolVersion":"2025-11-25","capabilities":{},
"clientInfo":{"name":"my-app","version":"1.0"}}}
The server responds with Mcp-Session-Id: 1868a90c-3a3f-4f5b, and subsequent requests must include this header:
POST /mcp HTTP/1.1
Mcp-Session-Id: 1868a90c-3a3f-4f5b
Content-Type: application/json
{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"search","arguments":{"q":"otters"}}}
2026-07-28: Single self-contained request, any instance can handle it
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"search","arguments":{"q":"otters"},
"_meta":{"io.modelcontextprotocol/clientInfo":{"name":"my-app","version":"1.0"}}}}
The key differences are clear: no handshake, no Session ID, any request can be routed to any instance behind a load balancer, eliminating the need for sticky routing or shared storage.
Stateless Protocol, Stateful Applications Still Possible¶
Removing protocol-level sessions does not mean your MCP Server cannot handle stateful business logic. The official recommended approach aligns with HTTP APIs: have the tools explicitly mint a handle (such as basket_id or browser_id), which the model will pass back as a regular parameter in subsequent calls.
The official team believes that this explicit handle, which is visible to the model, inferable, and transferable across tools, is often more flexible than session state hidden in transport layer metadata – the model can chain handles across different tool steps.
MRTR: Server Interaction Under Stateless Design¶
Stateless protocols face a classic problem: what if the server needs to confirm with the user (elicitation) or request sampling while a tool is executing? The old version relied on an open SSE bidirectional stream; the new version introduces Multi Round-Trip Requests (MRTR, SEP-2322) to solve this.
The workflow is as follows:
1. The client initiates a tools/call request;
2. The server returns resultType: "input_required", along with inputRequests (questions requiring user answers) and requestState (encoded server state);
3. After collecting user input, the client reissues the original call, attaching inputResponses and the echoed requestState to the parameters;
4. Any server instance can handle this retry, as all required context is contained within the payload.
Example response:
{
"resultType": "input_required",
"inputRequests": {
"confirm": {
"type": "elicitation",
"message": "Delete 3 files?",
"schema": { "type": "boolean" }
}
},
"requestState": "eyJzdGVwIjoxLCJmaWxlcyI6WyJhIiwiYiIsImMiXX0="
}
Additionally, SEP-2260 stipulates that the server can only initiate server-to-client requests while processing a client request, so users will never be interrupted by “unprompted” pop-ups – every interaction can be traced back to an action initiated by the user or Agent.
MRTR replaces previously long-connection-dependent server-initiated requests such as elicitation/create, sampling/createMessage, and roots/list, enabling elicitation and other interactive capabilities to be transmitted over stateless HTTP. Stateless MCP Servers already running in production at companies like Supabase can now implement scenarios such as “confirm before deleting data” precisely because of this feature.
Header-Based Routing and Cacheable Lists¶
Mcp-Method and Mcp-Name¶
Streamable HTTP transport now requires two HTTP headers: Mcp-Method and Mcp-Name (SEP-2243). The method name (such as tools/call) and tool/resource name (such as search) appear in both the header and the JSON body; if the two are inconsistent, the server should reject the request.
This means load balancers, API gateways, WAFs, and rate limiters can perform routing and policy enforcement directly based on the headers, without first parsing the JSON-RPC body. For example:
- Route requests with Mcp-Name: expensive-query to dedicated backends;
- Apply per-tool rate limiting or authentication for specific tools;
- Unify MCP traffic metering at the infrastructure layer.
ttlMs and cacheScope¶
Responses to tools/list, prompts/list, resources/list, and resources/read now carry ttlMs and cacheScope (SEP-2549), with semantics similar to HTTP’s Cache-Control. Clients can use these fields to determine how long to cache the tool directory and whether it can be shared across users, reducing the overhead of re-pulling the catalog every time a connection is reestablished, while maintaining stability for upstream prompt caches across reconnects.
Additionally, the key names for W3C Trace Context (traceparent, tracestate, baggage) in the _meta field have been fixed in the specification (SEP-414), facilitating distributed tracing correlation across SDKs, gateways, and downstream services.
Key Concurrent Changes¶
The 2026-07-28 release is more than just a stateless transformation; it includes multiple changes closely related to production deployment:
| Change | Description |
|---|---|
| Formalized Extension Framework | Tasks, MCP Apps, Enterprise Managed Authorization (EMA), etc. are now released as independent extensions, preventing the core specification from growing bloated |
| Tasks Extension | Moved from experimental core functionality to the io.modelcontextprotocol/tasks extension, using poll-based tasks/get and tasks/update |
| Authorization Hardening | RFC 9207 iss parameter validation (SEP-2468); Dynamic Client Registration (DCR) officially deprecated in favor of Client ID Metadata Documents (CIMD) |
| Deprecation Policy | Officially established a minimum 12-month deprecation window (SEP-2577 et al.), enabling planned upgrades rather than reactive responses |
| Deprecated Roots / Sampling / Logging | Replaced by tool parameters, direct LLM API integration, OpenTelemetry, etc.; legacy HTTP+SSE transport is also deprecated |
| JSON Schema 2020-12 | Tool inputSchema/outputSchema upgraded to full JSON Schema 2020-12 (SEP-2106) |
SDKs and Ecosystem¶
The official Tier 1 SDKs (TypeScript, Python, Go, C#) have been synchronized to support the 2026-07-28 specification, with the Rust SDK in beta. Each SDK provides migration notes for breaking changes.
Cloud vendors and toolchain partners also announced support on the release day, including AWS Bedrock AgentCore, Cloudflare Workers, Google Cloud, Microsoft Foundry, Netlify, and more. Community frameworks such as FastMCP 4.0 and Manufact’s mcp-use have also reported package size and performance improvements from the client-server split.
For existing implementations that rely on Mcp-Session-Id for routing or state management, migration costs do exist, but the official team has simplified the process based on early testing feedback during the SDK beta phase.
Developer Migration Recommendations¶
If you are maintaining a Remote MCP Server or integrating an MCP Client, you can evaluate the migration using the following steps:
1. Check Session Dependencies: Search your codebase for references to initialize and Mcp-Session-Id; remove them if they were only used for protocol handshakes; if they were used for business state, switch to the explicit handle pattern.
2. Add HTTP Headers: Add Mcp-Method and Mcp-Name to Streamable HTTP requests, and ensure they match the values in the request body.
3. Implement MRTR Flow: If your tools require user confirmation, implement the client logic for input_required → collect input → retry with inputResponses.
4. Leverage Cache Hints: Read ttlMs from responses such as tools/list to avoid unnecessary catalog refreshes.
5. Focus on Deprecated Items: Do not use Roots, Sampling, Logging, or legacy HTTP+SSE transport in new implementations; gradually transition OAuth integration from DCR to CIMD.
6. Read SDK Migration Notes: Each TypeScript/Python/Go/C# SDK repository has breaking change instructions specifically for the 2026-07-28 release.
The full specification and changelog can be viewed in the MCP specification repository; implementation questions can be quickly answered via the Working Group channel on the contributor Discord.
Summary¶
MCP 2026-07-28 has transformed Remote MCP Servers from “protocols requiring special session management” into “standard stateless HTTP workloads”. Load balancing, header-based routing, response caching, and distributed tracing – capabilities validated by web infrastructure over decades – can now be directly applied to Agent toolchains.
For Agent developers, this means the deployment and operational complexity of MCP Servers has dropped significantly; for platforms and cloud vendors, MCP is moving from experimental integration to production-grade infrastructure. If you are already using Remote MCP to connect officially hosted endpoints such as GitHub, Linear, or Supabase, this specification upgrade is worth following promptly by updating your SDK version to truly benefit from the stateless transformation.