1. Overview

On July 28, 2026, the Model Context Protocol (MCP) transitions to a new specification containing the largest architectural change since its launch. The revision centers on three points.

  1. A stateless protocol — the session concept is removed, and requests become self-contained
  2. OAuth 2.1-based authorization standardization — authorization, previously left to implementer discretion, is now enforced as a standard
  3. Official introduction of the Extension Framework — Roots/Sampling/Logging are split out of Core, and auditing/consent/approval functions are standardized

The essence of this shift is a transfer of security responsibility. The state management and trust boundaries that the protocol layer (sessions, handshakes) used to provide implicitly disappear, and that responsibility moves to the explicit design of developers and platform operators. A stateless architecture has clear benefits for scalability and load balancing, but if a client's state data is trusted without validation, a new attack surface opens up.


2. Key Security-Relevant Changes

2.1 Transition to a Stateless Architecture

The initialize handshake and the Mcp-Session-Id header are removed, and every request becomes self-contained. Protocol version, client information, and capabilities are now included in the _meta object of each request, and server capability discovery is replaced by the server/discover method.

Before (2025-11-25) — state maintained via Mcp-Session-Id after session establishment:

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"}}}

After (2026-07-28) — all context is included in the request itself:

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"}}}}

Security implications

Threat Description Mitigation
State hijacking If the server blindly trusts a resource handle passed by the client (e.g. basket_id), a predictable ID can let an attacker hijack another user's workflow Use handles with sufficient entropy and verify ownership
State object tampering If the integrity of a state object that is returned to the client and later sent back is not verified, privilege escalation becomes possible Apply signing (e.g. HMAC) or store server-side and reference by ID
Header/body mismatch If the Mcp-Method/Mcp-Name headers disagree with the JSON-RPC body, this creates a proxy/WAF bypass vector The server must mandatorily verify that headers and body agree

2.2 OAuth-Based Authorization Standardization

Authorization, which was previously left to implementer discretion, is now enforced under the OAuth 2.1 standard. There are four core components.

Component Standard Description Attack it defends against
Protected Resource Metadata RFC 9728 Exposes Authorization Server info via /.well-known/oauth-protected-resource Connecting to the wrong AS, misconfiguration
Resource Indicators RFC 8707 Specifies the target resource server via the resource parameter in a token request; the server verifies the token was issued for itself Token misuse (token passthrough), confused deputy
Client ID Metadata Documents (CIMD) - Replaces repeated per-server DCR registration with standard document-based configuration Registration abuse, client identity confusion
Issuer verification RFC 9207 Mandates verifying, via the iss parameter, that the token was actually issued by the requested AS OAuth mix-up attack

Example Protected Resource Metadata configuration:

{
  "authorization_servers": ["https://auth.example.com"],
  "resource": "https://mcp.example.com"
}

A token request including a Resource Indicator:

POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=...&
resource=https://mcp.example.com

2.3 Introduction of the Extension Framework

Security operations functions such as audit logging, user consent, and approval are now standardized as official Extensions.

  • Roots, Sampling, Logging: split from Core into Extensions, officially deprecated
  • MCP Apps: the first official Extension, providing server-rendered UI support
  • Tasks Extension: standardizes long-running operations

From a security standpoint, this means audit/consent/approval flows converge on a standard interface rather than each implementer's ad-hoc design — a positive for compliance and auditability. However, code that relied on former Core features (especially Sampling) must migrate to the Extension namespace pattern.


3. Breaking Changes Summary

Change Before (2025-11-25) After (2026-07-28)
Sessions initialize handshake + Mcp-Session-Id Removed, stateless
Error codes -32002 (Resource not found) -32602 (JSON-RPC standard)
Capability discovery Exchanged during handshake server/discover method
HTTP headers Mcp-Session-Id Mcp-Method, Mcp-Name required
SSE Server-Sent Events stream retained Replaced by Multi Round-Trip Requests (MRTR)
Authorization Implementation-dependent OAuth 2.1 standardized
Roots/Sampling/Logging Core features Split into Extensions (deprecated)
Caching Required separate implementation ttlMs, cacheScope fields provided

4. Migration Guide

4.1 Removing Session State

Old approach New approach
initialize handshake Capability discovery via server/discover
Mcp-Session-Id header Client info included in the _meta object
Session-based state storage State passed via explicit resource handles (e.g. basket_id)
Sticky sessions required Round-robin load balancing possible
// Before: session-based state management
class SessionManager {
  private sessions: Map<string, SessionState>;

