[Bug] Claude in Chrome MCP bridge fails on Windows - socket discovery doesn't find named pipes

Open 💬 30 comments Opened Jan 27, 2026 by Leoezlo

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:

  1. Lists .sock files in /tmp/claude-mcp-browser-bridge-<username>/ (Unix-only, doesn't exist on Windows)
  2. 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)
  3. /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

  1. Install Claude Code 2.1.20 on Windows
  2. Install Claude in Chrome extension in Chrome
  3. Run claude (starts MCP server subprocess)
  4. Open Chrome (extension spawns native host)
  5. 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

  • #20298, #20341, #20663, #20779, #20887 (all macOS - this is the Windows equivalent)

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

View original on GitHub ↗

30 Comments

github-actions[bot] · 5 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/21301
  2. https://github.com/anthropics/claude-code/issues/21300
  3. https://github.com/anthropics/claude-code/issues/21330

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

Leoezlo · 5 months ago

Important Update: This is a regression, not a design flaw

The original report incorrectly characterized this as a fundamental Windows architecture issue. Claude in Chrome has been working flawlessly on this Windows machine for months (across Windows 10 and Windows 11 machines).

Timeline

  • 2.1.19 (published Jan 23): Chrome integration was working fine
  • 2.1.20 (published Jan 27 at 00:39 UTC): Chrome integration broke — discovered this morning when tabs_context_mcp started returning "Browser extension is not connected"

What this means

The Bw7() / getSocketPaths() function (or the MCP server's socket discovery logic) was finding the Windows named pipe in previous versions. Something in 2.1.20 (or possibly a recent internal refactor) changed the socket discovery or connection architecture in a way that broke Windows named pipe discovery.

The changelog for 2.1.20 does not mention Chrome/MCP/socket changes, so this is likely a side effect of an internal refactor.

Previous version that worked

Unfortunately I cannot confirm the exact last-working version, but 2.1.19 or earlier was functioning correctly on Windows with the Chrome extension.

Suggested investigation

A diff of the socket discovery (getSocketPaths / Bw7) and MCP bridge connection logic between 2.1.19 and 2.1.20 should reveal the regression.

Leoezlo · 5 months ago

Confirmed: MCP bridge works on 2.1.19, broken in 2.1.20

Environment: Windows 11, Claude Code 2.1.19 (downgraded from 2.1.20)

Test: Called mcp__claude-in-chrome__tabs_context_mcp with createIfEmpty: true

Result on 2.1.19: ✅ Success — returned valid tab context:

{
  "availableTabs": [{"tabId": 1620920280, "title": "New Tab", "url": "chrome://newtab"}],
  "tabGroupId": 934554101
}

Result on 2.1.20: ❌ Fails — MCP server cannot find Windows named pipes (socket discovery in Bw7/getSocketPaths broken).

This confirms the regression was introduced in 2.1.20. The Chrome MCP bridge's Windows named pipe discovery stopped working in that release.

ajohnclark · 5 months ago

Confirmed downgrading to 2.1.19 fixes this issue on Windows 11-latest/Chrome-latest.

wickedside · 5 months ago

Same problem here, on 2.1.20/2.1.21.
Claude Code can't connect to claude in chrome extension on Windows 10/11
Downgrading to 2.1.19 works somehow

ryzamedia · 5 months ago

Today's update to 2.1.21 did not fix it unfortunately.

ajohnclark · 5 months ago

2.1.22 still broken. fix for anyone struggling: npm install -g @anthropic-ai/claude-code@2.1.19

meesp123 · 5 months ago

2.1.23 still broken.

scheatham-citadel · 5 months ago

Claude in Chrome stopped working for me on Windows 11 on both my personal and work laptop after version 2.1.19 - 2 to 3 days ago.

MerrickCai · 5 months ago

v2.1.25 still broken.

meesp123 · 5 months ago

2.1.27 still broken.

mlegdev · 5 months ago

Confirmed the issue still exists in v2.1.29. Same error: "Browser extension is not connected."

Traviseric · 5 months ago

Independent confirmation on Windows 11 (v2.1.29, Feb 2 2026)

Spent ~4 hours debugging this end-to-end on a Windows 11 machine (Build 26200.7623, username with space: Gaming pc, Node v24.12.0). Confirming OP's root cause analysis and adding new evidence.

Every component works individually

| Component | Status | How verified |
|-----------|--------|-------------|
| Native host creates pipe | ✅ | Spawned manually with stdio: ['pipe','pipe','pipe'] → stderr shows Creating socket listener: \\.\pipe\claude-mcp-browser-bridge-Gaming pcSocket server listening for connections |
| Pipe accepts connections | ✅ | net.connect('\\.\pipe\claude-mcp-browser-bridge-Gaming pc') → CONNECTED |
| Pipe responds to messages | ✅ | Sent JSON-RPC ping → got {"result":{"content":"Unknown method: ping"}} |
| Chrome auto-spawns native host | ✅ | Launched Chrome → --chrome-native-host PID appears automatically |
| Bridge spawns (via enabledMcpjsonServers) | ✅ | Added claude-in-chrome to settings → --claude-in-chrome-mcp PID appeared |
| Bridge finds native host | | Bridge runs but never connects to pipe. tabs_context_mcp → "Browser extension is not connected" |
| Bridge stderr output | None | Spawned manually with piped stdio — zero stderr, zero stdout response to MCP initialize message |

The disconnect

Confirmed by reading the minified cli.js (line ~6427):

  • Native host (--chrome-native-host, function e9q) uses Rj6() which correctly returns \\.\pipe\claude-mcp-browser-bridge-<username> on win32. Creates net.createServer(), calls .listen(). Works.
  • Bridge (--claude-in-chrome-mcp, function r9q) uses xQ4() (getSocketPaths()) for discovery. This function:
  1. Lists .sock files in /tmp/claude-mcp-browser-bridge-<user>/ — Unix-only
  2. Returns path.join(os.tmpdir(), ...)C:\Users\...\AppData\Local\Temp\claude-mcp-browser-bridge-Gaming pc — filesystem path, not a pipe
  3. Returns /tmp/claude-mcp-browser-bridge-<user> — Unix path

None of these are the Windows named pipe path. The bridge searches, finds nothing, and gives up.

Also disproven

  • Space in username (Gaming pc): Named pipe works fine with spaces. Both net.createServer and net.connect handle it correctly.
  • Race condition / pipe squatting: This is a secondary issue. Even with native host pre-running and pipe verified accessible, the bridge still can't find it.
  • Service worker dormant: Chrome auto-spawns native host on extension load; native host correctly creates pipe.
  • Config/eager loading: Tested both enabledMcpjsonServers: [] (lazy) and ["claude-in-chrome"] (eager). Same result either way.

Suggested fix

xQ4() / getSocketPaths() needs to include the Windows named pipe:

if (process.platform === 'win32') {
  paths.push(`\\\\.\\pipe\\claude-mcp-browser-bridge-${username}`);
}

Or the bridge should also try connecting to socketPath (from Rj6() / the pipe name getter), not just the paths from getSocketPaths().

Environment

  • Windows 11 Build 26200.7623
  • Claude Code 2.1.29 (npm global)
  • Chrome extension 1.0.41
  • Node v24.12.0
  • Username: Gaming pc (with space — irrelevant, pipe works fine)
Traviseric · 5 months ago

Correction: This is a regression in 2.1.20, not a design flaw

My previous comment characterized this as a fundamental gap in getSocketPaths(). That's wrong — Chrome MCP was working on Windows prior to 2.1.20. As @Leoezlo and @ajohnclark confirmed, downgrading to 2.1.19 restores full functionality.

The getSocketPaths() / xQ4() function was correctly finding Windows named pipes before 2.1.20. Something in that release changed the socket discovery or connection logic in a way that broke Windows named pipe discovery. The 2.1.20 changelog doesn't mention Chrome/MCP/socket changes, so this is likely a side effect of an internal refactor.

Fix path: A diff of the socket discovery and MCP bridge connection logic between 2.1.19 and 2.1.20 should reveal the regression.

Workaround for anyone stuck: npm install -g @anthropic-ai/claude-code@2.1.19 restores Chrome MCP on Windows.

alex2zimmermann-ux · 5 months ago

I found the root cause and a fix for this. The issue is in xQ4() (getSocketPaths) in cli.js - it doesn't include the Windows Named Pipe path \.\pipe\claude-mcp-browser-bridge-<username> in the socket search list.

One-line fix and full details here: #22635
Patch/Gist: https://gist.github.com/alex2zimmermann-ux/c4532b4f8b94640c6cde81c7f7552d8e

mlegdev · 5 months ago

Still broken in v2.1.30

Just tested the newly released v2.1.30 — the bug persists.

mcp__claude-in-chrome__tabs_context_mcp
→ "Browser extension is not connected"

Environment:

  • Windows 11
  • Claude Code v2.1.30
  • Chrome extension installed and running
  • Native host spawns correctly

This is now 8 consecutive broken versions (2.1.20 → 2.1.30). The regression has been present for over a week.

downgrading to v2.1.19 still works fine. The fix should be straightforward — just add the Windows named pipe path to the socket
discovery function:

if (platform === 'win32') {
paths.push(\\\\.\\pipe\\claude-mcp-browser-bridge-${username});
}

Any ETA on a fix? This is blocking all Windows users from using browser automation.

alex2zimmermann-ux · 5 months ago

The fix works on all versions including 2.1.30+ - here's how to apply it:

You need to use the npm version (not the standalone Windows installer) so you can modify cli.js:

npm install -g @anthropic-ai/claude-code

If you used the standalone installer, uninstall it first and switch to npm.

Then apply the one-line fix from my gist: https://gist.github.com/alex2zimmermann-ux/c4532b4f8b94640c6cde81c7f7552d8e

Tested yesterday on a fresh Windows machine with the latest version - works perfectly.

scheatham-citadel · 5 months ago

Confirmed the issue still exists in v2.1.31. Same error: "Browser extension is not connected." On Windows 11 using binary version.

scheatham-citadel · 5 months ago

Confirmed the issue still exists in v2.1.32. Same error: "Browser extension is not connected." On Windows 11 using binary version.

I really hope this gets fixed soon in the Native Windows version soon.

The options to get browser functionality back are:

1) Native version: And disable auto updates and downgrade to v2.1.19

