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
25 changes: 17 additions & 8 deletions docs/specification/draft/basic/patterns/cancellation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ title: Cancellation
<div id="enable-section-numbers" />

The Model Context Protocol (MCP) supports optional cancellation of in-progress requests
through notification messages. Either side can send a cancellation notification to
indicate that a previously-issued request should be terminated.
through notification messages. A client **SHOULD** send a cancellation notification
to indicate that a request it previously issued should be terminated.

A server **MUST** send `notifications/cancelled`
referencing a `subscriptions/listen` request ID when it tears down that subscription
stream (see [Subscriptions][subscriptions]). Servers **MUST NOT** send
`notifications/cancelled` for any other purpose.

## Cancellation Flow

When a party wants to cancel an in-progress request, it sends a `notifications/cancelled`
When a client wants to cancel an in-progress request, it sends a `notifications/cancelled`
notification containing:

- The ID of the request to cancel
Expand Down Expand Up @@ -40,18 +45,20 @@ How a client signals cancellation depends on the transport:
## Behavior Requirements

1. Cancellation notifications **MUST** only reference requests that:
- Were previously issued in the same direction
- Were previously issued by the client
- Are believed to still be in-progress
1. Receivers of cancellation notifications **SHOULD**:
1. Server-sent cancellation notifications **MUST** reference a
`subscriptions/listen` request, to terminate that subscription stream
1. Servers receiving cancellation notifications **SHOULD**:
- Stop processing the cancelled request
- Free associated resources
- Not send a response for the cancelled request
1. Receivers **MAY** ignore cancellation notifications if:
1. Servers **MAY** ignore cancellation notifications if:
- The referenced request is unknown
- Processing has already completed
- The request cannot be cancelled
1. The sender of the cancellation notification **SHOULD** ignore any response to the
request that arrives afterward
1. The client **SHOULD** ignore any response to the cancelled request that arrives

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be a MUST?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

maybe, but things like "afterwards" are always tricky in distributed systems - e.g. sending cancellation at the same time that a response starts its handler.

afterward

## Timing Considerations

Expand Down Expand Up @@ -90,3 +97,5 @@ Invalid cancellation notifications **SHOULD** be ignored:

This maintains the "fire and forget" nature of notifications while allowing for race
conditions in asynchronous communication.

[subscriptions]: /specification/draft/basic/patterns/subscriptions
34 changes: 17 additions & 17 deletions docs/specification/draft/basic/patterns/progress.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ title: Progress
<div id="enable-section-numbers" />

The Model Context Protocol (MCP) supports optional progress tracking for long-running
operations through notification messages. Either side can send progress notifications to
provide updates about operation status.
operations through notification messages. The server **MAY** send progress notifications
to report the status of requests the client has issued.

## Progress Flow

When a party wants to _receive_ progress updates for a request, it includes a
When a client wants to _receive_ progress updates for a request, it includes a
`progressToken` in the request metadata.

- Progress tokens **MUST** be a string or integer value
- Progress tokens can be chosen by the sender using any means, but **MUST** be unique
- Progress tokens can be chosen by the client using any means, but **MUST** be unique
across all active requests.

```json
Expand All @@ -30,7 +30,7 @@ When a party wants to _receive_ progress updates for a request, it includes a
}
```

The receiver **MAY** then send progress notifications containing:
The server **MAY** then send progress notifications containing:

- The original progress token
- The current progress value so far
Expand Down Expand Up @@ -61,30 +61,30 @@ The receiver **MAY** then send progress notifications containing:
- Were provided in an active request
- Are associated with an in-progress operation

2. Receivers of progress requests **MAY**:
2. Servers receiving a request with a progress token **MAY**:
- Choose not to send any progress notifications
- Send notifications at whatever frequency they deem appropriate
- Omit the total value if unknown

```mermaid
sequenceDiagram
participant Sender
participant Receiver
participant Client
participant Server

Note over Sender,Receiver: Request with progress token
Sender->>Receiver: Method request with progressToken
Note over Client,Server: Request with progress token
Client->>Server: Method request with progressToken

Note over Sender,Receiver: Progress updates
Receiver-->>Sender: Progress notification (0.2/1.0)
Receiver-->>Sender: Progress notification (0.6/1.0)
Receiver-->>Sender: Progress notification (1.0/1.0)
Note over Client,Server: Progress updates
Server-->>Client: Progress notification (0.2/1.0)
Server-->>Client: Progress notification (0.6/1.0)
Server-->>Client: Progress notification (1.0/1.0)

Note over Sender,Receiver: Operation complete
Receiver->>Sender: Method response
Note over Client,Server: Operation complete
Server->>Client: Method response
```

## Implementation Notes

- Senders and receivers **SHOULD** track active progress tokens
- Clients and servers **SHOULD** track active progress tokens
- Both parties **SHOULD** implement rate limiting to prevent flooding
- Progress notifications **MUST** stop after completion
15 changes: 9 additions & 6 deletions docs/specification/draft/basic/patterns/subscriptions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ omitted.
"method": "notifications/subscriptions/acknowledged",
"params": {
"_meta": {
"io.modelcontextprotocol/subscriptionId": "1"
"io.modelcontextprotocol/subscriptionId": 1
},
"notifications": {
"toolsListChanged": true,
Expand All @@ -78,8 +78,11 @@ any unsupported types gracefully.
## Receiving Notifications

All notifications delivered on the stream carry
`io.modelcontextprotocol/subscriptionId` in `_meta`, matching the ID of the
`subscriptions/listen` request that opened the stream. On stdio, where all messages
`io.modelcontextprotocol/subscriptionId` in `_meta`, identifying the
`subscriptions/listen` request that opened the stream. The value is the JSON-RPC ID of
the `subscriptions/listen` request. In the examples above, the request used `"id": 1`,
so the acknowledgment and all subsequent notifications carry the subscription ID `1`.
On stdio, where all messages
share a single channel, clients **MUST** use this field to correlate notifications
with their originating subscription.

Expand All @@ -89,7 +92,7 @@ with their originating subscription.
"method": "notifications/resources/updated",
"params": {
"_meta": {
"io.modelcontextprotocol/subscriptionId": "1"
"io.modelcontextprotocol/subscriptionId": 1
},
"uri": "file:///project/config.json"
}
Expand All @@ -102,8 +105,8 @@ A client **MAY** have multiple active subscriptions concurrently — for example
one listening for tools-list changes and another for resource updates. Each
subscription is identified by the JSON-RPC request ID of its
`subscriptions/listen` request, and every notification on the stream carries
that ID in `io.modelcontextprotocol/subscriptionId` so clients can demultiplex
them.
that ID in
`io.modelcontextprotocol/subscriptionId` so clients can demultiplex them.

## Cancellation

Expand Down
Loading
Loading