You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Remote HTTP MCP servers that require OAuth can be started many times in one CLI session, causing repeated initialize/OAuth/tool-list work against the same endpoint. In a real session with a single Azure DevOps MCP server configured, the Copilot CLI logs showed 79 MCP client for azure-devops connected events, repeated OAuth churn, 429 responses, and intermittent -32001 Request timed out errors.
The endpoint itself was healthy: DNS/TLS/connectivity were fine, the MCP initialize request returned the expected 401 OAuth challenge, and the OAuth metadata endpoint returned the expected tenant/scopes. The failure mode appears to be client-side startup/auth fan-out rather than network failure.
This is related to, but distinct from, #3456. That issue covers concurrent refresh-token grants once tools are already in use. This issue is about repeated remote MCP host/client startup and OAuth initiation across session/agent contexts and reconnect paths.
Note: timeout: 60000 is not an effective increase in 1.0.60 because the runtime applies a 60s floor/default. Raising it above 60000 only mitigates slow requests; it does not address the repeated startup/auth storm.
Observed behavior
One configured remote MCP server produced many successful client connection events in the same active session.
OAuth metadata/challenge paths were hit repeatedly.
The server emitted rate-limit responses (429) during the churn.
The client sometimes surfaced -32001 Request timed out.
Disabling the remote MCP server by default avoids the local symptom, but removes the tool unless manually re-enabled.
Runtime code-path evidence from the distributed 1.0.60 bundle
The public github/copilot-cli repository appears to contain only the release wrapper (README.md, install.sh, changelog, workflows), so I could not prepare a code PR against the real source. I inspected the installed runtime bundle at ~/.copilot/pkg/darwin-arm64/1.0.60/app.js instead.
Key findings from the minified runtime:
Each log line MCP client for <server> connected is emitted only after a fresh client.connect(...) in setupAndConnectClient, so repeated log lines represent repeated client connections, not repeated logging from one connection.
processHttpServer / processSseServer first try to start the remote client without an auth provider. On auth-required failure, they initiate OAuth and call startHttpMcpClient / startSseMcpClient again with the provider.
buildMcpOAuthHandler either emits mcp.oauth_required or directly runs browserless OAuth. There does not appear to be a global singleflight/dedupe across MCP host instances for the same server URL/resource.
The agent tool config path exposes getMcpServerProviderForAgent, which calls a host cache keyed by an agent/context key. getOrCreateHost creates a new MCP host for that key and starts the same mcpServers config. This can multiply remote MCP clients when multiple agents/contexts need the same configured server.
1.0.60 also records remoteReconnectMeta for HTTP/SSE servers and attempts reconnect on unexpected client close, which can further multiply connection attempts if the remote transport closes during auth replacement, timeout, or rate-limit responses.
The request options helper applies timeout: Math.max(config.timeout ?? 0, 60000) and resetTimeoutOnProgress: true, so the default/minimum request timeout is already 60s.
Expected behavior
For a given remote MCP server URL/resource/client identity, the CLI should avoid duplicate startup/auth work across all in-process MCP hosts.
Suggested fixes:
Add a process-wide singleflight for remote MCP OAuth/startup keyed by a stable remote identity, e.g. (transport type, normalized URL/resource, client_id/sub where applicable, relevant auth config).
Coalesce concurrent OAuth requests so multiple hosts await the same in-flight provider/token flow instead of each initiating its own.
Reuse/share remote MCP hosts or clients by config fingerprint where safe, instead of starting one remote client per agent/context when the underlying server config is identical.
If cached OAuth is already available, avoid the unauthenticated first-connect path, or ensure the failed unauthenticated transport is fully closed and marked intentional before starting the authenticated replacement.
Do not auto-reconnect on auth-required/401 replacement or intentional OAuth reconnect; rate-limit reconnects and avoid reconnecting when the server is already marked needs-auth or failed due to auth.
Remote MCP servers often back onto shared OAuth/token/rate-limit infrastructure. Starting many independent clients for the same configured remote endpoint can create unnecessary OAuth prompts, rate limits, and request timeouts even when the endpoint is healthy.
Describe the bug
Remote HTTP MCP servers that require OAuth can be started many times in one CLI session, causing repeated
initialize/OAuth/tool-list work against the same endpoint. In a real session with a single Azure DevOps MCP server configured, the Copilot CLI logs showed 79MCP client for azure-devops connectedevents, repeated OAuth churn,429responses, and intermittent-32001 Request timed outerrors.The endpoint itself was healthy: DNS/TLS/connectivity were fine, the MCP initialize request returned the expected
401OAuth challenge, and the OAuth metadata endpoint returned the expected tenant/scopes. The failure mode appears to be client-side startup/auth fan-out rather than network failure.This is related to, but distinct from, #3456. That issue covers concurrent refresh-token grants once tools are already in use. This issue is about repeated remote MCP host/client startup and OAuth initiation across session/agent contexts and reconnect paths.
Affected version
GitHub Copilot CLI 1.0.60 on macOS.
Configuration shape
Sanitized
.mcp.json:{ "mcpServers": { "azure-devops": { "type": "http", "url": "https://mcp.dev.azure.com/<org>", "timeout": 120000, "headers": { "X-MCP-Readonly": "true" } } } }Note:
timeout: 60000is not an effective increase in 1.0.60 because the runtime applies a 60s floor/default. Raising it above 60000 only mitigates slow requests; it does not address the repeated startup/auth storm.Observed behavior
429) during the churn.-32001 Request timed out.Runtime code-path evidence from the distributed 1.0.60 bundle
The public
github/copilot-clirepository appears to contain only the release wrapper (README.md,install.sh, changelog, workflows), so I could not prepare a code PR against the real source. I inspected the installed runtime bundle at~/.copilot/pkg/darwin-arm64/1.0.60/app.jsinstead.Key findings from the minified runtime:
MCP client for <server> connectedis emitted only after a freshclient.connect(...)insetupAndConnectClient, so repeated log lines represent repeated client connections, not repeated logging from one connection.processHttpServer/processSseServerfirst try to start the remote client without an auth provider. On auth-required failure, they initiate OAuth and callstartHttpMcpClient/startSseMcpClientagain with the provider.buildMcpOAuthHandlereither emitsmcp.oauth_requiredor directly runs browserless OAuth. There does not appear to be a global singleflight/dedupe across MCP host instances for the same server URL/resource.getMcpServerProviderForAgent, which calls a host cache keyed by an agent/context key.getOrCreateHostcreates a new MCP host for that key and starts the samemcpServersconfig. This can multiply remote MCP clients when multiple agents/contexts need the same configured server.remoteReconnectMetafor HTTP/SSE servers and attempts reconnect on unexpected client close, which can further multiply connection attempts if the remote transport closes during auth replacement, timeout, or rate-limit responses.timeout: Math.max(config.timeout ?? 0, 60000)andresetTimeoutOnProgress: true, so the default/minimum request timeout is already 60s.Expected behavior
For a given remote MCP server URL/resource/client identity, the CLI should avoid duplicate startup/auth work across all in-process MCP hosts.
Suggested fixes:
(transport type, normalized URL/resource, client_id/sub where applicable, relevant auth config).needs-author failed due to auth.Why this matters
Remote MCP servers often back onto shared OAuth/token/rate-limit infrastructure. Starting many independent clients for the same configured remote endpoint can create unnecessary OAuth prompts, rate limits, and request timeouts even when the endpoint is healthy.