Skip to content

fix(mcp): retain transport owner outside agent context#1734

Merged
mattzcarey merged 1 commit into
mainfrom
fix/mcp-transport-agent-ref
Jun 24, 2026
Merged

fix(mcp): retain transport owner outside agent context#1734
mattzcarey merged 1 commit into
mainfrom
fix/mcp-transport-agent-ref

Conversation

@whoiskatrin

@whoiskatrin whoiskatrin commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #1490.

Problem

McpAgent server-to-client requests could fail when invoked from a host callback reached through Worker Loader RPC, a service binding, or another entrypoint that does not inherit the original agent AsyncLocalStorage context.

The Streamable HTTP transport looked up its owning agent from ALS at send time and threw:

Error: Agent was not found in send

This affected requests such as elicitation, sampling, and roots initiated from sandbox-backed tool execution.

Fix

StreamableHTTPServerTransport now retains its owning McpAgent when the transport is created. The transport and agent share the same Durable Object lifetime, and this matches the existing McpSSETransport, which already captures its owner.

The transport still reads the request-scoped connection from ALS when available, but only to disambiguate a protocol-invalid case where multiple live streams claim the same active request ID. Normal explicit relatedRequestId routing uses the sole matching stream and does not depend on ALS. If context is absent and routing is ambiguous, the existing code fails closed rather than guessing.

No public API is added.

Why not re-enter ALS?

Re-entering agent context at a cross-isolate callback would synthesize an agent store without restoring the original connection or request. The transport already owns the agent reference it needs, so retaining that owner fixes the correct boundary without asking applications to wrap callbacks or import internal context state.

Tests

Added regressions that clear the agent ALS store before issuing an SDK elicitation and verify:

  • an elicitation with relatedRequestId completes on the originating POST stream;
  • an elicitation without relatedRequestId completes on the standalone GET stream.

Validation after rebasing onto current main:

  • focused outside-context regressions: 2/2
  • full MCP Workers suite: 492/492
  • packages/agents build
  • changed-file formatting and lint

Related Codemode work

#1793 preserves the outer MCP tool-call context through openApiMcpServer, allowing a host callback to supply the exact relatedRequestId. Together, the two changes cover the McpAgent.serve() + Dynamic Worker RPC setup reported in #1510:

@changeset-bot

changeset-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6e58373

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

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

Copy link
Copy Markdown
Contributor

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 bugs or issues to report.

Open in Devin Review

@pkg-pr-new

pkg-pr-new Bot commented Jun 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

agents

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

@cloudflare/ai-chat

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

@cloudflare/codemode

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

create-think

npm i https://pkg.pr.new/create-think@1734

hono-agents

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

@cloudflare/shell

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

@cloudflare/think

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

@cloudflare/voice

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

@cloudflare/worker-bundler

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

commit: 6e58373

StreamableHTTPServerTransport previously recovered its owning agent from AsyncLocalStorage at send time. Host callbacks reached through Worker Loader RPC have no ALS ancestry, so server-to-client requests such as elicitation failed with "Agent was not found in send".\n\nRetain the owning McpAgent for the transport lifetime, matching McpSSETransport. Explicit relatedRequestId routing works without ALS; request-scoped context remains an optional disambiguator when a client reuses an active request id across streams.\n\nAdd request-scoped and standalone elicitation regression coverage and document context behavior.\n\nFixes #1490.
@mattzcarey mattzcarey force-pushed the fix/mcp-transport-agent-ref branch from 6a74ede to 6e58373 Compare June 24, 2026 10:52
@mattzcarey mattzcarey changed the title fix(mcp): make server-initiated sends work without agent ALS context fix(mcp): retain transport owner outside agent context Jun 24, 2026
@mattzcarey mattzcarey merged commit cd2c430 into main Jun 24, 2026
7 of 8 checks passed
@mattzcarey mattzcarey deleted the fix/mcp-transport-agent-ref branch June 24, 2026 12:13
@github-actions github-actions Bot mentioned this pull request Jun 24, 2026
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.

agentContext ALS not preserved in Worker-Loader-child→host RPC callbacks; server-initiated MCP requests throw "Agent was not found in send"

2 participants