Skip to content

fix(mcp): forward relatedRequestId through McpAgent.elicitInput#1533

Merged
mattzcarey merged 1 commit into
mainfrom
fix/issue-1510-mcp-sdk-slop
May 15, 2026
Merged

fix(mcp): forward relatedRequestId through McpAgent.elicitInput#1533
mattzcarey merged 1 commit into
mainfrom
fix/issue-1510-mcp-sdk-slop

Conversation

@mattzcarey
Copy link
Copy Markdown
Contributor

@mattzcarey mattzcarey commented May 15, 2026

Summary

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.

this.server.registerTool("increase-counter", { ... }, async (_args, extra) => {
  const result = await this.elicitInput(
    { message: "...", requestedSchema: { ... } },
    { relatedRequestId: extra.requestId }   // ← explicit
  );
  ...
});

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 aligns McpAgent.elicitInput with the equivalent Server.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 relatedRequestId explicitly).

What changed

  • packages/agents/src/mcp/index.tselicitInput gains optional options: { relatedRequestId?: RequestId }; forwarded to _transport.send(elicitRequest, options). The WebSocket fallback path is untouched (per-connection routing makes relatedRequestId redundant there).
  • packages/agents/src/tests/agents/mcp.ts — the elicitNameCustom tool now destructures extra and passes { relatedRequestId: extra.requestId }, demonstrating the recommended pattern.
  • packages/agents/src/tests/mcp/elicitation.test.ts — added a dedicated test asserting the explicit-relatedRequestId path 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: with relatedRequestId set, 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 for agents.

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 around onmessage) — i.e., the proper SDK-side fix in @modelcontextprotocol/sdk to auto-propagate relatedRequestId lands and the heuristic mitigation is no longer needed — the "throw on unroutable JSON-RPC request" defensive behavior should be applied equivalently to createMcpHandler / WorkerTransport users. 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 opaque MCP error -32001: Request timed out. Failing fast at send() 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 pass
  • npm --workspace packages/agents run test:workers -- src/tests/mcp/transports/streamable-http.test.ts — 23/23 pass
  • npm --workspace packages/agents run test:workers -- src/tests/mcp — 412/412 pass
  • npx oxlint / npx oxfmt --check clean on touched files

Open in Devin Review

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-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 15, 2026

🦋 Changeset detected

Latest commit: 6037cee

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agents Patch

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

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 15, 2026

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@1533

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@1533

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@1533

hono-agents

npm i https://pkg.pr.new/hono-agents@1533

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@1533

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@1533

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@1533

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@1533

commit: 6037cee

@mattzcarey mattzcarey merged commit 8f699fe into main May 15, 2026
7 checks passed
@mattzcarey mattzcarey deleted the fix/issue-1510-mcp-sdk-slop branch May 15, 2026 12:24
@github-actions github-actions Bot mentioned this pull request May 15, 2026
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants