claude-code - 💡(How to fix) Fix Gmail MCP connector: write operations (label_thread/archive/trash) fail in remote routines due to JIT scope upscoping

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

The Gmail MCP connector works correctly in interactive Claude Code sessions (reads + writes both succeed) but write operations fail in remote routines (scheduled remote agents at claude.ai/code/routines). The failure mode is consistent and reproducible: all label_thread, unlabel_thread, archive, and trash calls return HTTP 403 with the message "Server returned 403 after trying upscoping" (sometimes also surfaced as "MCP server 'Gmail' requires re-authorization (token expired)").

Read operations (search_threads, get_thread, list_labels) succeed in the same routine session that fails writes — so this is not a token-expiry issue. It appears to be a scope-grant issue: the Gmail MCP requests the gmail.modify scope just-in-time via OAuth upscoping when a write is first attempted, which works in interactive sessions (the user clicks "Allow") but cannot succeed in a routine (no interactive consent surface).

Root Cause

The Gmail MCP connector works correctly in interactive Claude Code sessions (reads + writes both succeed) but write operations fail in remote routines (scheduled remote agents at claude.ai/code/routines). The failure mode is consistent and reproducible: all label_thread, unlabel_thread, archive, and trash calls return HTTP 403 with the message "Server returned 403 after trying upscoping" (sometimes also surfaced as "MCP server 'Gmail' requires re-authorization (token expired)").

Read operations (search_threads, get_thread, list_labels) succeed in the same routine session that fails writes — so this is not a token-expiry issue. It appears to be a scope-grant issue: the Gmail MCP requests the gmail.modify scope just-in-time via OAuth upscoping when a write is first attempted, which works in interactive sessions (the user clicks "Allow") but cannot succeed in a routine (no interactive consent surface).

Fix Action

Workaround

Treat routines as classify+propose+report only. Have a separate interactive surface (Claude-in-Slack, local Claude Code) perform the actual Gmail writes when the user gives the go-ahead. The routine produces the digest with proposed actions; the interactive agent applies them.

Affected routine ID for support context: trig_01M36Z1teyGC5zWkDPbopK8C (account febd00f1-c857-453f-b3cf-abdfffe64188).

RAW_BUFFERClick to expand / collapse

Summary

The Gmail MCP connector works correctly in interactive Claude Code sessions (reads + writes both succeed) but write operations fail in remote routines (scheduled remote agents at claude.ai/code/routines). The failure mode is consistent and reproducible: all label_thread, unlabel_thread, archive, and trash calls return HTTP 403 with the message "Server returned 403 after trying upscoping" (sometimes also surfaced as "MCP server 'Gmail' requires re-authorization (token expired)").

Read operations (search_threads, get_thread, list_labels) succeed in the same routine session that fails writes — so this is not a token-expiry issue. It appears to be a scope-grant issue: the Gmail MCP requests the gmail.modify scope just-in-time via OAuth upscoping when a write is first attempted, which works in interactive sessions (the user clicks "Allow") but cannot succeed in a routine (no interactive consent surface).

Environment

  • Claude Code via claude.ai → Routines / Remote Agents
  • Routine environment: Default Cloud Environment (env_01V1ByqnE16J3rWFMAHE9i1E, kind: anthropic_cloud)
  • Affected connector: Gmail (connector_uuid: 5f9f3a8d-2a2f-4ce6-a3e2-29afc2083329)
  • Model: claude-sonnet-4-6
  • Reproduced: 2026-05-11 and 2026-05-12 across multiple routine runs

Expected behavior

A routine that has the Gmail MCP attached should be able to call label_thread, archive, etc. successfully on the user's behalf, using scopes granted at connector-attachment time.

Actual behavior

Every write operation returns:

Server returned 403 after trying upscoping

…and the digest produced by the routine notes Auto-handled: 0 with all writes blocked. Reads work fine.

Steps to reproduce

  1. Connect Gmail at claude.ai/customize/connectors (verify modify scope grant).
  2. In an interactive Claude Code session, confirm label_thread works (it does).
  3. Create a remote routine with Gmail attached as an MCP connection.
  4. Have the routine call mcp__claude_ai_Gmail__label_thread on any thread.
  5. Observe the 403 in the routine run log.

What I've tried (none fixed it)

  • Reconnecting the Gmail connector (multiple times, including full revoke at https://myaccount.google.com/permissions → reconnect with all scope checkboxes selected)
  • Clearing and re-adding mcp_connections on the existing routine via the routines API
  • Creating a brand-new routine with identical config (test ID trig_01En28ij99f9iNQzGwSwb4as, since disabled) — same 403, confirming the bug is environment-level, not per-routine-state

Diagnostic evidence

  • Same OAuth identity ([email protected]), same connector_uuid, same Gmail tools available in both surfaces.
  • Reads succeed in the routine session that fails writes — rules out token expiry.
  • Local interactive Claude Code can write to Gmail concurrent with the routine failing to write.

Suggested fix

Make the Gmail connector grant gmail.modify (and other write scopes) at connector-attachment time, with full user consent up front — so routines can use these scopes without needing to upscope mid-session.

Workaround

Treat routines as classify+propose+report only. Have a separate interactive surface (Claude-in-Slack, local Claude Code) perform the actual Gmail writes when the user gives the go-ahead. The routine produces the digest with proposed actions; the interactive agent applies them.

Affected routine ID for support context: trig_01M36Z1teyGC5zWkDPbopK8C (account febd00f1-c857-453f-b3cf-abdfffe64188).

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

A routine that has the Gmail MCP attached should be able to call label_thread, archive, etc. successfully on the user's behalf, using scopes granted at connector-attachment time.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Gmail MCP connector: write operations (label_thread/archive/trash) fail in remote routines due to JIT scope upscoping