MCP Security Changes: An Enterprise Migration Guide
What the latest MCP specification changes mean for security teams, including stateless requests, authorization hardening, routing headers, cache scope, Tasks, Apps, and migration testing.
The Model Context Protocol changed substantially on July 28, 2026. This was not a routine documentation refresh. The new release removed the protocol-level handshake and session, introduced a stateless request model, strengthened authorization behavior, added gateway-friendly routing headers, formalised extensions, and moved long-running work into the Tasks extension. For enterprise teams, the result is potentially simpler infrastructure—but only if old security assumptions are deliberately replaced.
The official MCP 2026-07-28 announcement describes the release as the protocol's most important revision since remote MCP launched. This guide translates those changes into a security migration plan. It focuses on what an application security, identity, platform, or AI engineering team should verify before changing production clients and servers.
Why the stateless core changes the threat model
Earlier MCP versions began with initialize and initialized, and remote deployments could use Mcp-Session-Id as part of their transport lifecycle. The 2026-07-28 core removes that handshake and header. Each request stands on its own, carries the protocol version, client information, and relevant capabilities, and can be handled by any suitable server instance. A new server/discover call is available when a client needs capabilities in advance, but it is not a required precondition for every interaction.
Operationally, this removes pressure for sticky load-balancer sessions or a shared protocol-session store. Security teams should not interpret “stateless” as “no state exists.” Business workflows still create state: a browser session, shopping basket, repository task, transaction draft, or approval object may persist across calls. The difference is that application state should now be explicit, usually through a handle returned by one tool and supplied to another. That handle becomes a security-sensitive object identifier.
Test those handles like any other object-level authorization boundary. Can one user substitute another user's browser_id or task_id? Is a handle predictable, logged in unsafe locations, or accepted after the originating authority is revoked? Does the server bind it to user, tenant, client, and purpose, or merely trust possession? The removal of protocol sessions can improve clarity, but only when the application does not recreate an implicit bearer-session mechanism in a tool parameter.
Stateless routing also changes monitoring. A single workflow may touch several instances, so request IDs and application-level correlation become essential. Logs should preserve the authenticated actor, target server, tool, arguments after appropriate redaction, protocol version, client identity, policy decision, result classification, and any explicit state handle. A load balancer's connection log is no longer enough to reconstruct the chain.
Mixed-version behavior deserves active testing. Confirm how a new client reacts to an older server, how an upgraded server handles unsupported protocol versions, and whether a proxy strips or rewrites required metadata. Avoid silent downgrade paths. If a request arrives without the expected version, client identity, or capabilities, define whether the server rejects it or applies a deliberately limited compatibility policy.
Security value—and risk—of the new routing headers
Streamable HTTP requests in the new specification include Mcp-Method and, where relevant, Mcp-Name headers. This makes protocol intent visible to ordinary HTTP infrastructure. A gateway can rate-limit tools/call differently from discovery traffic, route a named tool to a dedicated backend, or create monitoring rules without parsing JSON-RPC request bodies.
That visibility is useful, but headers are untrusted input. A gateway must not authorize a request solely because Mcp-Name: read_document looks harmless. The backend still needs to parse the body, verify that the body method and tool match the routed expectation, authenticate the caller, validate arguments, and enforce resource-level permissions. Test mismatches deliberately: a benign header with a privileged body, duplicate headers, unusual casing, encoded names, an unsupported method, and a header changed by an intermediary.
Routing creates a new configuration surface. Inventory which proxies, CDNs, service meshes, and observability systems see these headers. Confirm that only intended values are accepted, logs do not expose sensitive arguments, and caching layers never treat an action request like a safe lookup. Rate limits should follow identity and consequence, not only an IP address. A tool that sends payments or changes access should have tighter budgets than a public documentation search.
Because any request can land on any instance, policy configuration must be consistent across the fleet. Test a denied request repeatedly and confirm it does not succeed on an instance with stale rules. Verify rolling deployments, policy-cache invalidation, key rotation, and rollback. An agent's non-determinism should not be compounded by inconsistent server enforcement.
Use headers for earlier rejection and better telemetry, but retain enforcement at the component that owns the resource. This mirrors a broader principle in AI agent security versus WAFs: gateways remain valuable, yet they cannot decide whether the model's selected action is appropriate for a particular user, tenant, or workflow.
Authorization hardening teams must implement, not merely document
The new release tightens several authorization details. Authorization servers should return an iss parameter in authorization responses, and clients must validate it before redeeming the code. This helps prevent authorization-server mix-up. Client credentials are bound to the issuer that created them rather than being reused across authorization servers. Dynamic Client Registration remains available for compatibility but is deprecated in favour of Client ID Metadata Documents.
These changes matter because remote MCP sits between multiple identities: a human user, client application, MCP server, authorization server, and downstream resource. A valid token is not automatically valid for every hop. The server must reject token passthrough, validate audience, issuer, expiry, and scope, and make a resource-level decision for the current user. The client must not send a token minted for an unrelated service simply because that service sits behind the tool.
Build a negative test matrix before migration. Try a correct issuer with the wrong audience, wrong issuer with a familiar client ID, expired access token, revoked refresh token, insufficient scope, a token for another tenant, and an authorization response whose issuer does not match discovery. Test localhost and command-line redirect behavior without weakening production redirect validation. Confirm credentials for one issuer are never selected for another after account or server switching.
The migration is also an opportunity to examine scope step-up. A client that begins with read access should not silently obtain write authority because an agent chooses a more powerful tool. The user needs an intelligible consent moment, the authorization server needs a bounded scope request, and the server must enforce it. Record who approved the step-up, which tool required it, how long it lasts, and whether cancelling the action leaves expanded authority behind.
Do not rely on a model refusal as evidence. Test the server directly with altered objects and scopes, then test through the connected client to observe consent and selection behavior. Our guide to AI agent identity and permission boundaries provides the system-level context; the new MCP release makes those controls more explicit but does not implement your business authorization for you.
Cacheable discovery requires integrity and lifecycle controls
The 2026-07-28 release lets list and read responses carry ttlMs and cacheScope. Clients can avoid repeatedly fetching tools, prompts, and resources. That reduces latency and load, but it also changes how quickly a revoked or repaired definition reaches users.
Treat cache policy as part of security policy. A public, immutable resource can tolerate a different lifetime from a tool definition that controls privileged action. The client should understand whether a response is private to a user, shared within a broader scope, or unsafe to cache. Intermediaries must not collapse authenticated variants into one object. Test one tenant's definitions and resources against another tenant's cache path.
Tool metadata can influence model behavior. If a malicious definition is cached, removing it at the origin may not immediately remove its effect. Conversely, an attacker who can tamper with a cache may poison many clients at once. Preserve a cryptographic digest or exact snapshot of definitions used in each assessment, verify provenance, and alert on unexpected changes. Where high-risk tools are concerned, a client should have a way to invalidate cached material quickly.
Migration tests should cover expiry, revalidation, server rollback, definition removal, and conflicting responses from different instances. Verify whether a cached permission or annotation is treated as authoritative after the underlying account changes. Keep authorization decisions short-lived and server-side; metadata caching must never become permission caching by accident.
This is especially relevant to MCP tool-poisoning and rug-pull attacks. The new cache signals can improve predictable lifecycle management, but they do not establish that the content is trustworthy. Buyers evaluating security products should ask whether observed definitions are versioned with findings and whether a retest forces or records refresh behavior.
Extensions, Tasks, and MCP Apps expand what must be assessed
Extensions now have a formal negotiation and lifecycle model. Two prominent examples are Tasks for long-running work and MCP Apps for interactive interfaces. Each adds useful capability and a distinct security boundary.
Tasks are server-directed and polled through operations such as tasks/get, tasks/update, and tasks/cancel. The removal of an unscoped tasks/list reflects an important design principle: enumeration can expose other users' work. Test task handles for predictability and substitution, bind them to identity and tenant, enforce authorization on every poll or update, and define retention. Cancellation should prevent further side effects where possible, not merely hide status from the client. Long-running work also needs idempotency, budget limits, deadlines, and audit correlation across the original request and later processing.
MCP Apps let tools return interactive HTML rendered by hosts in a sandboxed iframe. The official MCP Apps overview describes controlled communication over postMessage, tool-call proxying, requested permissions, and content-security policy metadata. Sandboxing is a boundary to verify, not a reason to stop threat modelling. Test origin validation, message source validation, capability grants, CSP allowlists, navigation, external resource loading, camera or microphone requests, and whether UI-initiated actions travel through the same consent and audit path as direct tool calls.
An attractive interface can misrepresent the action behind a button. The host should show trustworthy provenance and consequential parameters outside untrusted app content. A UI must not manufacture a fake approval screen, obscure the final destination, or persuade the user that a privileged call is read-only. Verify server and host behavior with altered templates and unexpected messages.
Extensions version independently. Inventory enabled extension IDs and versions, reject unknown critical behavior, and test downgrade or partial-support states. If a server assumes the host enforces a control that the host does not implement, the gap can cross organisational ownership. Capture those assumptions in the architecture and the assessment report.
A practical enterprise migration sequence
Start by freezing an inventory of current clients, servers, SDK versions, transports, sessions, authorization flows, tools, and extensions. Identify every place that depends on initialize, Mcp-Session-Id, legacy HTTP+SSE, roots, sampling, or logging. Record which applications keep state in transport sessions and which already use explicit resource handles.
Build a compatibility lab using synthetic identities and data. Upgrade one side at a time. Exercise discovery, listing, tool calls, errors, authorization, cancellation, and reconnect behavior across supported version combinations. Capture packets and application logs to confirm protocol metadata survives gateways. Test unsupported versions and removed features rather than only the successful path.
Next, migrate state deliberately. Replace hidden session assumptions with explicit, opaque handles bound to user, tenant, purpose, and expiry. Test object substitution, replay, logout, credential revocation, concurrent actions, instance failover, and rollback. Add correlation that survives load balancing without exposing sensitive identifiers to the model.
Harden authorization before enabling new capabilities. Validate issuer and audience, isolate client credentials by issuer, review registration strategy, constrain redirects, test scope step-up, and prevent token passthrough. Use controlled negative cases and retain server-side evidence. Review official SDK support carefully: having a new SDK installed does not prove every optional hardening feature is configured.
Then configure routing, caching, Tasks, and Apps according to risk. Allowlist expected method and name headers, compare them with request bodies, set consequence-aware rates, define cache scope and invalidation, bind task handles, and test the UI sandbox and consent path. Do not enable all extensions merely because both endpoints advertise them.
Finally, run regression tests through the complete implementation. Include a poisoned definition, an untrusted tool result, an alternate-tenant object, a cancelled long task, a changed cache entry, a mismatched issuer, and a header/body discrepancy. Repeat cases across model and prompt versions because agent selection may change independently of the protocol.
The migration is complete only when old assumptions have been removed, not when the service returns a successful tool result. Preserve the cases as a living suite and rerun them after SDK, gateway, model, prompt, permission, server, or extension changes. Oxyne validates supported MCP and tool-using agent behavior through exposed interfaces; explore the MCP security testing workflow or book a scoped demonstration to see how evidence-backed regression testing fits the migration.