Skip to content

MCP registry policy fetch returns 403 for Actions GITHUB_TOKEN, blocking all non-default MCP servers in CI #4346

Description

@ben-ogp

Bug

In GitHub Actions, when Copilot CLI authenticates with the workflow's built-in GITHUB_TOKEN (the documented, PAT-less Actions setup with copilot-requests: write), the MCP allowlist policy fetch fails with 403 and the CLI fails closed, blocking every non-default MCP server:

[WARNING] Failed to fetch MCP registry policy: Failed to fetch MCP registry policy: 403 Forbidden. Non-default MCP servers will be blocked until the policy can be fetched.
[ERROR] MCP server "notionApi" filtered: Could not verify server against any configured registry

The main completions path works fine with the same token (the run produces model output, billed to the org). Only the GET api.github.com/copilot/mcp_registry call is rejected — so MCP in Actions is effectively unusable for org-owned repos, even when the org's "MCP servers in Copilot" policy is Allow all.

This looks like the same server-side token-type rejection as #3396 ("GitHub App Server-To-Server Tokens are not supported for this endpoint"), which was addressed for the models/completions path by the July 2026 change, but apparently not for the mcp_registry policy endpoint.

Environment

  • Copilot CLI 1.0.77 (stable/latest via npm install -g @github/copilot — not the prerelease case from Prerelease CLI builds can block non-default MCP servers after registry policy fetch fails #2552)
  • GitHub Actions, ubuntu-latest, GitHub Enterprise Cloud org-owned private repo
  • Workflow permissions include copilot-requests: write; auth via GITHUB_TOKEN env (a ghs_ installation token)
  • Org Copilot policy "MCP servers in Copilot": enabled, registry access Allow all
  • MCP server declared in .github/mcp.json (auto-discovered path) and also tried via --additional-mcp-config — identical result

Evidence it's the token type, not org policy or config

Calling the same endpoint with a user OAuth token from a member of the same org:

$ gh api -i /copilot/mcp_registry
HTTP/2.0 200 OK
X-Accepted-Oauth-Scopes:            ← empty: no special scopes required
{"mcp_registries":[{"url":"","registry_access":"allow_all","owner":{...}}]}

The same call made by the CLI inside Actions with GITHUB_TOKEN returns 403, reproduced byte-for-byte across 6+ runs. Debug log sequence:

[DEBUG] Sending telemetry event: cli.telemetry (kind: mcp_policy_check)
[DEBUG] [rust:log] starting new connection 'Some("api.github.com")'
[WARNING] Failed to fetch MCP registry policy: Failed to fetch MCP registry policy: 403 Forbidden. Non-default MCP servers will be blocked until the policy can be fetched.

Also ruled out: repo Settings → MCP servers registration (no change), config-file location, secret plumbing.

Impact

  • All non-default MCP servers are blocked in the recommended PAT-less Actions setup; the only workaround is reintroducing a user PAT (e.g. via COPILOT_GITHUB_TOKEN) or moving the data access out of MCP entirely.
  • Compounding: in non-interactive -p runs, the model can see its configured MCP tools are missing and sometimes refuses the whole task, and the underlying 403 is only visible at --log-level debug — so the failure mode is opaque in CI.

Expected behavior

One of:

  1. GET /copilot/mcp_registry accepts Actions installation tokens, resolving the policy from the repo-owning org/enterprise (mirroring how the completions path was fixed).
  2. A documented CI behavior when the policy cannot be fetched under an installation token — e.g. honoring explicitly workspace-configured servers, or a documented opt-out — rather than silently failing closed.
  3. At minimum, the Actions guide and MCP allowlist reference documenting that MCP servers do not work with GITHUB_TOKEN auth, with the 403 warning surfaced at default log level.

Workaround (confirmed)

We removed the MCP dependency from the CI invocation and pre-fetch the data the prompt needed via the service's plain REST API in a prior workflow step; the CLI run itself works fine with GITHUB_TOKEN.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions