“MCP v2” sounds like one upgrade. It is really two: a source-code migration to a new SDK generation and a separate move to the stateless 2026-07-28 protocol. Treating them as one change is the fastest way to turn a manageable rollout into an architectural surprise.

Upgrade the SDK and the protocol as two independently tested decisions. Your application state is a third concern—and it belongs to your application.

The name needs one qualification. MCP protocol versions are date-based, while language SDKs use their own package versions. That means a Python or TypeScript “v2” package and the 2026-07-28 protocol are related, but they are not the same version number or the same migration.

Status note — 28 July 2026: the official MCP releases page still lists 2026-07-28 as a release candidate. The Python v2 SDK is 2.0.0rc1 and explicitly not recommended for production yet; TypeScript v2 documentation is still published under the beta track. Check the current status of your language SDK before adopting it in production.

One rollout, two migrations
01InventorySDK, transport, clients, state, capabilities
02SDK v2Source changes in an isolated branch
03Prove parityLegacy protocol still behaves correctly
042026 protocolOpt in and test modern behavior
05Roll outMixed-version matrix, telemetry, fallback

Do not cross both boundaries in one unobservable deployment.

Name the change correctly.

Teams often say “MCP v2” to describe a cluster of changes arriving together. Technically, there are at least three separate layers:

LayerWhat is changingWho owns the decision
SDK source Packages, imports, types, handlers, transports, and helper APIs Each language SDK and your application code
Wire protocol Negotiation, state, server-to-client interaction, subscriptions, routing, and result lifecycles The MCP specification and both endpoints
Application architecture Identity, workflows, retry safety, resumability, authorization, caches, and observability Your system

This separation matters because SDK source compatibility does not guarantee protocol compatibility. The official TypeScript protocol migration guide, for example, says SDK v2 defaults to legacy 2025 behavior and treats 2026-07-28 as an explicit opt-in. Conversely, the Go SDK added support for the new protocol in a v1.x package. Package major versions are not a reliable proxy for the wire revision.

Question 1 Should this codebase move from its current SDK APIs to the new SDK generation?
Question 2 Should this client-server pair start speaking the 2026-07-28 protocol?
Question 3 Is application state explicit, durable, authorized, and safe to retry?

Answer those questions independently. A small local server may take the SDK migration while continuing to speak the legacy protocol. A remote platform may need the stateless protocol urgently but choose a gradual SDK rollout across languages.

The protocol stops owning your session.

The central architectural change in the official 2026-07-28 release candidate is a stateless protocol core. Earlier implementations commonly initialized a session, exchanged capabilities, received an Mcp-Session-Id, and then routed later requests back to state associated with that session. The modern path makes each request self-contained.

ConcernLegacy 2025 behavior2026-07-28 generation
Startup initialize, then initialized Request metadata plus cacheable server/discover
Transport state Session ID may bind later requests to server state No protocol session on the modern path
Application state Often hidden behind the transport session Explicit workflow, result, resource, or continuation handle
Server-to-client work Server-initiated requests inside an active session Multi Round-Trip Requests return input_required
Subscriptions Several overlapping subscribe mechanisms Unified subscriptions/listen stream
Retries Transport/session behavior may mask interruption Client retries; writes must be idempotent by application design

01Discovery replaces the old handshake

server/discover describes identity, supported revisions, capabilities, and server metadata before the client makes normal requests. Because discovery is separate and cacheable, gateways and clients can reason about compatibility without creating a stateful protocol session.

02Application state becomes explicit

Stateless does not mean your product has no state. It means the protocol does not secretly store it for you. A browser automation server, for example, can return a server-generated handle such as browser_ref. Later tools accept that handle, resolve it after authorization, and fetch the underlying state from a durable store.

{
  "workflow_id": "workflow_123",
  "result_handle": "result_8f4",
  "user_id": "user_42",
  "expires_at": "2026-07-28T15:00:00Z"
}

