
This page is part of our MCP specification reference, a plain-English guide to the Model Context Protocol spec (version 2026-07-28), within The MCP Guide. Building a server? See MCP development.
Status in the 2026-07-28 spec: core (optional pattern)
Cancellation in MCP is how a client tells a server to stop work on a request it no longer needs. On a local stdio connection, the client sends a notifications/cancelled message with the request ID. On Streamable HTTP, simply closing the response stream is the cancel signal.
The cancellation page of the 2026-07-28 spec also sets rules for timeouts and for the race where a cancel arrives after the work is done. This page explains each piece in plain English.
Key Takeaways
- Clients cancel requests with
notifications/cancelledon stdio, or by closing the response stream on Streamable HTTP. - Servers must treat an HTTP client disconnect as cancellation of that request.
- Servers may only send
notifications/cancelledto end asubscriptions/listenstream. - Every request should have a timeout, and a maximum timeout even when progress arrives.
- Cancels can arrive late, so both sides must handle that race without errors.
Why cancellation exists
Users change their minds. An AI app may start a slow search, then the user asks something else. Without cancellation, the server keeps spending CPU, API calls and money on an answer nobody will read.
Cancellation also protects systems. The spec says timeouts and cancels help "prevent hung connections and resource exhaustion." That ties directly to the cost risks in resource exhaustion and runaway costs in MCP.
How it works
The cancel message
On stdio, the client sends a notification naming the request and an optional reason. This example is from the spec:
{
"jsonrpc": "2.0",
"method": "notifications/cancelled",
"params": {
"requestId": "123",
"reason": "User requested cancellation"
}
}
It is a notification, so the server sends no reply to it.
Transport-specific rules
The 2026-07-28 spec splits the rule by transport:
| Transport | How the client cancels |
|---|---|
| Streamable HTTP | Close the SSE response stream. The server "MUST treat a client disconnect as cancellation." No notifications/cancelled is needed. |
| stdio | Send notifications/cancelled with the request ID. There is no per-request stream to close. |
Our guides to Streamable HTTP and the stdio transport explain each transport.
What the server should do
When a cancel arrives, the server should stop processing, free resources and not send a response. It may ignore the cancel if the request is unknown, already finished, or cannot be stopped. The client should ignore any response that still arrives afterwards.
Server-sent cancels
Servers can send notifications/cancelled in exactly one case: to end a subscriptions/listen stream. The spec says servers "MUST NOT send notifications/cancelled for any other purpose." See MCP resource subscriptions for how those streams work.
Timeouts
The spec says implementations "SHOULD establish timeouts for all sent requests." When a timeout passes, the sender should cancel the request using the transport rule above.
Two refinements:
- SDKs and middleware should let you set timeouts per request.
- Clients may reset the timer when a progress notification arrives, but "SHOULD always enforce a maximum timeout."
Race conditions
Networks are not instant. A cancel can reach the server after it already sent the result. The spec says both sides "MUST handle these race conditions gracefully." Invalid cancels, such as unknown or already-finished request IDs, should simply be ignored. This keeps the "fire and forget" nature of notifications.
What changed across spec versions
| Version | Cancellation change |
|---|---|
| 2024-11-05 | Introduced; either side could cancel a request it had sent; clients could not cancel initialize (page) |
| 2025-11-25 | Same model, plus a rule that experimental task-augmented requests use tasks/cancel instead |
| 2026-07-28 | Client-only cancels; HTTP disconnect counts as cancel; new timeout section; server cancels only for subscriptions/listen |
In 2025-11-25, "either side" could cancel, because servers also sent requests. The 2026-07-28 release removed server-initiated requests and the initialize handshake, so those rules went away. Tasks moved to an extension that keeps its own tasks/cancel method. The 2026-07-28 changelog also removed SSE stream resumability, so a broken stream now loses the request and the client must retry with a new ID.
Cancelling a task
Long jobs run under the Tasks extension are cancelled differently. The client sends tasks/cancel with the task ID. The Tasks overview says cancellation is "cooperative": the server acknowledges it "but is not obligated to stop the work." The task may still end as completed or failed.
Common mistakes
- Sending
notifications/cancelledon HTTP and keeping the stream open. On Streamable HTTP, closing the stream is the signal. - Servers ignoring disconnects. A server that keeps working after an HTTP client leaves wastes money and breaks the spec.
- No timeouts. A single hung request can tie up resources indefinitely.
- Erroring on late cancels. Unknown or finished request IDs should be ignored, not treated as failures.
- Servers cancelling client requests. Server-sent cancels are only for ending subscription streams.
- Assuming cancel means rollback. Cancellation stops work. It does not undo actions already taken. Design destructive tools with that in mind, as covered in MCP tool annotations.
Next step
Cancellation and progress cover short jobs. For work that runs for minutes or hours, read the MCP Tasks extension, or see all topics in the MCP specification reference.
Frequently asked questions
How do I cancel an MCP request over HTTP?
Close the response stream for that request. In the 2026-07-28 spec, the server must treat a client disconnect as cancellation, and no notifications/cancelled message is needed.
Can an MCP server cancel a client's request?
No. In 2026-07-28, servers may send notifications/cancelled only to tear down a subscriptions/listen stream. Servers do not start requests, so there is nothing else for them to cancel.
Does cancellation undo what a tool already did?
No. Cancellation asks the server to stop further work. Anything already written, sent or deleted stays done unless the server has its own rollback logic.
What if the cancel arrives after the result?
Both sides must handle it calmly. The server can ignore a cancel for a finished request, and the client should ignore a response that arrives after it cancelled.
Should every MCP request have a timeout?
The spec says implementations should set timeouts for all sent requests, configurable per request, with a maximum timeout even when progress updates keep arriving.











