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
21 changes: 21 additions & 0 deletions docs/specification/draft/basic/patterns/cancellation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,27 @@ How a client signals cancellation depends on the transport:
- **stdio**: There is no per-request stream to close. The client **MUST** send a
`notifications/cancelled` notification referencing the request ID.

## Timeouts
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.

thanks for adding this guidance


Implementations **SHOULD** establish timeouts for all sent requests, to prevent hung
connections and resource exhaustion. When the request has not received a success or error
response within the timeout period, the sender **SHOULD** cancel the request and stop
waiting for a response. As described in
[Transport-Specific Cancellation](#transport-specific-cancellation), this means:

- **Streamable HTTP**: closing the response stream for the request, which constitutes
cancellation.
- **stdio**: sending a `notifications/cancelled` notification referencing the request ID.

SDKs and other middleware **SHOULD** allow these timeouts to be configured on a
per-request basis.

Implementations **MAY** choose to reset the timeout clock when receiving a
[progress notification](/specification/draft/basic/patterns/progress) corresponding to
the request, as this implies that work is actually happening. However, implementations
**SHOULD** always enforce a maximum timeout, regardless of progress notifications, to
limit the impact of a misbehaving client or server.

## Behavior Requirements

1. Cancellation notifications **MUST** only reference requests that:
Expand Down
6 changes: 5 additions & 1 deletion docs/specification/draft/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ the previous revision, [2025-11-25](/specification/2025-11-25).

6. Move experimental tasks out of the core protocol and into an official extension (`io.modelcontextprotocol/tasks`). The redesigned extension replaces the blocking `tasks/result` method with polling via `tasks/get` and a new `tasks/update` for client-to-server input, removes `tasks/list`, and allows servers to return task handles unsolicited without per-request opt-in ([SEP-2663](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2663)).

7. Multi Round-Trip Requests (MRTR) pattern introduced which replaces the previous approach of sending server-initiated requests, such as `roots/list`, `sampling/createMessage`, or `elicitation/create`. Servers return `inputRequests`, a new resultType containing the additional information needed to process the request. Clients respond with `inputResponses` on the next request providing the requested information. ([SEP-2322](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2322)).
7. Multi Round-Trip Requests (MRTR) pattern introduced which replaces the previous approach of sending server-initiated requests, such as `roots/list`, `sampling/createMessage`, or `elicitation/create`. Servers return an `InputRequiredResult` (`resultType: "input_required"`) whose `inputRequests` field carries the requests for the additional information needed to process the request. Clients respond with `inputResponses` on a retry of the original request providing the requested information. ([SEP-2322](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2322)).

8. All results now carry a required `resultType` field: `"complete"` for ordinary results and `"input_required"` for [multi round-trip request](/specification/draft/basic/patterns/mrtr) interim results. Clients **MUST** treat results from earlier-protocol servers that omit the field as `"complete"` ([SEP-2322](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2322)).

9. Remove SSE stream resumability and message redelivery (the `Last-Event-ID` header and SSE event IDs) from the Streamable HTTP transport. A broken response stream loses the in-flight request; clients **MUST** re-issue it as a new request with a new request ID ([SEP-2575](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2575)).

## Minor changes

Expand Down
57 changes: 27 additions & 30 deletions docs/specification/draft/client/elicitation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ Clients that support elicitation **MUST** declare the `elicitation` capability i

```json
{
"capabilities": {
"elicitation": {
"form": {},
"url": {}
"_meta": {
"io.modelcontextprotocol/clientCapabilities": {
"elicitation": {
"form": {},
"url": {}
}
}
}
}
Expand All @@ -66,8 +68,10 @@ For backwards compatibility, an empty capabilities object is equivalent to decla

```jsonc
{
"capabilities": {
"elicitation": {}, // Equivalent to { "form": {} }
"_meta": {
"io.modelcontextprotocol/clientCapabilities": {
"elicitation": {}, // Equivalent to { "form": {} }
},
},
}
```
Expand Down Expand Up @@ -126,7 +130,6 @@ The schema is restricted to these primitive types:
"description": "Description text",
"minLength": 3,
"maxLength": 50,
"pattern": "^[A-Za-z]+$",
"format": "email",
"default": "user@example.com"
}
Expand Down Expand Up @@ -237,7 +240,7 @@ Note that complex nested structures, arrays of objects (beyond enums), and other

#### Example: Simple Text Request

**Request:**
**Input request (delivered inside [`InputRequiredResult.inputRequests`](/specification/draft/basic/patterns/mrtr#inputrequests)):**

```json
{
Expand All @@ -258,22 +261,20 @@ Note that complex nested structures, arrays of objects (beyond enums), and other
}
```

**Response:**
**Client result (returned inside `inputResponses` on the retried request):**

```json
{
"result": {
"action": "accept",
"content": {
"name": "octocat"
}
"action": "accept",
"content": {
"name": "octocat"
}
}
```

#### Example: Structured Data Request

**Request:**
**Input request (delivered inside `InputRequiredResult.inputRequests`):**

```json
{
Expand Down Expand Up @@ -305,17 +306,15 @@ Note that complex nested structures, arrays of objects (beyond enums), and other
}
```

**Response:**
**Client result (returned inside `inputResponses` on the retried request):**

```json
{
"result": {
"action": "accept",
"content": {
"name": "Monalisa Octocat",
"email": "octocat@github.com",
"age": 30
}
"action": "accept",
"content": {
"name": "Monalisa Octocat",
"email": "octocat@github.com",
"age": 30
}
}
```
Expand Down Expand Up @@ -354,7 +353,7 @@ The `url` parameter **MUST** contain a valid URL.
This example shows a URL mode elicitation request directing the user to a secure URL where they can provide sensitive information (an API key, for example).
The same request could direct the user into an OAuth authorization flow, or a payment flow. The only difference is the URL and the message.

**Request:**
**Input request (delivered inside `InputRequiredResult.inputRequests`):**

```json
{
Expand All @@ -368,13 +367,11 @@ The same request could direct the user into an OAuth authorization flow, or a pa
}
```

**Response:**
**Client result (returned inside `inputResponses` on the retried request):**

```json
{
"result": {
"action": "accept"
}
"action": "accept"
}
```

Expand All @@ -395,7 +392,7 @@ Servers sending notifications:
Clients:

- **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.
- **MAY** wait for this notification to automatically retry requests that received an [`InputRequiredResult`](/specification/draft/basic/patterns/mrtr#inputrequiredresult) (echoing back its `requestState`), 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.

#### Example
Expand Down Expand Up @@ -465,7 +462,7 @@ sequenceDiagram
Elicitation responses use a three-action model to clearly distinguish between different user actions. These actions apply to both form and URL elicitation modes.

```json
"result": {
{
"action": "accept", // or "decline" or "cancel"
"content": {
"propertyName": "value",
Expand Down
24 changes: 12 additions & 12 deletions docs/specification/draft/client/roots.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ Clients that support roots **MUST** declare the `roots` capability in

```json
{
"capabilities": {
"roots": {}
"_meta": {
"io.modelcontextprotocol/clientCapabilities": {
"roots": {}
}
}
}
```
Expand All @@ -55,26 +57,24 @@ Clients that support roots **MUST** declare the `roots` capability in
To retrieve roots during the processing of a client request, servers send an `InputRequiredResult`
containing a `roots/list` request:

**Request:**
**Input request (delivered inside [`InputRequiredResult.inputRequests`](/specification/draft/basic/patterns/mrtr#inputrequests)):**

```json
{
"method": "roots/list"
}
```

**Response:**
**Client result (returned inside `inputResponses` on the retried request):**

```json
{
"result": {
"roots": [
{
"uri": "file:///home/user/projects/myproject",
"name": "My Project"
}
]
}
"roots": [
{
"uri": "file:///home/user/projects/myproject",
"name": "My Project"
}
]
}
```

Expand Down
Loading