Summary
When the MCP registry policy fetch fails, Copilot CLI fails closed and blocks all non-default MCP servers — including local stdio servers that the user defined themselves in their own ~/.copilot/mcp-config.json and launches as local child processes.
There is currently no way for a user to say "these are my own servers, run them regardless of registry reachability." I'd like a supported mechanism for that.
Environment
- Copilot CLI
1.0.81-0
- Windows (
win32-x64)
- Individual account, no managed/enterprise policy in effect
What happens
https://api.github.com/copilot/mcp_registry is currently returning 503:
HTTP/2.0 503 Service Unavailable
No server is currently available to service your request.
Which produces this in the CLI logs:
[MDM] No managed settings found at C:\Program Files\GitHubCopilot\managed-settings.json
[managedSettings] device MDM: no policy present on this device
[managedSettings] server policy: none for this account (404/empty) from https://github.com
[managedSettings] effective policy resolved: source=none, bypassDisabled=false, serverFetchFailed=false
[WARNING] Failed to fetch MCP registry policy: Failed to fetch MCP registry policy: 503 Service
Unavailable. Non-default MCP servers will be blocked until the policy can be fetched.
Note the combination: the CLI explicitly resolves source=none — there is no device policy and no server policy for this account — and then still blocks every user-configured server because a separate registry endpoint is unavailable.
Result: 4 locally-defined stdio servers (meshy, blender, game-image-creator, playwright) silently disappear from the session. Only the built-in github-mcp-server remains. The session is unusable for the work it was opened to do, and the only remedy is to wait for a GitHub-side outage to clear.
Why this is the wrong default for local servers
The gate appears to be transport-blind. A stdio server is a local executable that the user already:
- wrote into their own config file,
- pointed at a binary on their own disk,
- runs as a child process under their own uid, with their own env vars.
That is strictly less privileged than the !-shell and arbitrary file-write tools the CLI already grants. Gating it on the reachability of a remote registry doesn't add a meaningful security property for a user with no managed policy — it just converts a GitHub availability blip into a local outage.
Remote/HTTP servers are a different story, and I have no objection to those staying gated.
Requested change
Any one of these would resolve it. Roughly in order of preference:
- Exempt locally-defined
stdio servers from registry-policy gating when no managed policy is in force (source=none). The registry is a supply-chain control for servers the user didn't author; it shouldn't govern a local process the user already fully controls.
- A user-level trust list, e.g.
"trustedMcpServers": ["blender", "playwright"] in settings.json, mirroring the existing disabledMcpServers key. Ignored/overridden whenever a real managed policy is present, so enterprise control is unaffected.
- Fail open on transient fetch failures specifically (
5xx, timeouts, connection errors) when source=none, while continuing to fail closed on an actual policy that denies a server. A 503 is "we don't know", not "denied".
Current config surface
As far as I can tell from the shipped build, the only MCP-related keys accepted are mcpServers (in mcp-config.json) and disabledMcpServers (in settings.json). There's no positive-trust counterpart to disabledMcpServers, and the enforcement itself lives in the native runtime, so there's no user-side escape hatch at all today.
Related
The recurring theme across all of these is that a fetch failure for an absent or irrelevant policy takes down user-owned servers. This issue is the feature-side ask rather than another instance report.
Summary
When the MCP registry policy fetch fails, Copilot CLI fails closed and blocks all non-default MCP servers — including local
stdioservers that the user defined themselves in their own~/.copilot/mcp-config.jsonand launches as local child processes.There is currently no way for a user to say "these are my own servers, run them regardless of registry reachability." I'd like a supported mechanism for that.
Environment
1.0.81-0win32-x64)What happens
https://api.github.com/copilot/mcp_registryis currently returning503:Which produces this in the CLI logs:
Note the combination: the CLI explicitly resolves
source=none— there is no device policy and no server policy for this account — and then still blocks every user-configured server because a separate registry endpoint is unavailable.Result: 4 locally-defined
stdioservers (meshy,blender,game-image-creator,playwright) silently disappear from the session. Only the built-ingithub-mcp-serverremains. The session is unusable for the work it was opened to do, and the only remedy is to wait for a GitHub-side outage to clear.Why this is the wrong default for local servers
The gate appears to be transport-blind. A
stdioserver is a local executable that the user already:That is strictly less privileged than the
!-shell and arbitrary file-write tools the CLI already grants. Gating it on the reachability of a remote registry doesn't add a meaningful security property for a user with no managed policy — it just converts a GitHub availability blip into a local outage.Remote/HTTP servers are a different story, and I have no objection to those staying gated.
Requested change
Any one of these would resolve it. Roughly in order of preference:
stdioservers from registry-policy gating when no managed policy is in force (source=none). The registry is a supply-chain control for servers the user didn't author; it shouldn't govern a local process the user already fully controls."trustedMcpServers": ["blender", "playwright"]insettings.json, mirroring the existingdisabledMcpServerskey. Ignored/overridden whenever a real managed policy is present, so enterprise control is unaffected.5xx, timeouts, connection errors) whensource=none, while continuing to fail closed on an actual policy that denies a server. A503is "we don't know", not "denied".Current config surface
As far as I can tell from the shipped build, the only MCP-related keys accepted are
mcpServers(inmcp-config.json) anddisabledMcpServers(insettings.json). There's no positive-trust counterpart todisabledMcpServers, and the enforcement itself lives in the native runtime, so there's no user-side escape hatch at all today.Related
404variants of the same fail-closed behaviorThe recurring theme across all of these is that a fetch failure for an absent or irrelevant policy takes down user-owned servers. This issue is the feature-side ask rather than another instance report.