claude-code - 💡(How to fix) Fix claude-in-chrome: Bridge rejects valid OAuth token with 'Invalid OAuth token' (close 1008) [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#54290Fetched 2026-04-29 06:31:19
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
0
Timeline (top)
labeled ×5commented ×1

claude-in-chrome fails to connect because the bridge server (wss://bridge.claudeusercontent.com) rejects the OAuth token issued by claude --chrome with {"type":"error","error":"Invalid OAuth token"} and closes the WebSocket with code 1008. Re-running /login does not fix it — a fresh token from keychain is rejected the same way. All local prerequisites (extension installed/enabled, manifests in place, native messaging host running, both ends connected to the bridge) are verified working.

Error Message

[INFO] Bridge URL: wss://bridge.claudeusercontent.com [DEBUG] MCP server "claude-in-chrome": In-process Chrome MCP server started [INFO] [Claude in Chrome] ensureConnected called, connected=false, authenticated=false [DEBUG] [Claude in Chrome] Fetching user ID for bridge connection [DEBUG] [Claude in Chrome] Fetching OAuth token for bridge connection [INFO] [Claude in Chrome] Connecting to bridge: wss://bridge.claudeusercontent.com/chrome/bfc431e6-4fb1-4b8d-8d43-034a2aac310b [INFO] [Claude in Chrome] WebSocket connected, sending connect message [DEBUG] [Claude in Chrome] Bridge received: {"type":"error","error":"Invalid OAuth token"} [WARN] [Claude in Chrome] Bridge error: Invalid OAuth token [INFO] [Claude in Chrome] Bridge connection closed (code: 1008, duration: 0ms) [INFO] [Claude in Chrome] Bridge reconnecting in 2000ms (attempt 1)

Root Cause

claude-in-chrome fails to connect because the bridge server (wss://bridge.claudeusercontent.com) rejects the OAuth token issued by claude --chrome with {"type":"error","error":"Invalid OAuth token"} and closes the WebSocket with code 1008. Re-running /login does not fix it — a fresh token from keychain is rejected the same way. All local prerequisites (extension installed/enabled, manifests in place, native messaging host running, both ends connected to the bridge) are verified working.

Fix Action

Workaround

None known on the user side. chrome-devtools-mcp (separate plugin) works; native claude-in-chrome does not.

Code Example

[INFO] Bridge URL: wss://bridge.claudeusercontent.com
[DEBUG] MCP server "claude-in-chrome": In-process Chrome MCP server started
[INFO] [Claude in Chrome] ensureConnected called, connected=false, authenticated=false
[DEBUG] [Claude in Chrome] Fetching user ID for bridge connection
[DEBUG] [Claude in Chrome] Fetching OAuth token for bridge connection
[INFO] [Claude in Chrome] Connecting to bridge:
       wss://bridge.claudeusercontent.com/chrome/bfc431e6-4fb1-4b8d-8d43-034a2aac310b
[INFO] [Claude in Chrome] WebSocket connected, sending connect message
[DEBUG] [Claude in Chrome] Bridge received: {"type":"error","error":"Invalid OAuth token"}
[WARN]  [Claude in Chrome] Bridge error: Invalid OAuth token
[INFO] [Claude in Chrome] Bridge connection closed (code: 1008, duration: 0ms)
[INFO] [Claude in Chrome] Bridge reconnecting in 2000ms (attempt 1)

---

scopes:        ['user:file_upload', 'user:inference', 'user:mcp_servers',
                'user:profile', 'user:sessions:claude_code']
expiresAt:     1777405575255  (well in the future)
subscriptionType: max
rateLimitTier:    default_claude_max_20x
RAW_BUFFERClick to expand / collapse

Summary

claude-in-chrome fails to connect because the bridge server (wss://bridge.claudeusercontent.com) rejects the OAuth token issued by claude --chrome with {"type":"error","error":"Invalid OAuth token"} and closes the WebSocket with code 1008. Re-running /login does not fix it — a fresh token from keychain is rejected the same way. All local prerequisites (extension installed/enabled, manifests in place, native messaging host running, both ends connected to the bridge) are verified working.

Environment

  • Claude Code: 2.1.121 (Claude Code)
  • Chrome extension: 1.0.69 (ID fcoeoabgfenejglbffodgkkbkcdhcgfn)
  • Browser: Google Chrome 147.0.7727.116 (arm64)
  • OS: macOS 26.4.1 (Apple Silicon)
  • Subscription: claude_max (default_claude_max_20x, organizationType claude_max, role admin)
  • Account: [email protected]
  • accountUuid: bfc431e6-4fb1-4b8d-8d43-034a2aac310b

Reproduction

  1. claude --chrome --debug-to-stderr -p "use mcp__claude-in-chrome__tabs_context_mcp"
  2. Tool returns Browser extension is not connected.

Repeated immediately after a successful /login — same result.

Debug log (CLI side)

[INFO] Bridge URL: wss://bridge.claudeusercontent.com
[DEBUG] MCP server "claude-in-chrome": In-process Chrome MCP server started
[INFO] [Claude in Chrome] ensureConnected called, connected=false, authenticated=false
[DEBUG] [Claude in Chrome] Fetching user ID for bridge connection
[DEBUG] [Claude in Chrome] Fetching OAuth token for bridge connection
[INFO] [Claude in Chrome] Connecting to bridge:
       wss://bridge.claudeusercontent.com/chrome/bfc431e6-4fb1-4b8d-8d43-034a2aac310b
[INFO] [Claude in Chrome] WebSocket connected, sending connect message
[DEBUG] [Claude in Chrome] Bridge received: {"type":"error","error":"Invalid OAuth token"}
[WARN]  [Claude in Chrome] Bridge error: Invalid OAuth token
[INFO] [Claude in Chrome] Bridge connection closed (code: 1008, duration: 0ms)
[INFO] [Claude in Chrome] Bridge reconnecting in 2000ms (attempt 1)

The reconnect loop continues with the same error indefinitely.

Token state (after fresh /login, "Login successful")

Stored in Claude Code-credentials keychain entry, modified seconds before the failure:

scopes:        ['user:file_upload', 'user:inference', 'user:mcp_servers',
                'user:profile', 'user:sessions:claude_code']
expiresAt:     1777405575255  (well in the future)
subscriptionType: max
rateLimitTier:    default_claude_max_20x

Token is fresh, has the expected user:mcp_servers and user:sessions:claude_code scopes, and is not expired — yet the bridge rejects it. The same OAuth context successfully authenticates regular CLI traffic (chat, MCP) to 160.79.104.10 (bridge IP) — only the WebSocket handshake on /chrome/<accountUuid> fails.

What is verified working (rules out common causes)

  • Extension is installed/enabled in chrome://extensions/, version 1.0.69 ≥ 1.0.36 (docs requirement).
  • Logged into claude.ai with the same email in the same Chrome profile; account UUID confirmed identical to the CLI.
  • Native messaging host launches: ~/.claude/chrome/chrome-native-host shim execs 2.1.121 --chrome-native-host and creates /tmp/claude-mcp-browser-bridge-vova/<pid>.sock.
  • Both manifests present and well-formed at ~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.anthropic.claude_code_browser_extension.json (path matches actual shim).
  • Coexistence with Claude Desktop: when com.anthropic.claude_browser_extension.json (Claude Desktop's manifest) is also present, the extension preferentially launches Claude.app/Contents/Helpers/chrome-native-host and Claude Code's host is never invoked. Renaming the Desktop manifest to .bak was required to make Claude Code's host start at all. (Worth fixing independently — Claude Desktop on the same machine silently breaks Claude Code's Chrome integration.)
  • After Desktop manifest is disabled and extension state is cleared (Local Extension Settings/, Sync Extension Settings/, Extension State/), both CLI and Chrome establish ESTABLISHED TCP sessions to 160.79.104.10:443 — but the WebSocket handshake on the CLI side is rejected at the application layer with the error above.
  • /login (which reports "Login successful" and refreshes the keychain entry's mdat) does not clear the bridge rejection; the next bridge connect attempt within seconds still gets Invalid OAuth token.
  • Network has no proxies/VPNs; direct HTTPS to bridge returns expected 426 Upgrade Required from Cloudflare edge.

Hypotheses

  1. The bridge requires a scope or claim (e.g. user:chrome_bridge, user:claude_code_chrome) that is not in the scope set issued by /login for claude_max subscriptions.
  2. Bridge auth is keyed on something different than claudeAiOauth.accessToken (a session-scoped or ephemeral token), and the CLI is sending the wrong one.
  3. Token is rejected because of a server-side org-routing mismatch (multi-org user) — though this user has only one org.

Workaround

None known on the user side. chrome-devtools-mcp (separate plugin) works; native claude-in-chrome does not.

Asks for the team

  1. Confirm which OAuth scope/audience the bridge expects from claude_max subscriptions in 2.1.121.
  2. If the issued token is missing a scope, server should respond with Insufficient scope rather than Invalid OAuth token so users can act on it.
  3. Consider auto-detecting the Claude Desktop manifest collision and either skipping it or warning the user — currently it silently breaks the integration on machines that also have Claude Desktop installed.

I'm happy to provide more logs, packet captures of the WS handshake, or the (redacted) JWT header/payload of the rejected token if useful.

extent analysis

TL;DR

The most likely fix is to verify the OAuth scope required by the bridge server and ensure the token issued by /login includes the necessary scope, such as user:chrome_bridge or user:claude_code_chrome.

Guidance

  1. Verify the required OAuth scope: Check the bridge server documentation or contact the development team to confirm the expected OAuth scope for claude_max subscriptions in version 2.1.121.
  2. Inspect the issued token: Examine the token issued by /login to ensure it includes the required scope; if not, investigate why the scope is missing.
  3. Test with an updated token: If the issued token is missing the required scope, try updating the token to include the necessary scope and test the bridge connection again.
  4. Check for server-side routing issues: If the token appears correct, investigate potential server-side routing issues, such as org-routing mismatches, that could be causing the token rejection.

Example

No code snippet is provided as the issue is related to OAuth scope and token validation, which requires specific knowledge of the bridge server's expected scope and authentication mechanism.

Notes

The issue may be related to a missing scope in the token issued by /login or a server-side routing issue. Further investigation is required to determine the root cause.

Recommendation

Apply a workaround by verifying the required OAuth scope and ensuring the token includes the necessary scope. If the issue persists, consider contacting the development team for further assistance.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING