[BUG] Headless session start reports already-authorized claude.ai connectors as requiring authentication; tool calls then succeed

Status Open
Reported on v2.1.226
Maintainer reply None cached
Activity 4 comments · opened Aug 25, 2026

Environment

  • Claude Code 2.1.226 (native installer), Linux (Ubuntu 26.04, headless)
  • Headless SDK session: claude --print --sdk-url … --input-format stream-json --output-format stream-json (launched by Claude Code Remote Control)
  • MCP servers: claude.ai-managed connectors (Vercel, GitHub, Gmail, Google Calendar, Google Drive, Supabase, Claude Code Remote), several authorized in claude.ai connector settings well before the session

Observed

At session start, the injected context states:

The following MCP servers require authentication before their tools can be used: Claude_Code_Remote, Github, Gmail, Google_Calendar, Google_Drive, Supabase, Vercel, claude.ai Microsoft 365 … This session is non-interactive, so Claude cannot run the OAuth flow here. Tell the user that these servers need to be authorized …

Later in the same session, with no authentication action taken by anyone in between:

  • mcp__claude_ai_Vercel__list_teams → succeeds (returns the account's team)
  • mcp__claude_ai_Github__get_me → succeeds (returns the authenticated login)

So the banner misreported at least two connectors that were fully usable. ~/.claude/mcp-needs-auth-cache.json gained fresh entries for exactly the listed servers, timestamped at session start — the state is recomputed each session, so this is a startup misclassification rather than a stale cache, and clearing the file does not help.

Expected

The session-start needs-auth list reflects actual usability. If startup-time verification is not possible (e.g. token refresh is deferred to first tool call), the message should say the status is unverified rather than instructing the model to tell the user re-authorization is required.

Impact

The banner explicitly instructs the model to tell users these capabilities are unavailable until re-authorized. Agents that trust it report false unavailability and send users to re-run OAuth flows that are already complete. We now carry a standing operating rule to make a live read call before believing the banner, which works but shouldn't be necessary.

Hypothesis

The startup evaluation classifies a connector as needs-auth without attempting a token refresh; the refresh happens lazily on the first tool call, which is why calls succeed while the banner says otherwise.

Related (not duplicates)

#78220, #80635, #80822 cover the needs-auth cache wrongly blocking servers; #82527 covers interactive OAuth completing while the CLI still reports needs-auth. This report is the false-positive banner in headless sessions for claude.ai-managed connectors whose tools work on first call.

View original on GitHub ↗

3 Comments

aster-void · 1 month ago

Additional data point from a different launch path. For Remote Control sessions this looks like parent-process-lifetime state, not per-session recomputation.

Environment: Claude Code 2.1.247, Linux (NixOS), sessions hosted by claude remote-control — the same multiplexer as in the report; children are spawned as --print --sdk-url … --input-format stream-json --resume=https://api.anthropic.com/v1/code/sessions/cse_….

| Launch path | Banner |
|---|---|
| Plain claude -p, resumed across 4 turns | never appeared |
| RC-hosted session | appeared on 2 of 5 turns; list shrank 4 → 3 within one parent's lifetime |

Three things that narrow it down:

  1. Not the cache file. I deleted ~/.claude/mcp-needs-auth-cache.json mid-session; the banner still appeared on a later turn with the file absent, and the file was never regenerated afterwards — not by new -p sessions, not by a full service restart. This is consistent with your "clearing the file does not help", but also rules the file out as the source rather than merely as a fix.
  2. Restarting the RC parent stopped it. Parent uptime was 7h42m. After systemctl --user restart claude-rc, 6 consecutive turns clean.
  3. The config had been stable for months. settings.json carries "disableClaudeAiConnectors": true and was last modified five months before the affected parent started, so this is not a recently-changed setting that the process failed to pick up. Two parent processes with byte-identical config behaved differently.

An extra wrinkle for the connectors-disabled case: no mcp__* tools were loaded in any of these sessions. The listed servers were not merely mis-flagged as needing auth — they were disabled outright, and the banner still instructed the model to tell the user to go authorize them. That makes the false-unavailability problem worse than in your repro: there is no live read call available to disprove the banner, because the tools do not exist. An agent that trusts the banner has nothing to check it against.

The intermittency also seems informative — 2 of 5 turns, and the set shrinking 4 → 3 without any authentication action — which suggests something partially refreshes this state rather than computing it once at startup.

alxsbn · 1 month ago

Same shape from cloud code routines, with one difference: here the tools genuinely are absent, not just mis-flagged.

Our setup: scheduled routine, Custom HTTP MCP connector behind Cloudflare MCP Portal + Cloudflare Access OAuth (29 tools), authorized in claude.ai with every tool Always allow and enabled in the routine's "Runs with".

The same connector works in Claude Web at the same moment (29 tools listed, live tool call returns data). A local interactive Claude Code session fails identically, so the split is Claude Web vs Claude Code, not interactive vs headless.

Also I told the routine to distrust the notice and call anyway; it did, and reported the tools were not found via ToolSearch. Matches @aster-void's wrinkle, so no live read call can disprove the banner when the tools don't exist. Unlike that report, connectors are not disabled here: built-ins load fine in the same session

ryusan-o · 8 days ago

Additional data point: same symptom on Windows, with a Remote Control session driven from claude.ai/code in the browser.

Environment

  • Claude Code 2.1.292, Windows 10 Home (19045), Git Bash / PowerShell
  • Session started and driven from claude.ai/code in a desktop browser via Remote Control. The injected notice calls it "non-interactive" and lists claude-code-remote among the servers. That name does not appear in claude mcp list on the host.
  • Connectors: claude.ai-managed Google Drive, Gmail, Google Calendar, Notion, Slack, Figma, Freee, Claude Docs. All were authorized in claude.ai connector settings beforehand, and nobody re-authorized anything during the session.

Observed

  • The "The following MCP servers require authentication before their tools can be used: Claude_Docs, Figma, Gmail, Google_Calendar, Google_Drive, Notion, Slack, claude-code-remote, claude.ai Freee … This session is non-interactive …" reminder appeared at session start. It was re-injected several more times over roughly 24 hours.
  • Directly after one of those re-injections, mcp__claude_ai_Google_Drive__search_files, mcp__claude_ai_Gmail__search_threads and mcp__claude_ai_Notion__notion-search all succeeded, including against a Google shared drive.
  • claude mcp list on the host, run at the same time, shows every one of those connectors as ✔ Connected.
  • The claude.ai connector settings page shows every connector as connected. The only exception is Freee, which shows "Reconnect". In the list, Freee appears twice: as both Freee and claude.ai Freee.
  • ~/.claude/mcp-needs-auth-cache.json still holds entries timestamped at the previous day's session start (2026-10-06 09:22 local) for Google_Drive, Gmail, Google_Calendar, Notion, Slack, Figma, Claude_Docs and claude-code-remote. The only fresh entries are for Freee. So the long-lived Remote Control host seems to keep re-announcing a stale needs-auth snapshot rather than the current state. This matches @aster-void's parent-process-lifetime observation.

Impact
The agent faithfully relays the notice ("tell the user these need authorization"). The user is often away from the machine, on mobile, so they lose real time re-checking connector settings that were never broken. We now work around it by always making one cheap real tool call before reporting a connector as unavailable.

Expected

  • Clear needs-auth entries after a successful tool call or reconnect.
  • Don't re-inject a needs-auth list older than the current host state.
  • Ideally, label the notice "possibly stale — verify with a tool call" when it comes from cache.

Showing cached comments. Read the full discussion on GitHub ↗