MCP Goes Stateless: The 2026-07-28 Migration Guide

TL;DR
MCP 2026-07-28 spec migration guide: sessions and the initialize handshake are gone. What changed, what breaks, and how to move your MCP servers to stateless.
Official Sources#
| Resource | Description | Verified |
|---|---|---|
| MCP 2026-07-28 Final Specification | The full protocol specification (final as of July 28, 2026) | July 29, 2026 |
| MCP 2026-07-28 Release Candidate | Official announcement from the MCP team | July 29, 2026 |
| MCP Specification Changelog | Every change between 2025-11-25 and 2026-07-28 | July 29, 2026 |
| MCP TypeScript SDK | Official TypeScript SDK with 2026-07-28 support | July 29, 2026 |
| MCP Python SDK | Official Python SDK with 2026-07-28 support | July 29, 2026 |
| 2026 MCP Roadmap | The roadmap that led to these changes | July 29, 2026 |
| MCP Registry | Official MCP server discovery and indexing | July 29, 2026 |
| MCP Extensions Framework | MCP Apps, Tasks, and the extensions system | July 29, 2026 |
Last updated: July 29, 2026
The final MCP 2026-07-28 specification shipped yesterday, July 28, 2026. It is the biggest change since MCP launched. The protocol is now stateless. Sessions are gone. The initialize handshake is gone. Every request stands on its own.
This is not a cosmetic refactor. If you have not migrated your MCP servers yet, you are now behind the final spec. This guide covers what changed, what broke, and how to finish the migration.
What Changed on July 29, 2026#
The MCP 2026-07-28 specification went final on July 28, 2026 as scheduled. Here is what changed since the June 19 version of this guide:
- Spec is final, not a release candidate. The 2026-07-28 specification was published as the official protocol version. It is available at
https://modelcontextprotocol.io/specificationwith the full changelog at/specification/changelog. - All six SEPs are locked. The stateless core (SEP-2575, SEP-2567), Streamable HTTP headers (SEP-2243), multi-round-trip requests (SEP-2322), caching (SEP-2549), and tracing (SEP-414) are all final.
- MCP Apps and Tasks are official extensions. Both extensions shipped as part of the final spec with their own repositories and delegated maintainers. Servers can now declare MCP Apps UI templates and hosts can render them in sandboxed iframes.
- SDKs are updated. The TypeScript and Python SDKs have 2026-07-28 support in their latest releases. All SDKs have tier system scores.
- Roots, Sampling, and Logging are deprecated. These features continue to work but are now annotated as deprecated under the 12-month lifecycle policy.
- Spec changelog is live. Every change between 2025-11-25 and 2026-07-28 is documented at the specification changelog page.
What Actually Changed#
The 2026-07-28 final specification removes session management from the protocol layer entirely. The previous specification required a multi-step flow: client connects, sends initialize, receives initialized with an Mcp-Session-Id header, then includes that header on every subsequent request. That session ID pinned the client to a specific server instance.
The new spec eliminates all of that. A single self-contained request can hit any server instance. No sticky sessions. No shared session store. No deep packet inspection at the gateway. The _meta field on each request carries whatever context the server needs.
Here is the practical impact:
| Concern | Old (2025-11-25) | New (2026-07-28) |
|---|---|---|
| Session state | Server memory or shared Redis | None required - stateless |
| Load balancing | Sticky sessions required | Plain round-robin works |
| Server scaling | Complex - state coordination | Simple - any instance handles any request |
| Handshake | initialize/initialized flow | Eliminated |
| Capability discovery | Part of handshake | Separate /mcp/capabilities endpoint |
| Request routing | Parse body for session ID | Mcp-Method header - no body inspection |
The server-to-client request model also changed. Instead of holding connections open with Server-Sent Events for multi-turn operations, servers now return an InputRequiredResult with a requestState payload. The client re-issues the call with inputResponses and the echoed state. This allows stateless retry handling - if a request fails mid-way, the client can retry to any server instance.
Why Sessions Were Dropped#
The old session model made three assumptions that aged poorly:
-
Long-lived processes with shared memory. The initialize handshake assumed your MCP server ran as a persistent process that could track session state in memory. That works for local development. It does not work for serverless functions, containerized deployments with auto-scaling, or edge compute.
-
Sticky sessions are free. They are not. Sticky sessions require load balancer configuration, add failure modes when instances restart, and prevent true horizontal scaling. Many production deployments worked around this by adding Redis for shared session state - adding latency to every tool call.
-
Deep packet inspection is acceptable. Routing requests by session ID meant gateways had to parse request bodies. The new
Mcp-Methodheader allows routing decisions without body inspection, which simplifies gateway configuration and improves request handling time.
The MCP team's position: "Stateful sessions fight with load balancers." The protocol now aligns with how modern infrastructure actually works.
Breaking Changes#
If you have MCP servers in production, here is what breaks:
Initialize handshake removed. Servers that expect initialize as the first message will fail. Clients using the new SDKs will not send it.
Session ID routing gone. Any gateway or routing logic that depended on Mcp-Session-Id headers needs rewriting. The new pattern is Mcp-Method header routing.
Error code change. Missing resource errors shifted from -32002 to -32602 (JSON-RPC standard Invalid Params). Error handling that catches specific codes needs updating.
Tasks API lifecycle changed. Anyone who shipped against the 2025-11-25 experimental Tasks API needs to migrate. The new Tasks extension reshapes around stateless patterns using tasks/get, tasks/update, and tasks/cancel instead of the old subscription model.
Authorization validation stricter. Clients must validate the iss parameter per RFC 9207 and declare application_type during Dynamic Client Registration.
Migration Path#
The migration difficulty depends on how much session state your server currently maintains.
If Your Server Is Already Stateless#
Many simple MCP servers - file readers, API wrappers, documentation tools - do not actually use session state. They receive a request, perform an operation, return a result. For these servers, migration is minimal:
- Remove the
initialize/initializedhandlers - Add
Mcp-Methodheader support for routing - Update to the latest SDK version
- Test against the release candidate
If Your Server Maintains Session State#
Servers that track conversation context, user preferences, or in-progress operations need more work:
Before (stateful):
// Session-dependent lookup
private sessions = new Map<string, SessionContext>();
async handleToolCall(request: ToolCallRequest) {
const session = this.sessions.get(request.sessionId);
if (!session) throw new Error('Unknown session');
// Use session context
return this.executeWithContext(request, session);
}
After (stateless):
// Per-request validation with context in _meta
async handleToolCall(request: ToolCallRequest) {
// Context travels with request
const context = request._meta?.context;
// Validate authorization on every request
await this.validateToken(request._meta?.authorization);
return this.executeWithContext(request, context);
}
The key shift: context that used to live in server memory now travels with each request. Clients are responsible for including relevant context in _meta. Servers validate and use it without maintaining state.
If Your Server Uses Tasks#
The Tasks API migration is the most involved. The old model used subscriptions and server-sent events. The new model uses polling with state payloads:
Old pattern:
// Subscribe to task updates
const subscription = await mcp.tasks.subscribe(taskId);
for await (const update of subscription) {
console.log(update.status);
}
New pattern:
// Poll with state
let task = await mcp.tasks.get(taskId);
while (task.status === 'running') {
await sleep(1000);
task = await mcp.tasks.get(taskId, { requestState: task.state });
}
The requestState field allows the server to include opaque state that the client echoes back. This enables stateless resumption - any server instance can continue handling the task as long as it can access the underlying task store.
Externalize State Management#
For servers that genuinely need to maintain state across requests - multi-step workflows, caching, user preferences - the pattern is externalization. Move state from server memory to an external store.
// External state store (Redis, PostgreSQL, etc.)
interface TaskStore {
create(task: Task): Promise<string>;
get(taskId: string): Promise<Task>;
update(taskId: string, status: TaskStatus): Promise<void>;
cancel(taskId: string): Promise<void>;
}
// Any server instance can handle any request
async handleTaskGet(taskId: string) {
return this.taskStore.get(taskId);
}
async handleTaskCancel(taskId: string) {
return this.taskStore.cancel(taskId);
}
This approach enables true horizontal scaling. Load balancers distribute requests across instances using any algorithm. Every instance handles every request type identically because state lives externally.
New Capabilities#
The release candidate adds features alongside the stateless changes:
Caching support. The new ttlMs and cacheScope fields on responses allow clients and infrastructure to cache appropriately. A tools/list response with ttlMs: 3600000 tells clients they can cache the tool list for an hour.
Extensions framework. Optional capabilities now have formal governance with reverse-DNS identifiers, independent versioning, and dedicated repositories. Two official extensions ship with this release: MCP Apps (sandboxed server-rendered HTML interfaces) and Tasks (graduated from experimental core status).
Distributed tracing. W3C Trace Context keys are now standardized across SDKs. Observability tools can trace requests across MCP server chains.
Simplified routing. The required Mcp-Method and Mcp-Name headers enable routing decisions without body inspection. Gateways can route based on headers alone.
Timeline#
- May 21, 2026: Release candidate locked
- May 21 through July 27: Validation window for SDK maintainers and implementers
- July 28, 2026: Final specification published (now live)
- Now (July 29, 2026+): Migration enforcement window - updated SDKs no longer send initialize handshake
The specification includes a feature lifecycle policy: twelve-month deprecation windows before removal. This is the MCP team's commitment that future breaking changes will not be sprung on developers the way this one was. Roots, Sampling, and Logging are the first features under this policy - they continue to work through July 2027.
Migration Strategy by Server Type#
New servers: Target the 2026-07-28 spec immediately. There is no reason to build against the old spec - the final SDKs ship with no initialize handshake support.
Existing servers with Tier 1 SDK usage: Migrate now if you have not already. The official TypeScript and Python SDKs shipped 2026-07-28 support during the validation window. Updated SDK releases no longer send the initialize handshake.
Public servers with external users: Support both specs through Q4 2026 if your user base includes clients that have not yet updated. Most clients migrated during the validation window, but the transition period allows buffer for long-tail SDK users.
Community SDK users: Check with your SDK maintainer. Several community SDKs shipped 2026-07-28 support before the July 28 deadline.
What This Means for MCP Server Developers#
The stateless shift is a net positive for the MCP ecosystem. Infrastructure that was previously hard - load balancing, auto-scaling, serverless deployment - becomes straightforward. The mental model simplifies: a request is self-contained, a response is self-contained, and server instances are interchangeable.
The cost is migration work for existing servers and a breaking change in the protocol. That is a real cost. If you have not migrated yet, your un-migrated servers will stop working with current SDK clients.
But the alternative - maintaining a stateful protocol that fights with modern infrastructure - was not sustainable. The MCP team made the right call. The spec is final. Now is the time to finish migrating.
FAQ#
When does the MCP stateless specification take effect?#
The final specification published on July 28, 2026. The release candidate was available since May 21, 2026, giving developers roughly ten weeks to validate and migrate. As of July 29, the final spec is live. Updated SDKs no longer send the initialize handshake, so un-migrated servers will fail with new clients.
What happens to my MCP server if I do not migrate?#
Servers built against the old 2025-11-25 specification will stop working with clients using updated SDKs. The initialize handshake that old servers expect will not be sent. You need to either migrate to the stateless spec or pin your client SDK versions.
Do I need to rewrite my entire MCP server?#
It depends on your session usage. Simple servers that do not maintain session state need minimal changes - remove the initialize handler, add header support, update SDK. Servers with heavy session logic need to externalize state to a store like Redis or PostgreSQL.
How do I handle multi-turn conversations without sessions?#
Context travels with each request in the _meta field. Clients are responsible for including conversation context. Servers validate and use it without maintaining state. For complex workflows, use the Tasks extension with externalized task state.
What is the Tasks extension and how does it differ from the old Tasks API?#
The Tasks extension graduated from experimental status and was restructured for stateless operation. Instead of subscriptions and server-sent events, it uses a polling model with tasks/get, tasks/update, and tasks/cancel. The requestState field enables stateless resumption across server instances.
Can I support both the old and new specifications?#
Yes, during the transition period. Check the SDK version or request format to determine which protocol the client is using, and handle accordingly. This is recommended for public servers with established user bases through Q4 2026.
How do the new caching fields work?#
Responses can include ttlMs (time-to-live in milliseconds) and cacheScope to inform caching strategies. A tools/list response with ttlMs: 3600000 tells clients the tool list is stable for an hour. This reduces unnecessary round-trips and improves performance.
What are MCP Apps?#
MCP Apps is one of two official extensions shipping with this release. It enables sandboxed server-rendered HTML interfaces - MCP servers can provide UI components that clients render safely. This opens possibilities for richer tool interactions beyond text-only responses.
Continue Reading#
For more on the MCP ecosystem and how the 2026-07-28 spec affects your tools:
- The MCP 2026-07-28 Rewrite: What Breaks and How to Migrate - a complementary guide focused on the full breaking changes list, Roots/Sampling/Logging deprecation, and OAuth hardening
- MCP Clients Compared: How to Pick a Host for 2026 - how Claude Code, Cursor, VS Code, and other clients handle MCP in the stateless era
- Complete Guide to MCP Servers - building and deploying servers compatible with the 2026-07-28 spec
- How to Build MCP Servers - step-by-step tutorial with TypeScript SDK examples
- What Is MCP? - the Model Context Protocol explained for developers new to the ecosystem
Get the next deep dive like this in your inbox
One email a week on MCP and the rest of the AI dev stack. Free.
Read next on AI coding tools
What Is MCP (Model Context Protocol)? The 2026 Developer Guide
MCP (Model Context Protocol) is the open standard connecting AI apps to tools and data. How the 2026-07-28 spec works and how to install or build a server.
14 min readBest MCP Servers in 2026: The Developer Shortlist
Best MCP servers in 2026, ranked for Claude Code, Cursor and other agents: GitHub, Filesystem, Context7, Playwright, Postgres, Sentry and starter stacks.
10 min readThe MCP 2026-07-28 Rewrite: What Breaks and How to Migrate
MCP 2026-07-28 breaking changes: a stateless core, deprecated Roots, Sampling and Logging, and tougher OAuth, plus a migration checklist for server authors.
11 min readNew here? Start with
Technical content at the intersection of AI and development. Building with AI agents, Claude Code, and modern dev tools - then showing you exactly how it works.





