ToolsExplainer

Model Context Protocol: the definitive guide to how MCP works in 2026

A spec-level reference to MCP: history and governance, every revision up to 2026-07-28, the stateless request model, each primitive, transports, extensions, SDK tiers and the limits.

Illustration of a glass card showing a JSON-RPC tools/call request whose _meta block carries protocolVersion 2026-07-28 and clientCapabilities, with a struck-through initialize line, beside a tilted gradient panel listing five spec revisions from 2024-11-05 to 2026-07-28 and a chip reading 'resultType: input_required'.
Illustration of a glass card showing a JSON-RPC tools/call request whose _meta block carries protocolVersion 2026-07-28 and clientCapabilities, with a struck-through initialize line, beside a tilted gradient panel listing five spec revisions from 2024-11-05 to 2026-07-28 and a chip reading 'resultType: input_required'.

The Model Context Protocol (MCP) is the standard most AI applications now use to reach tools and data: a JSON-RPC 2.0 protocol in which a host application runs one client per server, and servers expose tools, resources and prompts. The current revision, 2026-07-28, is the largest change since launch. It removes the initialize handshake and protocol-level sessions, replaces server-initiated requests with a retry pattern, deprecates three features, and moves long-running tasks into an extension.

That matters to anyone who builds or operates MCP servers and clients, because much of what was true a year ago is now legacy behaviour. This guide is the spec-level reference: where the protocol came from and who governs it, every revision and what it changed, how a request actually flows in the 2026-07-28 model, every primitive on both sides of the wire, transports, authorisation, extensions, SDK tiers and the roadmap, plus an honest account of the criticisms. Every claim is checked against the specification and project pages as of October 2026, and links point to the passage that supports it.

If you are new to MCP, start with our beginner’s guide to what MCP is and the explainer on what an MCP server actually is. This piece assumes you know why the protocol exists and want to know exactly how it works.

What the Model Context Protocol is

The specification describes MCP as an open protocol that “enables seamless integration between LLM applications and external data sources and tools”, and names three roles. Hosts are LLM applications such as an IDE, a chat app or an agent runtime. Clients are connectors inside the host; each client talks to exactly one server. Servers provide context and capabilities, and can be local processes or remote services. The specification’s own analogy is the Language Server Protocol, which did the same job of decoupling editors from language tooling.

Four design principles explain most of the protocol’s shape:

  1. Servers should be extremely easy to build. The host carries orchestration complexity; servers focus on one capability.
  2. Servers should be highly composable. A host can run many in parallel without them knowing about each other.
  3. Servers should not see the whole conversation or into other servers. The host keeps the conversation and enforces isolation.
  4. Features can be added progressively. Capabilities are declared and negotiated, so clients and servers evolve independently.

The third principle is the one most often forgotten in production. A server receives only what the host chooses to send it, which is why consent, filtering and logging are host responsibilities in the spec, not server ones. The base layer is small: JSON-RPC messages, versioning and the message patterns are mandatory, and every other component MAY be implemented based on need.

Where MCP came from and who governs it

Anthropic open-sourced MCP on 25 November 2024, describing it as a new standard for connecting AI assistants to the systems where data lives. The launch shipped three things: the specification and SDKs, local MCP server support in the Claude desktop apps, and a repository of reference servers for systems such as Google Drive, Slack, GitHub, Git, Postgres and Puppeteer.

On 9 December 2025 Anthropic donated MCP to the Agentic AI Foundation (AAIF), a directed fund under the Linux Foundation co-founded by Anthropic, Block and OpenAI, with support from Google, Microsoft, AWS, Cloudflare and Bloomberg. The Linux Foundation’s announcement lists founding contributions of three leading projects: MCP, Block’s goose and OpenAI’s AGENTS.md. At the time Anthropic reported more than 10,000 active public MCP servers and adoption by ChatGPT, Cursor, Gemini, Microsoft Copilot and Visual Studio Code. By the 2026-07-28 release, the maintainers reported close to half a billion SDK downloads a month across the Tier 1 SDKs. Both figures are the project’s own.

How decisions are made

Legally, the project is now “Model Context Protocol a Series of LF Projects, LLC”, with code and specifications under Apache 2.0 and documentation under CC BY 4.0. Technically, it runs a four-level hierarchy modelled on Python and PyTorch:

