Claude-in-Chrome: tengu_copper_bridge feature flag forces WebSocket bridge, breaks local socket on Windows

Resolved 💬 4 comments Opened Mar 15, 2026 by cruzlauroiii Closed Mar 16, 2026

Bug Description

Claude-in-Chrome fails to connect on Windows when the tengu_copper_bridge feature flag is enabled server-side. The --claude-in-chrome-mcp subprocess uses a WebSocket bridge (wss://bridge.claudeusercontent.com) instead of the local named pipe (\.\pipe\claude-mcp-browser-bridge-{user}), causing persistent "Browser extension is not connected" errors.

Root Cause

The _Oz() function (bridge URL resolver) checks the tengu_copper_bridge feature flag. When enabled (server-side for subscribed users), it returns wss://bridge.claudeusercontent.com, which sets bridgeConfig in the chrome context.

The socket client factory (Xd1/createChromeSocketClient) then prefers BridgeClient (WebSocket) over pzA (local socket pool):

function Xd1(A) {
  return A.bridgeConfig ? L61(A)       // WebSocket bridge (y61/BridgeClient)
       : A.getSocketPaths ? QzA(A)     // Local socket pool (pzA)
       : k61(A);                        // Single socket (hKA)
}

The WebSocket bridge fails to authenticate/connect, and there is no fallback to local sockets.

Meanwhile, the local named pipe works perfectly:

  • Native host (--chrome-native-host) creates \.\pipe\claude-mcp-browser-bridge-{user}
  • Chrome extension connects via native messaging ✓
  • Pipe accepts connections and responds to tool calls ✓
  • net.createConnection('//./pipe/claude-mcp-browser-bridge-user') succeeds ✓

Steps to Reproduce

  1. Have tengu_copper_bridge feature flag enabled (appears to be on for Max subscribers)
  2. Install Chrome extension, click to activate native messaging
  3. Run any mcp__claude-in-chrome__* tool
  4. Get "Browser extension is not connected" error

Diagnosis Steps Performed

  1. Verified native host running (claude.exe --chrome-native-host, PID visible)
  2. Verified named pipe exists and accepts connections (manual net.createConnection test)
  3. Verified pipe responds to tool calls (sent tabs_context_mcp, got Chrome tab data back)
  4. Instrumented dzA (tool dispatcher) — confirmed client type is y61 (BridgeClient), NOT pzA (local socket pool)
  5. Patched _Oz() to return; (disable bridge) → MCP server immediately connected via local socket and returned real tab data

Complete Workaround (2 parts)

Part 1: Patch cli.js (disables WebSocket bridge, forces local socket)

# fix-claude-chrome.ps1
$cliPath = "$env:APPDATA\npm\node_modules\@anthropic-ai\claude-code\cli.js"
if (-not (Test-Path $cliPath)) { npm install -g @anthropic-ai/claude-code }
$code = Get-Content $cliPath -Raw -Encoding UTF8
$original = 'function _Oz(){if(!w8("tengu_copper_bridge",!1))return;'
$patched  = 'function _Oz(){return;if(!w8("tengu_copper_bridge",!1))return;'
if ($code.Contains($patched)) { Write-Host "Already patched." }
elseif ($code.Contains($original)) {
    $code = $code.Replace($original, $patched)
    [System.IO.File]::WriteAllText($cliPath, $code, [System.Text.Encoding]::UTF8)
    Write-Host "Patched: bridge disabled, local socket mode forced."
} else { Write-Host "Pattern not found - version may have changed." }

Part 2: Patch chrome-native-host.bat (routes native host through Node.js)

Replace chrome-native-host.bat in %USERPROFILE%\.claude\chrome\:

@echo off
REM Chrome native host wrapper script
REM Patched to use Node.js instead of standalone binary
"C:\Program Files\nodejs\node.exe" "%APPDATA%\npm\node_modules\@anthropic-ai\claude-code\cli.js" --chrome-native-host

This ensures both the native host AND the MCP server use the patched Node.js cli.js.

Then run Claude Code via npm:

%APPDATA%\npm\claude.cmd

Suggested Code Fix

Option A: Add fallback from bridge to local socket

When BridgeClient.ensureConnected() fails, fall back to local socket pool instead of returning "not connected".

Option B: Don't enable bridge on Windows when local socket works

function _Oz() {
  if (!w8("tengu_copper_bridge", false)) return;
  if (process.platform === "win32") return; // Use local pipe on Windows
  ...
}

Option C: Let users disable bridge via env var

function _Oz() {
  if (process.env.CLAUDE_CODE_DISABLE_BRIDGE) return;
  if (!w8("tengu_copper_bridge", false)) return;
  ...
}

Environment

  • Claude Code: 2.1.76 (standalone binary + npm)
  • OS: Windows 11 Pro 10.0.26200
  • Node.js: v25.8.1
  • Chrome extension: v1.0.61
  • Auth: OAuth (Max subscriber, user:inference scope)

Related Issues

  • #23828 — Windows & WSL working fixes (socket path discovery bug + bridge issue)
  • #22983 — Bridge pipe running but not connected (Windows)
  • #21300 — Extension not connecting despite MCP "connected"
  • #23526 — getSocketPaths missing pipe path

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