# MCP Specification — 2025-11-25 (Latest Stable)

> **Status:** Latest Stable (current `Latest` release)
> **Released:** 2025-11-25 · repo tags `2025-11-25` (stable), `2025-11-25-RC` (pre-release)
> **Spec site:** https://modelcontextprotocol.io/specification/2025-11-25
> **Authoritative schema:** [schema/2025-11-25/schema.ts](https://github.com/modelcontextprotocol/specification/blob/main/schema/2025-11-25/schema.ts)

This is the current stable revision of the Model Context Protocol. It keeps the stateful, JSON-RPC 2.0 core of 2025-06-18 and refines authorization (adding OpenID Connect Discovery and OAuth Client ID metadata documents), introduces optional **icons** metadata across server primitives, **URL-mode elicitation**, **incremental scope consent** (step-up authorization), **tool-calling in sampling**, and ships an **experimental Tasks** mechanism for long-running, pollable operations.

## At a glance
- **Protocol style:** stateful connections
- **Capability negotiation:** connection-level (`initialize`)
- **Transports:** stdio; Streamable HTTP
- **Server features:** Resources, Prompts, Tools, Logging
- **Client features:** Sampling, Roots, Elicitation
- **Authorization:** OAuth 2.1 + Resource Indicators (RFC 8707) + **OIDC Discovery** + Protected Resource Metadata (RFC 9728) + Client ID metadata documents + incremental scope consent
- **Experimental:** Tasks

## Architecture

Client-host-server topology built on JSON-RPC, focused on context exchange and sampling coordination.

- **Host:** creates/manages multiple clients, enforces consent and security policy, aggregates context. Each client has a 1:1 relationship with one server and maintains isolation between servers.
- **Client:** establishes one stateful session per server, negotiates capabilities, routes messages, owns subscriptions/notifications.
- **Server:** exposes resources/tools/prompts, may request sampling/roots/elicitation through client interfaces; can be a local process or remote service.

Design principles: servers should be easy to build, highly composable, must **not** read the whole conversation or "see into" other servers, and features can be added progressively. **Capability negotiation** is the contract: server features (resources, prompts, tools, logging) and client features (sampling, roots, elicitation, tasks) must be advertised in `capabilities` to be usable.

## Base Protocol

### Messages

All messages **MUST** be [JSON-RPC 2.0](https://www.jsonrpc.org/specification), UTF-8 encoded. Three kinds:

- **Requests** — `id` (string|integer) **REQUIRED**; **MUST NOT** be `null`; the requestor **MUST NOT** reuse an `id` within a session.
- **Responses** — `result` (any object) on success; `error` (`code` integer + `message`) on failure. The `id` **MUST** match the originating request (except when the request `id` was unreadable due to malformation).
- **Notifications** — one-way; **MUST NOT** carry an `id`; the receiver **MUST NOT** respond.

The `_meta` field is reserved for protocol-level and extension metadata; certain keys are reserved by MCP and implementers **MUST NOT** assume meaning for reserved keys. **JSON Schema dialect:** schemas without an explicit `$schema` default to [JSON Schema 2020-12](https://json-schema.org/draft/2020-12/schema); implementations **MUST** support at least 2020-12 and **SHOULD** document any additional dialects. The `icons` property is a standardized optional visual-identifier array (`src`, `mimeType`, `sizes`) usable on implementations/resources/tools/prompts; icon payloads **MAY** contain executable content (e.g. scripted SVG) so consumers **MUST** fetch them without credentials and treat them as untrusted.

### Lifecycle

Three phases: **Initialization → Operation → Shutdown**.

1. Client sends `initialize` with its `protocolVersion` (this **SHOULD** be the latest the client supports), client `capabilities`, and `clientInfo`.
2. Server responds with the negotiated `protocolVersion`, its `capabilities`, `serverInfo` (`name`/`title`/`version`/`description`/`icons`/`websiteUrl`), and optional `instructions`.
3. Client sends an `notifications/initialized` notification; only then does normal operation begin. Before `initialize` is answered the client **SHOULD NOT** send non-`ping` requests; before `initialized` the server **SHOULD NOT** send non-`ping`/non-logging requests.

**Version negotiation:** if the server supports the requested version it echoes it; otherwise it returns the latest version *it* supports. If the client cannot accept that version it **SHOULD** disconnect. Over HTTP the client **MUST** send `MCP-Protocol-Version: <version>` on every subsequent request.

### Transports

- **stdio** — client launches the server as a subprocess; newline-delimited JSON-RPC on stdin/stdout; messages **MUST NOT** contain embedded newlines; stdout is reserved exclusively for valid MCP messages; `stderr` is for optional logging. Clients **SHOULD** support stdio whenever possible.
- **Streamable HTTP** — the server exposes a **single MCP endpoint** supporting POST and GET. The client POSTs each JSON-RPC message with `Accept: application/json, text/event-stream`; the server answers synchronously (`application/json`) or opens an SSE stream. **Session management:** the server **MAY** assign an `Mcp-Session-Id` on the `InitializeResult` response; once issued, the client **MUST** send that header on subsequent requests and the server **MAY** reject mismatches with 404. **Resumability:** servers **MAY** attach SSE `id`s; clients resume after disconnect via HTTP GET with `Last-Event-ID`. Servers **MUST** validate the `Origin` header (403 on mismatch) and **SHOULD** bind to localhost locally to prevent DNS-rebinding. Replaces the deprecated HTTP+SSE transport from 2024-11-05.

### Authorization

Authorization is **OPTIONAL**. HTTP-based implementations **SHOULD** conform; stdio **SHOULD NOT** (use environment credentials instead). The model: the MCP server is an OAuth 2.1 **resource server**; the MCP client is the OAuth 2.1 **client**; a separate **authorization server** issues tokens.

- Built on **OAuth 2.1** (draft-ietf-oauth-v2-1-13) with PKCE and **Resource Indicators (RFC 8707)**.
- **Protected Resource Metadata (RFC 9728)** — MCP servers **MUST** implement it; clients **MUST** use it for authorization-server discovery (via `WWW-Authenticate: resource_metadata=…` on 401, or a `.well-known/oauth-protected-resource` URI). Servers **SHOULD** advertise required `scope` in the 401 challenge.
- **Authorization-server metadata** — the authorization server **MUST** expose either **OAuth 2.0 Authorization Server Metadata (RFC 8414)** *or* **OpenID Connect Discovery 1.0** (`.well-known/openid-configuration`); clients **MUST** support **both**, trying RFC 8414 first.
- **OAuth Client ID Metadata Documents** (draft-ietf-oauth-client-id-metadata-document-00) — clients/servers **SHOULD** support this public-client identification mechanism; RFC 7591 Dynamic Client Registration **MAY** be supported.
- **Incremental scope consent** — the step-up / scope-challenge flow: clients start with the minimal `scopes_supported` (or the 401 `scope`) and request additional scopes only when the server returns an insufficient-scope error (`WWW-Authenticate` with a narrowed challenge), satisfying least-privilege progressively.

### Versioning

There is no dedicated versioning page in this revision; protocol-version agreement is defined within **Lifecycle** (the `initialize` handshake and the `MCP-Protocol-Version` header). The version string for this revision is `2025-11-25`. The spec site's `/basic/versioning` URL does **not** resolve for 2025-11-25.

## Server Features

### Resources

Application-driven context exposed by URI. Capability `resources` with optional `subscribe` and `listChanged`. Operations: `resources/list` (paginated), `resources/read`, `resources/templates/list` (RFC 6570 URI templates, auto-completable). Resources carry `uri`, `name`, optional `title`/`description`/`mimeType`/`icons`/`annotations` (`audience`, `priority`, `lastModified`). Changes are signalled via `notifications/resources/*`; **resource links** let any `text` content embed typed links to other resources through their URI. Clients **MUST** obtain user consent before exposing resource data.

### Prompts

User-controlled templates (e.g. slash commands). Capability `prompts` with optional `listChanged`. Operations: `prompts/list` (paginated), `prompts/get` (with arguments). A prompt has `name`, optional `title`/`description`/`arguments`/`icons`; messages are `role` + typed `content` (text/image/audio/embedded-resource), each supporting `annotations`.

### Tools

Model-controlled functions. Capability `tools` with optional `listChanged`. Operations: `tools/list` (paginated) and `tools/call`. A tool defines `name`, optional `title`/`description`/`icons`, `inputSchema` (defaults to JSON Schema 2020-12), optional `outputSchema`, and `annotations` (e.g. `readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`). **Structured output:** when `outputSchema` is present, the server **MUST** return conforming results as a JSON object in `structuredContent`, and **SHOULD** also mirror it in a `TextContent` block for backwards compatibility; clients **SHOULD** validate against the schema. Results return `content[]`, an `isError` flag, and the optional `structuredContent`. A human **SHOULD** remain in the loop to authorize invocations.

### Utilities / Logging

Cross-cutting utilities: **pagination** (`cursor`/`nextCursor` on list ops), **completion** (`completion/complete` for argument auto-complete), **ping** (`ping`), **cancellation** (`notifications/cancelled`), **progress** (`notifications/progress`), and **logging** — capability `logging`; clients configure level via `logging/setLevel`, servers emit `notifications/message` with severity, logger name, and structured data.

## Client Features

### Sampling

Server-initiated LLM completions via `sampling/createMessage`. Clients **MUST** declare `sampling`; **human-in-the-loop** review of the prompt and result is **RECOMMENDED**. Requests carry `messages`, optional `systemPrompt`, `modelPreferences` (`hints`, `intelligencePriority`/`speedPriority`), `maxTokens`, and (when the client advertises `sampling.tools`) a `tools` array plus optional `toolChoice`. **Tool-calling support:** the client's LLM may emit `tool_use`; the server executes the tool and re-issues `sampling/createMessage` with the tool results, looping until `stopReason: "endTurn"`. The legacy `includeContext: "thisServer"|"allServers"` values (gated behind `sampling.context`) are soft-deprecated.

### Roots

Server-initiated discovery of filesystem boundaries. Capability `roots` (optional `listChanged`). Server sends `roots/list`; client returns `uri` (currently **MUST** be a `file://` URI) plus optional `name`. Clients emit `notifications/roots/list_changed` when the set changes. Clients **MUST** validate root URIs against path traversal and **SHOULD** prompt for consent before exposing them.

### Elicitation

Server-initiated requests for user information via `elicitation/create`. Capability `elicitation` with sub-modes `form` and `url` (an empty object is equivalent to `form`-only; at least one mode **MUST** be supported). Two modes:

- **Form mode** — in-band structured input. `requestedSchema` is restricted to a flat object of primitive properties (string/number/integer/boolean/enum, including `oneOf`/multi-select arrays); formats `email`, `uri`, `date`, `date-time`. Response `action` is `accept` (with `content`), `decline`, or `cancel`.
- **URL mode** (new in 2025-11-25) — out-of-band interaction for sensitive data (secrets, OAuth, payments) that must **not** transit the client. Parameters: `mode: "url"`, `url`, `elicitationId`, `message`. The client only collects consent and opens the URL; the response is `action: "accept"` with **no** content. Servers **MAY** fire `notifications/elicitation/complete` and **MAY** return error `-32042` (`URLElicitationRequiredError`) carrying required elicitations. Servers **MUST** use URL mode (never form mode) for passwords/API keys/tokens/credentials.

Privacy: clients **MUST** show which server is asking, provide clear decline/cancel controls, let users review form responses before sending, and never log/retain secrets.

## Experimental: Tasks

Introduced in 2025-11-25 as **experimental**. Tasks are durable state machines that wrap a request for pollable, deferred-result execution (expensive computation, batch jobs, external job APIs). Either party may be a **requestor** or **receiver**. A task is created by adding a `task` field (with optional `ttl`) to an augmentable request; the receiver returns a `CreateTaskResult` with a `taskId`, `status` (`working`→`completed`/`failed`/`cancelled`, plus `input_required`), `pollInterval`, and timestamps. The real result is fetched later via `tasks/result`; status via `tasks/get`, optional `notifications/tasks/status`, listing via `tasks/list`, termination via `tasks/cancel`. Capability `tasks` is structured per request category (e.g. `tasks.requests.tools.call` server-side; `tasks.requests.sampling.createMessage` / `tasks.requests.elicitation.create` client-side), with tool-level negotiation through `execution.taskSupport` (`required`/`optional`/`forbidden`). The design may be formalized or modified in future revisions.

## Changes vs 2025-06-18

- **OpenID Connect Discovery 1.0** added as a first-class authorization-server metadata mechanism (clients must support it alongside RFC 8414).
- **Icons metadata** — optional `icons[]` on implementations, resources, tools, and prompts.
- **Incremental scope consent** — step-up authorization via scope challenges (request additional scopes only on insufficient-scope errors).
- **URL-mode elicitation** (`mode: "url"`, `URLElicitationRequiredError` `-32042`, `notifications/elicitation/complete`) for sensitive out-of-band interactions.
- **Sampling tool-calling** — `sampling.tools` capability; servers may pass `tools`/`toolChoice` and run a multi-turn tool loop.
- **OAuth Client ID metadata documents** (draft-ietf-oauth-client-id-metadata-document-00) for public-client identification.
- **Experimental Tasks** — durable, pollable, deferred-result request augmentation.
- Unchanged: stateful JSON-RPC 2.0 core (batching already removed in 2025-06-18), connection-level capability negotiation, stdio + Streamable HTTP transports, structured tool output (`outputSchema`/`structuredContent`, from 2025-06-18), elicitation form mode, resource links.

## Skald relevance

This is the revision Skald's MCP client targets. The client lives in `crates/mcp-client/` (stdio + Streamable HTTP, with an `elicitation` integration test); runtime connection management is `src/core/mcp/mod.rs` (`McpManager`); server-initiated `elicitation/create` is handled by `src/core/elicitation/mod.rs` (`ElicitationManager` + bridge), surfaced in the unified **Inbox**, with secrets never logged or persisted. **Non-text tool-result content** (`image`/`audio`/`resource`/`resource_link`) is now preserved rather than dropped: it is persisted under `data/mcp_media/` and surfaced as a `/api/mcp-media/` URL in a markdown result (see [`../../mcp.md`](../../mcp.md) → *Media tool results*).

**Cancellation** (`notifications/cancelled`) is implemented: an abandoned `tools/call` (a `/stop` that drops the work future, or the 120 s timeout) now tells the server to stop via a per-transport drop-guard, instead of leaving it working on abandoned output. **Tasks** are polled **synchronously (block-and-poll)**: `call_tool` opts a task-capable tool in with the `task` field, then `poll_task` polls `tasks/get` until terminal and fetches the real result via `tasks/result` — so a task-mode call no longer hits the 120 s wall — sending `tasks/cancel` cooperatively if the call is dropped. Both are documented in [`../../mcp.md`](../../mcp.md) → *Cancellation & Tasks*. The block-and-poll variant holds the session for the task's duration and doesn't survive a self-restart; the **detached/durable** poller (DB-persisted tasks + background delivery via `inject_async_result`/`resume_turn`) is the tracked follow-up. Still unimplemented from this revision: **sampling**, **roots**, **URL-mode elicitation**, mid-task `input_required`, progress/completion/logging utilities, and OAuth authorization (HTTP transport).

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