fix(core): never send notifications/cancelled for the initialize hand… (#2668)

Co-authored-by: Felix Weinberger <fweinberger@anthropic.com>
Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
This commit is contained in:
Konstantin Konstantinov 2026-08-17 14:09:11 +03:00 • committed by GitHub
commit 3e90449fd5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 109 additions and 33 deletions

View file

@ -236,9 +236,11 @@ coverage, spawn `serveStdio` as a child process.
On a 2026-07-28 Streamable HTTP connection, aborting an in-flight client request
(`signal` / timeout) closes that request's SSE response stream — the spec cancellation
signal — instead of POSTing `notifications/cancelled`. Nothing to change in calling
code. 2025-era connections and stdio at any era still send `notifications/cancelled`.
Custom `Transport` implementations that open one underlying request per outbound message
and honor `TransportSendOptions.requestSignal` may opt in by declaring
code. 2025-era connections and stdio at any era still send `notifications/cancelled`
(except for the `initialize` handshake, which the spec forbids cancelling — an aborted
or timed-out `connect()` rejects locally and sends nothing). Custom `Transport`
implementations that open one underlying request per outbound message and honor
`TransportSendOptions.requestSignal` may opt in by declaring
`readonly hasPerRequestStream = true`.
### `ctx.mcpReq.log()` and the per-request `logLevel`

View file

@ -1506,7 +1506,11 @@ rewrite required unless noted.
on those survive verbatim. The cancelled-on-timeout signal is unchanged on legacy-era
connections and on stdio/in-memory at any era; on 2026-era Streamable HTTP the cancel
signal is the per-request stream close instead of a `notifications/cancelled` POST
(see [support-2026-07-28.md](./support-2026-07-28.md)).
(see [support-2026-07-28.md](./support-2026-07-28.md)). The one exemption is the
`initialize` handshake: an aborted or timed-out `connect()` still rejects locally, but
no `notifications/cancelled` goes on the wire — the spec forbids cancelling
`initialize`, and v1 sent one anyway. v1 tests asserting that notification need
re-baselining.
- **Also unchanged: SSE reconnection exhaustion.** `StreamableHTTPClientTransport`'s
standalone GET-stream reconnection behavior and its exhaustion signal carry over from
v1: when retries run out, the transport emits `onerror` with a plain `Error` whose