github / github/copilot-cli

MCP OAuth: initialize request after successful OAuth login omits User-Agent header, ignoring configured custom headers

Ouverte
#4,681 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

area:authentication area:mcp area:networking
Langage dominant
Shell
Étoiles
11.2k
Forks
1.9k
Merge moyen
14 h 16 min
PR mergées (30 j)
6

Description

Summary

When connecting to a remote MCP server (HTTP/Streamable-HTTP transport) that requires OAuth authentication, the underlying rmcp/reqwest-based HTTP client used by Copilot CLI/App does not send a User-Agent header on the initialize request that follows a successful OAuth token exchange. Custom headers configured for the MCP server in mcp-config.json (via copilot mcp add --header "...") are also not applied to this specific request.

This causes initialize requests to fail against any MCP server that is fronted by infrastructure which rejects requests without a User-Agent header (e.g. AWS WAF's managed rule AWSManagedRulesCommonRuleSet / NoUserAgent_HEADER, or similar reverse-proxy/WAF configurations), even though the OAuth handshake itself (authorize/token exchange) completes successfully.

Steps to Reproduce

  1. Configure a remote HTTP MCP server that requires OAuth, optionally with a custom header:
    copilot mcp add --transport http my-server https://example.com/mcp --header "User-Agent: MyCustomAgent/1.0"
    
  2. Trigger authentication (e.g. via Authenticate in the Copilot App, or by using the tool in Copilot CLI).
  3. Complete the browser-based OAuth login/consent flow successfully.
  4. Observe that the subsequent initialize request fails if the target server (or infrastructure in front of it) rejects requests lacking a User-Agent header — even though the configured custom User-Agent header was set on the server config.

Expected Behavior

  • The MCP client should always send a non-empty User-Agent header (e.g. an SDK/product default such as GitHubCopilotCLI/<version>) on all requests, including the post-OAuth initialize request.
  • Any custom headers configured for the MCP server (via --header, or the headers field in mcp-config.json) should be honored consistently across all requests sent to that server, including the OAuth-authenticated initialize request — not only a subset of requests.

Actual Behavior

  • The initialize request sent after a successful OAuth token exchange appears to omit the User-Agent header entirely (confirmed via server-side testing: a request without any User-Agent header reproduces the exact same generic, non-JSON 403 Forbidden response observed by the client).
  • Configuring a custom User-Agent header via copilot mcp add --header "User-Agent: ..." does not change this behavior — the header is stored in mcp-config.json but is not applied to the initialize request.
  • The resulting error surfaces as:
    RPC error -32603: Request session.mcp.oauth.login failed with message: failed to initialize MCP client: Send message error Transport [rmcp::transport::worker::WorkerTransport<rmcp::transport::streamable_http_client::StreamableHttpClientWorker<mcp::client::RawCapturingReqwestClient>>] error: unexpected server response: HTTP 403 Forbidden: <html>
    <head><title>403 Forbidden</title></head>
    <body>
    <center><h1>403 Forbidden</h1></center>
    </body>
    </html>
    , when send initialize request
    
  • The prior OAuth challenge/token exchange step succeeds (HTTP 401 with a proper WWW-Authenticate/OAuth challenge, then successful browser login/consent) — the failure occurs specifically on the follow-up initialize call.

Environment

  • GitHub Copilot CLI/App version: 1.0.82 (latest at time of testing)
  • OS: macOS (Darwin)
  • MCP server transport: http (Streamable HTTP), OAuth-protected (dynamic client registration / RFC 9728 protected resource metadata)
  • Same MCP server + OAuth flow works correctly in VS Code's Copilot Chat extension, suggesting this is specific to the rmcp-based client used by Copilot CLI/App rather than a server-side issue.

Additional Notes

  • This was root-caused by directly testing the target MCP server with and without a User-Agent header: omitting it reproduces byte-for-byte the same generic HTML 403 response seen by the CLI/App, while including any non-empty User-Agent returns the expected JSON response from the server's own application layer.
  • No corporate proxy, VPN, or network-level header rewriting was involved — headers were confirmed to pass through the network unmodified in isolated testing.
  • We suspect the initialize request after OAuth is issued via a code path (RawCapturingReqwestClient in rmcp::transport::streamable_http_client) that either uses a fresh/default reqwest::Client without the configured User-Agent/custom headers, or otherwise doesn't propagate the per-server header configuration used for other requests.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Suivez la requête d'initialisation qui suit OAuth à travers rmcp::transport::streamable_http_client et RawCapturingReqwestClient, en la comparant aux requêtes qui utilisent les headers configurés de mcp-config.json. Commencez par reproduire la requête post-connexion avec un User-Agent obligatoire et un header personnalisé. La tâche est terminée lorsque la requête d'initialisation envoie un User-Agent non vide et conserve les headers personnalisés configurés, avec une couverture de régression pour ce chemin OAuth.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
rust
Domaine
api, authentication, cli
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
Active
Clarté
Plutôt claire
Accessibilité débutants
55/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.