What MCP 2026-07-28 changes for integration architects
The fifth MCP revision turned the protocol stateless. Here is what changed on the wire, why it matters for gateways and load balancers, and how to migrate existing servers.
The Model Context Protocol has shipped five dated revisions: 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25 and, on 28 July 2026, 2026-07-28. The earlier ones added transports, authorization and structured output. This one changed the shape of the protocol itself. MCP is no longer a stateful, bidirectional session between a client and a server; it is a stateless request/response protocol that behaves like any other HTTP API.
For integration teams that is the most welcome change since OAuth arrived, because stateless traffic is what API gateways, load balancers, caches and serverless platforms were built for.
The changes that matter, in one table
| Area | Before (2025-11-25) | Now (2026-07-28) | Why integration teams care |
|---|---|---|---|
| Sessions | initialize handshake, Mcp-Session-Id header | Both removed. Each request carries version, client info and capabilities in _meta | No sticky sessions; any replica can serve any request |
| Capability discovery | Negotiated during initialize | New server/discover RPC (servers must implement it) | Gateways and registries can probe servers without opening a session |
| Server asks client for input | Server-initiated requests: sampling/createMessage, elicitation/create, roots/list | Multi Round-Trip Requests: server returns resultType: "input_required", client retries with answers | No callbacks into the client; human-in-the-loop works through plain retries |
| Routing | Method only inside the JSON body | Mcp-Method and Mcp-Name headers required on HTTP POST | Gateways can route and authorize per tool without parsing the body |
| List results | Could vary per connection | Deterministic, with required ttlMs and cacheScope | Tool lists can be cached at the edge, safely |
| Change notifications | HTTP GET stream, resources/subscribe | Single opt-in subscriptions/listen stream | One long-lived stream to size and time out deliberately |
| Stream resumability | Last-Event-ID redelivery | Removed; a broken stream means re-issue the request | Writes must be idempotent end to end |
| Long-running work | Experimental tasks in core | Official extension io.modelcontextprotocol/tasks with polling | Maps cleanly to asynchronous integration patterns |
| Deprecated | — | Roots, Sampling, Logging; HTTP+SSE transport; Dynamic Client Registration (in favour of Client ID Metadata Documents) | Remove from new designs; plan migration within the 12-month window |
What a stateless call looks like
There is no handshake before the first tool call. The client simply sends it, with everything the server needs to interpret the request attached:
POST /mcp HTTP/1.1
Host: tools.example.com
Authorization: Bearer eyJhbGciOi...
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: get_order_status
{
"jsonrpc": "2.0",
"id": 41,
"method": "tools/call",
"params": {
"name": "get_order_status",
"arguments": { "orderId": "4500012345" },
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": { "name": "sales-copilot", "version": "3.2.0" },
"io.modelcontextprotocol/clientCapabilities": {},
"traceparent": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
}
}
}
Three details are easy to miss. The Mcp-Method and Mcp-Name headers must match the body; if they disagree the server returns a HeaderMismatch error, which closes the obvious trick of authorizing on the header and executing something else. OpenTelemetry trace context (traceparent, tracestate, baggage) now has documented _meta keys, so one trace can follow the call from agent to gateway to integration flow. And every result carries a resultType, which is "complete" for ordinary results.
Multi Round-Trip Requests: human-in-the-loop without callbacks
Previously, if a server needed something mid-call (a confirmation, a missing parameter, an LLM completion) it sent its own request back to the client over the open session. That required a long-lived bidirectional connection and was awkward to secure. Under MRTR the server instead finishes the request with an interim result:
{ "jsonrpc": "2.0", "id": 42,
"result": {
"resultType": "input_required",
"inputRequests": { ... what the server needs, e.g. an approval ... },
"requestState": "opaque-server-token"
} }
The client gathers the answer (often by asking the user) and re-sends the original request with inputResponses and the requestState. Each leg is an ordinary request that any replica can serve.
For enterprise approvals this is a better fit than it first appears. "Release this payment of 48,000 EUR?" becomes an input_required result; the confirmation comes back as a new, separately authenticated and logged request. Your audit trail gets two clean events instead of one opaque session.
What changes for MCP gateways
- Route and authorize on headers. Per-tool policy can run on
Mcp-Method/Mcp-Nameat the edge, before the body is parsed. Still validate the body; the server enforces the match, and your gateway should too. - Drop session affinity. Remove sticky-session configuration and session stores built for
Mcp-Session-Id. Servers that need cross-call state now pass explicit, server-minted handles as tool arguments. - Cache tool lists properly. Honour
ttlMs, and never let a shared cache serve acacheScope: "private"list to another user: filtered tool lists are per user and per agent. - Size the one long-lived stream. Only
subscriptions/listenstays open. Give it its own timeout and connection limits rather than letting general request timeouts kill it. - Expect retries. Broken streams are no longer resumed. Combined with MRTR retries, the same logical operation may arrive more than once, so write tools need idempotency keys.
- Use
server/discoverfor health and inventory. It gives a registry or gateway the server's supported versions, capabilities and identity without side effects. - Translate versions at the edge if you must. Older clients still send
initialize. A gateway can terminate older revisions and speak 2026-07-28 upstream while clients catch up; servers reject unknown versions withUnsupportedProtocolVersion.
Authorization changes
The OAuth 2.1 foundation is unchanged, but four hardening steps landed:
- Authorization servers should return the
issparameter (RFC 9207), and clients must validate it before redeeming a code. This closes authorization-server mix-up attacks. - Client credentials are bound to the issuing authorization server and must be keyed by issuer; clients re-register if the issuer changes.
- Dynamic Client Registration is deprecated in favour of Client ID Metadata Documents, where the client ID is a URL to a document describing the client. For enterprises this is easier to govern: you can allow-list client metadata URLs instead of letting anything self-register.
- Clients using DCR must set an appropriate
application_typeto avoid redirect URI conflicts with OpenID Connect.
Deprecations and what to use instead
| Deprecated | Use instead |
|---|---|
| Roots | Pass directories, files or scopes as tool parameters, resource URIs or server configuration |
| Sampling | Call your LLM provider's API directly from the server (through your AI gateway) |
Logging (logging/setLevel) | Per-request io.modelcontextprotocol/logLevel, stderr for stdio servers, or OpenTelemetry |
| HTTP+SSE transport | Streamable HTTP |
| Dynamic Client Registration | Client ID Metadata Documents |
Deprecated features keep working for at least twelve months under MCP's new feature lifecycle policy, so there is time. Do not add them to new servers.
Migration checklist for existing MCP servers
- Upgrade to an SDK release that supports 2026-07-28 (TypeScript, Python, Go and C# are Tier 1) and keep support for the previous revision during transition.
- Implement
server/discover; returnio.modelcontextprotocol/serverInfoin result_meta. - Remove any in-memory session state; replace it with explicit handles passed as tool arguments, stored in a shared store.
- Replace server-initiated sampling, elicitation and roots calls with MRTR
input_requiredresults. - Return tools in deterministic order and set
ttlMsandcacheScopeon list results. - Add idempotency keys to every tool that writes, and make retries safe end to end in the integration flow behind it.
- Move long-running operations to the tasks extension instead of holding a request open.
- Propagate
traceparentinto the API gateway and integration platform so traces join up. - Update gateway policies to route on
Mcp-Method/Mcp-Nameand remove session affinity. - Switch new client registrations to Client ID Metadata Documents and validate
iss. - Re-run adversarial tests: header/body mismatch, replayed MRTR responses, oversized
requestState.
If you run SAP Integration Suite
SAP's MCP Gateway is a managed service, and SAP states that it handles MCP specification changes for you. That covers the gateway-facing protocol; it does not cover the APIs and iFlows behind your tools. Check that write operations exposed as tools are idempotent and that iFlows tolerate a repeated call, because the stateless model makes retries normal rather than exceptional. More in SAP Integration Suite MCP Gateway.
Frequently asked questions
Is MCP still JSON-RPC after 2026-07-28?
Yes. Messages are still JSON-RPC 2.0. What changed is that there is no session: each request is self-describing, and Streamable HTTP POSTs carry Mcp-Method and Mcp-Name headers.
Do old MCP clients break against a 2026-07-28 server?
A server can support several revisions. Clients can call server/discover to pick a version, and servers return UnsupportedProtocolVersion when they cannot serve the requested one. Many teams also let the gateway bridge older clients during migration.
How do I ask a user to approve an action under the new spec?
Return an input_required result from the tool call using the Multi Round-Trip Requests pattern. The client collects the approval and retries the original request with inputResponses, so the approval is a separate, logged and authenticated request.
Does stateless mean MCP servers cannot keep state?
No. The protocol has no sessions, but a server can mint an explicit handle (for example a cart or job ID), return it as data and accept it as a tool argument on later calls.
Sources and further reading
- Model Context Protocol: Key changes in 2026-07-28
- MCP blog: The 2026-07-28 Specification
- Google Developers Blog: Scaling AI agent infrastructure with the MCP stateless updates
- Gravitee: Key takeaways from the MCP specification release