-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Describe the bug
Description
When GitHub Copilot CLI connects to an MCP server that uses OAuth with dynamic client registration, the OAuth authorization flow can fail because the redirect_uri used in the authorize request does not match the loopback redirect URI
associated with the dynamically registered client.
In our case, the client was registered with one 127.0.0.1 callback port, but the subsequent /connect/authorize request used a different ephemeral port. The authorization server rejected the request with:
- invalid_request
- Invalid redirect_uri
Affected version
GitHub Copilot CLI 1.0.3.
Steps to reproduce the behavior
- Configure Copilot CLI to authenticate against an OAuth/OIDC provider that uses dynamic client registration.
- Let the client registration complete with a loopback redirect URI on 127.0.0.1 using a specific port.
- Start the Copilot CLI login flow.
- Observe that the subsequent /connect/authorize request uses a different loopback port.
- The authorization request fails with Invalid redirect_uri.
Expected behavior
Copilot CLI should use the same redirect URI during authorization that was established for the dynamically registered client, or otherwise preserve compatibility with native-app loopback redirect handling.
Actual behavior
The authorize request fails because the redirect URI sent by Copilot CLI does not exactly match the redirect URI stored for the client.
Additional context
Relevant auth server logs show the mismatch clearly:
ClientName: "GitHub Copilot CLI"
AllowedRedirectUris: ["http://127.0.0.1:64831/"]
redirect_uri in authorize request: "http://127.0.0.1:50719/"
Error: "invalid_request"
ErrorDescription: "Invalid redirect_uri"
Additional log sequence:
Start authorize request
Start authorize request protocol validation
client configuration validation for client "<client_id>" succeeded
Request validation failed
Invalid redirect_uri: "http://127.0.0.1:50719/"
This suggests the CLI may be registering or storing one loopback callback URI but initiating the browser auth flow with another.