anthropics / anthropics/claude-code

[BUG] `oauth_scope_insufficient` is surfaced as "Claude.ai login was rejected", driving an unfixable /login loop; the same failure is fully silent in the VS Code extension when `disableLoginPrompt` is set

オープン
#92,149 コメント 4 件 リアクション 0 件 担当者 0 名 GitHub で見る
area:auth area:mcp bug has repro platform:macos
主要言語
Python
スター
145k
フォーク
23.1k
PR マージ指標
PR 指標を取得中

説明

> **Revised 2026-09-04.** Earlier revisions of this issue contained two measurement errors in the Keychain data (wrong time span, and a claim that each authorization mints a service). Both are corrected below; see the comments for what changed. Only directly measured values remain.

### Summary

Three findings from diagnosing why claude.ai connectors were unavailable in the VS Code extension:

1. **A scope error is surfaced to the user as a login rejection**, sending them into a retry loop that cannot work.
2. **A rejected claude.ai login produces zero user-visible signal in the VS Code extension when `claudeCode.disableLoginPrompt: true`** — connectors silently vanish from `/mcp` with no banner, badge, or error.
3. **106 orphaned top-level Keychain services** named `Claude Code-credentials-<8-hex-hash>` accumulating at ~1 per day of use since 2026-04-24, each written once and never read again.

### Finding 1: scope error reported as a login rejection

Claude Code displays:

```
Remote Control disconnected - Claude.ai login was rejected - run /login, then /remote-control
```

The underlying API response is not a rejected login:

```
HTTP 401
{"error":{"message":"OAuth token lacks a scope this endpoint accepts",
"reason":"oauth_scope_insufficient","type":"authentication_error"}}
```

The token authenticates. It lacks a scope for `/v1/code/*`. `/login` performs a token refresh that reuses the existing scope set, so following the instruction produces a valid token missing the same scope, indefinitely. The message points the user at the one action that cannot resolve it.

Account is `organizationType: claude_max`, `organizationRole: admin`, so this is not a plan gate.

Suggested: surface `oauth_scope_insufficient` distinctly and direct the user to whatever grants the scope (`/remote-control`, or a full re-consent) rather than to `/login`.

### Finding 2: silent auth failure in the extension

`claudeCode.disableLoginPrompt` is documented as *"When true, never prompt for login/authentication in the extension. Used when authentication is handled externally."*

Suppressing the **prompt** is intended. Suppressing every trace that authentication failed is not. With it set, the extension's `/mcp` renders normally and simply omits the claude.ai connectors group:

```
User MCPs (~/.claude.json)
blotato connected 35 tools
blotato_nick connected 35 tools
Built-in MCPs (always available)
plugin:lovable:lovable connected 40 tools
plugin:playwright:playwright connected 24 tools
```

No connectors group, no `mcp__claude_ai_*` tools, no indication anything is wrong. A terminal session states the cause on line one. After `/login`, `/mcp` shows all 13 servers (Gmail 29 tools, Era Context 51, Lovable 40, Slack 13, Drive 11, Calendar 9, Fathom 9).

Setting `disableLoginPrompt` back to its default made the failure immediately visible, confirming the setting was what hid it.

Suggested: a non-modal indication on the `/mcp` panel when connectors are absent due to an auth failure, shown regardless of `disableLoginPrompt`.

### Finding 3: Keychain service accumulation

Measured by querying each service directly (`security find-generic-password -s `, metadata only, no secret material read):

```
services: 106 distinct (1 bare + 105 hash-suffixed)
first: 2026-04-24
last: 2026-09-04
span: 134 days, of which 100 have an entry and 34 have none
rate: ~1 per day of use
```

The bare `Claude Code-credentials` service (created 2026-07-17) is the account login and updates in place correctly. The suffixed siblings do not: a sampled entry was modified exactly 1 second after creation and never touched again.

**Correcting an earlier claim in this issue:** these are *not* minted per authorization attempt. On 2026-09-04 the user ran `/login` several times and exactly one service exists for that date. The rate tracks days of use, which is more consistent with a daily rotation that writes to a new service name than with per-auth registration.

Each holds OAuth material for connected Google and Slack accounts. 34 gap days align with non-use.

This differs in shape from #59460, where orphans live *inside* one keychain item under `mcpOAuth.|`. Here they are separate top-level services.

### Notes for triage

- Not a persistence failure. A cold-process `claude mcp list` with `CLAUDECODE` and `CLAUDE_CODE_SESSION_ID` unset listed every connector as Connected throughout, so #69417's mechanism does not apply.
- `claude mcp list` reporting "connected" is not evidence tools are live in a session. It reported 11 of 13 connected while zero `mcp__claude_ai_*` tools reached the session.
- No stale `CLAUDE_CODE_OAUTH_TOKEN` was pinned in shell profiles, Claude settings files, `launchctl`, or VS Code's `terminal.integrated.env.*`.
- In-app `/bug` submission fails with HTTP 403, which is why this is filed here.

### Ruled out during diagnosis

| Setting | Location checked | Value |
|---|---|---|
| `disableClaudeAiConnectors` | settings.json, settings.local.json, .claude.json | not set |
| `deniedMcpServers` | all three | not set |
| `disabledMcpServers` / `enabledMcpServers` | global + all project scopes | not set |
| `ENABLE_CLAUDEAI_MCP_SERVERS` | environment | unset |
| `CLAUDE_CONFIG_DIR` | environment | unset |

Auth mode is claude.ai OAuth. `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, `ANTHROPIC_BASE_URL` all unset. Single native install.

### Environment

- Claude Code 2.1.260, native install (`~/.local/bin/claude`). 2.1.258 installed 09-01, 2.1.259 on 09-03, 2.1.260 on 09-03.
- VS Code extension `anthropic.claude-code-2.1.260-darwin-arm64` (installed 09-04; 2.1.259 on 09-03)
- macOS, Darwin 25.3.0, arm64
- Credential storage: Keychain
- `remoteControlAtStartup: true`, which is why the failure announces itself every session

Related: #69417, #76150, #59460, #80422

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

調査の方向性

The issue names no source files or tests. Start at the /remote-control and /login authentication paths, then trace how /mcp renders connector state when disableLoginPrompt is true; separately inspect the Keychain write path behind Claude Code-credentials-. Done means scope errors are distinguished from rejected login, auth failures remain visible without a prompt, and repeated use no longer leaves unused top-level services.

索引モデルが issue の本文から書いたものです。

評価

技術スタック
macos, python, vscode
領域
authentication, desktop, security
issue の種類
バグ
難易度
5/5
見積もり時間
1週間以上
活発さ
活発
明瞭さ
おおむね明確
初心者へのやさしさ
32/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。