You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Only follow method-preserving redirects; resolve unfollowed ones on every path
Review follow-ups for the origin-scoped redirect handling:
- A same-origin 301/302/303 answering a POST is no longer followed: httpx2's
next-request rules turn those into a body-less GET, which would drop the
JSON-RPC message. Only redirects that keep the method (307/308, or any
status for a GET) are followed; the rest come back unfollowed like an
off-origin redirect and the call fails naming the location.
- The standalone GET stream and the resumption GET now handle an unfollowed
redirect the way the message POST does: the GET stream logs it and stops
instead of spending its reconnection attempts on the same answer, and a
resumed request is resolved with the error instead of being left waiting.
One helper builds the message for all three.
- OAuth authorization-server metadata discovery treats a 3xx from a
well-known candidate like a 4xx and tries the next candidate, matching the
protected-resource metadata handler, now that these requests see redirect
responses directly.
- The simple-tool example keeps the 30s/300s timeouts it had before it
stopped using the MCP client factory.
Copy file name to clipboardExpand all lines: docs/client/transports.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,7 +29,7 @@ Pass a URL string and you get **Streamable HTTP**, the transport you deploy behi
29
29
--8<--"docs_src/client_transports/tutorial002.py"
30
30
```
31
31
32
-
That is the whole production client. `Client` wraps the URL in `streamable_http_client(...)` for you, on top of an `httpx2.AsyncClient` configured the way MCP needs: a 30-second timeout for connect/write/pool, and a 300-second read timeout because the server may hold a response stream open. Whichever client is underneath, the transport follows a redirect only when it stays on the endpoint's origin (same scheme, host and port, or `http` to `https` on the same host with the default ports), which covers a trailing-slash redirect. A redirect anywhere else is not followed, and the call it answered fails with an `MCPError` naming the location; if that address is the server you meant, use it as the URL.
32
+
That is the whole production client. `Client` wraps the URL in `streamable_http_client(...)` for you, on top of an `httpx2.AsyncClient` configured the way MCP needs: a 30-second timeout for connect/write/pool, and a 300-second read timeout because the server may hold a response stream open. Whichever client is underneath, the transport follows a redirect only when it stays on the endpoint's origin (same scheme, host and port, or `http` to `https` on the same host with the default ports) and keeps the request method, which covers a 307/308 trailing-slash redirect. Any other redirect is not followed, and the call it answered fails with an `MCPError` naming the location; if that address is the server you meant, use it as the URL.
33
33
34
34
!!! check
35
35
A `Client` you have constructed is **not** connected. Construction only picks the transport;
0 commit comments