# MCP Specification — 2025-06-18 (Stable)

> **Status:** Stable
> **Released:** 2025-06-18
> **Spec site:** https://modelcontextprotocol.io/specification/2025-06-18
> **Authoritative schema:** [schema/2025-06-18/schema.ts](https://github.com/modelcontextprotocol/specification/blob/main/schema/2025-06-18/schema.ts)

Revision 2025-06-18 is the "modern stable" baseline of the Model Context Protocol. It supersedes the 2024-11-05 legacy revision by introducing the **Streamable HTTP** transport (single-endpoint, replacing the two-endpoint HTTP+SSE design), the **Elicitation** client feature (`elicitation/create`, server-initiated structured input from the user), and **structured tool output** (typed `structuredContent` validated against an optional `outputSchema`). It also tightens the authorization framework with OAuth 2.1 Resource Indicators (RFC 8707) and OAuth Protected Resource Metadata (RFC 9728), and removes JSON-RPC batching. The authoritative source of truth is the TypeScript schema; the spec text is normative where it restates requirements using BCP 14 keywords (MUST/SHOULD/MAY).

## At a glance
- **Protocol style:** stateful connections
- **Capability negotiation:** connection-level (`initialize`)
- **Transports:** stdio; **Streamable HTTP** (replaces HTTP+SSE)
- **Server features:** Resources, Prompts, Tools, Logging
- **Client features:** Sampling, Roots, **Elicitation**
- **Authorization:** OAuth 2.1 + Resource Indicators (RFC 8707)

## Architecture
Client-host-server topology built on JSON-RPC. A **host** creates and manages multiple **client** instances; each client holds a 1:1 **stateful session** with one **server** and enforces isolation between servers (a server cannot see the full conversation or other servers). Servers expose primitives (resources/prompts/tools) and MAY request client features (sampling/roots/elicitation). Design principles: servers must be easy to build, highly composable, mutually isolated, and progressively extensible via capability negotiation at `initialize`.

## Base Protocol

### Messages
All messages **MUST** be [JSON-RPC 2.0](https://www.jsonrpc.org/specification), UTF-8 encoded. Three kinds: **Requests** (with a string/integer `id`; the id **MUST NOT** be `null` and **MUST NOT** be reused within a session), **Responses** (`result` XOR `error`; both **MUST NOT** be set; error codes are integers), and **Notifications** (no `id`; receiver **MUST NOT** reply). The reserved `_meta` property carries extension metadata; key names with a `mcp`/`modelcontextprotocol` prefix are reserved. **JSON-RPC batching is disallowed** (each message is a standalone request/notification/response).

### Lifecycle
Three phases. (1) **Initialization** — client sends `initialize` with its supported `protocolVersion` (SHOULD be its latest), `capabilities`, and `clientInfo`; server responds with the negotiated `protocolVersion`, its `capabilities`, `serverInfo`, and optional `instructions`; client then sends `notifications/initialized`. The server SHOULD NOT send non-ping/logging requests before `initialized`. (2) **Operation** — both parties **MUST** respect the negotiated version and only use negotiated capabilities. (3) **Shutdown** — no dedicated message; the transport signals termination (stdio: close stdin → SIGTERM → SIGKILL; HTTP: `DELETE` the session or close streams). If versions mismatch the client **SHOULD** disconnect.

### Transports
Two standard transports. **stdio** — the client launches the server as a subprocess; newline-delimited JSON-RPC over stdin/stdout; messages **MUST NOT** contain embedded newlines; stderr is for logs only. **Streamable HTTP** — the server exposes a single **MCP endpoint** supporting `POST` and optionally `GET` (e.g. `https://example.com/mcp`), replacing the 2024-11-05 HTTP+SSE two-endpoint design:
- Every client JSON-RPC message is a fresh `POST`; the request **MUST** send `Accept: application/json, text/event-stream`. For a *request* the server responds either with `application/json` or by opening an SSE `text/event-stream`; for a *notification/response* the server returns `202 Accepted`.
- Server→client traffic (notifications/requests) flows over an SSE stream that the client opens via `GET` (server MAY decline with `405`). The server **MUST NOT** broadcast the same message across multiple concurrent streams.
- **Sessions:** the server MAY assign an `Mcp-Session-Id` (cryptographically secure, visible ASCII 0x21–0x7E) on the initialize response; the client **MUST** echo it on all subsequent requests; a `404` forces re-initialization; a `DELETE` terminates the session.
- **Resumability:** servers MAY attach SSE event `id`s; the client resumes via the `Last-Event-ID` header on `GET` (per-stream cursor; no cross-stream replay).
- Clients using HTTP **MUST** send `MCP-Protocol-Version: <version>` on all post-initialize requests. Servers **MUST** validate the `Origin` header (DNS-rebinding defence) and **SHOULD** bind localhost when local.

### Authorization
Optional, for HTTP transports only (stdio retrieves credentials from the environment). Built on OAuth 2.1 ([draft-ietf-oauth-v2-1-13](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13)) with PKCE. **Resource Server classification:** the MCP server is an OAuth 2.1 *resource server*; the MCP client is the OAuth 2.1 *client*; tokens are issued by a separate authorization server. Discovery: MCP servers **MUST** implement OAuth 2.0 Protected Resource Metadata ([RFC 9728](https://www.rfc-editor.org/rfc/rfc9728.html)) and signal the metadata URL via `WWW-Authenticate` on `401`; clients **MUST** use Authorization Server Metadata ([RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414)) and **SHOULD** use Dynamic Client Registration ([RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591)). **Resource Indicators (RFC 8707):** the client **MUST** send the `resource` parameter (identifying the target MCP server) in both the authorization and token requests. Token refresh is supported; scopes are server-defined.

### Versioning
Protocol versions are date strings (e.g. `2025-06-18`). Version negotiation happens only in `initialize` (see Lifecycle): the client sends the version it supports; the server returns it if supported, otherwise its latest other version; the client disconnects on an unsupported response. A `CHANGELOG.md` records revisions; SDKs adopt versions at their own pace and rely on negotiation for backwards/forwards compatibility.

## Server Features
Servers advertise implemented primitives in their capabilities. Control model: **Prompts** are user-controlled, **Resources** application-controlled, **Tools** model-controlled.

### Resources
Application-driven context exposed via URIs. Capability `resources` with optional `subscribe` and `listChanged`. Methods: `resources/list`, `resources/read`, `resources/templates/list` (RFC 6570 URI templates), plus `resources/subscribe`/`unsubscribe` and `notifications/resources/*`. **Resource links** — tools and resources can reference related resources; a `resource` content item (with `uri`, optional `mimeType`, and inline `text`/`blob`) embeds a resource, and tool results can emit resource links so clients can pull further context. All content items carry optional `annotations` (`audience`, `priority`, `lastModified`).

### Prompts
User-controlled templated messages. Capability `prompts` (with optional `listChanged`). Methods: `prompts/list`, `prompts/get` (takes `name` + `arguments`). A `PromptMessage` has `role` (`user`/`assistant`) and typed `content` (text/image/audio/embedded-resource). Arguments can be autocompleted via the completion utility.

### Tools
Model-controlled functions. Capability `tools` (with optional `listChanged`). Methods: `tools/list`, `tools/call`. A tool definition carries `name`, optional `title`/`description`, `inputSchema` (JSON Schema), and optional `outputSchema` (JSON Schema) and `annotations` (treated as untrusted). **Structured output:** a `tools/call` result returns a `content[]` array (text/image/audio/resource items) **plus an optional `structuredContent`** JSON object. When `outputSchema` is declared, the server **MUST** return structured results conforming to it and clients **SHOULD** validate; for backwards compatibility a tool returning `structuredContent` **SHOULD** also emit the serialized JSON in a `TextContent` block. Execution failures use `isError: true`; protocol errors use standard JSON-RPC codes.

### Utilities / Logging
Cross-cutting utilities: `ping` (liveness), `notifications/progress` (progress tracking), `notifications/cancelled` (cancellation via request id), `notifications/initialized`, and `completion/complete` (argument autocompletion). **Logging:** servers with the `logging` capability emit `notifications/message` with a level (`debug`..`emergency`) and structured data; clients set level via `logging/setLevel`.

## Client Features

### Sampling
Server-initiated LLM generation. Client capability `sampling`. Method `sampling/createMessage` — the server sends `messages`, optional `systemPrompt`, `maxTokens`, and `modelPreferences` (`hints` + normalized `intelligencePriority`/`speedPriority`/`costPriority` in 0–1); the client performs human-in-the-loop review, selects the model, and returns `role`/`content`/`model`/`stopReason`. Human approval is expected; the server never supplies API keys.

### Roots
Server-initiated inquiry into client filesystem boundaries. Client capability `roots` (with optional `listChanged`). Method `roots/list` returns `file://` URIs the server may operate within; `notifications/roots/list_changed` signals updates. Clients **MUST** validate URIs (path traversal) and obtain user consent.

### Elicitation
Server-initiated structured input from the end user. Client capability `elicitation`. Method `elicitation/create` — the server sends a human-readable `message` plus a `requestedSchema`, a *restricted* JSON Schema (flat object of primitive properties only: string/number/boolean/enums, no nesting). The client presents a form and responds with `action: "accept"` (+ `content` object), `"decline"`, or `"cancel"`. **Privacy/safety:** servers **MUST NOT** use elicitation to request sensitive information (passwords, API keys, credentials); clients **SHOULD** make the requesting server clear and provide explicit decline/cancel. Because responses may be sensitive, they must not be echoed into logs or persisted beyond need.

## Changes vs 2024-11-05
- **Streamable HTTP** replaces the HTTP+SSE two-endpoint transport (single `POST`/`GET` MCP endpoint, `Mcp-Session-Id` header, SSE resumability via `Last-Event-ID`, `MCP-Protocol-Version` header).
- **Elicitation** client feature added (`elicitation/create` with a restricted JSON Schema form; accept/decline/cancel).
- **Structured tool output** — tools may return `structuredContent` (typed JSON) plus an optional `outputSchema`; structured results SHOULD also serialize to a `TextContent` block.
- **Resource links** — tools/resources can reference related resources (embedded `resource` content items, annotations).
- **JSON-RPC batching removed** (was permitted in 2024-11-05; each message is now standalone).
- **Authorization strengthened:** OAuth 2.1 Resource Indicators (RFC 8707) with the `resource` parameter; OAuth 2.0 Protected Resource Metadata (RFC 9728) + Resource Server classification; Authorization Server Metadata (RFC 8414); Dynamic Client Registration (RFC 7591) recommended.
- **Protocol remains stateful** with connection-level capability negotiation; client features are now Sampling, Roots, and Elicitation.

## Skald relevance
Skald's MCP stack implements this revision. `crates/mcp-client/` provides the transport/runtime primitives — `McpServerClient` trait (`src/lib.rs:67`), stdio server, and `McpHttpServer` (`http_server.rs`) — while `src/core/mcp/mod.rs` (`McpManager`) registers and drives connected servers, and `src/core/elicitation/mod.rs` bridges the new `elicitation/create` server→client request through `ElicitationManager` (surfaced in the Inbox) with secrets never logged or persisted. 2025-06-18 is therefore the baseline that introduced the Elicitation feature Skald implements end-to-end.

## References
- [Specification overview](https://modelcontextprotocol.io/specification/2025-06-18)
- [Architecture](https://modelcontextprotocol.io/specification/2025-06-18/architecture)
- [Base protocol](https://modelcontextprotocol.io/specification/2025-06-18/basic)
- [Server features](https://modelcontextprotocol.io/specification/2025-06-18/server)
- [Client features](https://modelcontextprotocol.io/specification/2025-06-18/client)
- [Schema (schema.ts)](https://github.com/modelcontextprotocol/specification/blob/main/schema/2025-06-18/schema.ts)
- [Release 2025-06-18](https://github.com/modelcontextprotocol/modelcontextprotocol/releases/tag/2025-06-18)