2) Switch to the NPM installation 'deprecated' and downgrade to v2.1.19

3) Switch to the NPM installation 'deprecated' and manually patch every release version.

ajohnclark · 5 months ago

I've just moved on to chromedev/disabled chrome by claude to be able to use Opus 4.6.
claude mcp add chrome-devtools --scope user npx chrome-devtools-mcp@latest

Trevo88423 · 5 months ago

Working workaround: patch getSocketPaths() in cli.js

I've been hitting this same bug and found a workaround that fixes it. The root cause is exactly as described in this issue — getSocketPaths() never includes the Windows named pipe path (\\.\pipe\claude-mcp-browser-bridge-<username>), even though the native host creates it correctly.

The fix

Patch the socket discovery function in cli.js to append the Windows named pipe path to its search list. After patching, the MCP server finds the native host immediately and Claude in Chrome works perfectly.

Quick manual patch

  1. Find your cli.js:
  2. ```
  3. npm root -g
  4. ```
  5. Then open @anthropic-ai/claude-code/cli.js
  6. Back it up:
  7. ```cmd
  8. copy cli.js cli.js.backup
  9. ```
  10. Search for the getSocketPaths / socket discovery function (in minified code, search for claude-mcp-browser-bridge- — the function that builds an array of socket paths).
  11. Before its return statement, add a block that checks for win32 and pushes the named pipe path:
  12. ```js
  13. if (process.platform === "win32") {
  14. let pipePath = \\\\.\\pipe\\claude-mcp-browser-bridge-${username};
  15. if (!paths.includes(pipePath)) paths.push(pipePath);
  16. }
  17. ```
  18. (Use the same minified variable names the function already uses.)
  19. Restart Claude Code. The Chrome extension should connect immediately.

Automated patch script

Save this as patch_cli.js and run with node patch_cli.js. Re-run after every Claude Code update since updates overwrite cli.js.

const fs = require('fs');
const { execSync } = require('child_process');
const path = require('path');

const globalRoot = execSync('npm root -g', { encoding: 'utf8' }).trim();
const cliPath = path.join(globalRoot, '@anthropic-ai', 'claude-code', 'cli.js');

if (!fs.existsSync(cliPath)) {
  console.error('Could not find cli.js at:', cliPath);
  process.exit(1);
}

// Backup
const backupPath = cliPath + '.backup';
if (!fs.existsSync(backupPath)) {
  fs.copyFileSync(cliPath, backupPath);
  console.log('Backup created at:', backupPath);
}

const code = fs.readFileSync(cliPath, 'utf8');

// Check if already patched
if (code.includes('\\\\pipe\\\\claude-mcp-browser-bridge')) {
  console.log('Already patched!');
  process.exit(0);
}

// Find the socket discovery function by its unique content
const pattern = /(function \w+\(\)\{let \w+=\[\].*?claude-mcp-browser-bridge-.*?)(return \w+\})/s;
const match = code.match(pattern);

if (!match) {
  console.error('Could not find socket discovery function. cli.js may have changed.');
  process.exit(1);
}

const arrayName = match[0].match(/^function \w+\(\)\{let (\w+)=\[\]/)[1];
const userExpr = match[0].match(/claude-mcp-browser-bridge-\$\{(\w+\(\))\}/)[1];

const patch = `if(process.platform==="win32"){let W=\`\\\\\\\\.\\\\pipe\\\\claude-mcp-browser-bridge-\${${userExpr}}\`;if(!${arrayName}.includes(W))${arrayName}.push(W)}`;

const patched = code.replace(match[0], match[1] + patch + match[2]);
fs.writeFileSync(cliPath, patched);
console.log('Successfully patched! Restart Claude Code for the fix to take effect.');

Environment

  • Windows 11 Build 26200
  • - Node.js v24
  • - - Claude Code v2.1.33 (npm install)
  • - - - Chrome extension v1.0.45

Confirmed working — all mcp__claude-in-chrome__* tools connect and respond after patching.

---

Additional troubleshooting notes

If you're still stuck after patching cli.js, check these:

1. Native host bat file using Bun (claude.exe) instead of Node

Earlier versions of the native host bat file ran claude.exe --chrome-native-host, which uses Bun internally. Bun panics when trying to create Windows named pipes. The Claude Code team has since fixed this — the bat file should now use node cli.js --chrome-native-host. If yours still references claude.exe, update it:

Open chrome-native-host.bat (path is in the native messaging host manifest JSON at HKCU\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.anthropic.claude_code_browser_extension) and ensure it looks like:

@echo off
"C:\Program Files\nodejs\node.exe" "<path-to-global-node-modules>\@anthropic-ai\claude-code\cli.js" --chrome-native-host

You can find your global node_modules path with npm root -g.

2. Extension service worker caching stale "not connected" state

After applying the patch, the Chrome extension's service worker may still report "Browser extension is not connected" because it cached the previous failed ping/pong result. To fix:

  1. Go to chrome://extensions
  2. 2. Find "Claude in Chrome" and click the reload button (circular arrow)
  3. 3. Alternatively, toggle the extension off and back on

This resets the service worker and forces a fresh connection attempt through the now-patched pipe discovery.

afram123 · 5 months ago

Additional compounding bug: Claude Desktop registry conflict

In addition to the getSocketPaths() bug described above, there is a second issue that affects users who have (or previously had) Claude Desktop installed alongside Claude Code on Windows.

Problem

Both apps register Chrome native messaging hosts:

  • Claude Desktop: com.anthropic.claude_browser_extension
  • - Claude Code: com.anthropic.claude_code_browser_extension

The Chrome extension is hardcoded to connect to com.anthropic.claude_browser_extension (Desktop's host) first. Even after applying the getSocketPaths() patch, the extension will still route to Claude Desktop's native host instead of Claude Code's.

Registry entries

HKCU\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.anthropic.claude_browser_extension  --> Claude Desktop
HKCU\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.anthropic.claude_code_browser_extension  --> Claude Code

Fix

If you don't use Claude Desktop, remove its registry entry:

Remove-Item 'HKCU:\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.anthropic.claude_browser_extension' -Force

Then restart Chrome.

Summary

To fix Claude in Chrome on Windows (v2.1.20+), both fixes are needed:

  1. Patch getSocketPaths() in cli.js to include the Windows named pipe path (as described above)
  2. 2. Remove or redirect Claude Desktop's native messaging host registry entry if it exists

Confirmed working on Windows with Claude Code v2.1.34 and Chrome extension v1.0.45.

gitterxo · 5 months ago

what is completly funny is that they break this thing on every new version

now on 2.1.37 still doesn't work

what I do :

  • i've made a conversation on claude web with all the info from this github page
  • then on a new version I do findstr /n "claude-mcp-browser-bridge" "c:\nvm4w\nodejs\node_modules\@anthropic-ai\claude-code\cli.js"
  • i paste the contents into the claude chat and it gives me the fix

<img width="843" height="253" alt="Image" src="https://github.com/user-attachments/assets/951724f5-c6ae-463a-81e2-37ebc905dd47" />

what is incredibily annoying is that they do not use their own tool to fix it permanently

alex2zimmermann-ux · 5 months ago

Update for v2.1.38: Named Pipe fix is in, but a NEW issue breaks Chrome on Windows

The original getSocketPaths() Named Pipe bug from v2.1.20 has been fixed in v2.1.38. The function Tn4() (getSocketPaths) now correctly returns \.\pipe\claude-mcp-browser-bridge-<username> on Windows with an early return.

However, Chrome in Windows is STILL broken in v2.1.38 due to a different root cause: the tengu_copper_bridge feature flag.

New Root Cause (v2.1.38)

When tengu_copper_bridge is true in ~/.claude.json (under cachedGrowthBookFeatures), the bridge client selection in kHq() takes a different code path:

function kHq(A) {
  return A.bridgeConfig ? auA(A)        // WebSocket cloud bridge (USED when flag is true)
       : A.getSocketPaths ? NHq(A)      // Socket Pool with Named Pipe (BYPASSED)
       : FN6(A);
}

The function QHz() checks the flag and returns wss://bridge.claudeusercontent.com, which sets bridgeConfig. This makes kHq() use the WebSocket cloud bridge client (auA) instead of the local Socket Pool (NHq). The local Named Pipe (which works perfectly) is completely ignored.

The cloud WebSocket bridge then fails to connect/authenticate, resulting in the same "Browser extension is not connected" error.

Verification

  1. Named Pipe \.\pipe\claude-mcp-browser-bridge-<username> exists and accepts connections ✅
  2. Native host (--chrome-native-host) creates the pipe and listens ✅
  3. net.createConnection('\.\pipe\claude-mcp-browser-bridge-<username>') succeeds ✅
  4. Bridge (--claude-in-chrome-mcp) starts and connects to Claude Code via stdio ✅
  5. Bridge tries cloud WebSocket instead of local pipe → FAILS

Workaround

Edit ~/.claude.json and set:

"tengu_copper_bridge": false

Then restart Claude Code. The bridge will fall back to the local Socket Pool, find the Named Pipe, and connect successfully.

Note: This flag is set server-side via GrowthBook feature flags, so it may get re-enabled on next startup. A persistent fix would require Anthropic to either fix the cloud bridge on Windows or exclude Windows users from this flag.

Environment

  • Windows 11, Claude Code v2.1.38 (npm)
  • Chrome extension v1.0.47
  • Node.js v24.12.0
scheatham-citadel · 5 months ago

Claude in Chrome is working for me on Windows 11 with Claude Code v2.1.38 (native) in both Edge and Chrome with the Claude Extension installed (from https://chromewebstore.google.com/detail/claude/fcoeoabgfenejglbffodgkkbkcdhcgfn)

Its working with both "tengu_copper_bridge": true or false

Environment

Windows 11, Claude Code v2.1.38 (native)
Chrome extension v1.0.47

Please note a browser window must be launched prior to asking Claude to use its browser tool.

I have the below in my global CALUDE.md for ease of use:

# CLAUDE.md - Global Instructions

## Browser Automation
- Claude in Chrome works on Windows but requires correct startup sequence:
  1. Call `tabs_context_mcp(createIfEmpty: true)` first
  2. Then navigate/interact — tools fail without steps 1
- Chrome DevTools MCP (`mcp__chrome-devtools__*`) is available as a fallback.
gitterxo · 5 months ago

For me 2.1.38 did not work.

Only way i could make it work was to completely uninstall claude code and claude desktop, deleted all registry entries (using find in regex for anthropic) and then fresh install of claude code

The issue is 100% related to claude desktop or cowork which makes registry entries

eyesWIDEopen12392 · 3 months ago

Adding my experience to this issue. Windows 11 Pro (upgraded from Home), fresh MSIX install via winget, CoworkVMService confirmed running, chrome-native-host process confirmed running, registry entry pointing to correct ChromeNativeHost JSON file. Cowork only shows tab closing and file upload tools — no Chrome browsing tools. Claude in Chrome connector panel shows 'Install' despite extension being active. Support ticket opened 3/22, no response yet. Debug logs submitted via Cowork interface.

yoshiwo3 · 3 months ago

Still reproducible on v2.1.92 (2026-04-05)

Environment: Windows 11 Pro 10.0.26200, Claude Code v2.1.92 (npm), Chrome extension v1.0.66

Reproduction: Japanese username containing fullwidth space (U+3000). Named pipe \.\pipe\claude-mcp-browser-bridge-{user} is created by native host, but MCP client cannot connect — tabs_context_mcp returns "Browser extension is not connected."

Diagnostic evidence:

  • Native host process running correctly (ASCII path: C:\ProgramData\ClaudeCode\claude-code\cli.js)
  • Named pipe exists (verified via Get-ChildItem \.\pipe\)
  • Registry points to ASCII-path manifest (manually fixed)
  • Chrome extension spawns native host correctly
  • MCP client connects then immediately disconnects

Root cause (confirmed via #23828 analysis):

  1. getSocketPaths() returns filesystem paths (C:\Users\...\AppData\Local\Temp\...) instead of Named Pipe paths (\.\pipe\...) — different OS namespaces on Windows
  2. Username space sanitization mismatch between native host and MCP client

Fix status:

  • PR #34789 (patch files) → Closed, superseded by plugin approach
  • PR #35683 (plugin approach) → Still open, not merged
  • No official fix in v2.1.92

Request: Could the team review the getSocketPaths() fix for Windows Named Pipe support? This affects all Windows users with non-ASCII or space-containing usernames. The root cause analysis and proposed fixes are well-documented in #23828.

yoshiwo3 · 3 months ago

Update 2026-04-12: RESOLVED on v2.1.101 with bridge factory patch

Following my previous report on v2.1.92 (2026-04-05), I performed a deeper investigation on v2.1.101 and found the root cause — plus a working fix confirmed with tabs_context_mcp returning valid results.

Environment

  • Windows 11 Pro 10.0.26200
  • Claude Code v2.1.101 (npm, auto-updated 2026-04-12)
  • Chrome extension v1.0.66
  • Non-ASCII username containing fullwidth space (U+3000)

Root Cause: _91() factory unconditionally selects cloud bridge

In cli.js v2.1.101 (around offset 720109), the bridge connector factory is:

function _91(q){return q.bridgeConfig?f28(q):q.getSocketPaths?FL7(q):D28(q)}

When the MCP server context is constructed (around offset 11937076), both bridgeConfig and getSocketPaths: Gm4 are set. The ternary checks bridgeConfig first → cloud WebSocket bridge (wss://bridge.claudeusercontent.com) is always selected → fails on Windows → "Browser extension is not connected".

This confirms @robertmonroe's analysis in #23828 for v2.1.96 — same architectural issue with reshuffled minified symbols.

Key Findings

1. tengu_copper_bridge flag completely removed from codebase

The workaround from #22635 (setting tengu_copper_bridge: false in ~/.claude.json) no longer works. Full-text search of v2.1.101's cli.js returns zero matches for tengu_copper_bridge or copper. Furthermore, even when set to false client-side, the value is overwritten to true on restart by GrowthBook.

2. getSocketPaths (Gm4) correctly returns Named Pipe on win32

The v2.1.38 fix (#22635) is present in v2.1.101. Local socket discovery works — it's just bypassed by the factory.

3. Named Pipe works correctly with non-ASCII username

Verified via PowerShell NamedPipeClientStream — the pipe exists and accepts connections, even with U+3000 in the name. The fl1() function uses os.userInfo().username directly, matching the native host side. Username sanitization mismatch (previously suspected) is NOT the issue.

4. Chrome extension v1.0.66 Service Worker can break on toggle

After toggling the extension off→on, chrome://extensions/ displayed Failed to load the script unexpectedly on service-worker.ts-H0DVM1LS.js:0. Fix: uninstall and reinstall the extension from Chrome Web Store.

Working Fix: factory priority swap (52-byte in-place patch)

Original: q.bridgeConfig?f28(q):q.getSocketPaths?FL7(q):D28(q)
Patched:  q.getSocketPaths?FL7(q):q.bridgeConfig?f28(q):D28(q)

Same-length substitution — prefers getSocketPaths (local Named Pipe) when available, falls back to bridgeConfig otherwise. Non-Windows behavior unchanged since Gm4() returns pipe paths only on win32.

Result: tabs_context_mcp succeeded (tabGroupId returned).

Automation via SessionStart Hook

Since cli.js is replaced on every Claude Code update, I created a SessionStart hook that:

  • Locates cli.js via npm root -g
  • Matches the factory pattern with regex: /q\.bridgeConfig\?(\w+)\(q\):q\.getSocketPaths\?(\w+)\(q\):(\w+)\(q\)/
  • Applies the priority swap with dynamically captured symbol names (handles minified symbol churn across versions)
  • Also fixes HKCU registry (resets to ASCII manifest path for non-ASCII username environments)
  • Records status to ~/.claude/cache/chrome-fix-status.json
  • Safe no-op when already patched or when pattern structure changes

This is essentially the same approach as @robertmonroe's plugin in #23828, independently derived.

Additional prerequisites for non-ASCII username environments

  1. ASCII-path Native Host files at C:\ProgramData\ClaudeCode\ (Chrome cannot execute bat files via paths containing non-ASCII characters)
  2. HKCU registry pointing to ASCII manifest (reverts to non-ASCII on Claude Code restart — hence the hook)

Related issues

  • #22635 (closed, v2.1.38 pipe path fix — confirmed present in v2.1.101)
  • #23828 (open, @robertmonroe's v2.1.96 analysis + plugin)
m13v · 1 month ago

the seam isn't just adding the win32 pipe path to getSocketPaths, it's that the whole discovery model is unix-shaped. on linux/mac the bridge enumerates .sock files in a tmpdir because UDS is a filesystem object you can readdir. windows named pipes live in their own namespace (\Device\NamedPipe), no fs.readdir equivalent through node stdlib, you'd have to NtQueryDirectoryFile against the pipe device or hardcode the name pattern. patching Bw7 with the username-shaped path only works because the host name is deterministic. the moment two hosts coexist (Desktop + Code side by side, or multi-user RDP, or a stale orphan from a crashed session), discovery silently grabs the wrong one and the failure mode looks identical to 'not connected'.