github / github/copilot-cli

Allow locally-defined stdio MCP servers to run when the MCP registry policy fetch fails (no managed policy in force)

未关闭
#4,512 0 条评论 2 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

area:enterprise area:mcp
主要语言
Shell
星标
11.2k
派生
1.9k
平均合并
14 小时 16 分钟
30 天内合并 PR
6

描述

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:

  1. wrote into their own config file,
  2. pointed at a binary on their own disk,
  3. 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:

  1. 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.
  2. 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.
  3. 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
  • #2552 — non-default servers blocked after registry policy fetch fails
  • #4419 — fail-closed with an empty allow list on an account with no managed policy
  • #2486, #2481, #2498, #2479 — the 404 variants of the same fail-closed behavior
  • #4364, #4378, #4346 — same failure mode reached via cert / auth / CI token paths

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.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先定位负责获取并执行 MCP 注册表策略的原生运行时代码,然后检查对 mcp-config.json 和 settings.json 的解析。重现获取失败时的 source=none 情况,并比较本地 stdio 服务器与远程服务器或受托管策略约束的情况。在不削弱托管策略执行的前提下覆盖约定的行为,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
github
领域
cli, security
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
冷清
描述清晰度
基本清楚
新手友好度
38/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。