anthropics / anthropics/claude-code

Claude in Chrome: CLI never contacts the native messaging host (Status stays "Disabled")

Open
#95,004 3 comments 0 reactions 0 assignees View on GitHub
area:chrome area:mcp bug has repro platform:macos
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.