Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mcp-staging.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

The Model Context Protocol (MCP) is a stateless protocol: all the information needed to process a request is contained in the request itself. A server processes each request independently; no state should be inferred from previous requests, even those on the same connection or stream. In particular, an open connection or STDIO process is not a conversation or session: clients may interleave unrelated requests on the same transport, and a server MUST NOT treat connection or process identity as a proxy for conversation or session continuity. Specifically:
  • Servers MUST NOT rely on prior requests over the same connection to establish context (e.g., capabilities, protocol version, client identity). Every request supplies this metadata in its _meta field.
  • Servers MUST NOT require that a client reuse the same connection to perform related operations.
  • State that needs to span multiple requests (e.g., long-running tasks, application-level handles) MUST be referenced by an explicit identifier the client passes on each request.
Long-lived requests like subscriptions/listen remain request/response — the response is just an open stream of notifications. Their state is scoped to the request itself, not to the connection underneath.
For a walkthrough of how the per-request model maps to SDK code, see the Architecture guide.

Protocol Version Negotiation

Every request declares the protocol version it is using in its _meta field. On HTTP, this is also carried in the MCP-Protocol-Version header. If the server does not implement the requested version (whether the version is unknown to the server, or is a known version the server has chosen not to support), it MUST respond with an UnsupportedProtocolVersionError listing the versions it does support:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "Unsupported protocol version",
    "data": {
      "supported": ["DRAFT-2026-v1", "2025-11-25"],
      "requested": "1900-01-01"
    }
  }
}
The client SHOULD select a mutually supported version from the supported list and retry the request, or surface an error to the user if no compatible version exists. Servers MUST implement server/discover. Clients MAY call it before sending any other requests to learn the server’s supported versions up front, but are not required to — a client is free to invoke any RPC inline and handle UnsupportedProtocolVersionError if its preferred version is not supported.

Backward Compatibility with Initialization-Based Versions

A server that wishes to support both legacy clients (which expect an initialize handshake) and modern clients (which use per-request metadata) MAY implement both behaviors. A client that needs to interoperate with both kinds of servers can detect which is present:
  • HTTP. Try a modern request directly. If the server returns 400 Bad Request (or any other version error indicating the server does not implement the modern protocol), fall back to initialize and continue with the legacy version for subsequent requests.
  • STDIO. Because there is no per-request status code to drive fallback, a client that supports both eras SHOULD probe with server/discover first, setting its preferred modern version in _meta. If the server returns Method not found (-32601), fall back to the legacy initialize handshake. If the server returns UnsupportedProtocolVersionError, the server speaks a version of MCP without initialize — use one of its advertised supportedVersions instead of falling back to initialize.
A client that only supports modern (per-request-metadata) versions does not need to probe — it simply sends its preferred version and handles UnsupportedProtocolVersionError normally.

Extension Negotiation

Clients and servers can negotiate support for optional extensions beyond the core protocol. Extensions are advertised in the extensions field of capabilities, which is a map of extension identifiers to per-extension settings objects. Example client capabilities with extensions:
{
  "capabilities": {
    "roots": {},
    "extensions": {
      "io.modelcontextprotocol/apps": {
        "mimeTypes": ["text/html;profile=mcp-app"]
      }
    }
  }
}
Example server capabilities with extensions:
{
  "capabilities": {
    "tools": {},
    "extensions": {
      "io.modelcontextprotocol/apps": {}
    }
  }
}
Each extension specifies the schema of its settings object; an empty object indicates support with no additional settings. If one party supports an extension but the other does not, the supporting party MUST either revert to core protocol behavior or reject the request with an appropriate error. Extensions SHOULD document their expected fallback behavior.