Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions docs/specification/draft/basic/patterns/subscriptions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ notification types the client has not explicitly requested.

### Notification Filter

| Field | Type | Description |
| ----------------------- | ---------- | ----------------------------------------------------------------- |
| `toolsListChanged` | `boolean` | Receive `notifications/tools/list_changed` when tools change |
| `promptsListChanged` | `boolean` | Receive `notifications/prompts/list_changed` when prompts change |
| `resourcesListChanged` | `boolean` | Receive `notifications/resources/list_changed` when list changes |
| `resourceSubscriptions` | `string[]` | Receive `notifications/resources/updated` for these resource URIs |
| Field | Type | Description |
| ----------------------- | ---------- | --------------------------------------------------------------------------------------- |
| `toolsListChanged` | `boolean` | Receive `notifications/tools/list_changed` when tools change |
| `promptsListChanged` | `boolean` | Receive `notifications/prompts/list_changed` when prompts change |
| `resourcesListChanged` | `boolean` | Receive `notifications/resources/list_changed` when list changes |
| `resourceSubscriptions` | `string[]` | Receive `notifications/resources/updated` for these resource URIs |
| `elicitationComplete` | `boolean` | Receive `notifications/elicitation/complete` for this client's out-of-band elicitations |

All fields are optional. Omitting a field is equivalent to not subscribing to that
notification type.
Expand Down
61 changes: 56 additions & 5 deletions docs/specification/draft/basic/transports/streamable-http.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,20 @@ request to the MCP endpoint.
`Content-Type: text/event-stream` (an SSE response stream). The client
**MUST** support both.

<Note>

This revision of the core protocol defines no client-to-server
_notifications_ over Streamable HTTP. The only client-sent notification in
the core protocol, `notifications/cancelled`, is used only on the
[stdio](/specification/draft/basic/transports/stdio) transport; on
Streamable HTTP, closing the SSE response stream is itself the cancellation
signal and no `notifications/cancelled` message is expected (see
[Cancellation][cancellation]). The notification rules above describe the
transport mechanics for a notification POST; header requirements for
notification POSTs are not defined by this revision.

</Note>

## Receiving Messages

When the server returns an SSE response stream
Expand Down Expand Up @@ -233,6 +247,12 @@ The header value **MUST** match the
with `400 Bad Request` and a `HeaderMismatch` JSON-RPC error
(see [Server Validation](#server-validation)).

Because this revision of the core protocol defines no client-to-server
notifications over Streamable HTTP (see
[Sending Messages](#sending-messages)), the header–body match requirements in
this section are stated for _requests_; header requirements for notification
POSTs are not defined by this revision.

If the server does not implement the requested protocol 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 `400 Bad Request` and an
Expand Down Expand Up @@ -260,11 +280,15 @@ the header per [Server Validation](#server-validation).

| Header Name | Source Field | Required For |
| ------------ | ----------------------------- | ------------------------------------------------------ |
| `Mcp-Method` | `method` | All requests and notifications |
| `Mcp-Method` | `method` | All requests |
| `Mcp-Name` | `params.name` or `params.uri` | `tools/call`, `resources/read`, `prompts/get` requests |

These headers are **REQUIRED** for compliance.

If the `Mcp-Name` source value cannot be safely represented as a plain ASCII
header value, clients **MUST** encode it using the Base64 sentinel format
described in [Value Encoding](#value-encoding).

**`tools/call` request:**

```http
Expand Down Expand Up @@ -354,8 +378,19 @@ the header name `Mcp-Param-{name}`.
string, boolean). Parameters with type `number` are not permitted.
Integer values **MUST** be within the safe range for JavaScript
(−2<sup>53</sup>+1 to 2<sup>53</sup>−1)
- **MAY** be applied to properties at any nesting depth within the
`inputSchema`, not only top-level properties
- **MUST** only be applied to properties that are _statically reachable_
from the schema root: reachable via a chain consisting solely of
`properties` keys. The chain **MUST NOT** pass through `items` (or any
other array keyword), composition keywords (`oneOf`, `anyOf`, `allOf`,
`not`), conditional keywords (`if`/`then`/`else`), or `$ref`. Nested
object properties are permitted as long as every step in the chain is a
`properties` key. An `x-mcp-header` annotation anywhere else makes the
annotation — and thus the tool definition — invalid.

Header extraction is defined as reading the instance value at the exact
property path of the annotated property (the chain of `properties` keys
leading to it). If no value is present at that path in the call arguments,
the header is omitted.

Clients using the Streamable HTTP transport **MUST** reject tool definitions
where any `x-mcp-header` value violates these constraints. Rejection means
Expand Down Expand Up @@ -445,10 +480,21 @@ representation with the following format:
Mcp-Param-{Name}: =?base64?{Base64EncodedValue}?=
```

The same encoding rule applies to the `Mcp-Name` header value. Tool and
prompt names are only **SHOULD**-constrained to header-safe characters, so a
name (or resource URI) outside the safe set is carried as:

```text
Mcp-Name: =?base64?{Base64EncodedValue}?=
```

The prefix `=?base64?` and suffix `?=` indicate that the value is
Base64-encoded. These markers are case-sensitive and **MUST** appear exactly
as shown (lowercase). Servers and intermediaries that need to inspect these
values **MUST** decode them accordingly.
values **MUST** decode them accordingly. In particular, servers **MUST**
decode an encoded `Mcp-Name` or `Mcp-Param-{Name}` value before comparing it
to the corresponding request body value during
[Server Validation](#server-validation).

To avoid ambiguity, clients **MUST** also Base64-encode any plain-ASCII
value that matches the sentinel pattern (i.e., starts with `=?base64?`
Expand Down Expand Up @@ -476,7 +522,9 @@ When constructing a `tools/call` request via HTTP transport, the client
2. Append the `Mcp-Method` header and, if applicable, `Mcp-Name` header to
the request.
3. Inspect the tool's `inputSchema` for properties marked with
`x-mcp-header` and extract the value for each parameter.
`x-mcp-header` and extract the value at each annotated property's exact
property path, omitting the header when no value is present (see
[Schema Extension](#schema-extension)).
4. Encode the values according to the [Value Encoding](#value-encoding)
rules.
5. Append a `Mcp-Param-{Name}: {Value}` header to the request.
Expand Down Expand Up @@ -575,6 +623,9 @@ Validation failure conditions include:
- A required standard header (`MCP-Protocol-Version`, `Mcp-Method`,
`Mcp-Name`) is missing.
- A header value does not match the corresponding request body value.
For headers that permit the Base64 sentinel encoding (`Mcp-Name` and
`Mcp-Param-{Name}`), servers **MUST** decode encoded values (see
[Value Encoding](#value-encoding)) before comparing them to the body value.
- A header value contains invalid characters.

<Note>
Expand Down
16 changes: 15 additions & 1 deletion docs/specification/draft/client/elicitation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -387,13 +387,23 @@ of band and the client is not aware of the outcome until and unless the server s
Servers **MAY** send a `notifications/elicitation/complete` notification when an
out-of-band interaction started by URL mode elicitation is completed. This allows clients to react programmatically if appropriate.

The notification is delivered on a

@CaitieM20 CaitieM20 Jun 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should go on a subscription/listen stream.

If used this should come back on the result stream from the initial request. See the URL Mode Flow diagram which shows the intended usage. https://modelcontextprotocol.io/specification/draft/client/elicitation#url-mode-flow

I would remove all the changes in this file.

Even with MRTR we do allow progress notifications to go back on Result streams outside of subscription listen.

[`subscriptions/listen`](/specification/draft/basic/patterns/subscriptions) stream. A
client that wants to receive it opens (or already has) a `subscriptions/listen`
subscription with `elicitationComplete: true` in the notification filter, waits for the
completion notification, and then retries the original request.

Servers sending notifications:

- **MUST** only send the notification to the client that initiated the elicitation request.
- **MUST** only send the notification on a `subscriptions/listen` stream whose filter
included `elicitationComplete: true`.
- **MUST** include the `elicitationId` established in the original `elicitation/create` request.

Clients:

- **MUST** subscribe via `subscriptions/listen` with `elicitationComplete: true` to
receive completion notifications.
- **MUST** ignore notifications referencing unknown or already-completed IDs.
- **MAY** wait for this notification to automatically retry requests that received a [URLElicitationRequiredError](#error-handling), update the user interface, or otherwise continue an interaction.
- **SHOULD** still provide manual controls that let the user retry or cancel the original request (or otherwise resume interacting with the client) if the notification never arrives.
Expand All @@ -405,6 +415,9 @@ Clients:
"jsonrpc": "2.0",
"method": "notifications/elicitation/complete",
"params": {
"_meta": {
"io.modelcontextprotocol/subscriptionId": "1"
},
"elicitationId": "550e8400-e29b-41d4-a716-446655440000"
}
}
Expand Down Expand Up @@ -449,12 +462,13 @@ sequenceDiagram
User-->>Client: Provide consent

Client->>UserAgent: Open URL
Client->>Server: subscriptions/listen (elicitationComplete: true)
Client->>Server: tools/call(id: 2, Accept Response, requestState))
Note over Server: Server uses requestState to discover url info. <br/> It may need to block until the request is fulfilled.

Note over User,UserAgent: User interaction
UserAgent-->>Server: Interaction complete
Server-->>Client: notifications/elicitation/complete (optional)
Server-->>Client: notifications/elicitation/complete (optional,<br/>on the subscriptions/listen stream)

Note over Server: Continue processing with new information
Server-->Client: Result(id: 2, result)
Expand Down
Loading
Loading