Skip to content

MCP: user-configured api.githubcopilot.com/mcp/ server loses the injected Copilot token on 1.0.81-10, and /mcp auth cannot rescue it (github.com advertises no dynamic client registration) #4604

Description

@examon

Describe the bug

On 1.0.81-10 a user-configured https://api.githubcopilot.com/mcp/ server no longer receives the injected Copilot token. It starts with no Authorization header, takes a 401, and is reported as needing auth. The only remedy the CLI then offers — OAuth — is impossible, because github.com's authorization server does not advertise dynamic client registration:

Authenticating: github
Authentication failed: MCPOAuthError: Client registration failed: Authorization server does not support dynamic client registration

On 1.0.80 the same config works and that OAuth prompt is merely spurious. So 1.0.801.0.81-10 turns a cosmetic false prompt into a hard block for this configuration. Workarounds exist (a PAT header, a static oauthClientId, or switching to the built-in github-mcp-server), but none is discoverable from the error, which points at an /mcp auth that cannot succeed.

Affected version

1.0.81-10 (npm dist-tag prerelease). Not present on 1.0.80 (dist-tag latest). Linux x64, enterprise-routed account.

Steps to reproduce the behavior

Add the server exactly as a user would:

$ copilot mcp add --transport http github https://api.githubcopilot.com/mcp/

Then ask for a tool from it, denying shell so the model cannot silently answer with curl:

$ copilot -p "Call get_me from the MCP server named github and print only the login. \
    Do not use shell/curl/bash; if the MCP tool is unavailable say exactly UNAVAILABLE." \
    --allow-all-tools --deny-tool shell
version result /mcp shows
1.0.80 Get my user profile (MCP: github) → real login ✓ Connected, Tools (48/48 enabled)
1.0.81-10 UNAVAILABLE !, and Details: Tools unavailable: Error: MCP server "github" is not connected

Reproduced on 1.0.81-10 from a clean profile that never attempted auth, so this is not poisoned state from the failed OAuth attempt.

Debug log — the credential-injection path simply does not run

Same prompt, both versions pinned, each with its own HOME and COPILOT_HOME, both launched with --no-auto-update, counted with --log-level debug:

log line 1.0.80 1.0.81-10
Starting pending GitHub MCP server "github" after authentication 1 0
No access token was provided in this request 0 6
Browser-based OAuth required 0 2
1.0.80:     [DEBUG] Starting pending GitHub MCP server "github" after authentication

1.0.81-10:  [ERROR] worker quit with fatal: Transport channel closed, when
              Client(OAuthChallenge { ... "No access token was provided in this request" ...
                                      status_code: 401 })
1.0.81-10:  [WARNING] MCP OAuth authorization failed; reporting the server as needing auth
              {"server":"github","error":"Browser-based OAuth required for https://api.githubcopilot.com/mcp/"}

The built-in github-mcp-server connects fine in the same 1.0.81-10 run, so credentials and payload are healthy — it is specifically the injection into the user-configured server that stops happening.

Careful when reproducing: the launcher auto-updates, and the payload is resolved and cached per-HOME, so a throwaway HOME pulls whatever latest is rather than the version you think you pinned. Pin the payload per version, pass --no-auto-update, and re-print copilot --version from inside the same HOME/COPILOT_HOME as the failing run — nothing else establishes which build produced a result.

The second half: OAuth cannot rescue it

Verified unauthenticated, so this is independent of any local credential:

$ curl -s https://github.com/.well-known/oauth-authorization-server/login/oauth
{"issuer":"https://github.com/login/oauth", ... }      # no registration_endpoint

https://api.githubcopilot.com/.well-known/oauth-protected-resource/mcp/ advertises authorization_servers: ["https://github.com/login/oauth"], and that authorization server publishes no registration_endpoint. The runtime bypasses absent dynamic client registration only when the authorization server is Microsoft/Entra, so GitHub's own authorization server falls straight into registration and fails immediately.

Setting oauthClientId on the server does skip registration (a self-registered OAuth App), so this is not literally unrecoverable — but nothing in the failure points there. Note the current docs steer people to the built-in server, and the custom-remote example uses a PAT, so I can't claim the URL-only form is itself the documented path — only that it is the natural one to try, and that it used to work on 1.0.80.

Expected behavior

  1. Restore the token injection for a user-configured server on a recognized Copilot MCP host, so 1.0.81 behaves as 1.0.80 did; and
  2. Give GitHub's authorization server the same no-registration fallback that Microsoft/Entra already gets, so the offered remedy is not one that cannot succeed; and
  3. Don't offer authenticate on a server that is already carrying a bearer.

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:authenticationLogin, OAuth, device auth, token management, and keychain integrationarea:mcpMCP server configuration, discovery, connectivity, OAuth, policy, and registry

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions