Gmail MCP (custom-added server) returns "The caller does not have permission" on every call, even immediately after a fresh interactive OAuth grant

Open 💬 0 comments Opened Jul 13, 2026 by buketkonuk

Environment

  • Claude Code CLI 2.1.207
  • Gmail MCP server added manually (not the built-in claude.ai connector) via:

claude mcp add --transport http --client-id ... --client-secret ... --callback-port 8080 gmail https://gmailmcp.googleapis.com/mcp/v1

  • Own Google Cloud project, OAuth consent screen configured, test user added
  • Scopes granted at consent: https://mail.google.com/, gmail.modify, gmail.compose, gmail.readonly, gmail.metadata
  • Target account: a Google Workspace-less regular Gmail account (not enterprise/Workspace)

Expected behavior

After completing the OAuth consent flow and having Gmail MCP tools (list_labels, search_threads, etc.) load and appear callable, calling one of those tools should succeed (or fail with a scope-specific error), not a blanket permission-denied on every call.

Actual behavior

Every real Gmail tool call returns:

The caller does not have permission

This happens regardless of how "fresh" the auth is — including immediately after completing a brand-new interactive consent screen in the same session where the tools first became available.

Timeline

  • 5 Jul 2026 — Server added, authenticated via claude mcp login gmail (interactive terminal). claude mcp list showed Connected, but tools only appeared in a subsequent new session, not the one where the server was added.
  • 7 Jul 2026 — With status showing "✔ Connected", every tool call (list_labels, search_threads) returned "The caller does not have permission". Confirmed not scope-specific (both read and metadata-only calls failed identically). Retried across multiple fresh sessions — same result each time.
  • 7 Jul 2026 (later same day) — Re-authorized 3+ times via claude.ai Settings → Connectors. Error alternated between "The caller does not have permission" and "MCP server 'gmail' requires re-authorization (token expired)" — never stabilized into a working state.
  • 13 Jul 2026 — Ran mcp__gmail__authenticate in a live session, completed a genuinely new interactive browser consent flow from scratch (new code_challenge/state, full consent screen shown, scopes re-granted). Immediately afterward, the full Gmail tool set loaded (not just the auth stub tools), confirming the client believed the OAuth exchange succeeded. First real call, list_labels, still returned "The caller does not have permission".
  • Same session, shortly afterclaude mcp get gmail now reports Status: ! Needs authentication, despite no explicit sign-out or token revocation having occurred and the tool call happening only moments earlier while status presumably showed Connected. Status appears to silently flip after a failed call.

What's been ruled out

  • Not the Drive/Gmail OAuth client mixup described in anthropics/claude-code#51326 — this setup uses a dedicated, self-registered Google Cloud OAuth client, and the consent screen correctly shows Gmail-specific scopes only.
  • Not a stale/cached token — reproduced immediately after a brand-new consent grant in the same session.
  • Not tool-specific — reproduced on both list_labels (metadata-only) and search_threads (read scope).
  • Not fixed by repeated re-authentication — tried 5+ times across two dates (7 Jul, 13 Jul) via three different auth paths (claude mcp login, claude.ai connector settings re-auth, in-session mcp__gmail__authenticate).
  • Google Cloud side confirmed correct: Gmail API enabled, test user correctly added, OAuth consent screen shows Gmail-specific permission checkboxes, client type is Web application.

Suspected root cause

Given the pattern (fresh grant → tools load → first call fails → status silently reverts to "Needs authentication"), this looks like a server-side issue in the Gmail MCP gateway failing to correctly persist or validate the token/scope state immediately after issuance, rather than anything wrong with the OAuth configuration or consent flow on the user side.

Related reports

This appears to match the same underlying class of bug reported in:

  • anthropics/claude-ai-mcp#424 — account-scoped "caller does not have permission" on Gmail/Calendar, reproducible across surfaces, other users on the same tenant unaffected, closed without a confirmed root-cause fix
  • anthropics/claude-code#40225 — standalone Gmail MCP connector returns an empty/bare error on every call after a full re-auth cycle
  • anthropics/claude-ai-mcp#229 — built-in Gmail connector, permission denied despite consent screen correctly granting gmail.readonly

Ask

Would appreciate server-side visibility into the token/scope state for this OAuth client + account at the time of the failing calls (5 Jul, 7 Jul, and 13 Jul), to determine whether the grant is actually being persisted/validated correctly on the gateway side.

View original on GitHub ↗