Skip to content

fix(core): keep MCP OAuth login waiting after stray callback requests - #58342

Merged
rekram1-node merged 1 commit into
devfrom
oauth-stray-callback
Oct 23, 2026
Merged

rekram1-node merged 1 commit into
devfrom
oauth-stray-callback

Conversation

@rekram1-node

@rekram1-node rekram1-node commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #55201

Problem

During MCP OAuth login, opencode listens on a loopback callback for the authorization server's redirect. The handler treats every request to the callback path as that redirect. A request without OAuth parameters, such as a browser preflight, prefetch, or reload, fails the whole login with "OAuth state mismatch". The real redirect that arrives afterwards gets 409 OAuth callback already received, and no token exchange happens.

Change

 callback(request)
   if error param: fail login
+  if no state and no code: reply 400, keep waiting
   if state != expected: fail login
   if no code: fail login
   complete login

A request with no OAuth parameters at all gets the error page but no longer ends the login. Redirects that carry an error, a wrong state, or a state without a code still fail it, as before.

This is a trimmed version of #56812, which also answers CORS/Private Network Access preflights. Chrome no longer sends those for top-level navigations, so I kept only the part that stops a stray request from ending the login. @reynold-hu is credited as co-author.

A new test sends an OPTIONS request and a bare GET to the callback before the real redirect. Without the fix the redirect gets 409.

The loopback callback treated any request to its path as the OAuth
redirect. A request without OAuth parameters, such as a browser
preflight, prefetch, or reload, failed the login with "OAuth state
mismatch", and the real redirect that followed got 409.

Answer such requests with an error page but keep waiting. Redirects
that carry an error, a wrong state, or no code still fail the login.

Fixes #55201

Co-authored-by: Reynold Hu <88558425+reynold-hu@users.noreply.github.com>

@opencode-agent opencode-agent 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.

Looks good. I ran the #55201 reproduction (an OPTIONS preflight to the loopback callback, then the real redirect) from source on both checkouts. On the base the login ends with OAuth state mismatch (exit 1). With this change the preflight gets a 400, the real callback completes, and the CLI ends with Connected to mock (exit 0). The new test passes. Across test/mcp-oauth.test.ts and test/mcp.test.ts the only failure is a process-termination test that also fails on the base. tsc -b passes. Redirects that carry error, a wrong state, or a state without a code still fail the login.

Public API: unchanged.

No concerns.

@rekram1-node
rekram1-node merged commit 309522f into dev Oct 23, 2026
15 checks passed
@rekram1-node
rekram1-node deleted the oauth-stray-callback branch October 23, 2026 04:37
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.

mcp: loopback OAuth callback treats code-less requests (incl. Chrome PNA preflights) as fatal authorization failures

1 participant