[BUG] Claude in Chrome: handshake fails even after full recovery (CLI 2.1.117, ext 1.0.69)
Summary
mcp__claude-in-chrome__* tools return "Browser extension is not connected" on every call, despite:
- Claude Code CLI authenticated to the same org and email as the
claude.aiChrome session (verified via avatar menu +claude auth status) - Chrome extension installed, enabled, toggled OFF→ON
- Chrome fully restarted (
osascript quit+open -a) - Native messaging host respawned (new PID observed each toggle)
- Local + Managed Extension Settings for the extension wiped
/tmp/claude-mcp-browser-bridge-*/*.sockcleaned- Logged out of
claude.aiand back in, with matching account confirmed
Same-shape bug as #52559 (filed 2026-04-23). I can confirm the full recovery checklist from the community docs (toggle, storage wipe, Chrome restart, re-login) does not unblock it on CLI 2.1.117.
Environment
| Field | Value |
| --- | --- |
| OS | macOS Darwin 25.4.0 |
| Claude Code CLI | 2.1.117 (native build, ~/.local/share/claude/versions/2.1.117) |
| Browser | Google Chrome (latest stable); Brave also installed |
| Extension | Claude for Chrome 1.0.69_0, ID fcoeoabgfenejglbffodgkkbkcdhcgfn |
| Subscription | paid team plan |
Key observation — MCP says connected, tool says not connected
When probed with claude --chrome -p "..." --output-format=stream-json --verbose, the init event reports:
"mcp_servers":[
...,
{"name":"claude-in-chrome","status":"connected"},
...
]
So the MCP server registration succeeds. But the tool invocation itself (mcp__claude-in-chrome__tabs_context_mcp with no args) returns the "not connected" error verbatim. The failure is inside the native-host ↔ extension stdio dialogue, not at the MCP socket layer.
Native host state during failure
Host is alive with stdio PIPE to the Chrome extension AND a listening unix socket — but never receives an accepted client connection:
$ lsof -p <host-pid> | grep -E "sock|PIPE|unix"
2.1.117 <pid> user 0 PIPE ... ->... (stdin from extension)
2.1.117 <pid> user 1 PIPE ... ->... (stdout to extension)
2.1.117 <pid> user 4u unix ... /tmp/claude-mcp-browser-bridge-<user>/<pid>.sock
2.1.117 <pid> user 5 PIPE ... ->... (dup of fd 1)
No accepted client socket on the host. Each new claude --chrome -p probe also never opens a connection back to the socket:
$ lsof -U | grep claude-mcp-browser
2.1.117 <host-pid> user 4u unix ... /tmp/claude-mcp-browser-bridge-<user>/<pid>.sock
# only the listening entry
So either the extension is rejecting the handshake before the host accepts, or the host is rejecting before listening accepts — but the extension → host stdio is definitely live (PIPEs active, otherwise the service worker wouldn't have spawned the host at all).
Steps attempted (none fixed it)
chrome://extensions/→ Claude card → toggle OFF → verifyps aux | grep chrome-native-hostis empty → toggle ON → new host spawns →claude --chrome→ NOTCONNECTEDosascript -e 'tell application "Google Chrome" to quit'→open -a "Google Chrome"→ new host spawns → NOTCONNECTEDrm -rf "~/Library/Application Support/Google/Chrome/Default/Local Extension Settings/fcoeoabgfenejglbffodgkkbkcdhcgfn"+ Managed Extension Settings + Chrome restart → new host → NOTCONNECTED- Logout of
claude.aiweb, login back with the CLI account → refresh → NOTCONNECTED - All of the above combined, in the sequence recommended by community docs → NOTCONNECTED
Every probe observes fresh PIDs: 5 consecutive respawned hosts over the session, each with a fresh unix socket. Fresh bridgeSessionId per CLI probe, so the stale-session-lock gotcha can be ruled out.
Secondary finding — Brave manifest auto-regenerates
Not a blocker here, but contributes to making the CLI integration hard to keep stable on a dual-browser macOS install where Claude.app is also present:
~/Library/Application Support/BraveSoftware/Brave-Browser/NativeMessagingHosts/
com.anthropic.claude_browser_extension.json (re-appears whenever Claude.app launches)
Any launch of /Applications/Claude.app regenerates that manifest in Brave (and Chrome) even if the user previously renamed it to .disabled. If Claude.app is also installed, the desktop native-messaging wrapper can intercept the extension from the wrong binary; users have to chase the manifest and rename it again. Making the manifest write idempotent against a .disabled sibling, or honouring a .claude-no-regen marker, would help.
What would help diagnose further
The extension service worker's DevTools console would almost certainly show the actual rejection cause. Could the extension surface the handshake-refusal reason in the extension popup or in chrome.runtime.lastError? Right now the user-facing error message is fully generic and points at the three things that are demonstrably already correct (installed, enabled, logged into matching account).
Related issues
- #52559 — same-shape symptom, filed 2026-04-23
- #47202 —
--chromeflag: MCP client never connects to Chrome native host socket - #42344 — Chrome extension MCP tools report 'not connected' despite successful pairing (macOS, v2.1.90)
- #40758, #38845, #36910 — earlier broken-handshake reports on 1.0.63
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