Handles should be opaque, short-lived where appropriate, bound to the authenticated user, and safe to resolve on any server replica. Do not replace a protocol session with a raw database key or with unverified client claims.

03Long interactions get an explicit lifecycle

Multi Round-Trip Requests let an operation pause when it needs client input, then resume from a returned handle. Results declare whether they are complete or input_required. This makes a production approval, clarification, or configuration prompt visible instead of relying on a permanent back-channel.

{
  "resultType": "input_required",
  "requestInput": {
    "type": "confirmation",
    "message": "Deploy version 2.4.0 to production?"
  }
}

The new protocol also makes extensions first-class, moves long-running Tasks into an extension, adopts full JSON Schema 2020-12, adds routing metadata such as Mcp-Method and Mcp-Name, and strengthens authorization and trace propagation. Roots, Sampling, and protocol Logging are deprecated as core primitives; deprecation is a migration signal, not an instruction to delete them before all of your clients have an alternative.

Estimate impact from architecture, not tool count.

The number of exposed tools is a poor migration estimate. Transport topology, hidden session state, client ownership, and reliance on deprecated capabilities matter much more.

  1. Small local stdio server: usually a contained source migration. Pin the SDK, update imports and types, run the real client, and preserve legacy protocol behavior until the new path is needed.
  2. Remote server behind a load balancer: high architectural benefit and meaningful migration work. Stateless requests can remove sticky routing, but only after hidden session state becomes explicit.
  3. Custom MCP client or gateway: expect negotiation, discovery caching, MRTR, subscription, retry, and mixed-version work. Do not upgrade every connected server simultaneously.
  4. Session-heavy application: highest risk. Inventory authenticated identity, permissions, workflow state, temporary data, open transactions, caches, and resumable jobs before changing the transport.
  5. Roots, Sampling, Logging, or experimental Tasks user: create a capability-by-capability migration plan. Their replacements do not all live in the same layer.

The important distinction is between server configuration and user workflow state. A server may remain stateful internally—using a database, queue, object store, or cache—while still offering a stateless protocol surface. Every request must carry enough verified information to locate the right state safely.

Use a ten-step migration plan.

01Inventory before editing

Record the language, exact SDK and protocol versions, transports, clients, session state, server-initiated calls, Roots, Sampling, Logging, Tasks, custom extensions, and low-level protocol code. Search the repository; do not estimate from memory.

02Pin dependencies

Add an upper bound before prerelease testing so a routine install cannot silently cross a major version. Use the exact beta or release-candidate version in the migration branch and update it intentionally.

03Create an isolated migration branch

Keep the SDK change separate from new product features, data migrations, authentication redesigns, and unrelated refactors. A smaller diff makes regressions observable.

04Apply mechanical source changes first

Use official codemods and migration guides for package names, imports, renamed types, handler registration, error classes, and transport setup. Review every generated change. A codemod updates syntax; it cannot redesign a session-dependent architecture.

05Prove SDK parity on the legacy protocol

Before opting into 2026-07-28, prove that the migrated application still works with the protocol behavior it used before. This creates a useful rollback point and tells you which failures belong to the SDK migration.

06Remove hidden session dependencies

Give every piece of state a proper home: authenticated identity in verified credentials, permissions in authorization policy, tool inputs in explicit request parameters, workflow state behind an opaque handle, and resumable jobs in a durable queue or database.

07Make every write retry-safe

For each mutating tool, define an idempotency key, duplicate-request behavior, transaction boundary, partial-failure response, and rollback or reconciliation path. A retried response may arrive after the first operation already succeeded.

08Replace deprecated capabilities deliberately

Replace Roots with explicit tool parameters, resources, or server configuration. Move model invocation into your application or an appropriate provider API. Use normal observability infrastructure for logs and traces. Migrate experimental Tasks only after comparing their current extension lifecycle with your existing implementation.

