Adopt streamable_http_client API from MCP SDK#2620
Conversation
- Update import to use new streamable_http_client function - Convert httpx_client_factory to httpx.AsyncClient before passing to new API - Maintain backward compatibility by continuing to accept factories - Add deprecation warning for sse_read_timeout parameter The new API accepts httpx.AsyncClient directly instead of factories. We continue accepting factories for OAuth compatibility, converting them to clients at the boundary with the MCP SDK.
|
Warning Rate limit exceeded@jlowin has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 17 minutes and 38 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughThe changes update HTTP client configuration in the transport layer. The import statement corrects the module name to Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Convert read_timeout_seconds from timedelta to float before passing to httpx, matching the pattern used in the SSE transport.
Test Failure AnalysisSummary: Two timeout-related tests are failing because the is passing a object directly to httpx's timeout parameter, which expects a float (seconds). Root Cause: In , the code passes Suggested Solution: Convert the timedelta to seconds before passing to httpx, following the same pattern as the SSE transport: # In src/fastmcp/client/transports.py around line 294-295
if session_kwargs.get("read_timeout_seconds") is not None:
read_timeout_seconds = cast(
datetime.timedelta, session_kwargs.get("read_timeout_seconds")
)
httpx_client_kwargs["timeout"] = read_timeout_seconds.total_seconds()Detailed AnalysisFailing Tests
Error TracebackThis error occurs in httpx/httpcore when it tries to calculate a deadline by adding the timeout value to the current time. The httpx library expects timeout values as floats (seconds), but receives a timedelta object instead. Code ComparisonSSE Transport (correct) - if session_kwargs.get("read_timeout_seconds") is not None:
read_timeout_seconds = cast(
datetime.timedelta, session_kwargs.get("read_timeout_seconds")
)
client_kwargs["timeout"] = read_timeout_seconds.total_seconds()StreamableHttp Transport (incorrect) - if session_kwargs.get("read_timeout_seconds") is not None:
httpx_client_kwargs["timeout"] = session_kwargs.get("read_timeout_seconds")Related Files
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/fastmcp/client/transports.py (2)
255-267: Dead code:self.sse_read_timeoutis stored but never used.After the deprecation warning, lines 265-267 still process and store
sse_read_timeoutinself.sse_read_timeout, but this value is never referenced inconnect_session. Since the new API doesn't support this parameter, consider removing the dead code.if sse_read_timeout is not None: if fastmcp.settings.deprecation_warnings: warnings.warn( "The `sse_read_timeout` parameter is deprecated and no longer used. " "The new streamable_http_client API does not support this parameter. " "Use `read_timeout_seconds` in session_kwargs or configure timeout on " "the httpx client via `httpx_client_factory` instead.", DeprecationWarning, stacklevel=2, ) - if isinstance(sse_read_timeout, int | float): - sse_read_timeout = datetime.timedelta(seconds=float(sse_read_timeout)) - self.sse_read_timeout = sse_read_timeout
301-302: Document the httpx_client_factory calling convention requirement.The factory is called both with no arguments (line 232 in oauth.py) and with kwargs (headers, auth, timeout) at line 302. Custom factories must support both patterns. Add a docstring or type hint on the
httpx_client_factoryparameter explaining that factories should handle being called with optional kwargs, or accept**kwargsto forward unused parameters.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/fastmcp/client/transports.py(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
**/*.py: Write Python code with Python ≥3.10 and include full type annotations
Use specific exception types in error handling - never use bareexcept
Prioritize readable, understandable code - clarity over cleverness; avoid obfuscated or confusing patterns even if they're shorter
Files:
src/fastmcp/client/transports.py
🧠 Learnings (2)
📓 Common learnings
Learnt from: jlowin
Repo: jlowin/fastmcp PR: 0
File: :0-0
Timestamp: 2025-12-01T15:48:05.095Z
Learning: PR #2505 in fastmcp adds NEW functionality to get_access_token(): it now first checks request.scope["user"] for the token (which never existed before), then falls back to _sdk_get_access_token() (the only thing the original code did). This is not a reversal of order but entirely new functionality to fix stale token issues.
📚 Learning: 2025-12-13T19:58:20.851Z
Learnt from: CR
Repo: jlowin/fastmcp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-13T19:58:20.851Z
Learning: Applies to tests/**/*.py : Pass FastMCP servers directly to clients using in-memory transport for testing; only use HTTP transport when explicitly testing network features
Applied to files:
src/fastmcp/client/transports.py
🧬 Code graph analysis (1)
src/fastmcp/client/transports.py (2)
src/fastmcp/server/server.py (1)
settings(357-365)src/fastmcp/server/dependencies.py (1)
get_http_headers(523-566)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Run tests: Python 3.10 on windows-latest
- GitHub Check: Run tests: Python 3.13 on ubuntu-latest
- GitHub Check: Run tests: Python 3.10 on ubuntu-latest
- GitHub Check: Run tests with lowest-direct dependencies
🔇 Additional comments (2)
src/fastmcp/client/transports.py (2)
26-26: LGTM!Import correctly updated to use the new
streamable_http_clientAPI from the MCP SDK.
287-298: LGTM!Clean construction of httpx client configuration with proper timedelta-to-seconds conversion for the timeout parameter.
Adopts the new
streamable_http_clientAPI from the MCP Python SDK while maintaining backward compatibility.Changes
streamablehttp_clienttostreamable_http_clienthttpx_client_factorytohttpx.AsyncClientinstances before passing to the new APIsse_read_timeoutparameter which is no longer supported by the new APIImplementation Details
The new API accepts
httpx.AsyncClientdirectly instead of factories. FastMCP maintains its factory-based API for OAuth compatibility, creating clients from factories only when calling the MCP SDK:Closes #2594