The Model Context Protocol specification is the official, dated document that defines how MCP hosts, clients and servers communicate: the JSON-RPC 2.0 message formats, the stdio and Streamable HTTP transports, protocol version negotiation, an OAuth 2.1 authorization profile, and the tools, resources and prompts a server can expose. A TypeScript schema in the project repository is the source of truth for every message.
The latest revision of the Model Context Protocol specification, 2026-07-28, made the protocol stateless by removing the initialize handshake and protocol sessions, so much of what tutorials and AI answers say about the MCP spec now describes the legacy era. The MCP overview explains the protocol itself; this page covers what the specification requires. Bifrost, the open-source AI gateway, sits between MCP clients and servers that implement different revisions.
What does the MCP specification define?
The MCP specification defines the wire protocol between MCP clients and MCP servers: the message types, how each request declares its protocol version, the transports that carry messages, an authorization profile for HTTP, and the optional features each side can offer. It does not define SDK interfaces, model behavior, or how a host presents tools to users.
The 2026-07-28 specification splits the protocol into components. Three are mandatory for every implementation; the rest are adopted as needed:
| Component | What it covers | Requirement |
|---|---|---|
| Base protocol | JSON-RPC messages, _meta fields, error codes | MUST |
| Versioning | Per-request version, server/discover, extensions | MUST |
| Message patterns | Request and response, multi round-trip, subscribe and notify | MUST |
| Transports | stdio, Streamable HTTP, or custom | One per connection |
| Authorization | OAuth 2.1 profile for HTTP | SHOULD on HTTP |
| Server features | Tools, resources, prompts | Optional |
| Client features | Elicitation (roots and sampling deprecated) | Optional |
| Utilities | Progress, cancellation, completion | Optional |
Requirement words such as MUST and MAY carry their BCP 14 meanings (RFC 2119 and RFC 8174) only in capitals. The security principles, such as user consent before any tool call, are stated but cannot be enforced by the protocol; hosts must enforce them.
Hosts, clients and servers in the MCP specification
The MCP specification describes a client-host-server architecture. The host is the AI application, such as Claude Desktop, Claude Code or Cursor, and it creates one MCP client per server. Each client keeps a one-to-one link with a single MCP server, and no server sees the full conversation.
Servers offer three features, and the specification assigns each a different controller:
- Tools are model-controlled functions, such as
create_issue. - Resources are application-controlled data addressed by URI.
- Prompts are user-controlled templates, such as a slash command.
Clients offer one active feature, elicitation, which lets a server ask the user for missing input. Revision 2026-07-28 deprecated roots, sampling and logging, and servers no longer send requests to clients: a server that needs input returns a result with resultType: "input_required", and the client retries the original request with the answers.
How the MCP specification uses JSON-RPC 2.0 messages
Every MCP message is a UTF-8 encoded JSON-RPC 2.0 object of one of three types: a request with an id and a method, a response that returns either result or error under the same id, or a notification with no id that receives no reply. MCP tightens JSON-RPC in two places: request IDs must not be null, and every result carries a resultType.

Because there is no handshake, each request carries its protocol version and client capabilities in reserved _meta keys, which every server must read:
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "search_issues",
"arguments": {"query": "label:bug status:open"},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {"elicitation": {}},
"io.modelcontextprotocol/clientInfo": {"name": "example-host", "version": "1.4.0"}
}
}
}
A request missing a required _meta field is malformed and returns -32602 (Invalid params). The specification partitions the JSON-RPC server-error range: -32000 to -32019 is legacy and implementation-defined, and -32020 to -32099 is reserved for codes the specification defines:
| Code | Name | Returned when |
|---|---|---|
-32602 | Invalid params | Missing _meta field, or resource not found (replaced -32002) |
-32020 | HeaderMismatch | An HTTP header disagrees with the body |
-32021 | MissingRequiredClientCapability | The client did not declare a needed capability |
-32022 | UnsupportedProtocolVersion | Version not supported; data.supported lists alternatives |
A failed tool is not a protocol error: the server returns a normal result with isError: true, so the model can read the message and try again.
MCP transports in the specification
The MCP specification defines two standard transports and allows custom ones. stdio carries newline-delimited JSON-RPC over the standard input and output of a subprocess the client launches. Streamable HTTP sends each message as an HTTP POST to one MCP endpoint, with replies as a JSON object or a request-scoped server-sent events stream. Message semantics are identical on both.
| Transport | How messages move | Authentication | Status |
|---|---|---|---|
| stdio | One JSON-RPC message per line, no embedded newlines; stderr for logs | Credentials come from the environment, not the HTTP auth profile | Active |
| Streamable HTTP | One POST per message with MCP-Protocol-Version, Mcp-Method and Mcp-Name headers; Origin validated | OAuth 2.1 profile with protected resource metadata (RFC 9728) | Active |
| HTTP+SSE | A separate GET stream for server-to-client messages | Varies | Deprecated since 2025-03-26 |
| Custom | Any bidirectional channel; byte streams should reuse stdio framing | Transport's own best practices | Allowed |
The HTTP headers mirror body fields so load balancers and gateways can route without parsing JSON; a header that disagrees with the body returns 400 Bad Request. MCP endpoint covers the single URL a Streamable HTTP server serves.
MCP spec versions and what each revision changed
MCP spec versions are date strings in YYYY-MM-DD form that mark the last backwards-incompatible change; compatible additions ship without a new version. Each revision is labeled Draft, Current or Final. The current revision is 2026-07-28, one of five shipped since November 2024.
| Revision | Status | Headline changes |
|---|---|---|
| 2024-11-05 | Final | First public release: JSON-RPC base protocol, stdio and HTTP+SSE, tools, resources, prompts, sampling and roots |
| 2025-03-26 | Final | OAuth 2.1 authorization framework; Streamable HTTP replaces HTTP+SSE; JSON-RPC batching; tool annotations |
| 2025-06-18 | Final | Batching removed; structured tool output; elicitation; servers as OAuth resource servers; MCP-Protocol-Version header |
| 2025-11-25 | Final | Experimental tasks; URL-mode elicitation; Client ID Metadata Documents; JSON Schema 2020-12 by default |
| 2026-07-28 | Current | Stateless, no initialize or sessions; server/discover; multi round-trip requests; tasks moved to an extension; roots, sampling and logging deprecated |
The 2026-07-28 revision lists every breaking change, and the MCP overview summarizes them for server builders. A deprecated feature stays in the specification for at least twelve months before removal.
How MCP version negotiation and compatibility work
Under the 2026-07-28 MCP specification there is no negotiation handshake. Every request names its protocol version in _meta, and on HTTP also in the MCP-Protocol-Version header. A server that does not support that version returns UnsupportedProtocolVersionError (code -32022) listing the versions it supports, and the client retries with one of them.
Servers must implement server/discover, which returns supported versions, capabilities and identity in one call; clients may call it first or send requests directly. Versioning names three eras: modern (2026-07-28 and later), legacy (2025-11-25 and earlier, with the initialize handshake) and dual-era (both). The outcomes that matter in practice:
| Client | Server | Outcome |
|---|---|---|
| Modern | Modern | Works; a version mismatch returns -32022 and the client retries |
| Modern | Legacy | Fails; a server/discover probe makes the failure deterministic on stdio |
| Dual-era | Modern | Works; the client stays modern |
| Dual-era | Legacy | Works; the client falls back to initialize |
| Legacy | Modern | Fails; HTTP returns 400 Bad Request, with no fall-forward |
| Legacy | Dual-era | Works under the negotiated legacy revision |
Where the Model Context Protocol specification lives and how it changes
The Model Context Protocol specification is versioned by date and generated from a TypeScript schema (schema.ts) in the project's GitHub repository, with a JSON Schema generated from it for tooling. Changes go through Specification Enhancement Proposals (SEPs), and MCP is a Linux Foundation project.
- Change process. A SEP is a design document for a protocol or process change, reviewed as a pull request; the changelog cites a SEP for each change.
- Governance. Lead Maintainers, Core Maintainers and Maintainers form the MCP Steering Group, and seats belong to individuals, not companies. Specifications are licensed under Apache 2.0.
- Adjacent projects. The MCP Registry (in preview) publishes
server.jsonmetadata for public servers, and the MCP Inspector tests servers across protocol eras. Neither is part of the specification.
MCP: the protocol, the plumbing and the gateway follows a request on the wire and through a gateway.
The MCP specification with Bifrost
Bifrost, the open-source AI gateway built by Maxim AI, implements the Model Context Protocol specification on both sides of a connection, which is how it runs as an MCP gateway. As an MCP client, Bifrost connects to MCP servers over STDIO, HTTP or SSE, or generates a server from an OpenAPI document (beta). As an MCP server, Bifrost exposes every connected tool at one /mcp endpoint: POST carries JSON-RPC calls such as tools/list and tools/call, and GET opens an SSE stream.

The /mcp endpoint follows the handshake-based revisions: clients open with initialize, and the documented probe uses protocol version 2025-06-18. Toward upstream servers, Bifrost runs health checks that combine a ping (when the server supports one) with tools/list, each attempt bounded at 5 seconds, and reconnects automatically when a session expires, an SSE stream drops or a STDIO process exits.
Credentials follow the specification's split by transport. STDIO servers inherit their environment, and HTTP and SSE servers use one of Bifrost's six authentication types, including per-user OAuth and token exchange. Tool filtering makes tools/list return only the tools a virtual key allows and checks every tools/call against the same list.
For large tool sets, Code Mode cut input tokens by 92.8% across 508 tools on 16 servers at the same pass rate.
The same gateway routes LLM traffic to 25+ providers and 10,000+ models with 11 microseconds of overhead at 5,000 RPS. To connect your first MCP server, start with the gateway quickstart.
Run MCP clients and servers through one gateway
Connect servers over STDIO, HTTP or SSE, filter tools per virtual key, and log every call.
FAQ
What is Model Context Protocol in simple terms?
In simple terms, the Model Context Protocol is a shared language that lets an AI assistant ask another program what it can do, then ask it to do one of those things. That program, an MCP server, wraps something like GitHub or a database, and any MCP app, such as Claude Desktop or Cursor, can use it without custom code.
What is the MCP server architecture and how does it work?
An MCP host, such as Claude Desktop, creates one MCP client for each MCP server it uses. The client sends JSON-RPC 2.0 requests over stdio or Streamable HTTP; the server lists its tools, resources and prompts, runs calls against the system it wraps, and returns results. Under the 2026-07-28 revision, no session is kept between requests.
What is the latest MCP specification version?
The latest MCP specification version is 2026-07-28, labeled Current; 2025-11-25 is now Final. The biggest change is statelessness: the initialize handshake and the Mcp-Session-Id header are gone, every request carries its protocol version in _meta, and servers must implement server/discover. Dual-era servers can still serve 2025-11-25 clients.
Where is the MCP specification on GitHub?
The Model Context Protocol specification lives in the modelcontextprotocol organization on GitHub, with one TypeScript schema file per revision and a generated JSON Schema beside it. Changes are proposed as Specification Enhancement Proposals (SEPs).


