Skip to content

fix(bare): OAuth deferred MCP connection spawns in --bare mode despite connect_all being skipped #3358

@bug-ops

Description

@bug-ops

Description

In `--bare` mode, `agent_setup::build_tool_setup` correctly skips `connect_all()` for non-OAuth MCP servers. However, the deferred OAuth spawn guard in `src/runner.rs` is not protected by an `exec_mode.bare` check. If the config contains an OAuth-transport MCP server (e.g. Todoist), a background task is spawned that calls `connect_oauth_deferred()` and establishes a live MCP connection — even in bare mode.

This is a regression from the fix in #3298 that added the bare-mode guard for `connect_all()` but did not cover the OAuth deferred path.

Reproduction Steps

  1. Configure an OAuth MCP server in your config (e.g. Todoist with `[mcp.servers.oauth]`).
  2. Run: `RUST_LOG=info ./target/debug/zeph --config .local/config/testing.toml --bare 2>&1 | grep -E 'mcp|MCP'`
  3. Observe `mcp.connect_url{server_id=todoist}` log line appearing after `agent shutdown complete`.

Expected Behavior

No MCP connections (including OAuth-based) should be established in `--bare` mode.

Actual Behavior

INFO  zeph_core::agent: agent shutdown complete
INFO  mcp.connect_url{server_id=todoist}: rmcp::service: Service initialized as client ...

The OAuth deferred connection fires ~8ms after agent shutdown, confirming the tokio task was spawned but the agent had already exited.

Root Cause

In `src/runner.rs`:

// Spawn deferred OAuth connections now that the UI channel is ready and can
// display the authorization URL.
if tool_setup.mcp_manager.has_oauth_servers() {       // ← no exec_mode.bare guard
    let mgr = std::sync::Arc::clone(&tool_setup.mcp_manager);
    tokio::spawn(async move {
        mgr.connect_oauth_deferred().await;
    });
}

The guard should be `!exec_mode.bare && tool_setup.mcp_manager.has_oauth_servers()`.

Environment

Logs / Evidence

Session CI-600 live test. Log excerpt:

2026-04-24T19:15:55.369534Z  INFO zeph_core::agent: agent shutdown complete
2026-04-24T19:15:55.377358Z  INFO mcp.connect_url{server_id=todoist}: rmcp::service: Service initialized as client peer_info=Some(InitializeResult { ... "todoist-mcp-server" ... })

Metadata

Metadata

Assignees

Labels

P2High value, medium complexitybugSomething isn't workingmcpMCP client/server

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions