Routines: MCP tool call (Gmail send_message) silently no-ops but run reports SUCCEEDED

Status Open
Maintainer reply None cached
Activity 3 comments · opened Sep 28, 2026

Summary

A scheduled cloud Routine (Scheduled Cloud Agent, created via the /schedule flow / RemoteTrigger API) with MCP connectors attached silently fails to actually execute an MCP tool call that has a real side effect (specifically Gmail → send_message), while the routine run is still reported as ROUTINE_RUN_STATUS_SUCCEEDED with failure_reason: ROUTINE_RUN_FAILURE_REASON_UNSPECIFIED. There is no error surfaced anywhere in the API response, and no email is ever sent.

Environment

  • Feature: Routines / Scheduled Cloud Agents (claude.ai/code/routines, created via RemoteTrigger create/update)
  • Model: claude-sonnet-5
  • Environment: default (anthropic_cloud)
  • MCP connectors attached to the routine: two claude.ai connectors (one email-sending connector, one data-retrieval connector), both confirmed connected and working outside of Routines
  • Client: Claude Code (claude.ai), session created 2026-09-28

Steps to reproduce

  1. Create a routine with job_config.ccr.mcp_connections set to two working MCP connectors (a data-source connector and an email-sending connector), and a prompt instructing the agent to: (a) fetch some data via the data-source connector, (b) compose a message from it, (c) send it via the email connector's send_message-equivalent tool.
  2. Trigger the routine (run_once_at a few minutes out, or action: "run").
  3. Poll RemoteTrigger action: get — the run completes with status: ROUTINE_RUN_STATUS_SUCCEEDED, failure_reason: ROUTINE_RUN_FAILURE_REASON_UNSPECIFIED, and a finished_at timestamp.
  4. No email is received. No error is visible anywhere in the trigger/run metadata returned by the API.

