Skip to content

.mcp.json loaded twice when cwd = git root, causing remote MCP servers to fail #2291

@adthom

Description

@adthom

Describe the bug

Summary

When the current working directory is the git repository root, the CLI loads .mcp.json twice — once as "project" config and once as "workspace" config. The second pass tears down already-connected remote HTTP MCP servers and re-attempts connections that fail, leaving most servers permanently dead for the session.

Environment

  • Copilot CLI version: 1.0.12-0
  • OS: Windows 11 (PowerShell 7)
  • Model: Claude Opus 4.6

.mcp.json structure (sanitized)

{
  "mcpServers": {
    "local-stdio-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@example/mcp-server@latest", "mcp"],
      "tools": ["*"]
    },
    "remote-server-A": {
      "url": "https://remote-mcp-host/mcp/environments/<env-id>/servers/serverA",
      "type": "http",
      "tools": ["toolA1", "toolA2"]
    },
    "remote-server-B": {
      "url": "https://remote-mcp-host/mcp/environments/<env-id>/servers/serverB",
      "type": "http",
      "tools": ["toolB1", "toolB2"]
    }
    // ... 6 more remote HTTP servers, all same host, different endpoints
  }
}

All 8 servers are defined in a single .mcp.json at the repository root, which is also the cwd when launching copilot.

What happens (from logs)

Pass 1 — "project" config load

17:14:29.208Z [DEBUG] Loaded workspace MCP config from C:\path\to\repo\.mcp.json
17:14:29.209Z [DEBUG] Loaded MCP config from C:\path\to\repo\.mcp.json (project): 8 server(s)

All 8 servers begin connecting. The 7 remote HTTP servers hit an OAuth challenge, authenticate successfully, reconnect, and all connect within ~3 seconds:

17:14:30.198Z [ERROR] MCP transport for remote-server-A closed
17:14:30.198Z [ERROR] Server remote-server-A requires authentication, initiating OAuth flow
17:14:30.398Z [ERROR] Successfully authenticated with remote-server-A
17:14:30.399Z [ERROR] Starting remote MCP client for remote-server-A (reconnect)
17:14:32.546Z [ERROR] MCP client for remote-server-A connected, took 2147ms

This repeats for all 7 remote servers — all succeed.

Pass 2 — "workspace" config load (same file!)

~120ms after Pass 1, the same .mcp.json is loaded again under a different label:

17:14:29.951Z [DEBUG] Loaded workspace MCP config from C:\path\to\repo\.mcp.json
17:14:29.951Z [DEBUG] Loaded workspace MCP config from .mcp.json: 8 server(s)

Pass 2 starts its own stdio server. When that connects (~4.4s later), it triggers re-initialization of all remote servers:

17:14:34.395Z [ERROR] MCP client for local-stdio-server connected, took 4439ms
17:14:34.396Z [ERROR] Starting remote MCP client for remote-server-A ...

This tears down the working Pass 1 connections and tries to reconnect. But the reconnection attempts fail instantly (~30-70ms each) because the OAuth flow doesn't complete on the second attempt:

17:14:34.466Z [ERROR] MCP transport for remote-server-A closed
17:14:34.467Z [ERROR] Server remote-server-A requires authentication, initiating OAuth flow
17:14:34.467Z [ERROR] Failed to start MCP client for remote server remote-server-A: Error: Streamable HTTP error: Error POSTing to endpoint:
17:14:34.467Z [ERROR] Recorded failure for server remote-server-A

This repeats for all 7 remote servers — all fail. The session starts with none of them available.

Key evidence: it's deterministic

Tested across 2 separate sessions (full exit + relaunch). Identical sequence both times:

Phase Timing Result
Pass 1: project config loads T+0s 8 servers start connecting
Pass 1: OAuth succeeds T+0.2s All 7 remote servers authenticate
Pass 1: All connected T+3s ✅ All 7 remote servers working
Pass 2: workspace config loads T+0.1s Same file loaded again
Pass 2: stdio server connects T+5s Triggers remote server re-init
Pass 2: Tears down Pass 1 T+5s All 7 Pass 1 connections killed
Pass 2: Reconnect fails T+5.3s ❌ All 7 fail with Streamable HTTP error

Occasionally 1-2 servers recover via late retry, but the majority are permanently lost.

Affected version

GitHub Copilot CLI 1.0.12-0.

Steps to reproduce the behavior

  1. Create a git repository with .mcp.json at the root containing multiple remote HTTP MCP servers that require OAuth.
  2. cd into the repository root.
  3. Run copilot.
  4. Observe that most/all remote HTTP servers fail to load.

Expected behavior

  • .mcp.json at the repo root should be loaded once, regardless of whether cwd = git root.
  • If the same file is discovered from multiple config scopes, it should be deduplicated before initialization.

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions