Skip to content

fix(mcp): harden OAuth callback recovery#1926

Open
mattzcarey wants to merge 2 commits into
mainfrom
fix/mcp-oauth-callback-robustness
Open

fix(mcp): harden OAuth callback recovery#1926
mattzcarey wants to merge 2 commits into
mainfrom
fix/mcp-oauth-callback-robustness

Conversation

@mattzcarey

@mattzcarey mattzcarey commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • verify an OAuth callback's state nonce before allowing an error or code callback to alter the MCP connection state
  • let a genuine callback finish a connection that had previously been moved to failed
  • make addMcpServer() return live or persisted authorization URLs only while their embedded state is still redeemable; otherwise reconnect to mint a fresh flow

Why

A well-formed callback carrying an unknown state nonce could move an in-flight authorization from authenticating to failed, preventing the genuine callback from completing. An abandoned OAuth flow could also keep returning the same expired authorization URL after its ten-minute state lifetime.

Invalid, expired, or already-consumed callbacks now return their error without mutating the active connection. A genuine authorization-server error with a currently redeemable nonce still fails the connection. Calling addMcpServer() on a stale flow re-enters OAuth using the existing server id and persists the newly minted URL.

Review follow-up

  • both callback shapes (error and code) verify state before mutating the connection
  • removed an unreachable state guard after accounting for the auth-accepted states and the two recoverable states (authenticating and failed)
  • an error callback received after its state expires leaves the flow recoverable rather than changing it to failed; the next addMcpServer() call mints a new flow
  • scope is intentionally the callback state machine and addMcpServer() recovery. Synchronous getMcpServers() snapshots do not perform asynchronous state validation on their own; a stale displayed URL is replaced when the application calls addMcpServer()
  • no blocking verifier findings remain

Validation

  • pnpm --filter agents exec vitest run src/tests/mcp — 29 files, 538 tests passed
  • pnpm run check — passed
  • regression coverage includes error and code callbacks with unknown state, genuine completion from a failed state, replay/expiry behavior, hibernated URLs, hot in-memory URLs, malformed URLs, and fresh URL persistence

Includes a patch changeset for agents.


Open in Devin Review

@changeset-bot

changeset-bot Bot commented Jul 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7908442

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

This PR includes changesets to release 2 packages
Name Type
agents Patch
@cloudflare/agent-think 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 Jul 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

agents

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

@cloudflare/ai-chat

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

@cloudflare/codemode

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

create-think

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

hono-agents

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

@cloudflare/shell

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

@cloudflare/think

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

@cloudflare/voice

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

@cloudflare/worker-bundler

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

commit: 7908442

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.

1 participant