Skip to content

[v2] Expose per-request stream end (onRequestStreamEnd) in RequestOptions for custom long-lived requests #3060

Open

Description

@DanielSLew

Summary

Protocol.request() gives callers no way to learn that the per-request response stream ended. The client transport already supports this: TransportSendOptions.onRequestStreamEnd, which StreamableHTTPClientTransport fires when a request's SSE response ends. But only Client.listen() uses it (it calls transport.send() directly). RequestOptions has no equivalent, and _requestWithSchemaViaCodec passes requestSignal to transport.send() but not onRequestStreamEnd.

Why it matters

Extensions that define long-lived streaming requests can't detect a dead stream promptly. One example is events/stream from the Events extension (SEP-3415, see #2945). If the server restarts mid-stream, the POST's SSE body ends without a JSON-RPC response. The pending request then waits for its timeout, or for an application-level heartbeat watchdog. In @mastra/mcp we detect this through a 30s heartbeat window, so it takes up to 60s. subscriptions/listen gets immediate detection because it uses the transport option directly.

This is the request-level counterpart of #2739, which covers non-streaming requests left pending when their SSE response ends.

Proposal

Add an option to RequestOptions, for example onRequestStreamEnd?: () => void, and forward it to transport.send() the same way requestSignal is forwarded. Alternatively, reject the pending request with a distinct error when its stream ends before a response arrives. Transports with no per-request stream (stdio, InMemory) would keep ignoring it, as they do today.

Versions

We hit this on @modelcontextprotocol/client@2.2.0. It's still present on main (c05225a6): see RequestOptions in packages/core-internal/src/shared/protocol.ts and the transport.send(...) call in _requestWithSchemaViaCodec.

Activity

  1. added
    v1Issues / PRs related to v1.x
    v2Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes
    on Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    v1Issues / PRs related to v1.xv2Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions