11 KiB
MCP Specification — 2024-11-05 (Legacy)
Status: Legacy (first public release) Released: 2024-11-05 · repo tags
2024-11-05and2024-11-05-finalSpec site: https://modelcontextprotocol.io/specification/2024-11-05 Authoritative schema: schema/2024-11-05/schema.ts
This is the first public release of the Model Context Protocol specification (November 2024). It establishes the JSON-RPC 2.0 based, stateful, capability-negotiated protocol that all later revisions build upon: the Host/Client/Server architecture, the four server primitives (Resources, Prompts, Tools, Logging) and the two client features (Sampling, Roots), over stdio and the original HTTP+SSE transport. It is retained here as the historical baseline; later revisions (2025-03-26, 2025-06-18) added formal authorization, Streamable HTTP, structured tool output, and Elicitation — none of which exist in this version. The TypeScript schema (schema.ts) is the source of truth referenced by BCP 14 keywords (MUST / SHOULD / MAY).
At a glance
- Protocol style: stateful connections
- Capability negotiation: connection-level (during
initialize) - Transports: stdio; HTTP+SSE (the original two-endpoint SSE transport)
- Server features: Resources, Prompts, Tools, Logging
- Client features: Sampling, Roots
- Authorization: not part of the core spec — clients and servers MAY negotiate custom auth; HTTP transports carry transport-level security guidance only
Architecture
MCP follows a client-host-server architecture. A Host process creates and manages multiple Client instances; each Client has a 1:1 stateful session with exactly one Server. The Host enforces security policy, consent, and context aggregation; Servers are intentionally simple, composable, and isolated from one another — a server cannot read the whole conversation nor see into other servers. Servers receive only the contextual information they need, and the full conversation history stays with the Host.
Design principles: servers should be extremely easy to build, highly composable, mutually isolated, and incrementally extensible through capability negotiation. Servers may be local processes or remote services, and may request LLM access back through the client via Sampling.
Base Protocol
Messages
All messages MUST follow JSON-RPC 2.0. Three types are defined:
- Requests — MUST include a
string | numberidand amethod. Unlike base JSON-RPC, the id MUST NOT benull, and MUST NOT have been reused by the requestor within the same session. - Responses — MUST echo the request
id; exactly one ofresultorerrorMUST be set (never both); errorcodeMUST be an integer. - Notifications — MUST NOT include an
id.
Lifecycle
A strict three-phase lifecycle: Initialization → Operation → Shutdown.
- Initialization MUST be the first interaction. The client sends an
initializerequest carryingprotocolVersion(e.g."2024-11-05"), itscapabilities, andclientInfo. The server responds with its own negotiatedprotocolVersion,capabilities, andserverInfo. The client then MUST send annotifications/initializednotification before normal operations begin. - Before the server's
initializeresponse, the client SHOULD NOT send anything butping; before theinitializednotification, the server SHOULD NOT send anything butpingand logging. - Version negotiation: the client sends a supported version (SHOULD be its latest); if the server supports it, it responds with the same version, otherwise with another supported version (SHOULD be its latest). If the client cannot accept the server's version, it SHOULD disconnect.
- Capability negotiation: client (
roots,sampling,experimental) and server (prompts,resources,tools,logging,experimental) declare supported features. Sub-capabilities includelistChanged(prompts/resources/tools) andsubscribe(resources only). Both parties SHOULD respect negotiated capabilities for the whole session. - Shutdown has no dedicated message: stdio clients close the server's stdin, then escalate to
SIGTERM/SIGKILL; HTTP shutdown is signalled by closing the connection(s).
Transports
Two standard transports are defined; clients SHOULD support stdio whenever possible.
- stdio — the client launches the server as a subprocess; messages are newline-delimited on stdin/stdout and MUST NOT contain embedded newlines; the server MUST NOT write non-MCP data to stdout;
stderrMAY carry UTF-8 logs. - HTTP with SSE — the server exposes two endpoints: an SSE endpoint (client connects, receives an
endpointevent with a POST URI) and an HTTP POST endpoint to which the client sends all subsequent messages; server-to-client messages arrive as SSEmessageevents. Security: servers MUST validate theOriginheader, SHOULD bind to localhost only, and SHOULD require authentication. - Custom transports MAY be implemented provided they preserve the JSON-RPC format and lifecycle.
Authorization
Authentication and authorization were not part of the core specification in this revision (the /basic/authorization page does not exist for 2024-11-05). The base-protocol overview states auth "is not currently part of the core MCP specification" and that clients and servers MAY negotiate their own custom strategies. The only auth-related guidance is the transport-level security requirements above. (The OAuth 2.1 framework was introduced in a later revision, not this one.)
Versioning
There is no dedicated versioning page in this revision; version behavior is specified within the lifecycle handshake (see above). The negotiated version is a literal string such as "2024-11-05".
Server Features
Servers advertise any implemented features via capabilities; each listed below MUST be declared before use.
Resources
Application-driven contextual data, each identified by a URI. Capability resources with optional subscribe and listChanged. Methods: resources/list (paginated), resources/read (by URI), resources/templates/list (RFC 6570 URI templates, paginated), plus resources/subscribe / resources/unsubscribe when subscribe is supported. List changes emit notifications/resources/list_changed; subscribed resource updates emit notifications/resources/updated.
Prompts
User-controlled templated messages/workflows (typically surfaced as slash commands). Capability prompts with optional listChanged. Methods: prompts/list (paginated) and prompts/get (with arguments). A returned PromptMessage carries a role ("user" / "assistant") and a content item (text or image). List changes emit notifications/prompts/list_changed. Arguments may be auto-completed via the completion utility.
Tools
Model-controlled executable functions. Capability tools with optional listChanged. Methods: tools/list (paginated) and tools/call. A tool definition carries name, description, and an inputSchema (JSON Schema). A call response returns a content array of typed items (text and image content in this revision) plus a boolean isError flag. There is no structured output — results are unstructured content arrays. List changes emit notifications/tools/list_changed. Hosts SHOULD keep a human in the loop and confirm invocations.
Utilities / Logging
Capability logging (declared as {}). Servers emit notifications/message with a syslog (RFC 5424) severity level (debug, info, notice, warning, error, critical, alert, emergency), an optional logger name, and arbitrary JSON-serializable data. Clients MAY set the minimum level via logging/setLevel. Additional cross-cutting utilities referenced by the spec include pagination (server/utilities/pagination), argument completion (server/utilities/completion), and ping (basic/utilities/ping).
Client Features
Sampling
Server-initiated LLM requests, enabling nested/agentic behaviors. Capability sampling (declared as {}). The server sends sampling/createMessage with messages, optional modelPreferences (sub-string hints plus normalized costPriority / speedPriority / intelligencePriority in 0–1), optional systemPrompt, and maxTokens. The client (with a human in the loop) approves/edits the prompt and returns role, content, model, and stopReason.
Roots
Filesystem/URI boundaries the server may operate within. Capability roots with optional listChanged. The server calls roots/list and receives Root entries; each uri MUST be a file:// URI in this revision (plus an optional display name). Clients supporting listChanged MUST emit notifications/roots/list_changed when the set changes. Clients MUST validate URIs against path traversal and SHOULD obtain user consent before exposing roots.
Revision history
- 2024-11-05 — first public release of the specification (repo tag
2024-11-05). - 2024-11-05-final — final revision of the 2024-11-05 spec line (repo tag
2024-11-05-final). - 2024-10-07 — pre-public revision tag that existed before the public release.
Skald relevance
Skald's MCP client implementation lives in crates/mcp-client/: McpServer (stdio) and McpHttpServer (HTTP+SSE) both implement the McpServerClient trait defined in crates/mcp-client/src/lib.rs. The McpManager orchestrator in src/core/mcp/mod.rs registers and dispatches MCP tools to the agent tool-calling loop. This 2024-11-05 revision is the historical baseline the earliest MCP support targeted (stdio + HTTP+SSE, Resources/Prompts/Tools/Logging, Sampling/Roots); modern Skald also speaks newer revisions and therefore supports capabilities (e.g. Streamable HTTP, structured tool output) that did not exist in this legacy spec.