anthropics / anthropics/claude-code
Claude in Chrome: CLI never contacts the native messaging host (Status stays "Disabled")
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
# Claude in Chrome: CLI never contacts the native messaging host (Status stays "Disabled")
## Summary
`/chrome` reports `Status: Disabled` / `Extension: Installed` on every session.
Every link in the chain works in isolation, except one: **the CLI never opens a
connection to the native messaging host**. The host's stderr stays completely
silent for the entire lifetime of a `claude --chrome` session, while the same
host happily serves `ping` and `get_status` from the extension seconds earlier.
## Environment
| | |
|---|---|
| OS | macOS (Darwin 27.0.0), Apple Silicon |
| Claude Code | 2.1.274 (Homebrew cask) |
| Browser | Brave 153.1.95.101 (only Chromium browser installed) |
| Extension | 1.0.93, installed and signed in |
| Plan | Claude Max (`organizationType: claude_max`) |
| Auth | OAuth via `/login` (no API key, no `setup-token`) |
## What works (verified)
- **Extension to native host**: host stderr shows `Handling Chrome message type: ping`,
`Responding to ping`, `Handling Chrome message type: get_status`
- **Native host**: starts, creates `/tmp/claude-mcp-browser-bridge-$USER/.sock`,
listens, sets mode 0600, cleans stale sockets
- **Network**: `wss://bridge.claudeusercontent.com` returns `HTTP 101 Switching Protocols`
- **MCP server**: `claude-in-chrome` connects over stdio in 3 ms, exposes its tools
(`tabs_context_mcp`, `tabs_create_mcp`, `navigate`, `read_page`)
- **Host config**: present at the documented Brave path, `allowed_origins` matches
the extension ID
## What fails
The CLI writes the wrapper script, logs the bridge URL, then stops:
```
[DEBUG] [Claude in Chrome] Created Chrome native host wrapper script: ~/.claude/chrome/chrome-native-host
[INFO] Bridge URL: wss://bridge.claudeusercontent.com
[DEBUG] MCP server "claude-in-chrome": Successfully connected (transport: stdio) in 3ms
[DEBUG] [closeSessionTabGroup] bridge not connected, skipping
```
No connection attempt to the native host is ever made. Consequence: browser tools
are rejected upstream of the permission system, even with an explicit
`mcp__claude-in-chrome__*` allow rule loaded:
```
[DEBUG] executePermissionRequestHooks called for tool: mcp__claude-in-chrome__tabs_context_mcp
[DEBUG] mcp__claude-in-chrome__tabs_context_mcp tool permission denied
```
`~/.claude.json` never gains a `chromeExtension` pairing entry, across many restarts.
## How the native host silence was observed
The wrapper is a shell script, so stderr can be redirected to a file (the CLI
rewrites this wrapper on every startup, so it must be re-applied):
```sh
#!/bin/sh
exec 2>>/tmp/native-host.log
exec "/opt/homebrew/bin/claude" --chrome-native-host
```
The extension's traffic shows up immediately. A full `claude --chrome` session
started afterwards adds **zero** lines.
## Things ruled out
- Conflicting native hosts from other Chromium browsers (Chrome, Edge) and their
orphaned sockets: removed, hosts disabled
- Concurrent/stale `claude --chrome` sessions holding the integration: all closed
- Revoked OAuth token (`401 authentication_error: OAuth access token has been
revoked`): fixed via `/logout` + `/login`, error gone, symptom unchanged
- Stale `chromeExtension` pairing and `hasCompletedClaudeInChromeOnboarding`:
removed from `~/.claude.json` to force re-pairing, no effect
- Extension reinstalled from the Web Store: no effect
- Extension service worker console: empty, no errors
- macOS TCC: not involved (stdio + Unix socket, no Apple Events)
- Managed settings / `deniedMcpServers`: no managed-settings.json on the machine
- Permission hooks: `PermissionRequest` hook matches `Bash` only
## Steps to reproduce
1. macOS with Brave as the only Chromium browser, Claude in Chrome extension installed and signed in
2. `claude --chrome`
3. `/chrome` -> `Status: Disabled`, `Extension: Installed`
4. `Reconnect extension` -> no change; no `chromeExtension` entry appears in `~/.claude.json`
## Note
The integration also never worked while Google Chrome was the browser in use, so
this is not Brave-specific.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at the CLI handling for `claude --chrome` and `--chrome-native-host`, then inspect the generated `~/.claude/chrome/chrome-native-host` wrapper and the `/chrome` reconnect flow. Reproduce with the stated steps while capturing `/tmp/native-host.log` and checking `~/.claude.json`. Done means the CLI contacts the native messaging host and the pairing entry and `/chrome` status update accordingly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, shell
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100