The MCP 2026-07-28 spec is final: your Azure migration plan
On 28 July 2026 the Model Context Protocol project published the final 2026-07-28 specification, and the release candidate we analysed in May survived contact with its ten-week validation window largely intact. MCP is now a stateless request/response protocol. The initialize handshake and the Mcp-Session-Id header are gone, server-initiated requests are replaced by a new Multi Round-Trip Request pattern, list results are cacheable, and the authorization model has been tightened again, including a deprecation of Dynamic Client Registration in favour of Client ID Metadata Documents. Crucially for delivery teams, all four Tier 1 SDKs (TypeScript, Python, Go and C#) shipped support on release day, with Microsoft publishing v2.0 of the official MCP C# SDK the same morning. If you run MCP servers on Azure Container Apps, AKS or App Service behind Azure API Management, the migration window is now open and the tooling is ready. This is the follow-up playbook: what changed between the release candidate and the final, and how to sequence the work on Azure.
What shipped on 28 July
The stateless core, confirmed
The headline architecture holds. SEP-2575 removes the initialize/initialized handshake entirely: every request now carries its protocol version and client capabilities in _meta fields (io.modelcontextprotocol/protocolVersion and io.modelcontextprotocol/clientCapabilities), and clients identify themselves per request via io.modelcontextprotocol/clientInfo. SEP-2567 removes protocol-level sessions and the Mcp-Session-Id header from the Streamable HTTP transport, and it requires that list endpoints no longer vary per connection. Servers that genuinely need cross-call state must mint explicit handles and pass them as ordinary tool arguments.
The release announcement frames the operational payoff directly: a remote MCP server can now run behind a plain round-robin load balancer without shared storage. Maintainer David Soria Parra described the change to The Register as moving "state away from the server onto the wire protocol", and called this revision "the most substantial changes we have made to the specification, probably since adding authorization". He was equally blunt about the cost for anyone who hand-rolled their own implementation: "it's going to be a lot of uplift to make this correct." If you are on a Tier 1 SDK, most of that uplift is absorbed for you. If you built a custom MCP layer, budget real engineering time.
One addition since the RC discussion deserves attention: servers MUST now implement a server/discover RPC that advertises supported protocol versions, capabilities and identity. Clients may call it up front for version selection, or use it as a backward-compatibility probe. For gateway operators this gives you a clean, side-effect-free health and capability endpoint to wire into Azure API Management backend probes and smoke tests.
MRTR: server-initiated requests are gone
The final spec resolves the question of how interactive tools work without long-lived connections. The Multi Round-Trip Requests pattern (SEP-2322) replaces server-initiated requests such as roots/list, sampling/createMessage and elicitation/create. When a server needs more input mid-call, it returns an interim result with resultType set to "input_required" and an inputRequests field describing what it needs. The client gathers the answers and retries the original request with inputResponses attached. Every result now carries a required resultType field, and results from older servers that omit it are treated as "complete".
// Interim result from the server: it needs user confirmation
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"resultType": "input_required",
"inputRequests": [
{ "method": "elicitation/create", "params": { /* ... */ } }
]
}
}
// Client retries the ORIGINAL request, now carrying inputResponses
The consequence for infrastructure is that a tool call needing human confirmation is now two or more ordinary HTTP request/response cycles instead of one held-open stream with a reverse request inside it. Retries can land on different replicas. Servers that need to correlate an elicitation across retries encode their own identifier in requestState. On Azure this means your APIM timeout policies get simpler and your replicas stay interchangeable, but tools built on the old elicitation flow need reworking: the notifications/elicitation/complete signal introduced in 2025-11-25 is already removed again.
Subscriptions, and the end of SSE resumability
Two transport changes landed that were less discussed before the release. First, the HTTP GET endpoint and resources/subscribe are replaced by subscriptions/listen: one long-lived POST-response stream that clients opt into for specific change notification types (tool, prompt and resource list changes, plus resource subscriptions). Second, SSE stream resumability and message redelivery are removed. There is no Last-Event-ID replay; if a response stream breaks, the client re-issues the request with a new request ID. Idempotency just became your problem, by design. Tools that mutate state (create an invoice, trigger a deployment) should accept an idempotency key as a parameter, exactly as you would design a public REST API behind Azure Front Door.
Headers and caching: the gateway-friendly parts
SEP-2243 makes the Mcp-Method and Mcp-Name headers required on Streamable HTTP POST requests, so gateways can route, throttle and meter on the operation without parsing JSON-RPC bodies. SEP-2549 requires ttlMs and cacheScope fields on results from tools/list, prompts/list, resources/list, resources/read and resources/templates/list. A cacheScope of "public" explicitly permits shared intermediaries to cache the response. In APIM terms: per-tool rate limits become a one-line policy condition on a header, and list responses can be cached at the gateway with a TTL the server itself declares. The spec also nudges servers to return tools/list in deterministic order, which improves LLM prompt cache hit rates downstream. If you pay per token on Azure OpenAI or Azure AI Foundry with prompt caching, tool-list ordering is now a measurable cost lever.
Authorization: DCR is out, Client ID Metadata Documents are in
The auth SEPs from the RC landed as expected: authorization servers SHOULD include the iss parameter per RFC 9207 and clients MUST validate it before redeeming an authorization code (SEP-2468); client credentials are bound to the issuing authorization server and MUST NOT be replayed against another (SEP-2352); clients MUST declare an application_type during registration (SEP-837).
The bigger strategic shift is the deprecation of OAuth 2.0 Dynamic Client Registration (RFC 7591) as the client registration mechanism, in favour of Client ID Metadata Documents. Under CIMD, a client's identifier is a URL pointing at a hosted metadata document, rather than an identifier minted by each authorization server at registration time. DCR remains available for backwards compatibility with authorization servers that do not support CIMD, but new implementations should not build on it.
For Entra ID shops this is quietly good news. Entra's support for RFC 7591-style dynamic registration has always been limited, which forced many Azure MCP deployments into manual client pre-registration and made some earlier MCP auth guidance awkward to follow. The protocol moving away from DCR narrows the gap between what the spec expects and what Entra actually offers. Watch two things: which registration mechanisms the MCP hosts you depend on (Copilot Studio, Claude, custom hosts) implement as they adopt 2026-07-28, and how your API gateway or identity broker handles CIMD URLs if you sit between third-party clients and Entra. The release notes are candid that authorization remains where implementers spend most of their integration time. That has matched our experience on client engagements all year.
The deprecation registry: what is on the clock
The formal feature lifecycle policy (SEP-2596) is now active, with a minimum twelve-month deprecation window and a public registry of deprecated features. As of 28 July the registry includes:
- Roots, Sampling and Logging (SEP-2577): migrate to tool parameters or configuration, direct LLM provider APIs, and stderr or OpenTelemetry respectively. Note that logging/setLevel is already removed; log level now travels per request in _meta.
- The HTTP+SSE transport: deprecated in practice since 2025-03-26, now formally in the Deprecated state. Migrate to Streamable HTTP.
- Dynamic Client Registration: superseded by Client ID Metadata Documents as described above.
- includeContext values "thisServer" and "allServers": removed no later than Sampling itself.
Also gone outright, not just deprecated: ping, notifications/roots/list_changed, tasks/list, and the elicitation completion notification. The OpenTelemetry trace context conventions (traceparent, tracestate and baggage in _meta) are now documented in the spec, which means distributed traces can flow from your MCP host through your server into Application Insights without custom plumbing.
SDK readiness: you can start today
The release-day SDK story is unusually complete. All four Tier 1 SDKs support 2026-07-28 as of the announcement, and the Rust SDK has beta support. For .NET teams, the MCP C# SDK v2.0 shipped on 28 July with the new spec implemented, stateless-by-default behaviour, MRTR support, and opt-in sessions for the cases that still need them. The package split matters for dependency hygiene: ModelContextProtocol and ModelContextProtocol.AspNetCore for servers, ModelContextProtocol.Core for clients and low-level APIs, and the redesigned Tasks and experimental Apps extensions as separate optional packages (ModelContextProtocol.Extensions.Tasks and ModelContextProtocol.Extensions.Apps).
Microsoft states that v2.0 is backward compatible: existing v1 code continues to compile and run, and old clients and servers remain interoperable with v2 implementations, with the redesigned Tasks extension as the one exception. Treat that claim the way you treat every compatibility claim: true for the happy path, verified by your own integration tests before production. The Stacklok guidance quoted by The Register is worth keeping in mind here: deprecated features keep working for at least twelve months, but interoperability between old and new implementations is not guaranteed without deliberate fallback mechanisms.
Decision framework: when to migrate which server
Sequence by coupling, not by size. Migrate first the servers whose deployment topology is distorted by the old protocol (sticky sessions, Redis session stores, body-inspecting gateway policies), because those collect an immediate infrastructure dividend. Migrate last the servers that depend on deprecated features with no shipped replacement in your stack, and use the twelve-month window deliberately for those.
- Migrate now: stateless tool servers on Container Apps or AKS behind APIM. Upgrade the SDK, remove session affinity, rewrite gateway policies onto Mcp-Method and Mcp-Name, enable gateway caching for public list results. Days of work, immediate simplification.
- Migrate this quarter: servers using elicitation or long-running tools. These need MRTR rework and the new Tasks extension, including client-side persistence of task handles since tasks/list no longer exists.
- Plan carefully: servers using Sampling (rewire to direct Azure OpenAI or Anthropic API calls, with the cost and quota ownership questions that raises), custom protocol implementations, and anything still on the HTTP+SSE transport.
- Coordinate externally: auth flows involving DCR against third-party authorization servers. The CIMD transition depends on what your identity provider and your MCP hosts support, so this is a dependency-tracking exercise, not just a code change.
The Swedish and EU angle
Data-flow documentation shrinks. A protocol-level session store is a stateful component with a location, a retention period and a line in your GDPR Article 30 record. The final spec removes it from the architecture. Requests carry their context, are processed, and are gone. For Swedish organisations documenting agent data flows for DPOs or for Schrems-era transfer assessments, one fewer stateful middlebox is a concrete simplification. The new gateway caching does introduce a nuance: cacheScope "public" permits shared intermediaries to cache responses, so confirm that resource reads containing personal data are marked "private" before you enable APIM response caching broadly.
Auditability improves for NIS2-scoped organisations. RFC 9207 issuer validation, issuer-bound credentials and a documented registration mechanism give your security function citable, testable controls for agent access. The per-request logLevel and the documented OpenTelemetry conventions mean MCP telemetry lands in Application Insights with trace correlation intact, which is what an incident-reporting regime actually requires: reconstructable request chains, not just log volume.
Procurement answers get firmer. Public-sector buyers in Sweden ask about protocol stability in upphandling questionnaires, and MCP can now answer with a formal feature lifecycle: Active, Deprecated and Removed states, a minimum twelve-month deprecation window, and a public registry. If you are a vendor building agent products on MCP, cite the policy. If you are a buyer, ask vendors which deprecated features their product still depends on and what their migration date is. That single question separates maintained products from abandoned ones.
Takeaways
- The 2026-07-28 spec is final and all four Tier 1 SDKs shipped support on release day. There is no tooling excuse to wait.
- Upgrade SDKs first; the C# SDK v2.0 is backward compatible except for the redesigned Tasks extension.
- Collect the infrastructure dividend: disable session affinity, retire Redis session stores, rebuild APIM policies on Mcp-Method and Mcp-Name, and cache list results using server-declared ttlMs.
- Rework interactive tools onto MRTR and make mutating tools idempotent, because SSE resumability is gone and retries are now the recovery mechanism.
- Start the CIMD conversation with your identity team now; DCR is deprecated and Entra ID never loved it anyway.
- Inventory Roots, Sampling, Logging and HTTP+SSE usage against the public deprecation registry and assign each item an owner and a quarter.
- Before enabling gateway caching, verify cacheScope on anything that can return personal data.