The MCP 2026-07-28 specification makes the Model Context Protocol stateless at the protocol level. Sessions and Mcp-Session-Id are removed, initialization changes, server-initiated interactions use Multi Round-Trip Requests, and interrupted streams require a new request. For AI teams, this simplifies horizontal scaling but moves more responsibility for state, retry safety, and idempotency into the application.
TL;DR
- MCP protocol-level sessions and Mcp-Session-Id are gone.
- Sticky routing is no longer required because of MCP protocol sessions.
- The traditional initialize handshake has been removed.
- Protocol version and client capabilities now travel with requests.
- Server-initiated interactions move to Multi Round-Trip Requests.
- Broken SSE streams cannot resume. Clients issue a fresh request.
- Repeat-safe tool execution becomes an application responsibility.
- Roots, Sampling, and Logging are deprecated, not immediately removed.
- Python SDK v2 introduces several breaking changes.
- Teams that are not ready to migrate should pin MCP v1 before upgrading.
Why did MCP move to a stateless architecture?
MCP increasingly acts as an interface between AI applications and the tools, APIs, databases, business systems, and resources those applications need.
That makes infrastructure behavior increasingly important.
Earlier MCP revisions relied on protocol-level sessions. A client established a connection, completed initialization, received an Mcp-Session-Id, and subsequent requests could depend on information associated with that session.
That model is manageable on a single server.
It becomes more complicated when an MCP server runs across multiple instances.
If session information exists only in one application’s memory, subsequent requests may need to reach the same instance. Teams then need infrastructure such as:
- sticky routing,
- shared session storage,
- session replication,
- connection-aware recovery,
- or additional state synchronization.
The MCP 2026-07-28 revision changes that assumption.
MCP itself is now designed around stateless requests.
A request should carry the information required to process it instead of depending on hidden connection history.
Why does this matter in production?
Instead of an architecture that effectively behaves like:
a stateless deployment can operate more naturally as:
Any healthy instance can potentially process the next request.
That can simplify:
- Kubernetes deployments,
- horizontal scaling,
- autoscaling,
- rolling releases,
- failover,
- instance replacement,
- and ordinary round-robin load balancing.
This is especially relevant for teams building production AI agent development systems where agents need reliable access to tools and external services across distributed infrastructure.
What changed between stateful and stateless MCP?
The overall shift is from connection-dependent behavior toward request-dependent behavior.
| Aspect | 2025-11-25 and Earlier | MCP 2026-07-28 |
| Connection setup | initialize handshake required | Traditional handshake removed |
| Session identity | Mcp-Session-Id | Removed |
| Protocol version | Negotiated once | Supplied per request |
| Cross-call state | Often implicit and server-held | Explicit handles |
| Server to client interactions | Direct callbacks | Multi Round-Trip Requests |
| Change notifications | GET stream and subscriptions | subscriptions/listen |
| Stream recovery | SSE resumability | Request must be re-issued |
| Load balancing | Session-aware routing may be needed | Any instance can handle a request |
The operational benefit is clear, but there is a tradeoff:
Stateless MCP does not eliminate state. It makes state explicit.
How are protocol-level sessions handled now?
Earlier MCP implementations could associate negotiated capabilities, protocol versions, and other contextual information with a connection-level session.
MCP 2026-07-28 removes protocol-level sessions and the Mcp-Session-Id header from Streamable HTTP.
This means an incoming request does not need to reach a particular application instance simply because that instance owns its MCP session.
Does stateless MCP mean applications cannot store state?
No.
An AI workflow may still require information to persist across multiple tool calls.
Examples include:
- workflow progress,
- generated artifacts,
- authentication context,
- long-running business operations,
- intermediate agent results,
- and user-specific working data.
The difference is that this state should no longer depend implicitly on an MCP connection.
Servers can issue explicit handles that the client sends again as normal tool arguments.
Those handles can resolve to information stored in:
- Redis,
- SQL databases,
- distributed caches,
- object storage,
- workflow engines,
- or another application-owned persistence layer.
Example implementation pattern
def resolve_handle(handle: str) -> dict:
"""Resolve a server-minted handle from a shared store.
The spec requires the handle;
the storage choice is yours.
"""
raw = store.get(f"mcp:handle:{handle}")
return json.loads(raw) if raw else {} Implementation note: The storage mechanism above is an implementation example. The MCP specification does not require Redis or any specific database.
The architectural principle is more important:
State becomes visible and portable rather than hidden inside a connection.
This same principle matters when integrating MCP with broader Generative AI development initiatives, where LLM applications may need to maintain explicit workflow state across tools, APIs, and business processes.
What replaced the initialization handshake?
Earlier MCP interactions started with an initialization sequence:
That step allowed the client and server to negotiate protocol information.
Under MCP 2026-07-28, the traditional initialization handshake is removed.
Relevant information travels with individual requests through _meta.
Example request under MCP 2026-07-28
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_ticket",
"arguments": {
"title": "Checkout returns 500"
},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "my-agent",
"version": "1.4.0"
}
}
}
} Illustrative shape based on the fields identified in the specification changes. Check the published MCP schema for the normative definition.
Requests can carry information such as:
- protocol version,
- client identity,
- client capabilities,
- and relevant request metadata.
A protocol mismatch produces an UnsupportedProtocolVersionError.
What does server/discover do?
Servers must support server/discover, which advertises information such as:
- supported protocol versions,
- server capabilities,
- and server identity.
Clients can use it when they need to understand server capabilities before making another request.
This reinforces the stateless model because a server does not need to depend on information negotiated through a previous connection.
Official reference: MCP 2026-07-28 changelog
How do Multi Round-Trip Requests work?
This is one of the most important behavioral changes for teams building interactive AI agents.
Earlier MCP workflows could allow a server to request information from the client during an active operation.
Examples include:
- Sampling,
- Elicitation,
- and roots/list.
That approach depends on a persistent back-channel.
MCP’s new model introduces Multi Round-Trip Requests (MRTR).
Instead of calling the client directly, the server returns an interim result explaining what information is required.
The client obtains that information and retries the original request with the required response attached.
The MRTR flow
The result now includes a resultType.
A normal result uses:
complete
An interim response can use:
input_required
The server provides inputRequests, and the client supplies the relevant inputResponses when it re-issues the operation.
Why does MRTR matter for AI agents?
Neither request needs to reach the same server instance.
That is valuable for horizontally scaled agent infrastructure.
However, teams should identify workflows that currently assume:
- persistent client-server connections,
- callbacks,
- session-bound context,
- or server-side interaction state.
Those workflows may need more redesign than simple read-only MCP tools.
What changed for notifications and streaming?
Two changes deserve separate attention: notification subscriptions and stream recovery.
How do notifications work now?
The earlier HTTP GET notification mechanism and resource subscription methods are replaced by:
subscriptions/listen
Clients subscribe to relevant notification types such as:
- toolsListChanged
- promptsListChanged
- resourcesListChanged
- resourceSubscriptions
Request-scoped notifications such as:
- notifications/progress
- notifications/message
continue to travel with the response stream belonging to their request.
This is particularly relevant for teams maintaining:
- custom MCP clients,
- agent orchestrators,
- protocol gateways,
- adapters,
- and framework integrations.
What happens when an SSE stream fails?
SSE stream resumability has been removed.
Earlier implementations could rely on mechanisms such as:
Last-Event-ID
to recover from an interrupted stream.
Under the new model, a failed response stream means the client issues a fresh request with a new request ID.
That makes infrastructure routing simpler because the new request can reach another healthy server.
It also introduces a significant application-level risk.
Could the same MCP tool execute twice?
Yes.
Imagine an MCP tool that:
- creates a support ticket,
- sends an email,
- creates an invoice,
- places an order,
- updates a CRM record,
- changes permissions,
- triggers a deployment,
- or initiates a payment.
The server may successfully complete the operation, but the connection could fail before the client receives the final response.
The client retries.
Without additional protection, the operation may execute again.
The MCP specification does not provide a universal application-level idempotency mechanism for every tool.
Production systems should therefore evaluate patterns such as:
- idempotency keys,
- transaction IDs,
- request fingerprints,
- operation-status checks,
- deduplication storage,
- and domain-specific replay protection.
Practical implementation rule
For every mutating MCP tool, ask:
What happens if this exact tool call executes twice?
If the answer involves duplicate payments, tickets, emails, users, or other unwanted side effects, the tool needs replay protection.
Which MCP features are deprecated?
Three familiar MCP features are entering deprecation:
- Roots
- Sampling
- Logging
They are deprecated, not immediately removed.
The MCP project’s feature lifecycle includes Active, Deprecated, and Removed states, along with a minimum twelve-month deprecation window.
| Existing feature | Suggested direction |
| Roots | Pass directories through tool parameters, resource URIs, or configuration |
| Sampling | Integrate directly with the chosen LLM provider |
| Logging | Use stderr or OpenTelemetry |
Tasks have also moved outside the core protocol into an official extension.
Should teams remove deprecated features immediately?
No.
A better migration approach is:
- Identify where existing applications depend on them.
- Avoid creating new dependencies on deprecated functionality.
- Define replacement patterns.
- Include migration work in the engineering roadmap.
- Test interoperability between protocol versions.
Deprecation should trigger planning, not an emergency rewrite.
Official reference: MCP deprecated features registry
What other MCP 2026 changes should developers know?
Several smaller changes can also affect production implementations.
Cacheable results
List and read results now include cache information through a CacheableResult interface, including fields such as:
ttlMs
cacheScope
This can help clients reduce unnecessary polling.
Deterministic tool ordering
Servers should return tools from tools/list in deterministic order.
That can improve:
- client caching,
- reproducibility,
- and prompt-cache consistency.
OpenTelemetry support
Tracing information can travel through _meta, including:
- traceparent
- tracestate
- baggage
This supports more conventional distributed observability across AI and MCP infrastructure.
Authorization behavior
The specification also introduces changes around:
- issuer validation,
- credential isolation,
- authorization server identity,
- and client registration.
Teams running custom authentication or OAuth infrastructure should review the related specification updates separately.
What does stateless MCP mean for AI architecture?
The protocol change affects each layer differently.
| Area | Architectural impact |
| Session management | Protocol sessions no longer need to be maintained |
| Context propagation | Protocol information travels with requests |
| State persistence | Cross-call state becomes explicit |
| Retries | Failed streams cause new requests |
| Reliability | Duplicate execution must be considered |
| Authentication | Authorization is evaluated per request |
| Observability | Distributed tracing becomes more important |
| Scaling | Any healthy instance can process the next request |
The important takeaway is that responsibility has moved rather than disappeared.
Horizontal scaling becomes simpler
Stateless MCP servers fit more naturally behind:
- standard load balancers,
- Kubernetes services,
- container platforms,
- autoscaling systems,
- and distributed compute infrastructure.
However, scalable MCP deployments still require the broader infrastructure disciplines involved in production software delivery. Teams working through DevOps consulting services should include MCP servers in their decisions around container orchestration, observability, autoscaling, infrastructure reliability, and failure recovery.
State design becomes more deliberate
Engineering teams need explicit answers to questions such as:
- What information must survive between requests?
- Who owns that state?
- Where is it stored?
- How long should it remain?
- Can another MCP instance retrieve it?
- What happens if the underlying store is temporarily unavailable?
Explicit state often creates more application code, but it can also make behavior easier to test, observe, and reason about.
What does MCP stateless architecture mean for businesses building AI agents?
The protocol changes are technical, but they influence several business-level decisions.
1. Scaling production agents can become easier
Removing protocol-level sessions makes MCP servers more compatible with standard cloud scaling patterns.
Organizations expecting larger AI-agent workloads may benefit from simpler routing and instance management.
2. Reliability engineering becomes more important
Simpler routing does not mean production reliability becomes automatic.
Teams need deliberate strategies for:
- retries,
- duplicate execution,
- persistent state,
- tracing,
- failure recovery,
- and multi-step workflows.
3. MCP migration should be planned
An organization already using MCP should first inventory:
- current protocol versions,
- SDK versions,
- session assumptions,
- mutating tools,
- callback patterns,
- authentication,
- and third-party adapters.
That makes migration scope easier to estimate.
4. The entire ecosystem must be compatible
A production application may look like:
Updating only the server does not guarantee every layer correctly supports MCP 2026-07-28.
Compatibility testing needs to cover the complete execution path.
MCP may also sit behind AI-enabled dashboards, customer portals, SaaS interfaces, and other custom web applications. In those systems, MCP state management and retry behavior should be treated as part of the wider product architecture rather than as an isolated protocol decision.
What changes in Python SDK v2?
The protocol rewrite also introduced significant Python SDK changes.
For existing MCP applications, this is where the migration becomes tangible.
How should dependencies be pinned?
A normal rebuild should not unexpectedly become a major MCP migration.
Existing pinned dependency
dependencies = [“mcp==1.28.1”]
Not ready to migrate
dependencies = [“mcp>=1.28,<2”]
Migrating to v2
dependencies = [“mcp>=2,<3”]
The practical rule is:
Pin first. Migrate intentionally.
How does FastMCP change in SDK v2?
FastMCP becomes MCPServer, and transport configuration moves.
MCP v1
from mcp.server.fastmcp import FastMCP
mcp = FastMCP(
"Demo",
json_response=True,
stateless_http=True
)
mcp.run(transport="streamable-http") MCP v2
from mcp.server.mcpserver import MCPServer, Context
mcp = MCPServer("Demo")
mcp.run(
transport="streamable-http",
json_response=True,
stateless_http=True
) For a small server, this change is relatively straightforward.
Larger applications with custom middleware, transports, or framework abstractions should expect broader migration work.
How do Python fields change?
Python attributes now use snake_case, although the JSON wire format remains unchanged.
Before
if result.isError:
...
schema = tools.tools[0].inputSchema After
if result.isError:
...
schema = tools.tools[0].inputSchema These changes are individually small, but they can affect many files in a mature MCP codebase.
How does low-level handler registration change?
Projects using lower-level server APIs also need to update handler registration.
Before: decorator-based registration
server = Server("my-server")
@server.list_tools()
async def handle_list_tools():
... After: constructor-based registration
async def handle_list_tools(
ctx: ServerRequestContext,
params: PaginatedRequestParams | None,
) -> ListToolsResult:
...
server = Server(
"my-server",
on_list_tools=handle_list_tools
) Teams using higher-level abstractions may encounter less work here.
Custom protocol implementations should review the complete migration guide.
What other SDK changes can break existing projects?
Other documented changes include:
- McpError becoming MCPError
- HTTP client dependency changes
- removal of older Streamable HTTP helpers
- WebSocket transport removal
- resource URI type changes
- different server-initiated capability behavior
- serialization changes
Treat MCP v2 as a major application migration, not a routine dependency upgrade.
Official reference: Python SDK v1 to v2 migration guide
How should teams migrate to MCP 2026-07-28?
A staged migration is safer than immediately upgrading production systems.
Step 1: Pin your current SDK
Prevent dependency resolution from silently introducing MCP v2.
dependencies = [“mcp>=1.28,<2”]
Step 2: Audit connection-scoped assumptions
Search for:
- session dictionaries,
- connection-specific state,
- module-level state,
- socket-scoped caches,
- connection-bound middleware,
- client-specific in-memory stores,
- and connection-based rate limiting.
A codebase can contain connection-dependent behavior even if it has no class explicitly called Session.
Step 3: Externalize state that genuinely needs to persist
Determine which information must survive between requests.
Where persistent state is needed, move it behind an explicit state mechanism.
def resolve_handle(handle: str) -> dict:
"""Resolve a server-minted handle from a shared store.
The spec requires the handle;
the storage choice is yours.
"""
raw = store.get(f"mcp:handle:{handle}")
return json.loads(raw) if raw else {} The shared store is an implementation decision.
The important requirement is that another server instance can resolve the state when necessary.
Step 4: Find server-initiated interactions
Identify usage of:
- Sampling,
- Elicitation,
- Roots,
- callbacks,
- and other back-channel assumptions.
Map these to the new Multi Round-Trip Request model where required.
Step 5: Make mutating tools repeat-safe
Review every MCP tool that changes external state.
Examples:
create_ticket
send_invoice
place_order
create_user
trigger_deployment
charge_customer
Ask what happens if the operation executes twice.
Add application-level protection where required.
Step 6: Test mixed-version environments
A realistic test matrix should include:
Old client → Old server
Old client → New server
New client → Old server
New client → New server
Also test any frameworks, adapters, gateways, or middleware in between.
What MCP migration mistakes should teams avoid?
Assuming stateless means there is no state
Stateless MCP does not prevent stateful application workflows.
It changes how that state is represented and managed.
Assuming retries are automatically safe
A new request can repeat a mutating operation.
Retry safety needs to be designed into the application.
Treating deprecation as removal
Roots, Sampling, and Logging remain available during their deprecation lifecycle.
Teams have time to plan replacements.
Treating SDK v2 as a routine package update
SDK v2 contains breaking API changes.
Upgrade it as a planned engineering migration.
Testing only the MCP server
An agent framework or adapter can become the actual compatibility bottleneck.
Test the whole stack.
Assuming older and newer versions behave identically
Protocol interoperability does not guarantee identical behavior for features whose semantics have changed.
Test the workflows your application actually relies on.
How can you assess MCP migration readiness?
Engineering leaders can use the following framework before approving a migration.
Infrastructure
- Are MCP servers deployed across multiple instances?
- Is sticky routing currently required?
- Is any session information stored only in process memory?
- Can another healthy instance safely process the next request?
Application state
- Which workflows require cross-call state?
- Where does that state live?
- Is that storage available to every server instance?
- Can state be represented through explicit handles?
Reliability
- Which tools modify external systems?
- Are they idempotent?
- Can duplicate execution be detected?
- What happens after a network failure?
Compatibility
- Which MCP protocol versions are currently deployed?
- Which Python SDK versions are installed?
- Are frameworks and adapters compatible with v2?
- Have mixed-version scenarios been tested?
Observability
- Can individual MCP requests be traced across services?
- Is OpenTelemetry context propagated?
- Can engineers identify whether a tool was retried?
- Can duplicate execution be diagnosed?
Security
- Is authentication validated independently for every request?
- Are credentials scoped correctly?
- Are authorization-server issuers validated?
- Could state handles expose sensitive information if leaked?
When should an organization migrate?
Migration deserves higher priority when an organization:
- operates multiple MCP server instances,
- relies on sticky routing,
- is scaling AI-agent workloads,
- uses server-initiated workflows,
- has retry-sensitive tools,
- plans to adopt Python SDK v2,
- or wants a more cloud-native deployment model.
Teams running small experimental MCP servers or simple read-only tools have more flexibility.
The first step should not be:
Upgrade everything.
It should be:
Identify which assumptions in your current architecture the new MCP model changes.
Conclusion
The MCP 2026-07-28 rewrite changes more than protocol syntax.
Removing protocol-level sessions makes MCP servers easier to distribute, horizontally scale, restart, and load balance using conventional cloud infrastructure.
At the same time, state management, retries, duplicate-execution protection, observability, and workflow orchestration become more explicit application responsibilities.
For most existing systems, the safest migration sequence is:
Pin the current dependency → audit session assumptions → identify retry-sensitive tools → externalize necessary state → test adapters and dependencies → validate mixed-version behavior → migrate deliberately.
Teams designing new MCP-based AI-agent systems should start with the stateless model from the beginning.
Existing platforms should treat MCP v2 as an architectural migration, not simply another package update.
Frequently asked questions
Is MCP 2026-07-28 backward compatible with older clients?
Compatibility exists in several scenarios, but teams should not assume every old and new component behaves identically.
Features whose behavior changed substantially require explicit testing, particularly when applications depend on server callbacks, subscriptions, or stream recovery.
Do I need to migrate to MCP 2026-07-28 immediately?
No.
Existing applications have time to plan around deprecated functionality. The more urgent action for many teams is controlling dependency versions so an SDK upgrade does not happen accidentally.
Does stateless MCP mean my server cannot keep state?
No.
The protocol no longer manages hidden session state, but applications can still maintain cross-request state through explicit handles and application-managed persistence.
What replaces server-initiated Sampling and Elicitation?
Multi Round-Trip Requests allow the server to return an input_required result. The client obtains the required information and resubmits the original operation with that input.
What happens if an MCP response stream fails?
The client issues a new request. Because the underlying tool may execute again, mutating tools should be designed to tolerate or prevent duplicate execution.
What happens to Roots, Sampling, and Logging?
They are deprecated rather than immediately removed. Existing implementations have a migration period, while new functionality should move toward the recommended alternatives.
Can pip install mcp break an existing project?
An unconstrained dependency can introduce a major SDK version that contains breaking behavior.
Projects expecting MCP v1 should explicitly constrain the package:
dependencies = [“mcp>=1.28,<2”]