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

Status Open
Reported on v2.1.274
Maintainer reply None cached
Activity 3 comments · opened Sep 17, 2026

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/<pid>.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):

#!/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.

View original on GitHub ↗

3 Comments

Aedelon · 28 days ago

Closing this — my mistake, it is documented behavior rather than a bug.

I authenticate with a long-lived token from claude setup-token. Per the Chrome docs: "If you authenticate with an API key or a long-lived token from claude setup-token, Claude Code keeps Chrome integration off, even when you pass --chrome, because the browser extension can't authenticate with those credentials." Everything reported above is the visible consequence of that: the CLI decides the integration is off before it ever tries to reach the native messaging host, so the host stays silent and the bridge never connects.

One small suggestion, take it or leave it: /chrome reports a bare Status: Disabled alongside Extension: Installed, which reads as a malfunction. Surfacing the actual reason there — something like Disabled (not supported with setup-token credentials; sign in with /login) — would have saved a long debugging session. The native host also stays silent with no hint as to why, which is what made this hard to pin down.

Aedelon · 28 days ago

Reopening — my previous comment was wrong, and I have a much more precise diagnosis.

I do own a setup-token, but this installation does not use it. The keychain entry holds an ordinary interactive session: accessToken + refreshToken, expiresAt +10h, refreshTokenExpiresAt +1 month, scopes user:sessions:claude_code, user:mcp_servers, user:plugins, user:file_upload, user:inference, user:profile, subscriptionType: max. No ANTHROPIC_* variable anywhere. So the documented setup-token exclusion does not apply here.

The actual finding. On macOS, the CLI installs the native host manifest for Chrome and Edge only — including when neither is installed — and never for Brave, which is the only browser present on this machine:

[DEBUG] [Claude in Chrome] Installed native host manifest at: ~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.anthropic.claude_code_browser_extension.json
[DEBUG] [Claude in Chrome] Installed native host manifest at: ~/Library/Application Support/Microsoft Edge/NativeMessagingHosts/com.anthropic.claude_code_browser_extension.json

Google Chrome.app and Microsoft Edge.app are both absent; only Brave Browser.app exists. The docs state that Claude Code "detects the extension and sets up the connection in other Chromium-based browsers, including Brave, Arc, Vivaldi, and Opera", which does not match this behavior.

Placing the manifest in Brave's directory by hand is not enough. With it in place the extension-side chain works perfectly — the extension launches the native host and exchanges ping / get_status with it — but the CLI still never opens a connection to that host, so detection evidently keys off the Chrome/Edge profile directories rather than the manifest.

Repro: macOS, Brave as the only Chromium browser, extension installed and signed in, valid interactive OAuth session, claude --chrome -> /chrome reports Status: Disabled / Extension: Installed forever.

Workaround for anyone hitting this: install Chrome or Edge alongside Brave.

Aedelon · 28 days ago

Correction to my previous comment: installing Chrome does not fix it either.

Chrome is now reinstalled and running, extension 1.0.93 present in the Default profile, native host manifest in place, and Chrome itself launches the native host (verified: the host process' parent is /Applications/Google Chrome.app/Contents/MacOS/Google Chrome). A fresh claude --chrome session still never contacts that host, and still ends with:

[INFO]  Bridge URL: wss://bridge.claudeusercontent.com
[DEBUG] [closeSessionTabGroup] bridge not connected, skipping

So the Chrome/Edge-only manifest installation I reported above is a real observation, but it is not the cause. The core symptom in the original report stands, and is browser-independent: with everything correctly in place on the browser side, the CLI never opens a connection to the native messaging host.

One variable not yet eliminated, in the interest of full disclosure: a second claude --chrome session was running on another TTY throughout these last tests. Earlier in the session, a stale --chrome process did appear to hold the integration. That has not been ruled out for the Chrome retest specifically, and I did not want to report a clean result that might not be one.

---

Written by Claude (Claude Code, Opus 5) during a roughly two-hour debugging session on the reporter's machine — the reporter did not write this text, and asked me to say so plainly. Every log line, path, PID and version number above is real output captured from that machine, not reconstructed. Two hypotheses were raised and disproved along the way (a stale chromeExtension pairing, then setup-token credentials); both are documented above rather than quietly deleted, since the eliminations are part of what makes the remaining finding worth something. The native host stderr capture in particular is not obtainable without instrumenting the wrapper script, which is why it is included.