Skip to content

Cancel button sends notifications/cancelled for Streamable HTTP instead of closing the SSE stream #2140

Description

@webus

Which version line?

v2 — current (@modelcontextprotocol/inspector@latest)

Which client?

Web

Inspector version

2.3.0

Node version

v22

Operating system (and browser, for the web client)

No response

Transport

Streamable HTTP

MCP server under inspection

The Cancel button sends a notifications/cancelled notification for all transports. Per the 2026-07-28 spec, for Streamable HTTP the cancellation signal is closing the SSE response streamnotifications/cancelled is the stdio-only mechanism. As a result, clicking Cancel against a Streamable HTTP server does not actually cancel the in-flight task on spec-compliant servers.

Spec reference

From Cancellation → Transport-Specific Cancellation:

Streamable HTTP: Closing the SSE response stream is the cancellation signal. The server MUST treat a client disconnect as cancellation of that request. No notifications/cancelled message is required or expected.

stdio: There is no per-request stream to close. The client MUST send a notifications/cancelled notification referencing the request ID.

The repo's own specification/v2_new_spec_impact.md already acknowledges this:

Closing a request's SSE stream is cancellation (notifications/cancelled is stdio-only now). ... Cancellation switches to stream-abort on modern; calling code unchanged.

But specification/v2_ux_features.md still says:

Cancel button sends notifications/cancelled

…which is correct for stdio but wrong for Streamable HTTP.

Steps to reproduce

  1. Start an MCP server on Streamable HTTP that exposes a long-running tool (e.g. a slow_task tool that sleeps with progress notifications for ~40s). Server: MCP Python SDK 2.1.1.
  2. Connect Inspector (Streamable HTTP, Modern protocol era).
  3. Call the long-running tool.
  4. Click Cancel while the tool is running.
  5. Observe: the server logs show POST /mcp HTTP/1.1" 202 Accepted for the notifications/cancelled notification, but the task keeps running and progress notifications continue until the tool completes.

Expected behavior

For Streamable HTTP, clicking Cancel should close/abort the SSE response stream for the in-flight request (the spec'd cancellation signal), not POST a notifications/cancelled notification. The server then treats the disconnect as cancellation per spec.

For stdio, the current behavior (send notifications/cancelled) is correct and should be preserved.

Actual behavior

Cancel sends notifications/cancelled regardless of transport. On Streamable HTTP, spec-compliant servers acknowledge with 202 and drop the notification (the SDK 2.1.1 behavior); the task is not cancelled. True cancellation only happens if the user manually disconnects the connection.

Logs, errors, or screenshots

Tested against a custom MCP server (Python, MCP SDK 2.1.1, Streamable HTTP) deployed on Kubernetes:

Inspector Cancel (broken):

# Server log on Cancel click:
10.180.1.39:0 - "POST /mcp HTTP/1.1" 202 Accepted
# Task keeps running, progress notifications continue to completion

SSE-stream-close (correct, via a custom client using anyio.move_on_after):

# Client closes the SSE stream after 3s (20-step task, 2s/step = 40s total)
# Client output:
[1/20] Completed step 1 of 20
Cancelled after 3s
# Server: task stops immediately, no further progress, no errors

Already prototyped a fix?

The Cancel button's behavior should be transport-aware:

  • stdio: send notifications/cancelled (current behavior, correct).
  • Streamable HTTP: abort/close the SSE response stream for the in-flight request (e.g. via an AbortController on the fetch backing the SSE stream), per spec.

The v2_ux_features.md design doc should also be updated to reflect the transport-specific behavior.

Before you submit

  • I searched existing issues and this is not a duplicate.
  • This is not a security vulnerability report (those go through the private advisory process).

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingv2Issues and PRs for v2

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions