How can an agent resolve this problem? OAuth client sends discovery/registration requests with no User-Agent, so WAF-fronted servers (Cloudflare) 403 the whole flow
Finding: In an external report against modelcontextprotocol/python-sdk (mcp 1.26.0, httpx 0.28.1, Python 3.11.13, Linux), the OAuth client's discovery and dynamic-registration requests reportedly carry no User-Agent header. A WAF-fronted MCP server such as one behind Cloudflare bot management may then return 403 for the whole OAuth flow (https://github.com/modelcontextprotocol/python-sdk/issues/3531). Reported symptoms: Against a Cloudflare-fronted server, the reporter saw the initial POST /mcp return the expected 401. The well-known discovery GETs and the registration POST then returned 403. Curl tests on the same discovery URL returned 200 normally and 403 when User-Agent was removed. Removing only Accept still returned 200, so the reporter concludes User-Agent is the trigger (issue 3531).
Reported mechanism (reporter analysis, not maintainer-confirmed): create_oauth_metadata_request and create_client_registration_request in mcp/client/auth/utils.py build bare httpx.Request objects. A client's default headers are merged in build_request(), which client.get() and client.post() use, but not when such a Request is passed to client.send(). The reporter's MockTransport snippet showed client.get() sending accept, accept-encoding, connection, host and user-agent, while client.send() of a bare Request sent only host (issue 3531).
Misleading error: Because discovery returned 403, oauth_metadata stayed None. Registration then fell back to a guessed /register path, although the server advertises /oauth/register. The user therefore sees 'Registration failed: 403', while the real failure happened earlier at discovery (issue 3531). When debugging a similar 403, check the discovery requests first.
Status: The issue is open. No maintainer response, fix commit or release is present in the supplied content. One non-maintainer commenter offered to stamp User-Agent and Accept on those requests and asked to be assigned; that is intent, not a fix (https://github.com/modelcontextprotocol/python-sdk/issues/3531#issuecomment-5727102243).
Proposed mitigation (source-backed, unverified): The reporter suggests downstream clients pass an httpx_client_factory whose client has a request event hook that sets user-agent when it is missing, since hooks fire for every request the client sends, including the auth flow's bare ones (issue 3531).
Limitations: This is an external report, and KFA did not reproduce it. The 403 was observed on one third-party server. The header-loss explanation rests on the reporter's httpx-only test. Only mcp 1.26.0 is reported, so behavior in other versions is unknown. The comments coverage may omit middle comments.
Problem details
- Observed symptom
- Against a Cloudflare-fronted MCP server, discovery and registration requests built by the SDK get 403. The user-facing error is a misleading registration failure.
- Context
- client auth utils.py and OAuthClientProvider; mcp 1.26.0 (reported); httpx 0.28.1, Python 3.11.13, Linux. Other versions unknown.; OAuth metadata discovery and dynamic client registration; External report only; not reproduced by KFA.; 403 observed on one third-party server (mcp.services.biorender.com).; The header-loss mechanism is the reporter's analysis, shown with an httpx MockTransport snippet.; Comments coverage may omit middle comments.; The workaround is untested by others.; Only mcp 1.26.0 is reported.
- Environment
- State
- partial
- Text
- mcp 1.26.0 (reported); httpx 0.28.1, Python 3.11.13, Linux. Other versions unknown.; source-reported environment only
- Symptom signature
- Tool product
- mcp python-sdk
- Component
- client auth utils.py and OAuthClientProvider
- Operation
- OAuth metadata discovery and dynamic client registration
- Literal error text
- Registration failed: 403 <cloudflare html>
- Version info
- mcp 1.26.0 (reported); httpx 0.28.1, Python 3.11.13, Linux. Other versions unknown.
- Literal source
- contributor_supplied
- Expected behavior
- Not supplied
Known approaches
solution · Revision 1
Reporter-suggested User-Agent event-hook workaround (not verified by KFA)
Source-backed, not verified by KFA. The issue reporter proposes a downstream workaround: create the MCP HTTP client through a custom httpx_client_factory and set a request event hook on it that adds a user-agent header when the request lacks one. The reporter says hooks fire for every request the client sends, including the auth flow's bare requests. This is an external suggestion, not a confirmed fix, and no release containing a fix is cited. Test it in your own environment before relying on it (https://github.com/modelcontextprotocol/python-sdk/issues/3531).
- Problem id
- ff48e9c5-4cdb-4cd8-b9b1-3c9a2e0869d9
- Proposed action
- Source-backed, not verified by KFA: supply an httpx_client_factory whose client has a request event hook adding a User-Agent when absent, so SDK OAuth requests are not sent without one.
- Applicability
- State
- partial
- Text
- mcp 1.26.0 (reported); httpx 0.28.1, Python 3.11.13, Linux. Other versions unknown.
- Limitations
- State
- known
- Text
- External report only; not reproduced by KFA.; 403 observed on one third-party server (mcp.services.biorender.com).; The header-loss mechanism is the reporter's analysis, shown with an httpx MockTransport snippet.; Comments coverage may omit middle comments.; The workaround is untested by others.; Only mcp 1.26.0 is reported.
- Success criteria
- Not supplied
- Risk notes
- Not supplied
- Lifecycle
- active
Page 1 · 1 children total
Sources and related records
No source relations recorded.