RoleScopeCurrent holders (October 2026)
Lead MaintainersFinal authority, can veto any decisionDavid Soria Parra, Den Delimarsky
Core MaintainersSpecification and project direction; meet every two weeksSix people, including Clare Liguori, Caitie McCaffrey and Paul Carleton
MaintainersSDKs, documentation, working groupsListed in the repository’s MAINTAINERS file
ContributorsIssues, pull requests, discussionAnyone

Membership is personal: the governance page states there are “no seats reserved for specific companies”. Changes to the specification go through Specification Enhancement Proposals (SEPs), which since 2026-07-28 are markdown files in a seps/ directory with PR-derived numbers. Working groups (transports, tasks and events, registry, server cards, skills over MCP and others) produce SEPs; interest groups (security, enterprise, financial services and others) articulate problems.

The 2026-07-28 cycle also introduced a formal feature lifecycle and deprecation policy (SEP-2596): features are Active, Deprecated or Removed; a deprecation needs a SEP, a migration path and a minimum window of twelve months, measured from the release of the revision that first marks the feature Deprecated. Tier 1 SDKs must then mark the API deprecated in their next release. For anyone planning upgrades, that twelve-month window is the most useful governance change of the year.

Every MCP specification revision, in order

MCP names revisions by date. There have been five, and each changelog lists what moved. The table below summarises the major changes from each.

RevisionHeadline changesWhat it means for implementers
2024-11-05First public specification: stateful JSON-RPC connections with an initialize handshake; tools, resources, prompts, sampling and roots; stdio and HTTP with SSE transportsThe baseline. Remote servers needed two endpoints and a held-open SSE connection
2025-03-26OAuth 2.1 authorisation framework; Streamable HTTP replaces HTTP+SSE; JSON-RPC batching; tool annotations (read-only, destructive); audio content; completions capabilityRemote MCP becomes practical; annotations arrive, but as hints
2025-06-18Batching removed; structured tool output; servers classified as OAuth resource servers with protected resource metadata; RFC 8707 resource indicators required; elicitation added; resource links; MCP-Protocol-Version header required on HTTPAuth gains a proper resource-server model; tools can return typed JSON
2025-11-25OpenID Connect discovery; icons; incremental scope consent; tool-name guidance; URL-mode elicitation; tools in sampling; Client ID Metadata Documents; experimental tasks; formal governance and SDK tiersThe first release under formal governance; async work appears
2026-07-28Stateless core: no initialize, no Mcp-Session-Id; server/discover; per-request _meta; Multi Round-Trip Requests; subscriptions/listen; required resultType; Mcp-Method and Mcp-Name headers; cacheable list results; SSE resumability removed; tasks moved to an extension; Roots, Sampling, Logging and DCR deprecatedBreaking for every SDK and most servers; migration notes needed

Two patterns run through the table. Transport and session machinery has been simplified at almost every step, from two HTTP endpoints to one, and now from a stateful session to self-contained requests. And security has been added in layers, each closing a gap the previous one left: OAuth in March 2025, resource-server semantics and audience binding in June 2025, issuer validation and issuer-bound credentials in July 2026.

The 2026-07-28 changelog is long, and some minor items have real operational weight. Servers SHOULD return tools/list in a deterministic order so clients and LLM prompt caches stay stable. The resource-not-found error code moved from -32002 to -32602. Schema keywords were loosened to the full JSON Schema 2020-12 vocabulary, with a rule that implementations must not automatically dereference network $ref values. And the JSON-RPC server-error range is now partitioned: -32020 to -32099 is reserved for the MCP specification.

How an MCP request works in the 2026-07-28 model

Until July 2026, an MCP connection began with a handshake: the client sent initialize with its version and capabilities, the server replied with its own, the client sent notifications/initialized, and the pair then shared a session for the life of the connection. Over HTTP, that session was identified by Mcp-Session-Id.

The current revision deletes all of it. The base protocol now says plainly that a server processes each request independently and “no state should be inferred from previous requests”, even on the same connection. The rationale in SEP-2575 is operational: stateful MCP could not sit behind a plain round-robin load balancer, forced sticky sessions, lost state when an instance failed, and made both sides write session garbage collection and resynchronisation code.

The request envelope

Every request now carries its own context in _meta. Two fields are required on every request; two more are optional:

_meta keyRequiredPurpose
io.modelcontextprotocol/protocolVersionYesThe revision this request uses, for example 2026-07-28
io.modelcontextprotocol/clientCapabilitiesYesCapabilities relevant to this request
io.modelcontextprotocol/clientInfoNo (SHOULD be sent)Client name and version
io.modelcontextprotocol/logLevelNoOpt-in to log notifications for this request

A request missing a required field is malformed and must be rejected with -32602, or 400 Bad Request over HTTP. A server that needs a capability the client did not declare must return MissingRequiredClientCapabilityError (-32021). Servers should identify themselves in each result’s _meta under io.modelcontextprotocol/serverInfo. A tool call over HTTP therefore looks like this:

POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: get_weather

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": { "location": "Seattle, WA" },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientInfo": { "name": "ExampleClient", "version": "1.0.0" },
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}

Version negotiation without a handshake

There is “no negotiation handshake”. If a server does not implement the requested version it must answer with UnsupportedProtocolVersionError (-32022) listing the versions it does support, and the client retries with one of them. Clients that want capabilities up front can call server/discover, which every server must implement and which returns supported versions, capabilities, server info, optional natural-language instructions for the model, and cache hints. Calling it is optional, except on stdio where a dual-era client should probe with it first.

Results now have a type

Every result must carry a resultType. "complete" is an ordinary result. "input_required" means the server needs something before it can finish. Clients must treat a missing resultType from an older server as "complete", and extensions can add values (the Tasks extension adds "task").

Multi Round-Trip Requests replace server-initiated requests

Earlier revisions let a server send its own JSON-RPC requests to the client mid-call: sampling/createMessage, elicitation/create or roots/list. That needed a bidirectional channel and shared state across server instances. The 2026-07-28 transport rules now say servers must not send independent JSON-RPC requests on any stream.

Instead, under Multi Round-Trip Requests (SEP-2322), the server answers with an InputRequiredResult. It contains inputRequests, a map of the elicitation, sampling or roots requests it needs fulfilled, and optionally requestState, an opaque blob. The client gathers the answers, then retries the original request with a new JSON-RPC ID, the answers in inputResponses and the requestState echoed back unchanged. Only three requests may return this result: tools/call, resources/read and prompts/get.

Because requestState travels through the client, the spec makes servers treat it as attacker-controlled. If it influences authorisation, access or business logic, the server must protect its integrity with an HMAC or AEAD and should bind it to the authenticated principal, a short expiry and the originating request. Even then, the spec warns, those measures do not guarantee single use; one-time operations need server-side enforcement.

Notifications and subscriptions

Request-scoped notifications such as progress and log messages flow on the response stream of the request they belong to. Everything else that used to arrive on the HTTP GET stream now arrives through subscriptions/listen, a long-lived request whose response is a stream. The client opts in to specific types (toolsListChanged, promptsListChanged, resourcesListChanged, or a list of resource URIs), the server acknowledges the subset it will honour, and every notification is tagged with the subscription’s ID. ping, logging/setLevel and notifications/roots/list_changed were removed.

Flow of an MCP request in the 2026-07-28 revision: an optional server/discover call, then a request carrying protocol version and capabilities in _meta, a version check that can return UnsupportedProtocolVersion for a retry, server processing that can return an InputRequiredResult for a retry with inputResponses, and a complete result, with subscriptions/listen as an optional long-lived stream.

Figure 1: There is no session to set up. Each request is checked on its own, and the two retry loops (wrong version, more input needed) replace what the handshake and server-initiated requests used to do.

Living with older clients and servers

The versioning page splits implementations into modern (2026-07-28 and later), legacy (handshake-based, 2025-11-25 and earlier) and dual-era. Its compatibility matrix is blunt: a modern-only client against a legacy server fails, and a legacy client against a modern-only server fails too, because legacy clients have no way to fall forward. Dual-era clients detect the server’s era (on stdio, by probing with server/discover; on HTTP, by inspecting a 400 response body) and cache the answer per server process or origin. A dual-era server picks its behaviour from how the client opens: a request with modern _meta is served statelessly; an initialize selects legacy semantics for that process or session.

Two lanes compared. The legacy lane runs initialize and initialized, a session ID held by the server, server-initiated requests on an open stream, and resumable SSE with Last-Event-ID. The modern lane runs per-request _meta with optional server/discover, explicit handles passed as arguments, an InputRequired result the client answers by retrying the call, and re-issuing a request with a new ID if a stream drops.

