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

Status Fixed / completed
Reported on v2.1.212
Maintainer reply None cached
Activity 4 comments · opened Aug 7, 2026 · closed Aug 22, 2026

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 --chrome session (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

  1. Install Claude Code 2.1.220+ via Homebrew cask, with Claude browser extension 1.0.84 installed and enabled in a single Chrome profile.
  2. Run claude --chrome in a fresh terminal session.
  3. Run /chrome → observe Status: Disabled.
  4. Click "Reconnect extension" → tab flashes open/closed, status stays Disabled.
  5. Downgrade claude binary 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).

View original on GitHub ↗

3 Comments

jadshaker · 1 month ago

Additional data points:

  • Tested 2.1.228 and 2.1.233 (latest as of this writing) — both still reproduce the exact same failure (native host completes handshake, CLI never attaches to the bridge socket).
  • Ran 2.1.233 with a completely isolated $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.
  • Compared 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:

  • #64676
  • #73903
  • #85101
  • #79634

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.

jadshaker · 1 month ago

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):

  • Chrome 151.0.7922.137 (fresh profile, no prior state)
  • Claude extension 1.0.85, installed from the Chrome Web Store via ExtensionInstallForcelist policy
  • Claude Code 2.1.212 and 2.1.233 (linux-x64 builds), fresh ~/.claude.json, authenticated via CLAUDE_CODE_OAUTH_TOKEN
  • Native messaging manifest + wrapper script set up identically to what the CLI generates

Version matrix (native host version × interactive CLI version)

| Native host | CLI session | /chrome Status |
|---|---|---|
| 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/:

  • Every 2.1.212 CLI session immediately creates a log file:

``
{"debug":"In-process Chrome MCP server started", ...}
{"debug":"Starting connection with timeout of 30000ms", ...}
{"debug":"Successfully connected (transport: stdio) in 28ms", ...}
``

  • Neither 2.1.233 CLI session created any log file at all — the in-process Chrome MCP client never starts, so /chrome reports Status: Disabled no 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

  1. The original "CLI never dials the bridge socket" observation is a downstream symptom, not the root cause — on working 2.1.212 the session shows 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.
  2. One additional observed behavior on 2.1.233 (single occurrence, macOS + container run 1): the freshly-started CLI appears to delete /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>/fd confirm). 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

  • Regression window: >2.1.212, ≤2.1.220 (2.1.220, 2.1.224, 2.1.228, 2.1.233 all broken; 2.1.212 works)
  • Reproduces on macOS 26.5.2/arm64 (Homebrew install) and clean Debian 12 container/x86_64 — not machine-, OS-, arch-, or state-specific
  • Native host, extension, manifests, account: all healthy on every broken version
  • Broken versions never start the in-process "Claude in Chrome" MCP server in interactive sessions (no mcp-logs-claude-in-chrome file is ever created)
jadshaker · 1 month ago

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:

  • 2.1.239: /chrome → Enabled ✅
  • 2.1.231 (current Homebrew cask): Enabled, full browser tool chain verified working (tab create → navigate → screenshot → close) ✅
  • Native host during these tests was still the old 2.1.212 binary — irrelevant, consistent with the earlier matrix showing the CLI side determines the outcome.

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, /chrome showing a bare Status: 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 /chrome would prevent that entirely.

Considering this resolved on our end; leaving open for the observability suggestion and in case the flag flips again.

Showing cached comments. Read the full discussion on GitHub ↗