[BUG] claude -p (non-interactive mode) does not connect to claude.ai MCP servers

Resolved 💬 5 comments Opened Mar 23, 2026 by 2214962083 Closed Mar 23, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

When using claude -p (non-interactive/print mode), claude.ai remote MCP servers (Atlassian/Jira, Slack, Notion, Google Calendar, Gmail, Sentry, Cloudflare, Context7) are never connected, even though:

  1. OAuth tokens are valid and accessible
  2. The /v1/mcp_servers API call succeeds and returns the server list (verified via --debug)
  3. All local/project MCP servers (from .mcp.json) load normally in -p mode
  4. The same machine, same user, same project — interactive mode loads all 114+ MCP tools correctly

What Should Happen?

claude -p should connect to claude.ai MCP servers the same way interactive mode does, since:

  • The OAuth token is already available (no interactive login needed)
  • The server list fetch already runs in -p mode (only the connection step is skipped)
  • Local/project MCP servers already connect fine in -p mode

Error Messages/Logs

# Interactive mode: 114 tools (including claude.ai MCP)
$ claude
# /mcp shows all remote servers connected ✓

# Non-interactive mode: 0 claude.ai MCP tools
$ claude -p "List tools starting with mcp__claude_ai" \
    --output-format stream-json --verbose --max-turns 1 \
    --dangerously-skip-permissions < /dev/null

# init event in stream output:
# Total tools: 92, claude.ai MCP tools: 0
# Only local MCP tools (codebase-memory-mcp, chrome-devtools, etc.) present

With DEBUG=* claude -p ..., I can see the /v1/mcp_servers?limit=1000 request IS sent and the server list IS fetched, but the individual server connections are never established.

Steps to Reproduce

  1. Ensure you have claude.ai MCP servers configured (Atlassian, Slack, etc.) — verify they work in interactive mode
  2. Run:

``bash
claude -p "List all tools starting with mcp__claude_ai, one per line" \
--output-format stream-json --verbose --max-turns 1 \
--dangerously-skip-permissions < /dev/null 2>/dev/null \
| head -1 | python3 -c "
import sys, json
evt = json.loads(sys.stdin.readline())
tools = evt.get('tools', [])
mcp = [t for t in tools if t.startswith('mcp__claude_ai')]
print(f'Total: {len(tools)}, claude.ai MCP: {len(mcp)}')
"
``

  1. Observe: claude.ai MCP: 0

Root Cause (binary analysis of v2.1.81)

The MCP initialization has two phases in the startup code:

// Phase 1: Fetch cloud MCP server list — runs in BOTH modes ✓
cloudServers = isPrintMode && !isSimpleMode && !hasEnterpriseMcp()
  ? fetchCloudMcpServers()
  : Promise.resolve({});

// Phase 2: Connect to individual servers — SKIPPED in -p mode ✗
cloudMcp = isPrintMode
  ? Promise.resolve({ clients: [], tools: [], commands: [] })  // ← always empty
  : cloudServers.then(connectServers);

// Final merge
allMcp = Promise.all([localMcp, cloudMcp]).then(merge);

The isPrintMode ? Promise.resolve({}) : ... condition unconditionally skips cloud MCP connection in -p mode.

Suggested Fix

Either remove the -p gate:

cloudMcp = cloudServers.then(servers =>
  Object.keys(servers).length > 0 ? connectServers(servers) : { clients: [], tools: [], commands: [] }
);

Or add an opt-in flag (e.g., --connect-remote-mcp) for users who need cloud MCP in non-interactive mode.

Claude Code Version

2.1.81

Is this a regression?

I don't know

Claude Model

Opus

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Non-interactive/CI environment

Additional Information

Impact: This affects all non-interactive use cases — CI/CD pipelines, bot/bridge integrations (Telegram/Slack bots spawning claude -p), cron jobs, and SDK-style integrations.

Workaround: Configure each cloud MCP server as a local stdio server in .mcp.json using mcp-remote:

{
  "mcpServers": {
    "context7": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.context7.com/mcp"]
    }
  }
}

This works for servers without OAuth (Context7), but servers requiring OAuth (Atlassian, Slack, Notion) need individual OAuth flows through mcp-remote, defeating the purpose of unified claude.ai MCP.

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