claude-in-chrome: misleading "extension not connected" error masks real cause (stale auth metadata + multi-app native host collision)
Summary
On macOS, mcp__claude-in-chrome__* tools fail with:
Browser extension is not connected. Please ensure the Claude browser extension is installed and running...
…when the extension is correctly installed, Chrome is running, the correct account is logged in, the native messaging manifest is registered, and --chrome is passed. The real root cause is elsewhere and the error message sends users on a wild goose chase. On this machine, two independent conditions were contributing:
- Stale auth metadata —
claude auth statusreportedsubscriptionType: nullandorgName: nulldespite an active Max subscription. While in this state, chrome integration failed silently with the "not connected" error. Afterclaude auth logout && claude auth login, both fields populated correctly and the integration started working immediately with no other changes. - Native messaging host collision — with Claude desktop also installed, Chrome preferentially spawns
/Applications/Claude.app/Contents/Helpers/chrome-native-hostas the native host because the extension'sconnectNativecall appears to be hard-coded tocom.anthropic.claude_browser_extension(the desktop app's host name) rather thancom.anthropic.claude_code_browser_extension.
The primary ask of this issue is (1): if subscriptionType is null, or the feature genuinely isn't available for the account, don't return "Browser extension is not connected" — that error implies a local installation problem and is actively misleading. Return something like "Claude in Chrome requires a Claude Max/Pro subscription and an active session — try claude auth login" or, if subscription data is genuinely missing (not false), refuse to initialize and say so.
Environment
- macOS (Darwin 25.4.0)
- Claude Code 2.1.101
- Google Chrome 147.0.7727.56
- Claude in Chrome extension 1.0.66 (ID:
fcoeoabgfenejglbffodgkkbkcdhcgfn) - Claude desktop app also installed
- Account: Claude Max (active)
What was actually wrong
After a fresh claude auth logout && claude auth login, the feature worked on the first invocation with no additional changes. claude auth status before login had shown:
{
"loggedIn": true,
"email": "...",
"orgId": "...",
"orgName": null,
"subscriptionType": null
}
After re-login:
{
"loggedIn": true,
"email": "...",
"orgId": "...",
"orgName": "...",
"subscriptionType": "max"
}
So the auth session was in a half-valid state — logged in enough to make API calls, not logged in enough to have subscription metadata, and the chrome integration path chose to surface that as "extension not connected" instead of "your session is missing subscription info".
Everything we tried before spotting the subscription metadata
Logging this in detail so whoever debugs the error surface can see exactly how misleading it is:
- Verified extension ID
fcoeoabgfenejglbffodgkkbkcdhcgfnmatches the allowed origin in~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.anthropic.claude_code_browser_extension.json - Verified
claude auth statusemail matches the extension's logged-in account - Fully quit Chrome (⌘Q), restarted, retried — no change
- Uninstalled and reinstalled the Chrome extension — no change
claude mcp list— confirmedclaude-in-chromeis not an MCP server in the normal sense (it's built-in, gated behind--chrome)- Relaunched Claude Code with explicit
--chromeflag — no change (tools appear in the deferred tool list, but calling them still returns "not connected") - Checked
~/.claude/chrome/chrome-native-host— wrapper script is present, executable, points at a real binary - Opened the Claude in Chrome extension's
options.html#permissions,shortcuts, andoptionspages — no UI to pair with Claude Code (vs. Claude desktop) - Ran
lsof -U | grep claude-mcp-browser-bridge— found a live native host process, traced its PID viapsto/Applications/Claude.app/Contents/Helpers/chrome-native-host(the desktop host, not Claude Code's) - Fully quit the Claude desktop app (⌘Q from menu bar), toggled the extension off/on — Chrome still respawned the desktop host; the extension apparently hard-codes that host name
- Renamed
com.anthropic.claude_browser_extension.json→.bakto remove desktop from Chrome's native messaging lookup - Toggled the extension off/on again — this time Chrome spawned
/Users/.../.local/share/claude/versions/2.1.101 --chrome-native-host, i.e. the Claude Code binary. Confirmed viaps+lsof. - Verified the bridge socket (
/tmp/claude-mcp-browser-bridge-willclark/<pid>.sock) exists, is owned by the user, permissions aresrw-------, andnc -U <sock>accepts connections - Called
mcp__claude-in-chrome__tabs_context_mcpagain — still "Browser extension is not connected" - Killed the native host and the stale socket file, toggled the extension again, fresh native host spawned — still "not connected"
lsof -p <cli-pid>showed zero open unix sockets in the running Claude Code session — it was never attempting to connect on the client side- Restarted the entire Claude Code CLI session fresh with
--chrome(not resumed) — still "not connected" - At this point, noticed
subscriptionType: nullinclaude auth statusdespite being on Max - Ran
claude auth logout && claude auth login— fields populated, chrome integration worked on the very first tool call with no other changes
Suggested fixes
- Error surface: do not return "Browser extension is not connected" when the actual failure is a missing-or-stale subscription field, a feature gate, or any other server-side determination. If the client can see that
subscriptionTypeisnull/unknown, say so explicitly and suggestclaude auth login - Auth freshness: it should not be possible for
claude auth statusto showloggedIn: truewhileorgNameandsubscriptionTypeare bothnullon an active paid account. Either refresh that metadata on login, or refuse to mark the session asloggedIn: trueuntil the account profile has been hydrated - Multi-app native host routing: when both Claude desktop and Claude Code are installed, the Claude in Chrome extension should either let the user pick which app to pair with, or auto-detect which native host to use (e.g. try
com.anthropic.claude_code_browser_extensionfirst when Claude Code is the active caller). Requiring users to manually rename a JSON manifest is not a great story - Debug output:
--chrome --debug chromedidn't produce logs in~/.claude/debug/that would have short-circuited any of the above
Cost of this investigation
For context on how misleading the error message is, debugging this in an interactive Claude Code session consumed approximately 9.76M tokens (383 input / 230K cache creation / 9.47M cache read / 58.8K output) across multiple session restarts. I would've happily traded all of that for a single error string that mentioned "subscription" or "auth refresh." Please consider this issue a gentle vote in favor of more specific error messages. 🙂
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