-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Open
Labels
Description
Describe the bug
Copilot CLI fails OAuth token refresh with invalid redirect_uri error when using enterprise MCP servers that require fixed callback ports.
Context
Many enterprise OAuth servers (like Keycloak) enforce strict redirect URI validation that requires exact URI matches, including port numbers.
Copilot CLI uses random ephemeral ports for its OAuth callback server:
- Initial authentication works (the random port gets registered with the OAuth server)
- Token refresh fails because Copilot CLI spawns a callback server on a different random port
- The new port doesn't match the registered redirect URI
- OAuth server rejects with invalid redirect_uri
Why This Breaks Enterprise Deployments
Enterprise OAuth servers (like Keycloak with "Trusted Hosts" policy) often:
- Block Dynamic Client Registration from untrusted hosts
- Require redirect URIs to be explicitly pre-registered
- Validate redirect URIs with exact matching (including port)
Result: Users must re-authenticate via browser on every token expiration instead of automatic token refresh.
Affected version
0.0.410
Steps to reproduce the behavior
Prerequisites
- Enterprise MCP server with OAuth authentication (e.g., Keycloak)
- OAuth server configured with strict redirect URI validation (exact match required)
- Dynamic Client Registration disabled or restricted by "Trusted Hosts" policy
Steps
- Initial authentication
- Copilot CLI spawns callback server on random port (e.g., http://127.0.0.1:55167/callback
- Browser opens, user completes OAuth login
- Server registers the redirect URI with that specific port
- Tokens are stored successfully
- Wait for token expiration (typically 24 hours, or force expiration by manually editing ~/.copilot/mcp-oauth-config/.json to set a past expiresAt)
- Copilot CLI detects expired token
- Attempts token refresh by spawning callback server on a different random port (e.g., http://127.0.0.1:48923/callback)
- OAuth server rejects the request with invalid redirect_uri error
Expected behavior
Token refresh should succeed using the same callback port that was registered during initial authentication.
Implementation Options
- Fixed default port (like OpenCode uses port 19876)
- Configurable port via CLI flag or config file (like Codex's
mcp_oauth_callback_port) - Preferred port with fallback (like VS Code uses port 33418, falls back to random if unavailable)
Recommended Approach
Use VS Code's hybrid strategy (option 3):
- Try a default port (e.g.,
33418or19876) - Fall back to ephemeral port only if the default port is unavailable
- This balances enterprise compatibility with single-machine multi-instance scenarios
Comparison with Other Tools
| Tool | Port Strategy | Enterprise Compatible? |
|---|---|---|
| Copilot CLI (current) | Random ephemeral | ❌ No (breaks on refresh) |
| VS Code | Preferred 33418, fallback random | ✅ Yes |
| OpenCode | Fixed 19876 | ✅ Yes |
| Claude Code | Fixed 41842 | ✅ Yes |
| Codex | Ephemeral (configurable) | ✅ Yes |
Configuration Example
{
"mcpServers": {
"enterprise-mcp": {
"type": "http",
"url": "https://mcp.example.com",
"oauth": {
"callbackPort": 55167
},
"tools": ["*"]
}
}
}Additional context
No response
Reactions are currently unavailable