Skip to content

fix(agents): warn when addMcpServer falls back to the default callback URL#1719

Open
mattzcarey wants to merge 2 commits into
mainfrom
fix/1378-default-callback-warn
Open

fix(agents): warn when addMcpServer falls back to the default callback URL#1719
mattzcarey wants to merge 2 commits into
mainfrom
fix/1378-default-callback-warn

Conversation

@mattzcarey

@mattzcarey mattzcarey commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Note

This is a Fable experiment (model-authored PR). Please close if it adds no value.

Fixes #1378

Problem

addMcpServer has a guard that throws when sendIdentityOnConnect: false + explicit callbackHost + no callbackPath. But the guard is bypassed on two paths:

  • sendIdentityOnConnect: true (the case in the issue — an option about WS identity broadcasting silently disabling callback-path safety), and
  • a callbackHost auto-derived from the current request/connection (derivation happens after the guard).

On both paths the default callback URL (…/{agentsPrefix}/{kebab(class)}/{this.name}/callback) is silently generated and persisted. If the Worker doesn't route /agents/* through routeAgentRequest (e.g. narrowed run_worker_first + SPA assets, as in examples/assistant), the OAuth redirect never reaches the DO and the MCP server hangs in AUTHENTICATING with zero server-side signal.

Fix

Per the issue's least-disruptive option (and Matt's call): console.warn whenever the default callback URL is constructed because no callbackPath was provided. The warning names the server, prints the exact fallback URL, explains the routing requirement and the failure mode, and says what to do (callbackPath + getAgentByName).

The existing sendIdentityOnConnect: false throw is unchanged — this only adds a signal to the paths that previously proceeded silently. No behavioral change to URL construction.

Tests

Two new tests in packages/agents/src/tests/mcp/add-mcp-server.test.ts, via warn-capturing probe methods on the existing TestHttpMcpDedupAgent (default sendIdentityOnConnect: true, mocked connectToServer):

  • default URL without callbackPath → warning fires, includes server name, the full default URL (instance name visible), and the callbackPath remediation
  • explicit callbackPath → no warning

Full MCP suite: 492 passed (26 files). Typecheck/oxfmt/oxlint clean.

Notes for maintainers

  • Deliberately a warn, not a throw — throwing on the derived-host default would break currently-working setups that do route /agents/* correctly (the default URL is fine there). Escalating to a throw in the next major could be paired with breaking changes for next major #844.
  • The warning fires once per addMcpServer call (server registration time), not per request, so it can't spam logs.
  • Changeset included (agents patch).

Open in Devin Review

…k URL

The sendIdentityOnConnect:false guard throws for an explicit callbackHost
without callbackPath, but every other path (sendIdentityOnConnect:true,
or a derived callbackHost) silently built the default callback URL. That
URL embeds the instance name and only works when /agents/* is routed
through routeAgentRequest, so a misrouted Worker hangs OAuth in
AUTHENTICATING with no signal. Warn whenever the default URL is used.

Fixes #1378
@changeset-bot

changeset-bot Bot commented Jun 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 53fd1ad

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 found 1 potential issue.

Open in Devin Review

Comment thread packages/agents/src/index.ts Outdated
Comment on lines +10785 to +10788
// The sendIdentityOnConnect:false guard above throws for this case;
// every other path that lands here gets a warning instead — the
// default URL leaks the instance name and only works when the Worker
// routes the agents prefix through routeAgentRequest (#1378).

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.

🚩 Comment incorrectly claims sendIdentityOnConnect:false guard covers all paths to this branch

The comment at packages/agents/src/index.ts:10785 states "The sendIdentityOnConnect:false guard above throws for this case" — but this is only true when resolvedCallbackHost was explicitly provided by the caller. When the host is auto-derived from the request/connection at packages/agents/src/index.ts:10767-10776, the guard at packages/agents/src/index.ts:10754-10764 has already been passed (because resolvedCallbackHost was still undefined at that point). This means: with sendIdentityOnConnect:false, no explicit callbackHost, and a host auto-derived from the current request, the code reaches this else branch and only warns — the instance name still appears in the default callback URL despite the agent opting out of identity exposure. The underlying enforcement gap is pre-existing (the old ternary had the same control flow), but the new comment gives a false sense that it's fully handled. Consider either extending the guard to also check after auto-derivation, or correcting the comment to note this gap.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch — the comment over-claimed. Corrected in 53fd1ad: the throw only covers sendIdentityOnConnect: false with an explicit callbackHost; an auto-derived host bypasses it regardless of the option and now lands in the warn branch (which is the behavioral improvement this PR adds — that path was previously silent). Left the enforcement gap as a warn rather than extending the throw to derived hosts, since that would break currently-working setups that do route /agents/* correctly; a maintainer could escalate it in the next major (#844).

@pkg-pr-new

pkg-pr-new Bot commented Jun 9, 2026

Copy link
Copy Markdown

Open in StackBlitz

agents

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

@cloudflare/ai-chat

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

@cloudflare/codemode

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

create-think

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

hono-agents

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

@cloudflare/shell

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

@cloudflare/think

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

@cloudflare/voice

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

@cloudflare/worker-bundler

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

commit: 53fd1ad

The throw only covers sendIdentityOnConnect:false with an explicit
callbackHost; an auto-derived host bypasses it regardless of the option
and lands in the warn branch. Say so instead of over-claiming.
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.

addMcpServer: default callback URL silently breaks when callers don't set callbackPath + sendIdentityOnConnect: true

1 participant