fix(mcp): forward relatedRequestId through McpAgent.elicitInput#1533
Merged
Conversation
McpAgent.elicitInput now accepts an optional `options.relatedRequestId`
and forwards it to the underlying transport. Callers should pass
`{ relatedRequestId: extra.requestId }` from inside a tool handler so
the elicit message routes through the originating POST response stream
per the Streamable HTTP spec, rather than relying on transport-side
inference.
Update the elicitNameCustom test tool to demonstrate the explicit
pattern. Update three pre-existing tests (accept/cancel/error
round-trips) that previously read elicits from a standalone SSE
stream; with the explicit relatedRequestId, elicits now arrive on
the originating POST stream, which is the spec-recommended route.
🦋 Changeset detectedLatest commit: 6037cee The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
agents
@cloudflare/ai-chat
@cloudflare/codemode
hono-agents
@cloudflare/shell
@cloudflare/think
@cloudflare/voice
@cloudflare/worker-bundler
commit: |
threepointone
approved these changes
May 15, 2026
Merged
cjol
pushed a commit
that referenced
this pull request
May 20, 2026
McpAgent.elicitInput now accepts an optional `options.relatedRequestId`
and forwards it to the underlying transport. Callers should pass
`{ relatedRequestId: extra.requestId }` from inside a tool handler so
the elicit message routes through the originating POST response stream
per the Streamable HTTP spec, rather than relying on transport-side
inference.
Update the elicitNameCustom test tool to demonstrate the explicit
pattern. Update three pre-existing tests (accept/cancel/error
round-trips) that previously read elicits from a standalone SSE
stream; with the explicit relatedRequestId, elicits now arrive on
the originating POST stream, which is the spec-recommended route.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
McpAgent.elicitInputnow accepts an optionaloptions.relatedRequestIdand forwards it to the underlying transport. Callers should pass{ relatedRequestId: extra.requestId }from inside a tool handler so the elicit message routes through the originating POST response stream per the Streamable HTTP spec, rather than relying on transport-side inference.This restores the explicit pattern that existed in the pre-#970
examples/mcp-server//examples/mcp-elicitation/index.ts(deleted 2026-02-21 in #970 along with the WorkerTransport-based examples), and alignsMcpAgent.elicitInputwith the equivalentServer.elicitInput(params, { relatedRequestId })shape.Context: #1510 (the underlying spec-routing bug); #1513 (tracking the upstream MCP SDK propagation work); #1514 (transport-side heuristic mitigation that this PR makes unnecessary for callers that pass
relatedRequestIdexplicitly).What changed
packages/agents/src/mcp/index.ts—elicitInputgains optionaloptions: { relatedRequestId?: RequestId }; forwarded to_transport.send(elicitRequest, options). The WebSocket fallback path is untouched (per-connection routing makesrelatedRequestIdredundant there).packages/agents/src/tests/agents/mcp.ts— theelicitNameCustomtool now destructuresextraand passes{ relatedRequestId: extra.requestId }, demonstrating the recommended pattern.packages/agents/src/tests/mcp/elicitation.test.ts— added a dedicated test asserting the explicit-relatedRequestIdpath routes through the originating POST stream. Updated three pre-existing tests (accept/cancel/error round-trips) that previously read elicits from a standalone SSE stream: withrelatedRequestIdset, elicits arrive on the originating POST stream (spec-recommended), so those tests now read from the POST response body like the existing POST-only test in this file..changeset/mcpagent-elicit-input-related-request-id.md— patch changeset foragents.Follow-ups (deliberately out of scope for this PR)
Once #1514 is reverted in
packages/agents/src/mcp/transport.ts(transport-side AsyncLocalStorage of active request id, single-active-POST fallback, dispatch wrapper aroundonmessage) — i.e., the proper SDK-side fix in@modelcontextprotocol/sdkto auto-propagaterelatedRequestIdlands and the heuristic mitigation is no longer needed — the "throw on unroutable JSON-RPC request" defensive behavior should be applied equivalently tocreateMcpHandler/WorkerTransportusers. Today server-to-client JSON-RPC requests with no routable channel can be silently dropped until the SDK request timeout fires, which surfaces as an opaqueMCP error -32001: Request timed out. Failing fast atsend()time is much more diagnosable.Not doing it in this PR to avoid coupling to the in-flight #1514 revert.
Test plan
npm --workspace packages/agents run test:workers -- src/tests/mcp/elicitation.test.ts— 11/11 passnpm --workspace packages/agents run test:workers -- src/tests/mcp/transports/streamable-http.test.ts— 23/23 passnpm --workspace packages/agents run test:workers -- src/tests/mcp— 412/412 passnpx oxlint/npx oxfmt --checkclean on touched files