Claude in Chrome: Desktop wins host-selection race by default; forcing Claude Code's own host to launch (manifest-disable + extension toggle) still leaves MCP handshake incomplete

Open 💬 0 comments Opened Jul 9, 2026 by Eshquagama

Environment

  • macOS: 26.5.2 (build 25F84)
  • Google Chrome: 150.0.7871.115
  • Claude Code CLI: 2.1.204 (confirmed via running process path: `~/.local/share/claude/versions/2.1.204

--chrome-native-host`)

  • Claude Desktop: installed (/Applications/Claude.app)
  • Claude in Chrome extension: installed and enabled; extension ID fcoeoabgfenejglbffodgkkbkcdhcgfn
  • Both native-messaging manifests present and registered under `~/Library/Application

Support/Google/Chrome/NativeMessagingHosts/: com.anthropic.claude_browser_extension.json (Desktop) and
com.anthropic.claude_code_browser_extension.json` (Claude Code CLI)

## What was ruled out before this investigation

  • Extension policy / MDM — clean
  • Stale native-messaging host wrapper version — found and fixed, did not resolve the issue
  • Network/proxy/TLS interception on api.anthropic.com and bridge.claudeusercontent.com — both clean,

genuine cert chains, confirmed twice

  • Login-item auto-launch of Claude.app — not a login item
  • Documented GitHub-issue workaround (restart CLI with Chrome already running) — tried under controlled

conditions, no effect

  • /chrome → "Reconnect extension" documented flow — tried, no effect
  • Web-based reconnect URL (https://clau.de/chrome/reconnect) — tried manually, inconsistent behavior,

crashed Chrome once

## Root cause — now understood as two separate problems, not one
Part 1: host-selection race. When both native-messaging manifests are registered, Chrome/the extension
defaults to launching Claude Desktop's helper
(/Applications/Claude.app/Contents/Helpers/chrome-native-host), not Claude Code CLI's own host. Verified
twice via process path today, including once after Claude Desktop's helper was killed outright — it respawned
under a new PID with no relaunch of the Desktop GUI app, confirming the manifest registration alone is
enough for Chrome to relaunch it on demand.

Part 2: even when Claude Code's own host wins, the MCP handshake still never completes. This is new and,
we believe, the more important finding. With Desktop's manifest disabled (renamed aside, confirmed absent
from the active directory) and the extension manually toggled off/on in chrome://extensions/, Claude Code
CLI's own native-messaging host launched for the first time — verified by process binary path
(~/.local/share/claude/versions/2.1.204 --chrome-native-host), with no Desktop process running alongside
it. Despite this:

  • list_connected_browsers still returned []
  • tabs_context_mcp still returned "Browser extension is not connected"
  • The process itself was healthy: alive, normal idle state (S), ~2 minutes of uptime, not crashed
  • It had a correctly-formed bridge socket open (/tmp/claude-mcp-browser-bridge-<user>/<pid>.sock,

permissions srw-------, correct ownership)

  • A system-wide lsof -U check for that socket found **only the helper process's own reference to it — no

second endpoint ever connected**, from either the extension side or the CLI's own MCP client side

So the correct process launches, opens a well-formed socket, and sits there alive and listening — and nothing
on either end of the intended connection ever actually shakes hands on it. This points to a
handshake/connection-logic gap (extension-side, CLI-side, or both) that is separate from and downstream of
the Desktop/CLI host-selection conflict.

## What was tried and didn't work (this round)

  1. Kill Desktop's orphaned helper process directly (pkill, after confirming via ps aux that only the

helper, not Claude Desktop's GUI app, was running). Verified dead via ps aux before retesting.
list_connected_browsers/tabs_context_mcp still failed. No relaunch attempted on the CLI's own host either
— Chrome didn't spawn anything until later.

  1. User's own /chrome reconnect attempt — visually appeared to work (Claude side panel rendered in

Chrome, correct account). MCP-level check showed this was misleading: list_connected_browsers was [],
tabs_context_mcp failed, and the process that had spawned was confirmed to be Desktop's binary again, under
a new PID, with no GUI relaunch — same underlying situation as before, different visible symptom.

  1. Disable Desktop's manifest alone (renamed aside, confirmed via ls). Result: nothing spawned at all

in response to MCP tool calls — not Desktop's host (expected) and not Claude Code's own host either. Shows
the extension does not proactively re-probe for a native host just because the CLI issues a tool call.

  1. Disable Desktop's manifest + manually toggle the extension off/on in chrome://extensions/. This

forced a fresh probe. Claude Code CLI's own host launched for the first time (see Root Cause, Part 2, above)
— but the MCP connection still never completed.

  1. Desktop's manifest was renamed back to its original filename and reverted after every test, confirmed via

ls each time. Current state: normal, unmodified, matching how it was before this investigation began.

## Current status
Two distinct, confirmed problems:

  1. Host-selection defaults to Desktop when both manifests are present (workaroundable via manifest-disable +

extension toggle, but not persistently — Desktop's manifest gets rewritten when the app itself is relaunched,
and the workaround has to be redone).

  1. Even with the correct host running and a healthy, correctly-permissioned socket open, the actual MCP

handshake never completes on either end. This second problem has not been isolated further — unclear whether
the extension never attempts to signal mcp_connected, or whether the CLI's own MCP client never attempts to
connect to the socket it holds open.

---

*This report was compiled with the assistance of an AI coding agent (Claude Code) running local diagnostics,
including process/socket inspection, log analysis, and cross-referencing against related open issues in this
repository.*

View original on GitHub ↗