Fixing Claude Code's Chrome Extension on Windows

Updated

Terminal showing the Chrome extension fix process for Claude Code on Windows

Getting "Browser extension is not connected" when trying to use Claude Code's mcp__claude-in-chrome__* tools on Windows? You're not alone — and no, it's not your firewall. This error has been plaguing Windows users since the Chrome extension launched, and as of March 2026 there is still no official fix. I burned an entire evening chasing this down before realizing the root cause is a combination of Bun's broken named pipe support on Windows and a cloud WebSocket relay that fails silently. This guide walks you through the complete fix — step by step, with explanations of why each part matters.

Prerequisites

Before starting, make sure you have the following:

You can verify Node.js and npm are available by running:

node --version
npm --version

Understanding the Problem

Before diving into the fix, it helps to understand why this breaks. If you just want the solution, skip to the fix — but understanding the architecture makes troubleshooting much easier when things inevitably break again after an update.

How Chrome Native Messaging Works

Chrome's native messaging API allows browser extensions to communicate with native applications installed on the user's machine. The architecture has three components:

  1. Host manifest — a JSON file registered in the Windows registry (or a specific filesystem path on macOS/Linux) that tells Chrome where to find the native host binary and which extensions are allowed to connect.
  2. Native host binary — the executable Chrome launches when the extension requests a native messaging connection. On Windows, this is typically a .bat or .cmd wrapper that invokes the real runtime.
  3. Named pipes — the IPC mechanism Chrome uses on Windows to exchange messages between the extension and the native host. Messages are length-prefixed JSON blobs sent over stdin/stdout.

When Claude Code's Chrome extension activates, Chrome looks up the native messaging host manifest, launches chrome-native-host.bat, and begins exchanging messages over stdin/stdout. The native host process then bridges these messages to the running Claude Code CLI instance using a local named pipe.

Why Bun's Named Pipes Are Broken on Windows

The default Claude Code installer ships a native binary (claude.exe) that runs on the Bun JavaScript runtime. Bun is fast — genuinely impressive on macOS and Linux — but its Windows named pipe implementation has a known bug: it cannot reliably create or connect to the Windows named pipes used by Chrome's native messaging.

The result? The native host process starts, immediately fails to establish the pipe connection, and exits. Chrome sees the process die and reports the extension as disconnected. You see "Browser extension is not connected" in Claude Code, and the extension popup shows no active connection. No error logs, no warnings — just silence. This is the kind of bug that makes you question your sanity.

The tengu_copper_bridge Problem

Even after switching to Node.js, there's a second issue. Claude Code includes a feature gated behind the tengu_copper_bridge feature flag. When enabled (it's on by default for Max/Pro subscribers), Claude Code attempts to route extension communication through a cloud WebSocket relay at wss://bridge.claudeusercontent.com instead of the local named pipe.

The intent behind this bridge is to enable remote connections — for example, connecting to Claude Code running on a remote server from your local Chrome. But on Windows, this WebSocket bridge triggers a connect/destroy loop:

  1. Claude Code opens a WebSocket to the cloud relay
  2. The relay acknowledges the connection
  3. The bridge attempts to forward messages to the local pipe
  4. The pipe connection fails or times out
  5. The bridge destroys the connection
  6. Claude Code immediately retries — back to step 1

This loop runs indefinitely, burning CPU and network resources while never establishing a working connection. In the Claude Code logs, you'll see rapid sequences of WebSocket connected followed by WebSocket destroyed messages — sometimes hundreds per minute. I only noticed because my laptop fan spun up for no apparent reason. Fun times.

The Fix (3 Steps)

The fix addresses both root causes: we switch from Bun to Node.js for reliable named pipe support, and we disable the broken WebSocket bridge to force local pipe mode. The whole thing takes about 5 minutes.

Step 1: Install Claude Code via npm (Node.js)

Install Claude Code globally through npm so it runs on the Node.js runtime instead of Bun:

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

After installation, verify where npm installed the binary:

npm config get prefix

This returns your npm global prefix (typically C:\Users\<you>\AppData\Roaming\npm). The claude.cmd wrapper lives in this directory.

Critical: PATH ordering. This is where most people get stuck. The native Claude Code installer places claude.exe in %USERPROFILE%\.local\bin. If that directory appears before the npm global bin in your PATH, Windows will find the Bun-based claude.exe first and silently ignore the Node.js-based claude.cmd. Verify which one Windows resolves:

where claude

You should see the npm path (...\AppData\Roaming\npm\claude.cmd) listed before the native path (...\.local\bin\claude.exe). If the order is wrong, edit your user PATH environment variable: open Settings → System → About → Advanced system settings → Environment Variables and move the npm directory above .local\bin.

Step 2: Update the Chrome Native Host

The Chrome native messaging host manifest points to a batch file that Chrome executes when the extension connects. By default, this file may reference claude.exe (the Bun binary). We need to change it to use node.exe directly.

Open the file at:

%USERPROFILE%\.claude\chrome\chrome-native-host.bat

The original content typically looks something like:

@echo off
"%USERPROFILE%\.local\bin\claude.exe" --chrome-native-host

Replace the entire contents with:

@echo off
"C:\Program Files\nodejs\node.exe" "%APPDATA%\npm\node_modules\@anthropic-ai\claude-code\cli.js" --chrome-native-host

This tells Chrome to launch the Claude Code CLI using Node.js instead of Bun. The --chrome-native-host flag puts Claude Code into native messaging mode, where it reads/writes length-prefixed JSON on stdin/stdout.

Note: If your Node.js is installed elsewhere (e.g., via nvm-windows), adjust the node.exe path accordingly. Run where node to find it.

Step 3: Disable the WebSocket Bridge

This is the most important step. Even with Node.js handling the pipes correctly, the tengu_copper_bridge feature will hijack the connection and route it through the broken cloud relay. We need to disable it by patching the CLI source. It sounds scary — it's actually just adding six characters.

The Claude Code CLI source is a large minified JavaScript file at:

%APPDATA%\npm\node_modules\@anthropic-ai\claude-code\cli.js

The function that returns the bridge URL is minified — its name changes with every release (e.g., K_z in v2.1.x, WJY in v2.1.81). But the feature flag string tengu_copper_bridge and the URL bridge.claudeusercontent.com are always present. That's how you find it.

The function always follows this pattern:

function XXXX(){if(!l8("tengu_copper_bridge",!1))return;...return"wss://bridge.claudeusercontent.com"}

The fix: insert return; as the first statement so the function exits immediately, forcing local named pipe mode:

function XXXX(){return;if(!l8("tengu_copper_bridge",!1))return;...}

Option A: One-liner patch (Bash / Git Bash / WSL)

CLI_JS="$APPDATA/npm/node_modules/@anthropic-ai/claude-code/cli.js" && \
sed -i 's/\(function [A-Za-z0-9_$]*(){\)\(if(!l8("tengu_copper_bridge",!1))return;\)/\1return;\2/' "$CLI_JS" && \
echo "Patched: $(grep -c 'return;if(!l8("tengu_copper_bridge"' "$CLI_JS") match(es)"

This uses sed with a capture group to find the function signature + feature flag check and insert return; between them. It works regardless of the minified function name.

Option B: PowerShell patch

$cli = "$env:APPDATA\npm\node_modules\@anthropic-ai\claude-code\cli.js"
$content = Get-Content $cli -Raw
$patched = $content -replace '(function \w+\(\)\{)(if\(!\w+\("tengu_copper_bridge")', '$1return;$2'
Set-Content $cli $patched -NoNewline
Write-Host "Patched. Verify:" (Select-String 'return;if\(' $cli).Count "match(es)"

Option C: Manual edit

Open cli.js in your editor, search for tengu_copper_bridge, find the enclosing function keyword, and type return; right after the opening brace {.

Verifying the patch

After patching, verify with:

# Bash
grep -c 'return;if(!l8("tengu_copper_bridge"' "$APPDATA/npm/node_modules/@anthropic-ai/claude-code/cli.js"

# PowerShell
(Select-String 'return;if\(' "$env:APPDATA\npm\node_modules\@anthropic-ai\claude-code\cli.js").Count

Both should return 1.

Warning: Do not set the LOCAL_BRIDGE=1 environment variable as an alternative. Despite the name, this routes traffic to ws://localhost:8765, a local WebSocket server that doesn't exist in a standard installation. It will fail with a different error.

Verifying the Fix

After applying all three steps, verify everything is working:

  1. Restart Chrome completely (close all windows, not just the tab). Chrome caches the native messaging host process.
  2. Open a terminal and run claude. Confirm it launches via Node.js — you can check with where claude to ensure claude.cmd is resolved.
  3. Test a Chrome MCP tool. In your Claude Code session, try a simple command that uses the Chrome extension, for example: /mcp__claude-in-chrome__get_page_text or ask Claude to read the current page. If the extension is connected, it will return the page content.
  4. Check the extension popup. Click the Claude Code extension icon in Chrome's toolbar. It should show a "Connected" status with the active Claude Code session.

If everything is working, you'll see tool calls to mcp__claude-in-chrome__* functions executing successfully instead of the "Browser extension is not connected" error.

Troubleshooting

Still getting "Browser extension is not connected"

The most common cause is PATH ordering. Run where claude in your terminal and check which binary appears first. If claude.exe (Bun) appears before claude.cmd (Node.js), fix your PATH as described in Step 1. After changing PATH, close and reopen your terminal for the change to take effect.

Extension shows "Connected" but tools fail

This usually means the Chrome native host is pointing to the wrong binary. Double-check %USERPROFILE%\.claude\chrome\chrome-native-host.bat and make sure it references node.exe and the correct path to cli.js. Verify the path exists:

dir "%APPDATA%\npm\node_modules\@anthropic-ai\claude-code\cli.js"

If the file doesn't exist, npm may have installed to a different prefix. Check with npm config get prefix and adjust accordingly.

Fix works but breaks after an update

Running npm update -g @anthropic-ai/claude-code replaces cli.js with a fresh copy, removing the patch. You must re-apply Step 3 after every update. The function name will have changed (it's re-minified each build), but the one-liner commands in Step 3 handle this automatically — they match by the tengu_copper_bridge string, not the function name.

Just re-run the Bash or PowerShell one-liner from Step 3 and restart Chrome. The native auto-updater can also reinstall claude.exe, but as long as your PATH ordering is correct, the npm version will still take priority.

High CPU usage from Claude Code

If you missed Step 3 (the bridge patch) but completed Steps 1 and 2, you may see Claude Code consuming excessive CPU. This is the WebSocket connect/destroy loop. Apply Step 3 to stop it.

How do I know if the patch is still applied?

Run this diagnostic check after any update:

# Bash — returns 1 if patched, 0 if needs re-patching
grep -c 'return;if(!l8("tengu_copper_bridge"' "$APPDATA/npm/node_modules/@anthropic-ai/claude-code/cli.js"

# Check Claude Code version
node -e "console.log(JSON.parse(require('fs').readFileSync(process.env.APPDATA+'/npm/node_modules/@anthropic-ai/claude-code/package.json','utf8')).version)"

# Verify native host points to node.exe
cat ~/.claude/chrome/chrome-native-host.bat

FAQ

Will this fix survive Claude Code updates?

Mostly, yes. Steps 1 and 2 are durable — npm stays installed and the native host batch file won't be overwritten by updates. However, Step 3 (the cli.js patch) must be re-applied after every npm update -g @anthropic-ai/claude-code. The good news? The one-liner commands from Step 3 handle this automatically — they match by the tengu_copper_bridge string, not the function name, so they work across all versions.

Does this affect Claude Code's other features?

No. The only thing disabled is the cloud WebSocket bridge (tengu_copper_bridge), which is used for remote extension connections. All other Claude Code features — terminal interaction, file editing, MCP tools, code generation — work exactly the same. You also retain full Chrome extension functionality through the local named pipe.

Why doesn't Anthropic fix this officially?

Fair question. There are open GitHub issues tracking this (listed below), and Anthropic is aware of the problem. The Bun named pipe bug is an upstream issue in the Bun runtime, and the WebSocket bridge was designed primarily for macOS/Linux environments where it works fine. A proper fix likely involves either Bun fixing their Windows pipe implementation or Anthropic adding a Windows-specific code path that bypasses the bridge automatically. Until then, we patch.

Can I use WSL instead?

Running Claude Code inside WSL avoids the Windows named pipe issue, but creates a different problem: the Chrome extension runs in Windows-native Chrome, while Claude Code runs inside the Linux VM. The native messaging bridge can't cross the WSL boundary. You would need Chrome installed inside WSL with a display server (like WSLg), which adds significant complexity. The fix described in this article is simpler and keeps everything running natively on Windows.

What about the Claude Desktop app?

This fix is specifically for Claude Code (the CLI tool) and its Chrome extension. The Claude Desktop app uses a different architecture and is not affected by these issues.

The function name changed after an update. How do I find it?

The bridge function is minified and renamed every release. Known names include K_z (v2.1.x) and WJY (v2.1.81) — yours will be different. Don't search for the function name. Instead, search for the stable string tengu_copper_bridge which is always present. The one-liner commands in Step 3 use regex to match any function name before this string, making them version-proof.

The Automated Fix: Let Claude Code Repair Itself

Here's the part I love: once you have Claude Code working (even partially), you can ask it to fix itself. There's something deeply satisfying about an AI tool patching its own source code. Claude Code has full terminal access and can edit files, which means it can patch its own cli.js and update the native host batch file — completely autonomously.

If you have Claude Code installed via npm (Step 1) and can at least run it in the terminal, try this prompt:

The Chrome extension shows "Browser extension is not connected".
I'm on Windows. Please:
1. Check my chrome-native-host.bat and fix it to use node.exe
2. Find cli.js, search for "tengu_copper_bridge", and add "return;" at the start of that function
3. Verify the fix

Claude Code will run the necessary commands to locate the files, make the edits, and verify the changes. This is especially useful when you need to re-apply the patch after an npm update — instead of manually searching through the minified cli.js every time, just ask Claude Code to do it:

I just updated claude-code via npm. Re-apply the tengu_copper_bridge patch to cli.js.

Claude Code will find the function containing the feature flag (regardless of how the minified name has changed), add the return; statement, and confirm the patch is in place.

This approach turns a recurring maintenance task into a 10-second conversation. It's also a great example of how Claude Code's terminal access makes it useful far beyond code editing — see our article on using Claude Code for Windows system diagnostics for more examples.

Alternative: npm Post-Install Hook

To auto-patch after every npm update, save the PowerShell one-liner from Step 3 as patch-claude-bridge.ps1 and add it as a postinstall hook in your global npm config. Or, if you use Bash (Git Bash / WSL), create a shell alias:

# Add to ~/.bashrc or ~/.bash_profile
alias patch-claude='CLI_JS="$APPDATA/npm/node_modules/@anthropic-ai/claude-code/cli.js" && \
  sed -i '\''s/\(function [A-Za-z0-9_$]*(){\)\(if(!l8("tengu_copper_bridge",!1))return;\)/\1return;\2/'\'' "$CLI_JS" && \
  echo "Patched: $(grep -c '\''return;if(!l8("tengu_copper_bridge"'\'' "$CLI_JS") match(es)"'

Then after any update: patch-claude and restart Chrome.

Relevant GitHub Issues

This problem affects a significant number of Windows users. The following GitHub issues in the claude-code repository track various aspects of the bug:

  • #23828 — Chrome extension disconnects immediately on Windows. The original report that identified the Bun named pipe failure.
  • #22635 — "Browser extension is not connected" on Windows 11. Includes community-contributed workarounds and discussion of the Node.js path.
  • #34788 — WebSocket bridge connect/destroy loop causing high CPU. Identifies tengu_copper_bridge as the culprit.
  • #33778 — Chrome MCP tools fail silently after update. Documents the need to re-patch cli.js after npm updates.

Star and subscribe to these issues to get notified when an official fix lands.

Related Articles

marcus a.
marcus a.

Musician, tech nerd, and product builder. Shipping edge-first products from the mountains.

start a project arrow_forward