ruby-sdk/docs/_server
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Koichi ITO 3da0c10bed Make subscriptions/listen refusable for hosts that cannot stream
## Motivation and Context

The documented Rails controller pattern builds a fresh transport per request and renders `body.first`,
but a modern client's `subscriptions/listen` made `handle_request` return the streaming `Proc` body,
so exactly the documented configuration answered every notification-stream request with a 500 - quietly,
since tool calls and listings kept working. Nothing gated the route: `serves_subscriptions_listen?` was
hardcoded `true` and consulted only by `Server#discover` for capability stripping,
and the modern path deliberately ignores `stateless:`.

`StreamableHTTPTransport.new` now accepts `serve_subscriptions_listen:` (default `true`, behavior unchanged).
When `false`, the transport skips the listen interception so the method falls through the dispatcher as
unimplemented - the spec's 404 with JSON-RPC `-32601`, in an Array body the controller pattern can render - and
`serves_subscriptions_listen?` reflects the setting, so `Server#discover` stops advertising the `listChanged`/`subscribe`
capability flags through its existing wiring and the advertisement agrees with the actual behavior.
The documented controller example passes the flag and explains why; refusing implicitly in `stateless:` mode
was rejected because a stateless transport mounted as a long-lived Rack app serves listen streams correctly
(listen delivery deliberately precedes the stateless notification guard).

On the default streaming side, the listen body is now a small streaming-body object rather than a bare `Proc`:
it still responds to `call` and deliberately not to `each` (Rack would otherwise classify it as enumerable
and break the streaming), while `first` raises an error naming `serve_subscriptions_listen: false`
and pointing at the transports documentation, so a host that buffers the body the documented way fails with
guidance instead of a bare `NoMethodError`.

Fixes #531.

## How Has This Been Tested?

With the issue's reproduction script (default: a streaming body whose `body.first` raises the guidance;
with the flag: 404, `application/json`, and an Array body whose first element is the `-32601` error),
new transport tests covering the refusal shape, the capability stripping on `server/discover`, and the guidance
raise with the body's streaming classification, the full suite, RuboCop, and the conformance suite, all green;
the docs build passes every internal link and anchor check.

## Breaking Changes

None. The keyword defaults to the current behavior; refusal is opt-in.
2026-08-25 02:53:08 +09:00
..
cancellation.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
completion.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
configuration.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
custom-methods.md Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
discover.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
elicitation.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
index.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
logging.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
mrtr.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
notifications.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
pagination.md Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
ping.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
progress.md [Doc] Align the Docs Page Names With the MCP Specification 2026-08-22 18:07:38 +09:00
prompts.md Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
resources.md Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
roots.md Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
sampling.md Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
server-context.md Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
subscriptions.md Make subscriptions/listen refusable for hosts that cannot stream 2026-08-25 02:53:08 +09:00
tools.md Move the Documentation From README.md to the Documentation Site 2026-08-21 13:24:04 +09:00
transports.md Make subscriptions/listen refusable for hosts that cannot stream 2026-08-25 02:53:08 +09:00