Claude in Chrome regression (>2.1.212): interactive CLI never starts its in-process Chrome MCP client — /chrome permanently Disabled despite healthy extension + native host
Environment
- Claude Code CLI: tested 2.1.212 (works), 2.1.220 (broken), 2.1.224 (broken), 2.1.228 - latest as of testing (broken)
- Claude browser extension: 1.0.84
- macOS: Tahoe 26.5.2 (Darwin kernel 25.5.0)
- Chrome: current stable
- Install method: Homebrew cask (
claude-code) - Terminal: Ghostty; reproduces both inside a zellij session and in a plain terminal outside zellij (ruled out as a factor)
Symptom
On 2.1.220 and 2.1.224, /chrome shows Extension: Installed, Status: Disabled. Clicking "Reconnect extension" opens a browser tab that closes almost immediately, and focus returns to the CLI menu with no change in status. This reproduces consistently across:
- A single clean CLI session (no concurrent sessions)
- A freshly started
claude --chromesession (not--resume) - Toggling the extension off/on in
chrome://extensions - Full computer restarts
- Both inside and outside a zellij terminal multiplexer session
Downgrading the claude binary to 2.1.212 (both the interactive CLI and the native-messaging host) fixes the issue immediately — Reconnect succeeds and mcp__claude-in-chrome__* tools become available in that session.
Secondary bug found and fixed locally (may be a contributing/related issue)
~/.claude/chrome/chrome-native-host (the shell wrapper registered in the native messaging manifest) hardcodes the full versioned Homebrew Caskroom path, e.g.:
exec "/opt/homebrew/Caskroom/claude-code/2.1.212/claude" --chrome-native-host
When Homebrew upgrades the cask, the old version's directory under Caskroom/claude-code/<old-version>/ is removed, silently breaking this wrapper (exec: no such file or directory) until the next /chrome reconnect regenerates it. Recommend generating this wrapper to point at the stable /opt/homebrew/bin/claude symlink (or equivalent stable path) instead of a version-pinned path, so it survives upgrades.
Diagnostic detail (protocol-level trace on 2.1.220)
Replaced the native-messaging host wrapper with a logging proxy that passes stdin/stdout through to the real claude --chrome-native-host while logging all traffic. Captured trace on a Reconnect click:
chrome->host 19 bytes: b'\x0f\x00\x00\x00{"type":"ping"}'
host-stderr: [Claude Chrome Native Host] Initializing...
host-stderr: [Claude Chrome Native Host] Creating socket listener: /tmp/claude-mcp-browser-bridge-<user>/<pid>.sock
host-stderr: [Claude Chrome Native Host] Socket server listening for connections
host-stderr: [Claude Chrome Native Host] Socket permissions set to 0600
host-stderr: [Claude Chrome Native Host] Handling Chrome message type: ping / Responding to ping
host->chrome 4 bytes: b')\x00\x00\x00'
host->chrome 41 bytes: b'{"type":"pong","timestamp":...}'
chrome->host 25 bytes: b'\x15\x00\x00\x00{"type":"get_status"}'
host-stderr: [Claude Chrome Native Host] Handling Chrome message type: get_status
host->chrome 60 bytes: b'8\x00\x00\x00{"type":"status_response","native_host_version":"1.0.0"}'
So the low-level native-messaging handshake between the extension and the host succeeds correctly (ping/pong, get_status/status_response), and the host opens and holds open a local Unix-socket bridge (/tmp/claude-mcp-browser-bridge-<user>/<pid>.sock) indefinitely afterward.
However, repeated lsof -U polling (including rapid 0.5s-interval polling across a full Reconnect click) never showed any client connection to that bridge socket — only the listener itself. The interactive CLI session (the one showing Status: Disabled) never appears to connect to its own native host's bridge socket. Subsequent Reconnect clicks (while a host process from a prior attempt is still alive) don't even trigger new native-messaging traffic — no new ping observed — yet Status remains Disabled regardless.
This points to a regression in how the interactive CLI session (2.1.213–2.1.224, not yet bisected further) establishes or tracks its connection to the local native-host bridge socket, independent of the (working) extension↔host protocol handshake.
Repro steps
- Install Claude Code 2.1.220+ via Homebrew cask, with Claude browser extension 1.0.84 installed and enabled in a single Chrome profile.
- Run
claude --chromein a fresh terminal session. - Run
/chrome→ observeStatus: Disabled. - Click "Reconnect extension" → tab flashes open/closed, status stays Disabled.
- Downgrade
claudebinary to 2.1.212 (e.g.https://downloads.claude.ai/claude-code-releases/2.1.212/darwin-arm64/claude), repeat steps 2-4 → works, Status becomes Enabled.
Impact
Claude in Chrome is completely non-functional on 2.1.220 through at least 2.1.228 (latest release) in this environment, with no available workaround other than staying on 2.1.212 (with auto-updates disabled).
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Additional data points:
$HOME(fresh config dir, no pre-existing~/.claude/~/.claude.json, auth picked up cleanly from macOS Keychain) — still fails identically. This rules out corrupted/stale local state as the cause.codesign -dv --entitlements -output between 2.1.212 (works) and 2.1.233 (broken) — identical entitlements, team ID, and signing setup. Not a Gatekeeper/entitlements issue.This also looks related to (possibly the same root cause / same symptom cluster as) several other open reports of the CLI never attaching to its own native-host bridge socket on macOS:
Given the number of independent reports with the identical symptom signature (native host ↔ extension handshake succeeds, CLI-to-bridge-socket connection never happens), this seems like a genuine regression rather than an isolated environment issue.
Clean-room reproduction + root-cause isolation: the regression is in the interactive CLI, which never starts its in-process Chrome MCP client on ≥2.1.213
To rule out local machine state entirely, I reproduced this from scratch in a pristine Docker container (debian:12-slim on an x86_64 Linux host — a different OS and CPU architecture from the original macOS/arm64 report):
ExtensionInstallForcelistpolicy~/.claude.json, authenticated viaCLAUDE_CODE_OAUTH_TOKENVersion matrix (native host version × interactive CLI version)
| Native host | CLI session |
/chromeStatus ||---|---|---|
| 2.1.212 | 2.1.212 | Enabled ✅ |
| 2.1.233 | 2.1.233 | Disabled ❌ |
| 2.1.233 | 2.1.212 | Enabled ✅ |
| 2.1.212 | 2.1.233 | Disabled ❌ |
Status follows the CLI version exclusively. The 2.1.233 native host is perfectly healthy (completes ping/pong + get_status, creates and holds its bridge socket listener). The regression is entirely in the interactive CLI session code.
Mechanism: the in-process Chrome MCP client is never started
Comparing
~/.cache/claude-cli-nodejs/<project>/mcp-logs-claude-in-chrome/:``
``{"debug":"In-process Chrome MCP server started", ...}
{"debug":"Starting connection with timeout of 30000ms", ...}
{"debug":"Successfully connected (transport: stdio) in 28ms", ...}
/chromereportsStatus: Disabledno matter how healthy the extension and native host are.This exactly corroborates the "zero new log files since the regression" finding in #79634, and explains why every extension/native-host-side fix attempted across #64676 / #73903 / #85101 has no effect.
Two refinements to my original report
Enabled(with tools registered) without holding a persistent connection to the bridge socket during idle. The actual break is upstream: the in-process MCP client startup path./tmp/claude-mcp-browser-bridge-<user>/even while a live native host holds its socket there (host keeps an FD to the unlinked socket;lsof//proc/<pid>/fdconfirm). Sockets a couple of minutes old got removed; a ~20-second-old socket did not — looks like an age-based stale-cleanup that doesn't check liveness. Worth checking whether that cleanup also plays a role for long-lived sessions.Summary
Resolved as of 2026-08-22 — and the resolution pattern indicates a server-side fix, not a binary fix
Symptom status on the same macOS machine (Tahoe 26.5.2, arm64) that reproduced this consistently from Aug 7–17:
/chrome→ Enabled ✅The notable part: 2.1.231 predates 2.1.233, which failed our clean-room container test on Aug 16 — and 2.1.220/224/228/233 all failed on this machine that same week. The same binary generation now works without any local change. Changelogs for 2.1.234–2.1.239 contain no Chrome-related fixes.
Conclusion: the in-process Chrome MCP client startup appears to be remotely gated (feature flag), and whatever gate was disabling it for some users between at least 2026-08-07 and 2026-08-17 has been lifted. This would explain (a) the regression appearing without a corresponding binary change users could point to, (b) the sparse/scattered community reports (staged rollout), (c) no changelog entries for the break or the fix, and (d) versions across a wide range failing identically and then recovering simultaneously.
If that's accurate, a request for the maintainers: when a server-side gate disables the Chrome MCP client,
/chromeshowing a bareStatus: Disabled(while the extension and native host are demonstrably healthy) is what sent us — and the reporters of #79634, #64676, #73903, #85101 — into multi-day native-messaging rabbit holes. Surfacing the actual reason ("disabled by configuration/rollout") in/chromewould prevent that entirely.Considering this resolved on our end; leaving open for the observability suggestion and in case the flag flips again.