09Test a mixed-version matrix

ClientServerWhat to prove
LegacyLegacyExisting behavior remains unchanged
Modern-capableLegacyNegotiation or fallback is predictable
LegacyModern-capableCompatibility mode works where promised
ModernModernDiscovery, stateless requests, MRTR, retries, and subscriptions work

Include the actual gateway, reverse proxy, load balancer, authentication provider, cache, and deployment topology. Local stdio tests do not prove a remote migration.

10Test failure, not only success

Disconnect during a response. Retry a write. Send the same idempotency key twice. Route the next request to another replica. Expire a workflow handle. Remove a required capability. Deny an authorization check. Interrupt an MRTR flow and resume it. A stateless design is credible only when these failures have explicit outcomes.

Apply SDK-specific changes.

Python v2

The Python v2 line replaces the familiar FastMCP class with MCPServer, makes the client a first-class package, uses snake_case model attributes, and reorganizes transport configuration. High-level decorators remain familiar, but low-level integrations need closer manual review. At the time of writing, the official repository says v1 remains the stable production choice and recommends a bound such as mcp>=1.27,<2.

TypeScript v2

The TypeScript SDK splits client, server, core, and Node transport concerns into separate packages, requires Node.js 20 or newer, and is ESM-first while retaining a CommonJS build. The official upgrade guide recommends installing v2 packages alongside v1, migrating files incrementally, and removing v1 only after no old imports remain.

npx @modelcontextprotocol/codemod@beta v1-to-v2 .

For protocol behavior, TypeScript exposes explicit modern and legacy modes. Its protocol-version documentation also describes an automatic mode that probes server/discover and falls back for legacy peers. Treat that as controlled negotiation, not permission to skip the compatibility matrix.

Should you upgrade now?

Move sooner

  • You operate a remote server across several replicas
  • Sticky sessions or session recovery create operational pain
  • You control both client and server rollout
  • You are building a new MCP platform or gateway
  • You need modern extensions or the new Tasks lifecycle

Move cautiously

  • Your production service is stable and session-dependent
  • Your main clients do not yet support the modern protocol
  • Your language SDK remains prerelease
  • You rely on low-level SDK internals
  • You lack mixed-version and failure-path tests

New server baseline

  • Design each request to reach any replica
  • Keep application state behind explicit opaque handles
  • Use Streamable HTTP for remote deployments
  • Make write tools idempotent
  • Enforce authorization server-side on every operation

Release gate

  • The target SDK is acceptable for your production policy
  • Legacy and modern peers behave as documented
  • Retries, interruptions, and replica changes are tested
  • Telemetry distinguishes protocol and application failures
  • A tested rollback path remains available

A good answer can be “not yet.” Pin the current stable SDK, remove hidden state, add idempotency, build the compatibility matrix, and wait for the SDK or client ecosystem to reach your production threshold. That work is not wasted; it reduces migration risk and improves the existing server.

For a new remote server, the design direction is clearer: make requests stateless, application state explicit, writes retry-safe, and authorization independent of whatever the model says. Then adopt the modern protocol when your chosen SDK and clients support it at the maturity level you need.

What MCP v2 does not solve.

The new generation improves the protocol and SDK architecture. It does not automatically reduce tool-token cost, choose the right tool boundaries, enforce your business permissions, make dangerous actions reversible, or teach an agent a non-obvious workflow.

Those remain design responsibilities. Use the token-efficient MCP API rules to keep discovery and results compact. Add an optional agent skill only when a good interface still needs a repeatable multi-tool workflow, domain decision rules, or setup and verification guidance.

MCP should transport requests and results. It should not be the place where your application secretly keeps identity, permissions, workflow state, or retry semantics.

The practical recommendation is simple: inventory first, migrate the SDK and protocol separately, make state explicit, test mixed versions and failure paths, then roll out gradually. “MCP v2” is an important direction—not a reason to replace a working production system overnight.