DEV Community

UB3DQY
UB3DQY

Posted on

Hidden Gmail and Calendar integrations quietly broke my Claude SDK pipeline

I lost a few hours to one of those bugs that feels fake when you first describe it out loud.

My Claude Agent SDK pipeline kept failing with the most generic error possible:

Command failed with exit code 1
Enter fullscreen mode Exit fullscreen mode

No useful stderr. No clear traceback. No obvious repro beyond "real sessions fail, synthetic tests sometimes pass."

At first I thought it was just another boring auth problem. Then I thought it was a subprocess visibility problem. Then I thought it was WSL. All of those were plausible. None of them were the whole story.

The actual cause was stranger:

after claude auth login, my account quietly picked up account-level Gmail and Google Calendar MCP integrations that I had never explicitly enabled, could not see in the Claude web UI, and could not remove from the CLI. Those integrations wanted an interactive Google OAuth flow, and that was enough to break every non-interactive Claude SDK subprocess I was using for automation.

The workaround was one CLI flag:

extra_args={"strict-mcp-config": None}
Enter fullscreen mode Exit fullscreen mode

That was the end of the bug.

Finding it was the hard part.

Where this showed up

I use Claude Agent SDK inside a small memory pipeline.

The shape is straightforward:

  • a hook fires at the end of a Codex session
  • the hook spawns flush.py
  • flush.py calls Claude Agent SDK
  • the result gets written into a daily markdown log

This is exactly the kind of automation that should be boring once it's set up.

Instead, real Codex sessions started failing. The hook would fire, the downstream script would start, and then the Agent SDK step would die with:

Fatal error in message reader: Command failed with exit code 1
Enter fullscreen mode Exit fullscreen mode

That was enough to break the memory pipeline completely. No flush, no daily log entry, no durable memory from those sessions.

And because the error was happening in a subprocess layer, the surface signal was awful. It just looked like "the SDK sometimes fails."

Why this was so annoying to debug

There were at least three reasons this bug wasted my time.

1. The first fix appeared to work

At one point I thought I had solved it just by running:

claude auth login
Enter fullscreen mode Exit fullscreen mode

And for a moment, it looked like I had.

Synthetic tests passed. The bundled Claude binary responded. The pipeline looked alive again.

That "fix" turned out to be fake.

It worked briefly because the environment had not yet fully populated the auth-related cache state that was about to cause the real failure.

So I got the worst possible debugging gift: a temporary false victory.

2. The important error wasn't where I was looking

I had already added stderr visibility around the SDK call, expecting to catch the real CLI failure there.

That didn't help much, because the Google MCP auth path wasn't producing a nice actionable stderr message.

The auth prompt was effectively happening on the wrong channel for my diagnostic setup. The SDK stderr callback got nothing useful. ProcessError.stderr was empty. All I had was the outer shell of the failure.

From the outside, it still looked like "exit code 1, good luck."

3. The integrations were invisible

This was the part that really crossed from "normal debugging" into "what exactly is this system doing?"

In Claude.ai web settings, I could see the usual visible things. But I could not see any Gmail or Google Calendar integrations anywhere I would expect:

  • not in Settings → Connectors
  • not in Settings → Customize → Skills
  • not in Customize → Connectors

And yet on disk, after claude auth login, I could see this:

{
  "claude.ai Gmail": {"timestamp": 1776092446619},
  "claude.ai Google Calendar": {"timestamp": 1776092446683}
}
Enter fullscreen mode Exit fullscreen mode

That came from:

~/.claude/mcp-needs-auth-cache.json
Enter fullscreen mode Exit fullscreen mode

And the CLI confirmed the same story:

claude.ai Gmail:           https://gmail.mcp.claude.com/mcp - ! Needs authentication
claude.ai Google Calendar: https://gcal.mcp.claude.com/mcp - ! Needs authentication
Enter fullscreen mode Exit fullscreen mode

At that point the bug finally started making sense.

What was actually happening

Here is the version I wish someone had handed me before I started digging:

When you authenticate Claude via OAuth, your account may receive account-level MCP integrations as part of its backend claims.

In my case, that included:

  • claude.ai Gmail
  • claude.ai Google Calendar

Those integrations were not local project config.
They were not something I had added manually in the repo.
And they were not removable with normal local MCP commands.

For example:

claude mcp remove "claude.ai Gmail"
Enter fullscreen mode Exit fullscreen mode

returned:

No MCP server found with name: "claude.ai Gmail"
Enter fullscreen mode Exit fullscreen mode

Which makes sense once you realize the CLI isn't managing them as local entries. They are attached at the account/backend layer.

Then the next failure follows naturally:

  1. bundled Claude CLI starts inside a non-interactive SDK subprocess
  2. it checks account-level MCP claims
  3. it sees Gmail and Calendar need additional Google auth
  4. it tries to initiate an interactive OAuth flow
  5. there is no TTY / browser / normal user interaction path
  6. subprocess stalls or exits with code 1