Figure 2: The same features exist on both sides; what changed is where the state lives. In 2026-07-28 it travels with each request or in explicit handles.

For most teams the practical consequence is that a server fleet should be dual-era for at least a release cycle, and client upgrades should land before server-only cut-overs.

The MCP primitives: what servers and clients offer

MCP calls its feature types primitives. Servers offer three; clients offer three, two of which are now deprecated. The distinction that matters most is who decides when each is used.

PrimitiveOffered byWho controls itKey methods (2026-07-28)Status
ToolsServerThe modeltools/list, tools/callActive
ResourcesServerThe applicationresources/list, resources/read, resources/templates/listActive
PromptsServerThe userprompts/list, prompts/getActive
ElicitationClientThe user, at the server’s requestelicitation/create inside InputRequiredResultActive
SamplingClientThe client’s model, with human approvalsampling/createMessage inside InputRequiredResultDeprecated
RootsClientThe user or workspaceroots/list inside InputRequiredResultDeprecated
Completion, pagination, cachingServer utilitiesThe applicationcompletion/complete, cursors, ttlMs and cacheScopeActive
LoggingServer utilityThe applicationnotifications/message, per-request logLevelDeprecated

Tools

Tools are model-controlled: the model discovers and calls them. A tool has a name, optional title, description, optional icons, an inputSchema (which must be a valid JSON Schema object, never null), an optional outputSchema and optional annotations. Results can contain text, images, audio, resource links and embedded resources, plus structuredContent that should validate against the output schema. Tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) are hints, and clients must treat them as untrusted unless they come from a trusted server.

Tool names should be 1 to 128 characters drawn from ASCII letters, digits, underscore, hyphen and dot. Uniqueness is scoped to one server, so aggregators are told to disambiguate, for example by prefixing with a server identifier, and not to rely on serverInfo.name, which is not guaranteed unique.

The spec separates two error channels, and the separation is deliberate. Protocol errors (unknown tool, malformed request) are JSON-RPC errors. Tool execution errors, including input validation failures since 2025-11-25, come back inside the result with isError: true, so the model can read the message and try again.

With sessions gone, the spec now includes non-normative guidance on stateful tools: a creation tool returns a handle such as bsk_a1b2c3, the model passes it to later calls, and the server looks up state by that key. The guidance is specific: for authenticated servers “a handle is a name, not a capability”, so authorisation is checked against it on every call; for unauthenticated servers it must be high-entropy and short-lived; and its retention policy belongs in the tool description so the model can see it.

The tools page also sets a baseline for security. Servers must validate inputs, apply access controls, rate-limit invocations and sanitise outputs. Clients should confirm sensitive operations, show inputs before calling, validate results before passing them to the model, time out calls and log tool usage for audit.

Resources

