HTTP MCP OAuth: pending flow state lost across a turn boundary, breaks manual complete_authentication on remote sessions

Status Open
Reported on v2.1.267
Maintainer reply None cached
Activity 1 comment · opened Sep 16, 2026

Environment:

  • Claude Code version: 2.1.267 (native install)
  • Session type: remote/sandboxed (browser's localhost:<callbackPort> redirect is not reachable from the session — confirmed via lsof/curl, nothing listens on that port from the session's own network namespace)
  • MCP server: HTTP-type with OAuth ("type": "http", oauth.clientId + oauth.callbackPort in .claude.json), specifically an Org62-Sobject-Read server pointing at https://api.salesforce.com/platform/mcp/v1/platform/sobject-reads

Summary:
For an HTTP MCP server configured with OAuth, calling authenticate followed later by complete_authentication (the documented fallback for remote sessions, where the redirect page can't load) fails with "No OAuth flow is in progress for <server>. Call authenticate first, then retry with the callback URL." — even when the callback URL's state matches exactly what authenticate just returned, and even when the user completes the browser login as fast as possible.

Repro steps:

  1. In a remote/sandboxed Claude Code session, call <server>__authenticate. Receive an authorization URL with a code_challenge/state.
  2. Open the URL in a browser, complete login/consent. Browser redirects to http://localhost:<port>/callback?code=...&state=... — page fails to load (expected in remote sessions per the tool's own docs), but the URL is captured from the address bar.
  3. Call <server>__complete_authentication with that exact callback URL.
  4. Actual: "No OAuth flow is in progress for <server>..." — every time, regardless of how quickly step 3 follows step 2.
  5. Expected: the flow completes and exchanges the code for a token.

Isolating evidence:
Called authenticate and immediately (same turn, no user round trip, near-zero delay) called complete_authentication with a deliberately fake code. That returned a different error: "Authentication failed for <server>: retry your request" — i.e., the pending flow was found and it proceeded to attempt a token exchange (which correctly failed on the bogus code). This shows the pending-flow state exists and is briefly valid immediately after authenticate, but does not survive a normal turn boundary (assistant sends message → waits for user → user replies), which is unavoidable for any real browser-based OAuth login. This makes the manual complete_authentication fallback effectively non-functional for HTTP MCP OAuth on remote sessions.

Suspected cause: pending OAuth flow state (PKCE verifier + expected state) for HTTP MCP OAuth appears to be held in memory scoped to a single turn/tool-execution context rather than persisted for the lifetime of the flow, so it's discarded before a human can complete the browser step and report back.

Secondary note (unrelated, encountered while diagnosing): hitting the generic login.salesforce.com domain (rather than the org's My Domain) for this particular External Client App produced OAUTH_AUTHORIZATION_BLOCKED - Cross-org OAuth flows are not supported for this external client app — resolved by using "Use Custom Domain" to the org's actual My Domain. Not a Claude Code bug, but worth noting since it compounds the above (extra turns spent on login retries before ever reaching the state-loss issue).

🤖 Filed via Claude Code

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