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
I've searched for my issue in the issue tracker before opening this issue
Description
Constructing an HTTP MCPToolset with an explicit http_client= fails at connect
time with a TypeError about an unexpected follow_redirects keyword argument.
The URL-only path (MCPToolset('http://...')) is unaffected.
Root cause
When http_client= is passed, MCPToolset adapts it to a factory:
pydantic_ai/mcp.py (~L2322): factory = _make_httpx_client_factory(http_client),
passed as httpx_client_factory= to the FastMCP transport.
_make_httpx_client_factory (~L2344) returns a closure with signature factory(headers=None, timeout=None, auth=None). This matches the mcp SDK's McpHttpClientFactory protocol (mcp/shared/_httpx_utils.py), which declares
exactly headers, timeout, auth.
But the actual caller is FastMCP, not the mcp SDK directly. In fastmcp/client/transports/http.py (~L176, fastmcp 3.3.1) it calls:
i.e. FastMCP passes follow_redirects= (intentionally — note its own # type: ignore[call-arg]), which is beyond the McpHttpClientFactory protocol the
pydantic-ai closure was written against. The closure has no **kwargs, so it raises.
Suggested fix
Make the closure tolerant of extra kwargs the transport may pass (its return type is
already Callable[..., httpx.AsyncClient]):
Arguably FastMCP is calling factories outside the documented McpHttpClientFactory
protocol; but since MCPToolset is built on FastMCP's client, accepting **kwargs
here is the pragmatic and forward-compatible fix.
Minimal, Reproducible Example
No live server required — it fails while building the httpx client, before any request:
AI notice: this bug was spotted and this report was generated by ANthropic's Claude Opus 4.7
Initial Checks
Description
Constructing an HTTP
MCPToolsetwith an explicithttp_client=fails at connecttime with a
TypeErrorabout an unexpectedfollow_redirectskeyword argument.The URL-only path (
MCPToolset('http://...')) is unaffected.Root cause
When
http_client=is passed,MCPToolsetadapts it to a factory:pydantic_ai/mcp.py(~L2322):factory = _make_httpx_client_factory(http_client),passed as
httpx_client_factory=to the FastMCP transport._make_httpx_client_factory(~L2344) returns a closure with signaturefactory(headers=None, timeout=None, auth=None). This matches the mcp SDK'sMcpHttpClientFactoryprotocol (mcp/shared/_httpx_utils.py), which declaresexactly
headers, timeout, auth.But the actual caller is FastMCP, not the mcp SDK directly. In
fastmcp/client/transports/http.py(~L176, fastmcp 3.3.1) it calls:i.e. FastMCP passes
follow_redirects=(intentionally — note its own# type: ignore[call-arg]), which is beyond theMcpHttpClientFactoryprotocol thepydantic-ai closure was written against. The closure has no
**kwargs, so it raises.Suggested fix
Make the closure tolerant of extra kwargs the transport may pass (its return type is
already
Callable[..., httpx.AsyncClient]):This is robust regardless of whether the module is on
httpxorhttpx2.Notes
httpx2inpydantic_ai.mcp, warn onhttpxfallback #5664 (prefer httpx2 in pydantic_ai.mcp) touches the samemodule but does not modify
_make_httpx_client_factory.McpHttpClientFactoryprotocol; but since
MCPToolsetis built on FastMCP's client, accepting**kwargshere is the pragmatic and forward-compatible fix.
Minimal, Reproducible Example
No live server required — it fails while building the httpx client, before any request:
Actual behavior
Expected behavior
The user-supplied
http_clientis used for the connection (it works on theMCPServerStreamableHTTP(url, http_client=...)deprecated path).Python, Pydantic AI & LLM client version