What I tried to isolate the cause

  • Confirmed the email MCP connector works correctly when called directly, interactively, in an ordinary (non-Routine) Claude Code session with the same account/connector — the email is sent and received immediately.
  • Ran the exact same task (fetch record via connector A, generate content, send via connector B's send tool) manually in an interactive session, using the identical underlying MCP tools — it worked on the first try.
  • Hypothesized the routine's session_context.allowed_tools (which I had set to ["Bash"] only) might be gating MCP tool calls too, since Routines are the only place I've seen an explicit allowed_tools allowlist required alongside mcp_connections. Updated allowed_tools to explicitly include the fully-qualified MCP tool names (e.g. mcp__<connector-name>__<tool>), and re-ran the routine. Still SUCCEEDED, still no email sent.
  • Explicitly instructed the routine's prompt: "if any MCP tool call fails or is denied, do NOT finish silently — report the exact tool and error in your final message." The run still completed successfully with no visible complaint and no email.
  • I could find no tool or API (in the standard Claude Code toolset, including RemoteTrigger, TaskGet/TaskOutput, and the MCP resource-listing tools) that lets me read the actual transcript/message history of a Routine's cloud session (cse_... session id) to see what the agent actually attempted and what error (if any) it received from the MCP tool call. This made it impossible to self-diagnose beyond the isolation test above.

Impact

This makes Routines currently unreliable/unusable for any workflow whose entire purpose is an MCP connector side effect (sending an email, creating a record, posting a message, etc.), because:

  1. The failure is completely silent — the routine reports success even though nothing happened.
  2. There's no way for a user (or an assisting Claude Code session) to inspect what happened inside the routine's cloud session to diagnose further.

Ask

  • Please confirm whether this is a known limitation/bug with MCP tool execution specifically inside Routines/CCR cloud sessions (as opposed to interactive sessions), and if so, what's needed in job_config to make MCP connector tool calls actually execute.
  • Consider exposing a way (API or tool) to read a Routine run's session transcript, so users/agents can self-diagnose failures like this one without needing platform-side log access.

Happy to provide the routine ID / session IDs from my run privately if useful for debugging — omitted here since this is a public issue.

View original on GitHub ↗

3 Comments

stonianua · 16 days ago

Useful isolation already — especially “interactive same connectors work” vs “Routine reports SUCCEEDED with zero side effect.” A few peer checks that have helped on similar silent-MCP-in-CCR cases:

  1. Treat SUCCEEDED as “agent finished a turn,” not “tools ran.” Several Routine/CCR paths mark the run succeeded when the model stops, even if every MCP call was skipped, denied, or never dispatched. If the final assistant message never names a concrete tool_use / mcp__…__send_message id, assume the side effect never left the model.
  1. Confirm the run session actually attached the connectors. After a firing, open the cse_… session from the Routine UI (or any session deep-link you get) and check the MCP / connectors panel inside that session. Interactive sessions can show connected connectors while the Routine-spawned session quietly inherits none (or a stripped allowlist). Your create_trigger “stores no MCP connectors” class of warnings on sibling issues is the same failure mode.
  1. allowed_tools: ["Bash"] plus later fully-qualified MCP names is still brittle. If the Routine schema only accepts built-in tool names (or a separate mcp_connections grant path), putting mcp__connector__tool into allowed_tools can be ignored without error. Safer A/B: one run with allowed_tools omitted/default (if the API allows), and one with only the email connector attached (no Bash allowlist) so you can see whether Bash-only configs are masking MCP.
  1. Probe with a read-only MCP tool first. Before send_message, have the Routine call a harmless list/get on the same email connector (or the data connector you already use). If read tools also never appear in the session / never return data, this is connector attachment, not send-specific. If reads work and only send no-ops, look for a side-effect / policy gate on mutating tools in headless CCR.
  1. Transcript gap is real. Until Routine run transcripts are exposed, the practical self-check is: (a) force the prompt to echo back the exact tool name + raw tool result JSON before finishing, and (b) watch the destination inbox / Sent folder with a unique subject token. If the echo never includes a tool result payload, the call never happened regardless of SUCCEEDED.

Happy to compare notes if you get one firing where the session UI shows the Gmail connector attached but send_message still produces no Sent mail — that would pin it on tool dispatch vs connector attach.

klauscruz · 13 days ago

Update with new data from today's recurring run (cron-based, not a manual one-off test):

  • The routine's prompt instructs: check a dedup folder in the data-source connector, create it if missing, then process eligible items found in a 24h lookback window, then send email, then add processed items to the folder.
  • Today's run (status: SUCCEEDED) actually created the dedup folder (confirmed via the connector's own list-folders call afterward — folder exists with a timestamp matching the run's fired_at). So at least one MCP tool call (a create/write operation on the data-source connector, not the email connector) did execute successfully inside the Routine's cloud session.
  • However, the folder was created empty — no items added — and no email was sent, even though there genuinely were 2 matching records in the lookback window (confirmed independently by querying the data-source connector myself, interactively, right after).

This shifts my suspicion: it's not necessarily that all MCP tool calls silently no-op in a Routine session (since the folder-create call did work). It looks more like whatever the agent did for the "list eligible items in the last 24h" step came back empty inside the Routine's session — either:

  • the time-window calculation/parameters used inside the Routine session differ from what I'd use interactively (e.g. a wrong anchor for "now", or a malformed date-range query), or
  • it only got as far as the dedup-folder housekeeping step and never attempted the actual list/filter call, or the email send, for some other reason (and still reported SUCCEEDED).

Still no way to inspect the Routine's session transcript to see which calls were actually attempted vs skipped — that remains the main blocker to pinning this down further. Reiterating the ask for transcript visibility on Routine runs; it would make this kind of bug trivial to diagnose instead of requiring manual interactive reproduction every time.

klauscruz · 12 days ago

Second consecutive weekday with this bug. Today's scheduled cron fire also returned SUCCEEDED with zero emails sent, despite 2 genuinely eligible meetings existing in the lookback window (confirmed independently via the data-source connector, both with full generated content — summaries, chapter breakdowns, action items, etc., so there's no ambiguity about eligibility or content-readiness this time).

Also tightened the Routine's own eligibility logic since yesterday (added more matching signals, since the original title-based filter alone was too narrow) — that change is unrelated to this bug and didn't affect the outcome; the run still silently did nothing actionable.

At this point it's 2/2 production days with real eligible data where the Routine has produced zero output while reporting success. Both days required full manual recovery (fetch record → generate content → send via the email connector → mark processed) run interactively, which — as before — worked immediately both times, on the first try, for all 4 meetings recovered so far across the two days.