That was the whole bug.

Not my prompt.
Not my retry logic.
Not the summary logic.
Not even the main auth state in the obvious sense.

Just hidden MCP integrations pulling a subprocess into an auth flow it had no way to complete.

Why this matters beyond my repo

This is not really about my particular memory pipeline.

It matters because subprocess-based Claude SDK automation is a completely normal pattern. People use it for:

  • capture pipelines
  • background summarizers
  • hook-triggered analysis
  • scheduled jobs
  • internal tools

All of those run in contexts where interactive browser auth is either awkward or impossible.

If account-level integrations that require fresh OAuth can quietly attach themselves after login, and if they are invisible in the UI, then the failure mode becomes:

  • everything looks fine in your normal interactive CLI
  • your automation suddenly fails in the background
  • the error surface is generic
  • and the root cause is not where you would reasonably look first

That is a nasty class of bug.

The workaround that fixed it

The workaround was to isolate the subprocess from account-level MCP discovery.

In practice, that meant passing:

ClaudeAgentOptions(
    allowed_tools=[],
    max_turns=2,
    extra_args={"strict-mcp-config": None},
)
Enter fullscreen mode Exit fullscreen mode

That translates to the bundled Claude binary getting:

--strict-mcp-config
Enter fullscreen mode Exit fullscreen mode

And once I did that, the subprocess stopped trying to discover or auth those account-level MCP integrations.

The pipeline started running cleanly again.

That was the actual fix.

Deleting the cache file:

rm ~/.claude/mcp-needs-auth-cache.json
Enter fullscreen mode Exit fullscreen mode

did not really fix anything. It just bought a little time until the state was regenerated.

The part I still don't love

The workaround is fine. I'm happy to use it in automation.

What I don't love is the product behavior that made it necessary.

From a developer point of view, a few things feel wrong here.

Hidden integrations are a bad default

If my account has Gmail and Calendar MCP integrations attached, I should be able to see them in the UI and turn them off.

Right now, from the outside, it feels like they exist in a shadow layer of account state that can affect automation without being visible where a user would normally manage integrations.

Opt-out without visible opt-in is rough

I didn't explicitly wire Gmail or Calendar into this project. Yet they still ended up influencing subprocess behavior after OAuth login.

That is a surprising default for anyone using Claude as a programmable toolchain component instead of just a chat app.

Non-interactive contexts should fail more gracefully

If the process is clearly non-interactive, the CLI should not wander into a user-hostile auth path and then collapse into a generic exit code.

At minimum, I would want:

  • a clear message saying an MCP integration requires interactive authentication
  • the name of the integration
  • and ideally a way to skip it automatically in SDK subprocess mode

What I wish the docs said

The one warning I really needed was something like this:

If you use Claude Agent SDK in non-interactive subprocesses, account-level MCP integrations attached through OAuth may trigger additional authentication flows. If those integrations are not fully authenticated, subprocess calls may fail. Use strict MCP config isolation for automation workloads.

That single paragraph would have saved me hours.

The short version

If you hit a mysterious Claude Agent SDK subprocess failure with a generic exit code 1, and your interactive CLI mostly works, check whether hidden account-level MCP integrations are involved before you start rewriting your own code.

In my case, the real sequence was:

  • I thought the pipeline was unauthenticated
  • then I thought stderr visibility was missing
  • then I thought WSL was the root cause
  • and the real issue turned out to be hidden Gmail and Calendar MCP integrations trying to force Google OAuth inside a non-interactive subprocess

The fix was not glamorous:

extra_args={"strict-mcp-config": None}
Enter fullscreen mode Exit fullscreen mode

But at least now I know what class of failure I was dealing with.

And honestly, that's often the hardest part.


I'm building this as part of a markdown-first memory system for Claude Code and Codex. I keep expecting the hard parts to be prompt design or summarization quality. More often than not, the real work is figuring out which invisible layer is making the obvious layer look broken.

Top comments (2)

Collapse
 
warwickmcintosh profile image
Warwick McIntosh

The Gmail/Calendar MCP tools are a perfect example of silent breakage. They work in testing, you ship, and six months later Google changes an API or deprecates an endpoint and your agent just silently fails. You need health checks for MCP tools specifically - not just "can I connect" but "does this tool actually return useful data for this query type."

Collapse
 
ub3dqy profile image
UB3DQY

Yeah, totally. That’s basically the broader lesson I took from this too.
In my case it failed even before I got to “does the tool return useful data?” The subprocess got pulled into an auth flow just because those MCP integrations were attached at the account level and weren’t fully authenticated.
So “can I connect?” really isn’t enough. A tool can be technically present and still be useless, or even break background automation just by existing in the environment.
Feels like MCP integrations need a much more real notion of health than just “endpoint is reachable.”