Bug Description
Claude in Chrome browser automation tools always return "Browser extension is not connected" on Windows, even though the native host is running correctly and the named pipe exists. The MCP server cannot discover the native host's pipe.
Platform
- OS: Windows 10 (build 19045)
- Claude Code: 2.1.20 (latest)
- Browser: Chrome (also tested with Brave)
- Extension: Claude in Chrome (fcoeoabgfenejglbffodgkkbkcdhcgfn)
- Node.js: v24.12.0
Root Cause Analysis
The native host (--chrome-native-host, class GvK) creates a named pipe server at \.\pipe\claude-mcp-browser-bridge-<username>.
The MCP server (--claude-in-chrome-mcp, function JvK) uses getSocketPaths() (function Bw7) to discover native host sockets. However, Bw7() only returns file system paths:
- Lists
.sock files in /tmp/claude-mcp-browser-bridge-<username>/ (Unix-only, doesn't exist on Windows)
path.join(os.tmpdir(), 'claude-mcp-browser-bridge-<username>') → C:\Users\<user>\AppData\Local\Temp\claude-mcp-browser-bridge-<username> (a file path, not a pipe)
/tmp/claude-mcp-browser-bridge-<username> (Unix path, doesn't exist on Windows)
None of these are the Windows named pipe path \.\pipe\claude-mcp-browser-bridge-<username>.
The socketPath from TO1() correctly returns the Windows named pipe path on win32, but either the MCP server doesn't use it for client-side discovery, or it only attempts connection at startup before the native host exists.
Evidence
All verified during debugging:
| Check |
Result |
Registry (HKCU\SOFTWARE\Google\Chrome\NativeMessagingHosts) |
Correct: com.anthropic.claude_code_browser_extension only |
| Native host manifest JSON |
Correct path and allowed_origins |
| Chrome spawns native host |
Verified via wmic (parent PID = chrome.exe) |
| Named pipe exists |
\.\pipe\claude-mcp-browser-bridge-jesus present |
| Pipe accepts connections |
Tested with PowerShell NamedPipeClientStream and Node.js net.createConnection |
| MCP server responds on pipe |
Sent native messaging format message, got {"result":{"content":"Unknown method: undefined"}} |
| Killing native host removes pipe |
Pipe disappears → native host owns it (is the server) |
| MCP server still running after pipe removed |
Confirmed → MCP server is not the pipe owner |
| Temp directory has bridge socket |
No claude-mcp-browser-bridge-* file in %TEMP% or /tmp |
tabs_context_mcp works |
Always returns "Browser extension is not connected" |
Steps to Reproduce
- Install Claude Code 2.1.20 on Windows
- Install Claude in Chrome extension in Chrome
- Run
claude (starts MCP server subprocess)
- Open Chrome (extension spawns native host)
- Call any
mcp__claude-in-chrome__* tool → "Browser extension is not connected"
Expected Behavior
The MCP server should discover and connect to the native host's Windows named pipe at \.\pipe\claude-mcp-browser-bridge-<username>.
Suggested Fix
Bw7() (getSocketPaths) should include the Windows named pipe path when process.platform === 'win32':
if (platform === 'win32') {
paths.push(`\\.\pipe\claude-mcp-browser-bridge-${username}`);
}
Or the MCP server should also try connecting to socketPath (from TO1()) when discovering native hosts, not just the paths from getSocketPaths().
Related Issues
Additional Context
- Claude Desktop was never installed on this machine (or was fully uninstalled including registry entries before testing)
- No competing native messaging hosts
- Extensively debugged over 3+ hours including process analysis, pipe protocol testing, and source code review of the minified
cli.js
- Dan Guido's X post documents the macOS version of this issue; this is the Windows-specific variant where the socket discovery architecture fundamentally doesn't work with Windows named pipes
Bug Description
Claude in Chrome browser automation tools always return "Browser extension is not connected" on Windows, even though the native host is running correctly and the named pipe exists. The MCP server cannot discover the native host's pipe.
Platform
Root Cause Analysis
The native host (
--chrome-native-host, classGvK) creates a named pipe server at\.\pipe\claude-mcp-browser-bridge-<username>.The MCP server (
--claude-in-chrome-mcp, functionJvK) usesgetSocketPaths()(functionBw7) to discover native host sockets. However,Bw7()only returns file system paths:.sockfiles in/tmp/claude-mcp-browser-bridge-<username>/(Unix-only, doesn't exist on Windows)path.join(os.tmpdir(), 'claude-mcp-browser-bridge-<username>')→C:\Users\<user>\AppData\Local\Temp\claude-mcp-browser-bridge-<username>(a file path, not a pipe)/tmp/claude-mcp-browser-bridge-<username>(Unix path, doesn't exist on Windows)None of these are the Windows named pipe path
\.\pipe\claude-mcp-browser-bridge-<username>.The
socketPathfromTO1()correctly returns the Windows named pipe path on win32, but either the MCP server doesn't use it for client-side discovery, or it only attempts connection at startup before the native host exists.Evidence
All verified during debugging:
HKCU\SOFTWARE\Google\Chrome\NativeMessagingHosts)com.anthropic.claude_code_browser_extensiononlywmic(parent PID = chrome.exe)\.\pipe\claude-mcp-browser-bridge-jesuspresentNamedPipeClientStreamand Node.jsnet.createConnection{"result":{"content":"Unknown method: undefined"}}claude-mcp-browser-bridge-*file in%TEMP%or/tmptabs_context_mcpworksSteps to Reproduce
claude(starts MCP server subprocess)mcp__claude-in-chrome__*tool → "Browser extension is not connected"Expected Behavior
The MCP server should discover and connect to the native host's Windows named pipe at
\.\pipe\claude-mcp-browser-bridge-<username>.Suggested Fix
Bw7()(getSocketPaths) should include the Windows named pipe path whenprocess.platform === 'win32':Or the MCP server should also try connecting to
socketPath(fromTO1()) when discovering native hosts, not just the paths fromgetSocketPaths().Related Issues
Additional Context
cli.js