[BUG] Routine cloud sessions resolve a different Gmail MCP server registration than interactive sessions on the same account, causing 100% draft-creation failure since ~2026-05-20 23:00 UTC.
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
On a single Anthropic account (Talon.sturgill@gmail.com), two classes of Claude Code on the web sessions are resolving different Gmail MCP server registrations:
Interactive cloud sessions: ToolSearch for create_draft returns mcp__d91189ac-f000-45a9-a9ed-a7425f1e19f0__create_draft. Calls execute normally.
Routine / non-interactive cloud sessions: ToolSearch for create_draft returns only mcp__Gmail__create_draft. Every call — including a 4-byte payload — returns:
Streamable HTTP error: Error POSTing to endpoint: MCP tool call requires approval
immediately, with no inline approval UI rendered to the session.
list_drafts against the same named-alias registration fails identically, ruling out OAuth scope, payload, schema, name resolution at the client, and harness allowlist (mcp__Gmail__* is allowed; user has accepted "always allow"). Disconnect/reconnect of the Gmail integration does not change the binding.
Routine sessions previously created drafts successfully against this account for weeks. The regression cutover sits inside a ~5 hour window last night: a routine completing at 2026-05-20 18:46 UTC delivered its draft; the next routine at 2026-05-20 23:39 UTC, and every routine since, returns the error above.
What Should Happen?
This is a server-selection regression, not a client bug. Either the named-alias registration was switched to require per-call human approval (which non-interactive sessions structurally cannot provide), or routine sessions on this account were re-bound from the working UUID-prefixed registration to the named alias. We need either confirmation of what shipped in that window and a rollback, or a documented mechanism to force routine sessions to bind to the UUID-prefixed registration.
Error Messages/Logs
Streamable HTTP error: Error POSTing to endpoint: MCP tool call requires approval
Returned verbatim from every call to `mcp__Gmail__create_draft` in the broken session, including a 4-byte test payload:
to: ["Talon.sturgill@gmail.com"]
subject: "MCP test 2026-05-21"
body: "test"
The identical error is returned by `mcp__Gmail__list_drafts` against the same registration. No HTTP status code, no JSON envelope, no stack trace — that single string is the entire response body.
The routine's own catch handler recorded the failure to `out/gmail_draft_id.txt` on the affected branches with this placeholder:
PENDING_APPROVAL — Gmail MCP create_draft was blocked by the harness (tool requires approval, no interactive session). The payload is fully built and committed. Open the draft manually via out/gmail_payload.json or out/gmail_draft_preview.html.
No client-side logs beyond that — the error returns immediately and the session has no further telemetry to attach.
Steps to Reproduce
1. On account Talon.sturgill@gmail.com, connect the Gmail integration on claude.ai/code (already connected and confirmed working).
2. Open a fresh interactive cloud session in any repo. In chat, run:
ToolSearch query: "create_draft" max_results: 10
Observe: returns exactly one tool named
mcp__d91189ac-f000-45a9-a9ed-a7425f1e19f0__create_draft
3. In the same interactive session, call that tool with this minimal payload:
to: ["Talon.sturgill@gmail.com"]
subject: "MCP test interactive"
body: "test"
Observe: returns a draft id (e.g. r4277309467001118109). The draft appears
in Gmail Drafts within seconds.
4. Trigger a routine (non-interactive) cloud session on the same account. For
our setup this is any of the Alaska.Ai column routines under
Talonsturgill/linkedin-alaska-ai-weekly — concretely the latest is the
Anchorage Desk routine that ran at 2026-05-21 13:39 UTC on branch
claude/linkedin-desk-2026-05-21 (Claude Code session id
01CJ8vp9fRRNknZ8kc7zuqEv per the PR body / session URL pattern). Any
non-interactive trigger surface should reproduce — webhook, scheduled
trigger, GitHub Action triggered job.
5. In that routine session, before the failing call, run:
ToolSearch query: "create_draft" max_results: 10
Observe: returns exactly one tool named
mcp__Gmail__create_draft
(different from step 2 — no UUID-prefixed variant is exposed in this
session.)
6. In that routine session, call the tool with the same minimal payload:
to: ["Talon.sturgill@gmail.com"]
subject: "MCP test routine"
body: "test"
Observe: returns the exact string
Streamable HTTP error: Error POSTing to endpoint: MCP tool call requires approval
No draft is created. No approval prompt renders.
7. In the same routine session, run:
mcp__Gmail__list_drafts pageSize: 5
Observe: returns the identical error string. The named-alias registration
rejects every call, not just create.
8. Inspect .claude/settings.local.json in the repo root:
{"permissions":{"allow":["mcp__Gmail__create_draft","mcp__Gmail__search_threads"]}}
The harness allowlist matches the tool name being called. The error is
not from the client-side approval gate.
Comparison artifacts for log lookup:
- Worked: Cold Take routine, session completed 2026-05-20 18:46 UTC, PR https://github.com/Talonsturgill/linkedin-alaska-ai-weekly/pull/8, branch
claude/linkedin-contrarian-2026-05-20-02. Resulting draft id recorded:r-4765449699230921012. - First failure: The Stack routine, session completed 2026-05-20 23:39 UTC, PR https://github.com/Talonsturgill/linkedin-alaska-ai-weekly/pull/10, branch
claude/linkedin-stack-2026-05-20.out/gmail_draft_id.txtrecorded thePENDING_APPROVALplaceholder. - Still failing: Anchorage Desk routine, session completed 2026-05-21 13:39 UTC, PR https://github.com/Talonsturgill/linkedin-alaska-ai-weekly/pull/14, branch
claude/linkedin-desk-2026-05-21. SamePENDING_APPROVALplaceholder.
The repository is public (or at minimum accessible to Anthropic support with the account context above) so the artifacts under each branch's out/ directory — including gmail_payload.json for the failed runs — can be inspected directly to confirm payload validity.
Minimal reproduction without routine triggers: if a routine surface isn't available for testing, the divergence can be observed by running step 2's ToolSearch from any interactive session on the account (returns UUID-prefixed) and comparing against the captured ToolSearch output from any of the three routine session logs above (returns named alias).
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.146 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Repository (public, all artifacts reproducible):
https://github.com/Talonsturgill/linkedin-alaska-ai-weekly
Per-routine evidence — out/ artifacts on each failing branch:
- PR #14 Anchorage Desk:
out/gmail_payload.json(the fully-built payload the routine generated) andout/gmail_draft_id.txt(thePENDING_APPROVALplaceholder the routine wrote whencreate_draftrejected it) on branchclaude/linkedin-desk-2026-05-21. - PR #10 The Stack: same two files on branch
claude/linkedin-stack-2026-05-20. Thegmail_draft_id.txton this branch has since been updated to a real id (r1050369637301707005) — that id was fired from an interactive session (this one) using the UUID-prefixed registration, which is the exact divergence the bug is about. Commita52a2f7is the manual-fix;f...before it is the routine's original placeholder. - PR #8 Cold Take (control — routine that worked):
out/gmail_draft_id.txtrecording draftr-4765449699230921012on branchclaude/linkedin-contrarian-2026-05-20-02. Same routine code, same payload shape, ran four hours before the cutover, landed.
Config files relevant to the bug:
.claude/settings.local.json:{"permissions":{"allow":["mcp__Gmail__create_draft","mcp__Gmail__search_threads"]}}— confirms the failing tool name is on the harness allowlist, ruling out client-side approval gate.- No
.mcp.json, no.claude/mcp.json, nomcpServersblock anywhere in the repo — rules out project-local MCP server overrides.
Current workaround in place:
The routines stop at writing out/gmail_payload.json and committing it. A human-in-the-loop interactive session (which resolves the UUID-prefixed registration) fires the draft from that JSON. Round-trip works every time. This is brittle — defeats the point of the routine — but unblocks shipping.
Screenshots that would help if your team wants visual confirmation (I can't capture from this container, but the account-holder can):
- The chat panel of a failing routine session showing the verbatim
Streamable HTTP error...string returned fromcreate_draft. - The Claude Code on the web Integrations panel showing the Gmail integration listed once, with its "always allow" toggle set.
- The Gmail Drafts UI showing the manually-fired drafts (proving the underlying OAuth grant is healthy and the account can receive drafts from MCP) versus the absence of the routine-generated ones.
Cross-reference, if useful: The Anchorage Desk PR (#14) is a "no defensible target this cycle" run — the email body is the validator's drop list rather than a finished post. It's a particularly clean reproduction because the failure is purely about Gmail transport, not about any content the routine was trying to ship. The other two failing branches (#10, ##14 again) failed identically with very different payload shapes (one full HTML post with image, one tabular drop-list). Payload content is not a variable.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