[BUG] MCP OAuth: browser confirms "Authentication successful" but CLI still reports "Needs authentication" (HTTP transport, fixed --callback-port)

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 0 comments · opened Jul 30, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet (closest related but not matching: #37747, #66511, #72818 — none match this exact symptom of browser-confirmed success not reflected client-side)
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code (2.1.220, confirmed via claude update — already up to date)

What's Wrong?

For a remote HTTP MCP server (https://mcp.lovable.dev), the OAuth authorization flow completes successfully on the server/browser side (the browser shows "Connected / Authentication successful. You can close this tab and return to Claude Code."), but the CLI never registers the successful auth. claude mcp get lovable continues to report Status: ! Needs authentication afterward, and the local auth-needed marker file (~/.claude/mcp-needs-auth-cache.json) gets its timestamp for the lovable entry refreshed (re-flagged as needing auth) at the same moment the browser shows success — i.e. the CLI silently drops a completed authorization instead of persisting it.

This happened consistently across three attempts:

  1. Initial state: /mcp → Authenticate → browser shows a redirect_uri mismatch error page.
  2. Removed and re-added the server (claude mcp remove lovable / claude mcp add --transport http lovable https://mcp.lovable.dev --scope user) → same redirect_uri mismatch on /mcp → Authenticate.
  3. Removed and re-added again with a fixed callback port (claude mcp add --transport http lovable https://mcp.lovable.dev --scope user --callback-port 45678) → /mcp → Authenticate → this time the browser completed the flow and showed the success page — but claude mcp get lovable still shows "Needs authentication" immediately after, and mcp-needs-auth-cache.json's lovable timestamp was bumped to match.

No error is surfaced to the user in the CLI//mcp UI explaining why the completed authorization wasn't accepted — from the user's perspective the browser said "success" but nothing changed.

Expected Behavior

When the OAuth provider redirects back with a valid authorization code and the CLI's token exchange succeeds (which the browser's "Authentication successful" page implies happened on the provider's side), claude mcp get <server> should report Status: ✓ Connected (or similar) and the server's tools should become available. If the CLI-side token exchange itself fails after a successful provider-side authorization, that failure should be surfaced explicitly (not silently re-flagged as "needs auth" with no error).

Actual Behavior

  • Browser: "Connected / Authentication successful. You can close this tab and return to Claude Code."
  • CLI (claude mcp get lovable), run immediately after: Status: ! Needs authentication
  • ~/.claude/mcp-needs-auth-cache.json: the lovable entry's timestamp field is updated to a new (later) value at the same time — i.e. the CLI actively re-marks the server as needing auth rather than leaving stale state.
  • No error message is shown anywhere in the CLI output explaining the discrepancy.

Environment

  • Claude Code CLI version: 2.1.220 (macOS, Darwin 25.5.0)
  • MCP server: lovable, transport http, URL https://mcp.lovable.dev
  • Config scope: user (global), with --callback-port 45678 set explicitly to work around a separate/earlier redirect_uri mismatch (attempt 1 above)
  • No proxy, VPN, or SSH/remote session involved — local interactive /mcp flow in a native terminal session

Steps to Reproduce

  1. claude mcp add --transport http lovable https://mcp.lovable.dev --scope user --callback-port <fixed-port>
  2. In a Claude Code session, run /mcp and select Authenticate for lovable
  3. Complete the OAuth flow in the browser through to the "Authentication successful" confirmation page
  4. Run claude mcp get lovable — observe Status: ! Needs authentication despite step 3

Additional Notes

This is a different failure mode from the DCR client_id eviction case in #72818 (that one dead-ends at /authorize with an HTTP error page before any success is shown) — here the entire browser-side flow completes successfully, and the failure is purely in the CLI's handling/persistence of that successful result. Also distinct from the pure redirect_uri mismatch reports (#37747, #66511) that fail before reaching a success page at all — the --callback-port fix did get us past that stage, but exposed this second, later-stage failure.

Happy to provide additional debug output if there's a way to get more verbose OAuth/token-exchange logging from the CLI.

View original on GitHub ↗