TL;DR

MCP is versioned. A reliable upgrade note must answer four separate questions:

  1. Which normative specification revision is pinned?
  2. Which transport and authorization profiles are selected?
  3. Which behaviors come from the SDK or host rather than the protocol?
  4. Which security decisions remain application policy?

The 2025 revisions introduced important remote and authorization concepts, including Streamable HTTP and more explicit protected-resource flows. The 2025-03-26 revision is a historical pin discussed here; the primary-source links below point to the later 2025-11-25 specification. Always select one exact revision for a deployment. Neither revision turns Tool Annotations, discovery metadata, a registry, a schema, or a model refusal into an authorization boundary. This article is a migration method, not a claim that every client supports every feature.

Read a Specification Change Correctly

Classify every statement before implementing it:

Class Meaning Example decision
normative protocol required by the pinned MCP revision implement and run conformance tests
optional capability supported only when negotiated advertise and test the capability
authorization profile OAuth/resource-server behavior configure issuer, audience/resource, scopes, and key rotation
SDK behavior library-specific API or compatibility pin the library and inspect its tests
host convention UI, approval, or model integration never treat it as server authorization
ecosystem service registry, catalog, gateway, or vendor product apply provenance and lifecycle governance

This classification prevents a common failure: reading an example, SDK convenience method, or host feature as if it were a mandatory protocol guarantee.

Version Matrix

The exact content of a revision must be checked against its official document. A useful migration matrix looks like this:

Surface Questions to answer
lifecycle Did initialization, notifications, or capability negotiation change?
transport Is the deployment using stdio, current Streamable HTTP, or a legacy route?
sessions Who creates the session ID, how is it bound, and how does reconnect work?
authorization Which resource metadata, issuer, audience, scopes, and token profile apply?
tools Which annotations, structured results, pagination, and cancellation are supported?
JSON-RPC Are notifications, errors, correlation, and any batch behavior supported by both peers?
compatibility Which old clients need a separate adapter or route?

Do not publish a timeline as a substitute for this matrix. A date in a changelog does not prove that a client, SDK, or provider implements the feature.

Remote HTTP and Legacy SSE

The older HTTP-plus-SSE pattern commonly used a server-to-client event stream and a separate message endpoint. A current Streamable HTTP profile can use one MCP endpoint with request/response and streaming behavior according to the selected specification.

The migration is not just a URL change:

  • establish the supported Content-Type and response shape;
  • preserve JSON-RPC request IDs and cancellation;
  • bind sessions to the authenticated principal and tenant;
  • define whether requests are stateless or session-aware;
  • test reconnect, Last-Event-ID or equivalent resume behavior only if the profile supports it;
  • verify proxy buffering, idle timeouts, and graceful drain;
  • keep a clearly labeled compatibility route if old clients cannot migrate.

Do not describe legacy SSE as “the MCP streaming protocol,” and do not claim that a single endpoint automatically provides bidirectional or resumable semantics. Those are profile and implementation behaviors.

Authorization: OAuth Is a Profile, Not a Shortcut

Remote MCP needs a trusted caller identity and a protected-resource policy. The authorization profile may use OAuth metadata, a resource indicator, PKCE, bearer tokens, or another workload identity depending on the topology and revision.

The resource server must still:

  1. validate a trusted issuer and the intended audience/resource;
  2. verify signature, algorithm, expiry, not-before, key rotation, and clock policy;
  3. map provider claims to an internal principal;
  4. check scope and tenant policy on every operation;
  5. authorize the exact object and side effect;
  6. redact tokens and sensitive claims from telemetry.

Do not write “OAuth 2.1 is mandatory for every MCP client” without citing the exact authorization profile. Do not implement an authorization server in an example by signing tokens with an application secret and calling that production OAuth.

Dynamic Client Registration

Dynamic registration can reduce manual setup for public clients, but it also creates a client lifecycle:

  • who may register;
  • which redirect URIs are accepted;
  • how localhost and production redirects differ;
  • how registrations expire or are revoked;
  • how client metadata is reviewed;
  • how a tenant is selected;
  • how secrets and tokens are stored.

If the authorization server does not support or permit registration, use an approved provisioning flow. Registration is not authorization to access a tenant or tool.

Tool Annotations Are Hints

Tool annotations can help a host show risk or choose a confirmation UI:

Hint What it may communicate What it cannot prove
read-only expected absence of external mutation actual runtime behavior or object access
destructive expected high-impact mutation whether a particular call is authorized
idempotent expected repeat behavior durable idempotency under a timeout
open-world expected interaction with external entities safety or destination trust

The server must enforce the behavior it advertises. A malicious or stale descriptor can lie, and a tool can behave differently from its description after a deployment.

JSON-RPC and Optional Features

Check both peers before using optional JSON-RPC behavior:

  • request and notification semantics;
  • error codes and data handling;
  • request IDs and out-of-order responses;
  • cancellation;
  • structured or paginated results;
  • batch support, if the pinned MCP and SDK profiles actually support it.

Do not claim that every MCP implementation must accept arbitrary JSON-RPC batches unless the exact normative revision says so and the SDK passes conformance tests. Batches also need per-item authorization, size limits, ordering rules, and partial-failure semantics.