  async handleRequest(sessionId: string, request: Request) {
    const session = this.sessions.get(sessionId);
    // Relies on session state
  }
}

// After: explicit handle-based
class StatelessHandler {
  async handleRequest(request: Request) {
    // Everything needed is included in the request
    const { basketId, clientInfo } = request.params._meta;
    // basketId is passed as an explicit parameter and processed
    // Note: verifying basketId ownership and integrity is mandatory
  }
}

4.2 Authorization Migration

Old approach New approach
Custom-built authorization OAuth 2.1 compliance
Separate configuration required Auto-discovery via .well-known/oauth-protected-resource
Token scope unspecified Scoped via Resource Indicators (RFC 8707)
DCR-based client registration Migrate to CIMD-based configuration
Issuer verification optional Issuer verification mandatory (RFC 9207)

Implementation checklist:

  1. Configure the .well-known/oauth-protected-resource endpoint (RFC 9728)
  2. Implement an OAuth 2.1-compliant authorization flow (PKCE required)
  3. Apply Resource Indicators (RFC 8707)
  4. Add issuer (iss) parameter verification logic (RFC 9207)
  5. Migrate to CIMD-based client configuration

4.3 Extension Migration

// Before: Sampling relying on Core
server.setCapabilities({
  sampling: { /* ... */ }
});

// After: using functionality split into Extensions
server.setCapabilities({
  extensions: {
    "io.modelcontextprotocol/sampling": { /* ... */ },
    "io.modelcontextprotocol/logging": { /* ... */ }
  }
});

4.4 Production Migration Checklist

  • Remove session state: migrate Mcp-Session-Id-based state storage logic to explicit resource handle structures
  • Fix error codes: change -32002 -> -32602
  • Configure OAuth: set up the .well-known/oauth-protected-resource endpoint (RFC 9728)
  • Resource Indicators: verify RFC 8707 adoption
  • CIMD migration: plan the move from DCR-based to CIMD-based configuration
  • Verify Extensions: confirm Roots, Sampling, and Logging have been split from Core
  • Stateless testing: verify stateless behavior across multiple instances behind a load balancer
  • Header validation: add logic to verify that Mcp-Method/Mcp-Name headers match the body content
  • _meta object validation: implement integrity checks for the client-supplied _meta object
  • Token validation: add issuer (iss) parameter verification logic (RFC 9207)

5. Migration Tools

Tool Purpose Link
mcp-herald A static migration linter for the MCP 2026-07-28 spec. Scans source code to detect breaking-change signatures and suggests fixes https://github.com/studiomeyer-io/mcp-herald
mcp-auth-adapter An adapter sitting in front of an OAuth 2.0/OIDC IdP that provides the functionality (RFC 9728/8707/9207) required by the MCP authorization spec https://github.com/velias/mcp-auth-adapter

Recommended usage order: (1) scan the entire codebase with mcp-herald to enumerate breaking changes, (2) fix protocol-layer items such as sessions/error codes/Extensions, (3) standardize the authorization layer with mcp-auth-adapter, (4) run integration tests in a stateless environment (multiple instances + load balancer).


6. Conclusion and Recommendations

The core of the 2026-07-28 MCP spec is the shift to a stateless architecture, standardization of authorization under OAuth 2.1, and the introduction of the Extension Framework. As the trust boundaries the protocol used to provide implicitly disappear, security responsibility moves to developers and platform operators, and the quality of each implementation's security design now determines the overall security level of the system.

Given the 12-month deprecation window, the following phased approach is recommended.

Phase Duration (recommended) Work
1. Diagnosis 1 month mcp-herald scan, assess breaking-change impact
2. Protocol migration 2-3 months Remove sessions, fix headers/error codes, migrate Extensions
3. Authorization standardization 2-3 months Implement OAuth 2.1 flow, apply RFC 9728/8707/9207
4. Verification 1-2 months Stateless load testing, penetration testing, verify header/body mismatch and handle-tampering scenarios
5. Parallel operation Remaining time Support old and new specs in parallel before retiring the legacy path

In particular, throughout the migration it is essential to keep in mind that if validation logic for client-supplied data (resource handles, state objects, _meta) is missing during the stateless transition, hijacking and privilege-escalation vectors that did not exist in the session era can emerge.