Resources are application-driven: the host decides what context to include, through a picker, search or its own heuristics. Each resource has a URI (file://, https://, git:// or a custom scheme) and returns text or base64 binary content. Resource templates expose parameterised URIs. Content annotations declare intended audience and priority, though the roadmap concedes most implementers have not adopted them. Change notification for a specific resource now goes through subscriptions/listen with resourceSubscriptions, replacing resources/subscribe.

Prompts

Prompts are user-controlled: templates the user picks, typically as slash commands, with arguments the server fills in. The spec clarifies that “user-controlled” refers to who decides when a prompt is used, not who wrote it; the content is the server’s. That distinction matters for security review, because prompt text from a third-party server is as untrusted as a tool description.

Elicitation

Elicitation lets a server ask the user for input in the middle of a tool call, resource read or prompt fetch. It has two modes. Form mode sends a restricted subset of JSON Schema (flat objects with primitive properties only) and gets structured data back through the client. URL mode, added in 2025-11-25, sends the user to a URL so that sensitive data never passes through the client; servers must not use form mode for passwords, API keys, tokens or payment credentials and must use URL mode instead. Responses use a three-action model: accept, decline or cancel. In 2026-07-28 the elicitationId and completion notification from URL mode were removed; the client learns the outcome by retrying the original request.

Sampling and roots, now deprecated

Sampling let a server ask the client’s model for a completion, with model preferences, a system prompt and, since 2025-11-25, tool definitions for a nested tool loop. Roots told a server which directories it should treat as its boundary. Both, along with logging, are deprecated as of 2026-07-28 with earliest removal in the first revision released on or after 28 July 2027. The suggested migrations are direct: integrate with a model provider’s API instead of sampling; pass paths as tool parameters, resource URIs or configuration instead of roots; log to stderr or OpenTelemetry instead of protocol logging.

The reasons in SEP-2577 are candid: low client adoption for both sampling and roots, vague semantics for roots (servers were never required to honour them), and implementation complexity for sampling, which needs human approval, model selection and, since tool support, a full tool loop. Anyone who read early MCP material describing sampling as the route to agentic servers should treat that as historical.

Utilities: completion, pagination and caching

Completion gives IDE-style suggestions for prompt arguments and resource template values. List operations paginate with opaque cursors. New in 2026-07-28, tools/list, prompts/list, resources/list, resources/templates/list, resources/read and server/discover results carry ttlMs, a freshness hint in milliseconds, and cacheScope, which says whether shared intermediaries ("public") or only the requesting client ("private") may cache the response. Combined with deterministic tool ordering, that lets a client keep its tool catalogue and its model’s prompt cache stable between reconnects.

Transports: stdio and Streamable HTTP

The spec now treats a transport as a binding: it defines framing, delivery, metadata carriage and cancellation, but not meaning. There are two standard bindings, and custom transports are allowed if they preserve the JSON-RPC format, the message patterns and the per-request metadata model.

stdio. The client launches the server as a subprocess. Messages are newline-delimited JSON-RPC on stdin and stdout; the server must not write anything to stdout that is not an MCP message and may use stderr for any logging. Cancellation is a notifications/cancelled message. Dual-era clients probe with server/discover and fall back to initialize on any non-modern error.

Streamable HTTP. The server exposes one MCP endpoint that accepts POST. Every client message is its own HTTP POST with an Accept header listing both application/json and text/event-stream; notifications get 202 Accepted; requests get either a JSON body or an SSE stream scoped to that request. Closing the stream cancels the request. Resumable SSE via Last-Event-ID was removed, so a broken stream means the client must reissue the request with a new ID.

The headers are where 2026-07-28 most changes operations. Every POST must carry MCP-Protocol-Version, and the standard request headers Mcp-Method (all requests) and Mcp-Name (the tool name or resource URI for tools/call, resources/read and prompts/get). If a header disagrees with the body, the server rejects the request with HeaderMismatch (-32020). A tool can also mark specific parameters for mirroring into headers with x-mcp-header. The point is that load balancers, gateways and WAFs can route, meter and authorise on headers without parsing JSON. The baseline security rules are unchanged: servers must validate the Origin header on all incoming connections and answer an invalid one with 403, and local servers should bind to 127.0.0.1 rather than 0.0.0.0.

The legacy HTTP+SSE transport from 2024-11-05, deprecated in practice since 2025-03-26, is now formally Deprecated under the lifecycle policy.

Authorisation in brief

Authorisation is OPTIONAL in MCP. HTTP implementations that support it should follow the specification’s OAuth 2.1 profile; stdio implementations should not, and should read credentials from the environment. In the HTTP profile, a protected MCP server is an OAuth resource server that publishes RFC 9728 protected resource metadata; the client discovers the authorisation server, uses PKCE and an RFC 8707 resource indicator, and in 2026-07-28 must validate the iss parameter against the recorded issuer before redeeming the code. Client credentials are now bound to the issuer that minted them, and Dynamic Client Registration is deprecated in favour of Client ID Metadata Documents.

The rule that matters most for architecture is in token handling: servers must validate that a token was issued for them, and “MUST NOT accept or transit any other tokens”. That forbids token passthrough to upstream APIs. Machine-to-machine and enterprise SSO flows live in two authorisation extensions, OAuth Client Credentials and Enterprise-Managed Authorization. The full flow, the attacks it stops and the ones it does not are covered step by step in our guide to MCP security and authentication.

Extensions: tasks, apps, skills and auth

Since 2026-07-28, extensions are a formal mechanism. Each has an identifier such as io.modelcontextprotocol/tasks, and both sides advertise support in an extensions map inside their capabilities: clients per request, servers in server/discover. If only one side supports an extension, the supporting side must revert to core behaviour or reject the request. Official extensions live in ext- repositories under the MCP GitHub organisation; experimental ones live in experimental-ext- repositories and need a sponsoring working or interest group. SDKs are not required to implement any extension for conformance.

ExtensionIdentifier or repoWhat it adds
Tasksio.modelcontextprotocol/tasksDurable handles for long-running work: CreateTaskResult with resultType: "task", polling with tasks/get, mid-flight input with tasks/update, cooperative tasks/cancel
MCP Appsio.modelcontextprotocol/uiInteractive HTML interfaces rendered inline in the conversation, in a host-controlled sandboxed iframe
Skills over MCPSkills extensionDiscovering workflow instructions and supporting files through MCP resources
OAuth Client Credentialsio.modelcontextprotocol/oauth-client-credentialsMachine-to-machine authentication
Enterprise-Managed AuthorizationAuth extensionCentralised access control through the enterprise identity provider

Tasks are the most consequential change for agent builders. In 2025-11-25 they were an experimental core feature with a blocking tasks/result; in 2026-07-28 they became an extension with polling, a new tasks/update for client input, no tasks/list, and the right for servers to return a task handle without per-request opt-in. Statuses are working, input_required, completed, failed and cancelled. AWS, quoted in the release post, says it contributed the extension. The skills extension connects MCP to the folder-based format described in our Claude Skills explainer: skills tell an agent how to do something, MCP tools give it the means.

SDKs and the tier system

The project publishes official SDKs in ten languages, classified by the SDK tiering system adopted in 2025-11-25. Tiers are earned against an automated conformance suite, not assigned by reputation.

TierConformanceNew protocol featuresIssue triageCritical bugsSDKs (as of October 2026)
Tier 1100%Before the new spec version ships2 business days7 daysTypeScript, Python, C#, Go, Rust, Ruby
Tier 280%Within 6 monthsWithin a monthTwo weeksJava
Tier 3No minimumNo commitmentNoneNoneSwift, PHP, Kotlin

The SDK list comes from the official SDK page. The tier list moves: the 2026-07-28 release post said all four Tier 1 SDKs (TypeScript, Python, Go and C#) supported the new revision on day one, with Rust in beta, while the SDK page now lists six Tier 1 SDKs including Rust and Ruby. An SDK can be relegated if conformance tests on its latest stable release fail continuously for four weeks, or if issues go unaddressed for two months. Experimental features and extensions such as Tasks and MCP Apps are not required for any tier, so check each SDK’s own extension support before relying on it.

The MCP Registry completes the ecosystem picture. It is a metadata repository, not a package host: entries in a server.json format point to npm, PyPI or Docker packages or to remote URLs, namespaces are verified through DNS, and it is meant to be consumed by downstream aggregators. It does not support private servers; organisations are told to run their own registry that implements the same OpenAPI interface.

Criticisms and limits of MCP

MCP has won the integration argument, but several criticisms are fair, and the specification itself concedes some of them.

The protocol cannot enforce its own security model

The specification lists consent, data privacy and tool safety as key principles, then states that “MCP itself cannot enforce these security principles at the protocol level”. Hosts are told to build consent flows, access controls and documentation. In practice that leaves a wide gap. Tool descriptions are text the model reads, so a malicious server can hide instructions in them; Invariant Labs showed in April 2025 that such a server can override instructions provided by other, trusted servers. Annotations that claim a tool is read-only are hints. Client tooling has had its own bugs: CVE-2025-6514 recorded an OS command injection in the mcp-remote package, rated 9.6 by its CNA, triggered by a crafted authorisation endpoint from an untrusted server.

None of this is a flaw in JSON-RPC framing; it is the consequence of a protocol whose purpose is to let models act on text from third parties. OAuth protects the transport, not the content. The defences are architectural: curated server lists, per-caller tool allow-lists, human approval for destructive tools, isolation for local servers and a log of every call.

Tool definitions inflate every prompt

Every tool a host exposes is a definition the model reads on every turn. The project’s own client best practices say that with dozens of servers and hundreds of tools, definitions “can consume the majority of the context window” before the model reads the user’s message. Anthropic’s engineering team reported an example where loading tools on demand through code execution cut usage from 150,000 tokens to 2,000 tokens, a 98.7% saving.

The protocol’s answer so far is host-side. The best-practices page recommends progressive discovery once definitions pass a threshold, for example 1% to 5% of the context window, via a search_tools meta-tool, plus programmatic tool calling to keep intermediate results out of context. The roadmap lists server-side progressive discovery as a deliverable, which is an admission that tools/list returning a whole catalogue does not scale on its own.

Statefulness has moved, not disappeared

Removing sessions makes MCP servers ordinary HTTP workloads that scale behind round-robin load balancers. It also moves the cost. State that once lived in the transport now lives in handles the model must carry between calls, or in requestState blobs the server must sign, expire and bind to a user. Resumable streams are gone, so a dropped connection loses the in-flight request. Every SDK had breaking changes; the release post says plainly there will be migration cost, especially for anyone who depended on session identifiers. And a legacy client against a modern-only server simply fails.

There is also a design tension between handles and the stated principle that servers should not see the conversation. A handle carried by the model is visible to the model, which the maintainers argue is a feature (the model can thread it between tools). It also means handle design is now a security decision, which is why the tools page spends a section on it.

Churn, and features that did not land

Five revisions in under two years, two of them breaking, is fast for an interoperability standard. Batching was added in March 2025 and removed in June 2025. Sampling, promoted in early material as the route to agentic servers, is deprecated after low adoption. Tasks were redesigned within one cycle. The roadmap itself says tools/call allowing both content and structuredContent “has confused server and client authors alike” and will be redesigned. The new lifecycle policy, with its twelve-month window and registry of deprecated features, is the right response; whether the pace slows is something to watch in the next release.

MCP gateways: where the spec stops and operations start

Most of the gaps above are filled by infrastructure in front of the servers rather than by the protocol. An MCP gateway aggregates many servers behind one endpoint, decides which tools each caller can list and call, holds upstream credentials so tokens never sit on laptops, and logs every call. The 2026-07-28 headers make this easier: Mcp-Method and Mcp-Name let a gateway authorise and meter by tool without parsing bodies, and cacheable list results let it serve stable catalogues.

Bifrost, Maxim AI’s open-source gateway written in Go, is one example. It acts as an MCP client to upstream servers and exposes the aggregated tools as an MCP server to clients such as Claude Desktop, alongside routing LLM traffic. Tool access is scoped per virtual key, and a key with no MCP configuration gets no MCP tools at all, deny by default. Bifrost does not execute tool calls automatically unless Agent Mode is enabled for named tools, and its Code Mode, which swaps hundreds of definitions for four meta-tools, reduces input token usage by up to 92.8% in its published benchmark at 508 tools. The MCP gateway explainer covers the mechanics and the trade-offs in depth.

The MCP roadmap: what to watch

The roadmap, updated on 22 August 2026, names five priority areas for the next six to twelve months, each with named Core Maintainers.

  1. Agentic messaging primitives. Server-initiated events, including webhooks, so clients learn when async work finishes without polling; a composition review so Tasks, subscriptions and progress share one lifecycle and cancellation model; Tasks moving towards the core.
  2. HTTP-native transport unification. Streamable HTTP as the single binding, spoken over stdio for local servers (the maintainers suggest HTTP/2 over stdio), and ETags for versioned results, including tool calls.
  3. Agent identity and enterprise security. DPoP, workload identity federation, ID-JAG and RFC 8693 token exchange, so agents can act with their own or delegated identity rather than pasted API keys.
  4. Improved primitives. A redesigned tool result shape, server-side progressive discovery, and a decision on whether content annotations should stay.
  5. SDK developer experience. An extension contract for SDKs and an experiment generating a candidate Tier 1 SDK from the specification and conformance suite.

If you are deciding how MCP fits next to agent-to-agent protocols, our comparison of A2A and MCP covers the boundary between tool access and agent delegation.

What to do with this

The 2026-07-28 revision rewards teams that treat MCP as infrastructure rather than a plug-in format. A short list, keyed to where you sit:

  • You maintain servers. Upgrade to a Tier 1 SDK release that speaks 2026-07-28 and stay dual-era until your clients have moved. Replace any reliance on Mcp-Session-Id with explicit handles, check authorisation on every handle, and sign any requestState that affects access. Return tools in a deterministic order and set ttlMs honestly.
  • You build clients or hosts. Implement the era probe, cache it per server, and plan for InputRequiredResult on every tool call. Stop adding sampling or roots support. Put progressive discovery behind a threshold before your tool count grows, and show users tool inputs before calls that change anything.
  • You run MCP for an organisation. Use the new headers. Route, rate-limit and log by Mcp-Method and Mcp-Name at a gateway, keep upstream credentials there, and allow-list tools per caller. Track the deprecated features registry: July 2027 is the earliest point at which sampling, roots, logging and Dynamic Client Registration can disappear.
  • You are choosing whether to adopt. The protocol has a neutral home, named maintainers, a conformance suite and a deprecation policy. That is enough stability to build on, provided you budget for one breaking migration a year and keep the security work on your side of the wire, where the spec says it belongs.

Sources

  1. Introducing the Model Context Protocol (25 November 2024) Anthropic
  2. Donating the Model Context Protocol and establishing the Agentic AI Foundation Anthropic
  3. Linux Foundation announces the formation of the Agentic AI Foundation Linux Foundation
  4. MCP specification 2026-07-28: Key Changes Model Context Protocol
  5. MCP specification 2026-07-28: Overview Model Context Protocol
  6. MCP specification 2026-07-28: Versioning and Compatibility Model Context Protocol
  7. MCP specification 2026-07-28: Multi Round-Trip Requests Model Context Protocol
  8. MCP specification 2026-07-28: Streamable HTTP Model Context Protocol
  9. MCP specification 2026-07-28: Tools Model Context Protocol
  10. MCP specification 2026-07-28: Deprecated Features Model Context Protocol
  11. MCP specification 2025-11-25: Key Changes Model Context Protocol
  12. MCP specification 2025-06-18: Key Changes Model Context Protocol
  13. MCP specification 2025-03-26: Key Changes Model Context Protocol
  14. MCP governance and stewardship Model Context Protocol
  15. MCP feature lifecycle and deprecation policy Model Context Protocol
  16. MCP SDK tiering system Model Context Protocol
  17. MCP roadmap Model Context Protocol
  18. MCP extensions overview Model Context Protocol
  19. The 2026-07-28 Specification (MCP blog, 28 July 2026) Model Context Protocol
  20. SEP-2575: Make MCP Stateless Model Context Protocol
  21. SEP-2577: Deprecate Roots, Sampling and Logging Model Context Protocol
  22. MCP client best practices Model Context Protocol
  23. Code execution with MCP Anthropic
  24. MCP Security Notification: Tool Poisoning Attacks Invariant Labs
  25. Bifrost as an MCP gateway Maxim AI

Frequently asked questions

What is the Model Context Protocol?

The Model Context Protocol (MCP) is an open standard, built on JSON-RPC 2.0, that lets AI applications connect to external tools and data through a common interface. A host application runs one client per server; servers expose tools, resources and prompts. Anthropic released it in November 2024 and it is now a project of the Linux Foundation's Agentic AI Foundation.

What is the latest MCP specification version?

As of October 2026 the current revision is 2026-07-28, released on 28 July 2026. It replaced 2025-11-25. Its headline change is a stateless core: no initialize handshake, no protocol-level sessions, and protocol version plus client capabilities sent in the _meta field of every request.

Is MCP stateless now?

At the protocol level, yes. Since 2026-07-28 a server must not rely on earlier requests to know the client's version, capabilities or identity, and the Mcp-Session-Id header is gone. Applications can still hold state, but they do it through explicit handles, such as a basket ID returned by one tool and passed into the next.

What are the MCP primitives?

Servers offer three: tools (functions the model can call), resources (data the application chooses to include) and prompts (templates the user picks). Clients can offer elicitation (asking the user for input), sampling (asking the client's model for a completion) and roots (filesystem boundaries). Sampling and roots are deprecated in 2026-07-28.

Who controls the Model Context Protocol?

MCP is a series of LF Projects, LLC, under the Agentic AI Foundation, a directed fund of the Linux Foundation co-founded by Anthropic, Block and OpenAI. Technical decisions sit with individual maintainers, not companies: two Lead Maintainers, a group of Core Maintainers who meet every two weeks, and maintainers of SDKs and working groups. Changes go through Specification Enhancement Proposals.

Do old MCP clients work with 2026-07-28 servers?

Only if the server is dual-era. A legacy client that opens with initialize fails against a server that supports only the new revision, because legacy clients have no way to fall forward. Servers and clients that implement both eras interoperate, and the versioning page includes a full compatibility matrix.

Is MCP secure?

The protocol defines OAuth 2.1-based authorisation for HTTP servers and lists consent, privacy and tool-safety principles, but it says outright that it cannot enforce them. Tool poisoning, prompt injection through tool results and over-broad tool access have to be handled by hosts, by review and allow-lists, and often by a gateway in front of the servers.

All tools →