github / github/copilot-cli

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

Offen
#4,681 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

area:authentication area:mcp area:networking
Vorherrschende Sprache
Shell
Sterne
11.2k
Forks
1.9k
Ø Merge
14 Std. 16 Min.
Gemergte PRs (30 T.)
6

Beschreibung

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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Verfolge die OAuth-Follow-up-Initialize-Anfrage durch rmcp::transport::streamable_http_client und RawCapturingReqwestClient und vergleiche sie mit den Anfragen, die die konfigurierten mcp-config.json-Header verwenden. Beginne damit, die Anfrage nach dem Login mit einem erforderlichen User-Agent und einem benutzerdefinierten Header zu reproduzieren. Erledigt ist die Aufgabe, wenn die Initialize-Anfrage einen nicht leeren User-Agent sendet und konfigurierte benutzerdefinierte Header beibehält, mit Regressionstests für diesen OAuth-Pfad.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
rust
Bereich
api, authentication, cli
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Aktiv
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
55/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.