Chrome MCP fails with misleading "Browser extension is not connected" when CLI's OAuth token is missing the bridge scope

Resolved 💬 2 comments Opened May 24, 2026 by kalebjdavenport Closed May 27, 2026

Summary

Calling any mcp__claude-in-chrome__* tool from standalone claude returns:

Browser extension is not connected. Please ensure the Claude browser extension is installed and running...

The error message points at extension install / account / restart-Chrome troubleshooting, but in my case none of those were the cause. The actual cause was that my CLI's OAuth token in macOS Keychain only had the user:inference scope and was missing user:sessions:claude_code (which the Chrome bridge requires).

Re-running claude login from scratch fixed it: the new token came back with the full scope set and Chrome MCP started working immediately.

Environment

  • Claude Code 2.1.150 on macOS
  • Google Chrome Beta with the Claude in Chrome extension installed and signed in
  • Claude Max subscription

Reproduction

With an existing Keychain token that only has the user:inference scope:

security find-generic-password -s 'Claude Code-credentials' -w \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['claudeAiOauth']['scopes'])"
# → ['user:inference']

From Warp (or any terminal), run claude and ask it to call mcp__claude-in-chrome__tabs_context_mcp with createIfEmpty=true. It fails in ~5 seconds with the "Browser extension is not connected" error.

Meanwhile, Claude Desktop on the same machine drives Chrome fine — confirming the extension/account/network are not the problem.

Fix

security delete-generic-password -s 'Claude Code-credentials'
claude   # opens browser, prompts for OAuth
# After completing login:
security find-generic-password -s 'Claude Code-credentials' -w \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['claudeAiOauth']['scopes'])"
# → ['user:profile', 'user:inference', 'user:sessions:claude_code', 'user:mcp_servers', 'user:file_upload']

Chrome MCP starts working immediately after the new login. No other changes needed.

Why this is hard to diagnose

The "Browser extension is not connected" message lists three potential causes (extension installed/running, account mismatch, restart Chrome) — none of which apply when the actual cause is a missing OAuth scope. There's no hint in the error that auth/scopes might be involved.

It's especially confusing because there's a parallel native-messaging-host stack on the same machine that Claude Desktop uses but standalone Claude Code does not:

  • ~/Library/Application Support/Google/Chrome*/NativeMessagingHosts/com.anthropic.claude_code_browser_extension.json
  • ~/.claude/chrome/chrome-native-host (the wrapper that execs claude --chrome-native-host)
  • /tmp/claude-mcp-browser-bridge-$USER/*.sock

When the error appears, it's natural to start poking at the NMH layer (manifest paths, service-worker eviction, socket peers, deviceId pairing state, side panel state, etc.) — none of which are actually involved in standalone claude's Chrome MCP path. The CLI uses wss://bridge.claudeusercontent.com/chrome/<accountUuid> directly, not the local NMH bridge.

Suggested improvement

When the CLI gets back a rejection from the Chrome bridge that's caused by missing scopes, surface a more specific message, e.g.:

Your Claude Code token is missing the user:sessions:claude_code scope required for Chrome integration. Run claude logout && claude login to refresh.

That one change would have saved me hours of chasing unrelated layers.

Related issues

These don't capture this root cause but are adjacent:

  • #25551 (wrong-Chrome pairing on multi-Chrome machines)
  • #15125 (multi-profile / multi-instance feature request)

Diagnostic one-liner

For anyone else hitting this:

security find-generic-password -s 'Claude Code-credentials' -w \
  | python3 -c "import sys,json; s=json.load(sys.stdin)['claudeAiOauth']['scopes']; print('OK' if 'user:sessions:claude_code' in s else 'MISSING_SCOPE'); print('scopes:', s)"

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