Repository navigation
OAuth discovery initialize POST probe can create server sessions that are never DELETEd #1048
Description
Summary
During OAuth discovery, when a GET to the MCP endpoint returns 404 or 405, AuthorizationManager falls back to POSTing a synthetic JSON-RPC initialize request to the endpoint in order to elicit a 401 response with a WWW-Authenticate header. If the server actually accepts that initialize instead of rejecting it (e.g. authorization is optional, or initialize is served before authentication), the server may allocate a session and return an Mcp-Session-Id. The client discards any non-401 probe response without ever sending an HTTP DELETE for that session, so the session is orphaned on the server.
Separately, the MCP spec does not clearly indicate that clients should send initialize as part of OAuth discovery at all. The probe exists as a pragmatic workaround for streamable HTTP servers that reject a session-less GET, but it means discovery — which callers reasonably expect to be a read-only operation — can have server-side side effects.
Current behavior
At 6839cfd, resource metadata discovery works like this:
discover_resource_metadata_url()first issues aGETagainst the base URL viafetch_resource_metadata_url(), hoping for a401+WWW-Authenticate.- Many streamable HTTP servers answer a session-less
GETwith404/405, in which casefetch_resource_metadata_url_with_post_probe()POSTsRESOURCE_METADATA_POST_PROBE_BODY— a syntheticinitializerequest withprotocolVersion: 2024-11-05. - Any response other than
401is logged and discarded. If the server processed theinitializeand returned anMcp-Session-Id, noDELETEis ever sent for it.
The probe was introduced in #960 to pass the client conformance suite against servers that reject session-less GETs.
Why this is a problem
- Servers where authorization is optional (or where
initializeis allowed pre-auth) accumulate orphaned sessions: one per discovery attempt, never cleaned up. - Callers that use discovery to check whether a server supports OAuth (the same usage pattern described in OAuth discovery should distinguish discovered authorization metadata from synthesized legacy endpoints #1037) trigger this side effect on servers that don't require auth at all — exactly the servers that will process the probe.
- The spec describes discovery via
401+WWW-Authenticate(RFC 9728) and well-known metadata paths; it does not sanctioninitializeas a discovery mechanism, so servers have no reason to expect or special-case this probe.
Possible fixes
- Best-effort cleanup: when the probe response is not
401and carries anMcp-Session-Idheader, send an HTTPDELETEfor that session before discarding the response. - Make the probe a last resort: try the well-known
oauth-protected-resourcepaths before falling back to the POST probe (today the probe runs before the well-known lookup), so most servers never receive a syntheticinitialize. - Upstream spec clarification: raise with the spec repo whether clients are intended to send
initializeas part of OAuth discovery at all, and what server-side session semantics apply to unauthenticated probe requests.
Options 1 and 2 are complementary and could both be implemented in the SDK regardless of the spec discussion.
Related
- fix: pass client conformance suite #960 (introduced the POST probe for conformance)
- OAuth discovery should distinguish discovered authorization metadata from synthesized legacy endpoints #1037 / feat: expose oauth discovery metadata source #1041 (metadata provenance — orthogonal, but same discovery code path)
Activity