A Safe Migration Plan

1. Inventory

Record current clients, SDKs, server versions, transports, authentication, sessions, tools, resources, prompts, side effects, and proxy behavior.

2. Pin

Choose the target MCP revision, transport profile, authorization profile, SDK versions, and feature flags. Store these in the repository and deployment manifest.

3. Build a Compatibility Matrix

text
client x SDK x transport x authorization x capability

For every cell, mark supported, unsupported, adapter-required, or untested. Do not infer support from a product name or a marketing page.

4. Migrate the Boundary

Run the new transport behind a separate route or deployment. Preserve the old route only for clients with an explicit compatibility need. Keep tenant and object authorization identical across both paths.

5. Add Conformance and Abuse Tests

Test initialization, capabilities, tool discovery, resource reads, prompt retrieval, cancellation, malformed messages, token expiry, unknown keys, cross-tenant objects, annotation lies, oversized results, reconnects, duplicate side effects, and proxy behavior.

6. Shadow and Roll Back

Replay redacted fixtures against both paths. Compare protocol events and business outcomes, not only HTTP status. Keep a rollback route until the error, latency, cost, and authorization distributions are understood.

Migration Artifacts

Use a manifest rather than a prose-only migration:

json
{
  "mcp_revision": "pinned-revision",
  "transport_profile": "pinned-profile",
  "authorization_profile": "pinned-profile",
  "sdk": {
    "name": "pinned-sdk",
    "version": "pinned-version"
  },
  "compatibility_routes": [
    {"name": "legacy-transport", "expires": "review-date"}
  ],
  "features": {
    "annotations": true,
    "structured_results": true,
    "batch": false
  },
  "tests": {
    "conformance": "suite-id",
    "abuse": "suite-id",
    "replay": "fixture-version"
  }
}

The manifest is not a security policy by itself. The runtime and deployment must enforce its limits and authorization decisions.

Registry and Discovery Governance

A registry or catalog can improve discovery, but it introduces supply-chain decisions:

  • verify publisher identity and package provenance;
  • pin server versions and hashes where possible;
  • review declared tools and side effects;
  • scan dependencies and deployment permissions;
  • isolate credentials and network egress;
  • support revocation, uninstall, and deletion;
  • treat descriptions and resources as untrusted content.

Automatic installation is a privileged operation. A catalog entry is not proof that a server is safe or that all of its tools should be exposed.

Testing Matrix

Test Expected invariant
version mismatch fail before capability use
unsupported transport clear negotiation or compatibility error
token for another resource reject before Tool execution
missing scope or wrong tenant deny without object-existence leakage
annotation contradicts behavior server policy wins
oversized result bounded failure or authorized artifact reference
canceled request downstream work stops or compensates
duplicate mutation deterministic idempotency result
reconnect after node loss no unauthorized session resurrection
malicious tool result treated as untrusted data

Common Misreadings

  • “Streamable HTTP replaces all SSE.” It changes the preferred current profile; compatibility routes may remain.
  • “PKCE authenticates the user.” PKCE binds an authorization-code exchange; token and resource authorization are separate.
  • “Annotations drive permission.” They are hints; the server enforces policy.
  • “A Schema prevents injection.” It constrains shape, not intent, ownership, or result content.
  • “A Registry is an app store with trust.” Discovery and installation require supply-chain governance.
  • “A supported client means every feature works.” Capability and version matrices are still required.

Production Checklist

  • [ ] Pin the MCP revision, transport profile, authorization profile, and SDK.
  • [ ] Separate normative requirements from optional capabilities and host conventions.
  • [ ] Document Host, Client, Server, external systems, and trust boundaries.
  • [ ] Validate issuer, audience/resource, algorithm, expiry, scopes, and key rotation.
  • [ ] Bind sessions to authenticated principals and tenants.
  • [ ] Treat annotations, descriptors, resources, and results as untrusted data.
  • [ ] Test cancellation, reconnect, duplicate delivery, batching if supported, and proxy behavior.
  • [ ] Keep compatibility routes isolated and scheduled for review.
  • [ ] Govern registry provenance, version pinning, credentials, egress, and deletion.

Frequently Asked Questions

Is 2025-03-26 the current MCP specification?

It is one revision. Pin the revision used by your deployment and consult the corresponding official document; later revisions and SDKs may change supported behavior.

Does MCP require OAuth 2.1 and dynamic registration everywhere?

No. Requirements depend on the selected authorization profile and topology. Registration is a client lifecycle feature, not a permission grant.

Are Tool Annotations security controls?

No. They are behavior hints for a host. Server-side identity, tenant, object, purpose, and side-effect policy remains authoritative.

Does Streamable HTTP make migration automatic?

No. Test transport, session, cancellation, reconnect, authorization, proxy, and duplicate-delivery semantics with real clients.

Is a Registry part of core MCP?

Not as a universal trust boundary. It is an ecosystem or deployment service that needs provenance and lifecycle governance.

Conclusion

Specification work is safest when every claim carries a version and a boundary. Pin the MCP revision, select the transport and authorization profiles, check actual SDK support, and keep application policy outside descriptive hints. A migration is complete only when conformance, security, compatibility, rollback, and data-governance evidence all agree.

Primary Sources