You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Serve subscriptions/listen over the dual-era stream loop
Remove the transport-level rejection of subscriptions/listen on the
stream-pair modern path: the method now dispatches through serve_one to
the registered ListenHandler like every other modern request. Over
stdio the listen request simply stays pending - the ack and every event
are request-scoped notifications on the duplex pipe, and the response
arrives only when the stream ends gracefully. server/discover's
subscription capability advertisement is now truthful on this transport.
Two era-scoped generalizations ride the dispatcher's new per-request
seams, fixing the class rather than the listen instance:
- Era lock at first client-visible success frame. A classified-modern
request commits the modern lock immediately before its first
non-error frame is written (notification, progress, or response),
not when its dispatch returns. Plain requests lock at their response
exactly as before; a listen locks at its ack, so an initialize
pipelined behind a live stream is rejected with -32022 instead of
flipping the connection legacy mid-stream. Classification failures
and pre-frame cancellations still never lock, and progress written
for a request that later fails locks correctly (the client that
stamped a valid envelope already committed to modern).
- Quiet cancellation for every classified-modern request. After an
inbound notifications/cancelled the server sends nothing further for
that request - no result, no error - matching the transport spec's
MUST NOT. Legacy-era requests keep the byte-identical code-0
"Request cancelled" answer released 2025 clients unblock on.
The single-exchange HTTP and direct in-process paths need no seam:
cancellation is structurally silent there (stream close / caller's own
scope).
Copy file name to clipboardExpand all lines: docs/whats-new.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -191,7 +191,7 @@ That file is the pitch in one place: one server, one `Resolve`-backed tool, and
191
191
192
192
### Change notifications become one stream
193
193
194
-
At 2026-07-28 the standalone HTTP GET stream and `resources/subscribe` are replaced by `subscriptions/listen`: the client opens one long-lived stream and names the notification kinds it wants. `MCPServer` serves it out of the box; you publish with `await ctx.notify_resource_updated(uri)` (and `notify_tools_changed()`, and so on), and multi-replica deployments plug in a shared `SubscriptionBus`. On the client (since `2.0.0b2`), `async with client.listen(...)` opens the stream: the filter goes in as keyword arguments, typed change events come back, and `sub.honored` is the subset the server agreed to deliver. One honest caveat: over stdio the server does not serve the stream yet.
194
+
At 2026-07-28 the standalone HTTP GET stream and `resources/subscribe` are replaced by `subscriptions/listen`: the client opens one long-lived stream and names the notification kinds it wants. `MCPServer` serves it out of the box; you publish with `await ctx.notify_resource_updated(uri)` (and `notify_tools_changed()`, and so on), and multi-replica deployments plug in a shared `SubscriptionBus`. On the client (since `2.0.0b2`), `async with client.listen(...)` opens the stream: the filter goes in as keyword arguments, typed change events come back, and `sub.honored` is the subset the server agreed to deliver. This works on both transports: over streamable HTTP the stream is the request's SSE response, and over stdio the events ride the duplex pipe while the listen request stays pending.
195
195
196
196
**[Subscriptions](handlers/subscriptions.md)** covers publishing and serving, **[its Clients twin](client/subscriptions.md)** the watching end, and **[Deploy & scale](run/deploy.md)** the bus.
0 commit comments