anthropics / anthropics/claude-code
[SOLVED] Claude in Chrome "not connected" on Windows: stale oauth:tokenCache causes a 401 loop — fix inside
- 主要语言
- Python
- 星标
- 145k
- 派生
- 23.1k
- PR 合并指标
- PR 指标待抓取
描述
## TL;DR — this is SOLVED, here is the fix
If `list_connected_browsers` / `tabs_context_mcp` returns **"Claude in Chrome is not connected"** on Windows and you have already reinstalled the extension, re-signed in, restarted Chrome and rebooted — **stop, none of that is the problem.**
Two stale encrypted OAuth caches in Claude Desktop's `config.json` put the app in an endless `401` loop. Delete them and it works:
```powershell
# 1. Fully quit Claude Desktop first.
$cfg = "$env:LOCALAPPDATA\Packages\Claude_\LocalCache\Roaming\Claude\config.json"
# 2. Back up byte-for-byte
Copy-Item $cfg "$cfg.bak-$(Get-Date -Format yyyyMMddTHHmmss)"
# 3. Remove ONLY these two keys, keep everything else:
# oauth:tokenCache
# oauth:tokenCacheV2
# 4. Start Claude Desktop. It reissues fresh tokens by itself.
```
Verification after restart: `/api/oauth/profile` returns `200` instead of `401`, and `list_connected_browsers` returns your browser. Rollback is restoring the backup.
Total time: about a minute. We spent two hours before finding it, because the error message points at the wrong thing (see below).
---
## Why the error message sends everyone the wrong way
This is the most expensive part of the bug, and it is a one-line fix.
`list_connected_browsers` calls `ensureConnected()` first:
- success → returns JSON; an empty roster is `[]`
- failure → returns the generic `onToolCallDisconnected()` text
That generic text is:
> The Chrome extension isn't reachable right now. […] the extension is likely not installed or not signed in.
> 1. Install the Claude in Chrome extension […]
> 2. Open the Claude side panel in Chrome and sign in with the same account as this app.
**It is not a statement about the extension.** It is emitted when *Claude Code's own bridge client* fails to connect or authenticate. But it reads as a diagnosis of the user's setup, so every user does exactly what it says — reinstall, re-login, restart Chrome — and none of it can possibly help.
Reading the closed duplicates below, the same pattern repeats in nearly all of them: users verify the extension and login exhaustively, because the message told them to.
**Ask:** distinguish "client failed to connect/authenticate" from "connected, zero browsers", and do not blame the user's extension when the failure is local.
---
## Root cause of the connection failure
After a hard reboot plus a re-authentication, `config.json` retained two stale encrypted OAuth caches: `oauth:tokenCache` and `oauth:tokenCacheV2`.
- The app polled `/api/oauth/profile` every ~30s and received `401`.
- The current version clears the token cache automatically **only on `403`**, not on `401`.
- So it looped indefinitely on a cache it would never invalidate.
- Fresh, valid credentials in `~/.claude/.credentials.json` were present the whole time and simply unused.
**Ask:** invalidate the cached token on `401` as well (or on any auth failure), instead of `403` only.
---
## Second, independent defect: the integration is silently gated off in Desktop
Separate from the above, Claude Code launched **by Claude Desktop** never enables Claude in Chrome at all.
The gate (from the shipped bundle, order matters):
```js
function qBe(e){
if(!fKt()) return false; // 1. OAuth scope check
if(e===true) return true; // 2. --chrome
if(e===false) return false; // --no-chrome
if(CLAUDE_CODE_ENABLE_CFC===true) return true; // 3. env var
if(CLAUDE_CODE_ENABLE_CFC===false) return false;
if(De()) return false; // 4. ← returns true under Desktop
let o=ie();
if(o.claudeInChromeDefaultEnabled!==undefined) // 5. never reached
return o.claudeInChromeDefaultEnabled;
return false;
}
```
Observed:
- No `claude.exe` process spawned by Desktop carries `--chrome` (verified across all running processes).
- No `--claude-in-chrome-mcp` child process exists.
- The user setting `claudeInChromeDefaultEnabled` was already `true` and is never consulted, because `De()` short-circuits first.
- The browser tools are still advertised in the tool list and, when called, emit the misleading text above.
Workaround, since the env var is checked before `De()`:
```powershell
[Environment]::SetEnvironmentVariable('CLAUDE_CODE_ENABLE_CFC','true','User')
# then fully restart Claude Desktop
```
Confirmed by A/B: the same binary run headless **without** `--chrome` but **with** the env var returns the browser; without the env var the MCP server is not registered at all.
**Ask:** Desktop should honour `claudeInChromeDefaultEnabled`, or pass `--chrome`.
---
## Third, minor: Desktop ships a dangling native-messaging registration
`HKCU\Software\Google\Chrome\NativeMessagingHosts\com.anthropic.claude_browser_extension` points at
```
…\LocalCache\Roaming\Claude\ChromeNativeHost\com.anthropic.claude_browser_extension.json
```
which the installation never creates — the folder contains only `chrome-native-host.exe`. Authoring the JSON by hand does make Chrome launch the host, but it does **not** affect `list_connected_browsers`, because the normal transport is the hosted bridge, not native messaging.
Package is `SignatureKind: Developer`, so this may be specific to that distribution channel. Same finding independently reported in #58968.
---
## For anyone debugging this: how the connection actually works
Worth stating, because it invalidates most of the obvious guesses.
The primary transport is **not** native messaging. Extension and Claude Code each open an independently authenticated WebSocket to:
```
wss://bridge.claudeusercontent.com/chrome/
```
`list_connected_browsers` sends `list_extensions` over that socket. Native messaging (`\\.\pipe\claude-mcp-browser-bridge-`) is a separate, secondary transport.
**Verified NOT to be the cause** — we tested all of these:
| Suspected | Result |
|---|---|
| Extension not installed / not signed in | Installed, signed in, `from_webstore: true`, no `disable_reasons` |
| Chrome side panel not open | Open, no effect |
| Missing native-host manifest | Created it → host launched → still "not connected" |
| Chrome enterprise policies | None present in HKLM / HKCU / WOW6432Node |
| Chrome restart / machine reboot | No effect |
| Claude Code version skew (2.1.255 vs 2.1.257) | Fresh 2.1.255 works fine |
| Stale in-memory token in a long-lived process | A process started 42 min after re-auth failed identically — the staleness was on disk |
| `ant-device-registry.json` frozen weeks earlier | Browser tools worked for a week after that date |
| Filesystem corruption (boot chkdsk) | `0 bad file records`, nothing repaired |
Discriminator that finally isolated it: within the same minute, on the same machine, same extension, same account, same binary version — a **headless** `claude.exe --chrome -p …` returned the browser while the **Desktop-hosted** session returned "not connected".
---
## Environment
- Windows 11 Pro 10.0.26200
- Chrome 152.0.7977.65, extension `fcoeoabgfenejglbffodgkkbkcdhcgfn` v1.0.90
- Claude Desktop 1.40609.1.0 (MSIX, `SignatureKind: Developer`)
- Claude Code bundled in Desktop 2.1.255; standalone CLI 2.1.257
## Summary of asks
1. Clear the OAuth token cache on `401`, not only on `403`.
2. Make the browser-tool error distinguish a local connect/auth failure from an empty roster, and stop attributing it to the user's extension.
3. Have Desktop honour `claudeInChromeDefaultEnabled` (or pass `--chrome`).
4. Ship the missing `com.anthropic.claude_browser_extension.json`.
## Related issues
All describe the same symptom; all closed without a working resolution:
#58009, #58968, #72606, #76347, #79228, #29528, #71058
贡献指南
这个仓库没有索引到贡献指南
调研方向
Start by tracing the Desktop-hosted browser integration from the qBe gate and ensureConnected(), then inspect the OAuth polling around /api/oauth/profile and the config.json token-cache keys. Reproduce the Desktop-versus-headless difference and the 401 loop described in the issue. Done means the four listed asks are addressed and browser-tool errors distinguish authentication failure from an empty roster.
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- powershell, python
- 领域
- api, authentication, backend-api-design, desktop
- Issue 类型
- 缺陷
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 活跃
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100