· 9 min read
MCP v2: What's Changing, What's Deprecated, and Why
MCP v2 breaking changes explained: the protocol goes stateless and deprecates sampling, roots, and logging. What is changing across every MCP SDK, why, and whether you should migrate yet.
Copy a command, then paste it into the command palette (Ctrl K to open).
Introduction
If you have built anything on the Model Context Protocol, the next few weeks matter. MCP v2 (protocol revision 2026-07-28) finalizes on July 28, 2026. The release candidate was locked on May 21, 2026, and SDK maintainers are validating it against real workloads during a ten-week window before the spec is published.
This is not a point release. v2 makes the protocol stateless, formalizes extensions as first-class components, and deprecates three subsystems that many existing servers rely on: sampling, roots, and logging.
This article is the language-agnostic companion to our SDK-specific guides. It covers what is changing and why, so that when the stable SDKs land you understand the shape of the migration regardless of whether you write TypeScript, Python, Go, or C#. For the current v1 TypeScript walkthrough, see The MCP TypeScript SDK: A Complete Guide; a v2 update to that guide will follow once the SDKs reach stable.
IMPORTANT
As of this writing the v2 SDKs are in beta. The MCP team is explicit: "For any critical workloads, the stable SDK releases remain the recommended versions," and "public APIs may still change between the betas and the stable releases." Treat the code shapes below as directional, not final.
What you'll learn:
- The headline change: why MCP is going stateless
- Which subsystems are deprecated (sampling, roots, logging) and what replaces each
- What the stateless shift means for the SDKs you build on
- What extensions are, and the two official ones shipping with v2
- Whether you should migrate now or wait for stable
The Headline Change: MCP Goes Stateless
The single biggest change in v2 is that the protocol becomes stateless.
In v1, every session began with an initialize / initialized handshake, and the server issued an Mcp-Session-Id that the client sent back on every subsequent request. That session ID pinned a client to a specific server instance. If you scaled your server horizontally, you needed sticky sessions so that follow-up requests landed on the same process that ran the handshake.
v2 removes all of that:
- No
initialize/initializedhandshake. - No
Mcp-Session-Idheader. - Client information now travels in
_metafields on each request, so any request is self-contained. - Two new operational headers,
Mcp-MethodandMcp-Name, let infrastructure route and observe requests without parsing the body. - Caching metadata (
ttlMsandcacheScope) is now part of the protocol.
The practical payoff: a request can be handled by any server instance. No sticky sessions, no session affinity, no shared session store. This is a much better fit for serverless and autoscaled deployments, where you cannot assume the next request reaches the same box.
This one change is also the reason behind most of the deprecations below. Several v1 features quietly assumed a long-lived, stateful connection between one client and one server process. Once that assumption is gone, those features no longer fit.
What's Deprecated, and Why
Three subsystems are deprecated under v2's new lifecycle policy. Deprecated does not mean removed. Each remains functional during a one-year grace period, so existing v1 servers keep working. But new code should adopt the replacements.
Sampling
What it was: Sampling let a server ask the client's LLM to generate text mid-execution (via createMessage in the TypeScript SDK). It powered "agentic servers" that could reason and make decisions internally by borrowing the client's model.
Why it's going away: Sampling requires the server to reach back into the client while it is not handling a client request, which only works over a persistent, stateful connection. That is exactly the assumption v2 removes. In a stateless world, the server processing your request may not be the one holding a connection to your client at all.
What replaces it:
- Direct integration with LLM provider APIs. If your server needs a model, call the provider (Anthropic, OpenAI, etc.) directly from the server. You control the model, the keys, and the cost.
- The
InputRequiredResultpattern for the cases where you genuinely need something from the client mid-task. Instead of a live callback, the server returns a result that says "I need this input," and the client retries the request with the answer. Because each round-trip is a fresh, self-contained request, it can be retried against any server instance, keeping the interaction stateless.
If you use sampling today, this is the deprecation most likely to require real rework, because the replacement changes where the model call happens (server-side, not client-side).
Roots
What it was: Roots were URIs the client provided to scope what the server should operate on, for example file:///home/user/my-project to tell a code-analysis server which directory to scan. Servers read them with listRoots().
Why it's going away: Roots were another piece of session-scoped state pushed from client to server and held for the life of a connection.
What replaces it: Pass the same information explicitly, per request:
- Tool parameters — accept the working directory or scope as a tool input.
- Resource URIs — encode the scope directly in the resource being requested.
- Server configuration — set boundaries at deploy time when they are static.
Logging
What it was: Structured log messages sent from the server to the client over the MCP protocol, filtered by a client-set level (logging/setLevel).
Why it's going away: Protocol-level logging tied observability to a live client connection, which is awkward for stateless, multi-instance deployments and duplicates tooling that already exists.
What replaces it:
- stderr for stdio transports. Write logs to standard error; the host captures them. (This was already the recommended practice for stdio servers in v1, since stdout is reserved for the protocol.)
- OpenTelemetry for structured, production-grade observability. Emit traces and metrics to your existing OTel pipeline rather than through MCP.
What the Stateless Shift Means for the SDKs
Beyond the deprecations, statelessness ripples through every SDK's surface. The specifics differ by language, and the v2 SDKs are still settling, so this is a map of what kind of change to expect rather than a list of exact symbols. Three patterns show up regardless of which SDK you use:
- Transports get reshaped. Removing sessions is a transport-level change, so expect HTTP transports to be renamed or split by runtime, and expect the old SSE transport (a two-endpoint design built around a persistent stream) to disappear. A single, unified request/response transport fits the stateless model; a long-lived stream does not.
- Errors split into protocol errors and local SDK errors. v2 draws a clearer line between "the request itself was malformed" (a wire-protocol error the other side should see) and "something failed locally, like the HTTP connection dropped." If your code inspects error types, expect that distinction to surface in the API.
- Request context becomes transport-aware. Because a stdio server has no HTTP request behind it, the per-request context object separates protocol-level fields from transport-specific ones (like auth info that only exists over HTTP). Handlers read those optional fields defensively.
None of this requires action today. It is a map of what the eventual migration touches so you can gauge its size for your codebase, whatever language you build in. When the SDKs reach stable, our language-specific guides will cover the concrete renames.
AGENT BRIEFINGS
What actually matters for building and scaling AI agents in production — and what's just hype. Straight from the work, no filler.
Should You Migrate Now?
Short answer: not for production, not yet. Here is the state of play as of early July 2026:
- The v2 SDKs are still pre-stable across the board. The TypeScript and Python SDKs are in beta; Go and C# are on pre-release/preview builds. Exact versions are moving quickly, so check each SDK's releases rather than trusting a number quoted here.
- Stable is close. The spec finalizes July 28, 2026, and stable SDK releases are expected around the same timeframe.
- The betas are opt-in. Upgrading the SDK does not automatically switch your server to the new protocol revision. You choose when to adopt v2 behavior.
- Pin exact versions if you experiment. Public APIs may change between the pre-stable builds and stable, so a floating version range can break you.
A reasonable plan for most teams:
- Now: Read the spec changes (this article). Audit your servers for sampling, roots, and logging usage. Note where you rely on session state.
- On stable (post July 28): Upgrade a non-critical server first. Work through the renamed imports and the deprecated subsystems.
- Within the grace year: Migrate the rest before the deprecated subsystems are removed.
What's New: Extensions
v2 does not only subtract. It also formalizes extensions as first-class protocol components with reverse-DNS identifiers and independent versioning. Instead of bolting capabilities onto the core spec, features can now evolve as versioned extensions.
Two official extensions launch with v2:
- MCP Apps — server-rendered UIs, so a server can present a rich interface to the user rather than only returning text and structured data.
- Tasks — a standard pattern for long-running operations, so a server can kick off work that outlives a single request and report on it. This pairs naturally with the stateless core: a task is addressable across instances rather than tied to one connection.
Expect the extension model to be where much of MCP's future capability growth happens, precisely because extensions can ship and version without waiting on a full spec revision.
What This Means for Your Existing v1 Servers
If you have MCP servers in production today, nothing breaks on July 28. To recap:
- v1 servers keep working. Deprecations have a one-year grace period.
- You are not forced to migrate on a deadline; you are forced to migrate before the grace period ends.
- The biggest real change is sampling. Roots and logging have straightforward replacements you may already be halfway to. Sampling moves the model call from client to server, which is an architectural shift, not a rename.
- Statelessness is a gift if you run at scale. It removes sticky-session complexity from your infrastructure.
Plan for it now, migrate on stable, and you will have a full year of runway.
Resources
- MCP 2026-07-28 Release Candidate — the protocol changes, straight from the source
- MCP SDK v2 Betas — per-language beta status and versions
- TypeScript SDK v2 Migration Guide — the concrete TS upgrade path
- MCP Specification — the full protocol spec
Related Articles
- The MCP TypeScript SDK: A Complete Guide — the current v1 SDK deep dive
- Create Your First MCP Server in 5 Minutes — beginner quickstart
- Getting Started with FastMCP in TypeScript — a streamlined framework
- Securing MCP Servers with OAuth and Keycloak — authentication
- Top AI Agent Protocols in 2026 — where MCP fits among agent protocols
AGENT BRIEFINGS
Stay measured as the field moves.
What actually matters for building and scaling AI agents in production — and what's just hype. Straight from the work, no filler.
$ subscribe agent-briefings
→ what works in production, what doesn't.
→ frameworks, MCP, evals, managed services.
→ signal over hype.