Pydantic AI MCP Client: Connect a Remote MCP Server in v2
Connect a Pydantic AI agent to a remote MCP server with the MCP capability or MCPToolset: headers, tool filters, and what replaced MCPServerStreamableHTTP.
Tarun Khatri
Published · Updated · 7 min read
The Pydantic AI MCP client is the MCP capability in version 2: pass a URL and headers, then add it to your agent.
This guide connects a Pydantic AI agent to Weir's remote MCP server for public X (Twitter) data. You'll limit its tools and see the agent answer with search_x. Many guides online still use version 1 class names, which fail on 2.x. We run Weir.
import os
from pydantic_ai import Agent
from pydantic_ai.capabilities import MCP
weir = MCP(
url="https://api.weirapp.io/mcp",
headers={"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"},
allowed_tools=["search_x"],
)
agent = Agent("anthropic:claude-sonnet-5-5", capabilities=[weir])
How to connect Pydantic AI to a remote MCP server
You need the slim package with two extras, a Weir key and a model key. The Weir key rides in a header on every request, so there's no sign-in step. That suits scripts, scheduled jobs and servers.
- Installpip install "pydantic-ai-slim[anthropic,mcp]" in a virtual environment.
- Get a Weir keyCreate one under API keys in your Weir dashboard. Keep it in WEIR_API_KEY.
- Set a model keyAnthropic models read ANTHROPIC_API_KEY from the environment.
- Run the agentUse async with agent, then agent.run(), as in the script below.
As of 22 October 2026, PyPI lists pydantic-ai-slim 2.59.0, which needs Python 3.11 or later. The mcp extra pulled in FastMCP's client and the official mcp SDK on our install.
Skip the anthropic extra and the agent fails to start, with an ImportError that names it. Swap it for your provider's extra if you use another model.
Pydantic AI MCP client example: ask X a question
The script is 22 lines. Part one builds the capability and the agent:
import asyncio, os
from pydantic_ai import Agent
from pydantic_ai.capabilities import MCP
weir = MCP(
url="https://api.weirapp.io/mcp",
headers={"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"},
allowed_tools=["search_x", "get_x_post"],
)
agent = Agent(
"anthropic:claude-sonnet-5-5",
capabilities=[weir],
instructions="Search X with limit 5 or less. Link every post you cite.",
)
Part two opens the connection and asks:
async def main(question: str) -> None:
async with agent:
result = await agent.run(question)
print(result.output)
print(result.usage)
asyncio.run(main("What has @pydantic posted about MCP lately?"))
Swap the model string for any provider Pydantic AI supports. The MCP part stays the same.
Three things happen that you don't see:
allowed_toolshides the rest. Weir serves over 40 tools, Reddit included. The model gets only the two you name.async with agentholds one connection. It opens the MCP session before the run and closes it after.- Weir's own advice comes along. The capability adds the server's instructions to the agent's, so the model reads Weir's rules on small limits and
402errors.
What does the agent get back?
The model calls search_x with a handle and a keyword. We made that call through Weir's MCP server on 22 October 2026:
→ search_x {"fromUsers": ["pydantic"], "query": "MCP -filter:nativeretweets", "limit": 3}
← 3 posts · 4 credits · nextCursor set
2026-09-30 26 likes "Your coding agent knows your code by heart and has never
seen a production request. The Logfire MCP server fixes that..."
2026-09-17 20 likes a post about AGNTCon + MCPCon Europe in Amsterdam
2026-09-16 2 likes a one-line reply
The tool result reaches the model as JSON, with each post's url, text and counts. Our stub replayed this response, so the run above saw the same three posts.
The reply also carries meta.nextCursor, so the model can ask for page two. Weir's docs say only a null cursor marks the end. If one page is enough, say so in your instructions.
Weir bills 1 credit per call plus 1 per X post, and failed calls are free:
Each post costs a credit, so the limit in your instructions is a spending cap too.
Paid packs start at $5 for 25,000 credits and never expire, as of October 2026. Your model tokens are billed by your provider. Every Weir rate is on our pricing page.
What replaced MCPServerStreamableHTTP?
MCPToolset did, in Pydantic AI 2.0.0, which PyPI dates to 23 June 2026. On 2.59.0, the old import raises ImportError.
Here's what changed, from Pydantic AI's migration table:
| Version 1 | Version 2 |
|---|---|
MCPServerStreamableHTTP |
MCPToolset |
MCPServerSSE, MCPServerStdio |
MCPToolset |
Agent(mcp_servers=[...]) |
Agent(toolsets=[...]) |
agent.run_mcp_servers() |
async with agent: |
MCP(url=...) ran remotely |
MCP(url=..., native=True) |
Watch the last row. In version 1, MCP(url=...) handed the URL to your model provider. In version 2, your own process connects unless you set native=True.
Which one should you use? Pick the MCP capability for one server and a fixed list of tools. Pick MCPToolset to filter with code, prefix the names or share one connection between agents:
import os
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPToolset
weir = MCPToolset(
"https://api.weirapp.io/mcp",
headers={"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"},
include_instructions=True,
)
x_only = weir.filtered(lambda ctx, tool: tool.name.startswith(("search_x", "get_x_")))
agent = Agent("anthropic:claude-sonnet-5-5", toolsets=[x_only.prefixed("weir")])
The filter keeps every X tool, then .prefixed("weir") renames search_x to weir_search_x. The prefix stops clashes when two servers share a tool name. Note that include_instructions is off by default here, unlike on the capability.
To check a connection without a model, call the free get_usage tool directly:
async def check() -> None:
async with weir:
print(await weir.direct_call_tool("get_usage", {}))
asyncio.run(check())
If it doesn't work
MCPError: Server returned an error responseat connect. Pydantic AI hides the HTTP status. In our test it was Weir's401for a missing key. Weir's free/v1/whoamiendpoint tells you if a key works.- The handshake times out.
MCPToolsetwaits 5 seconds by default. Build one withinit_timeout=30. 401withauthorization_token. We saw it send the raw key, with noBearer. Put the full header inheadersinstead.cannot import name 'MCPServerStreamableHTTP'. You're on version 2. Switch toMCPToolsetor theMCPcapability.headersandhttp_clienttogether fail. They're mutually exclusive. Set headers on your ownhttpx2.AsyncClientinstead.- A tool returns
402. Your Weir credits ran out, and retrying won't help.
When not to use Weir
- Your agent has to post or DM on X. Weir is read-only.
- You want private data. Weir reads public posts, not bookmarks, DMs or home timelines.
- Price per post matters most. TwitterAPI.io lists $0.15 per 1,000 tweets as of October 2026, less than our $5 pack.
- You need a guarantee. Weir isn't licensed by X or affiliated with it, so access can change.
FAQ
Does Pydantic AI support MCP?
Yes. Pydantic AI's docs list three ways in: the MCP capability, the lower-level MCPToolset, and MCPServerTool for a provider's own MCP support. For a remote server with a key, start with the capability.
How do I pass headers to an MCP server in Pydantic AI?
Pass headers={...} to MCP or MCPToolset. Both send them on every request. If you also need custom TLS or pooling, build an httpx2.AsyncClient with the headers and pass it as http_client.
Can the model provider call the MCP server instead of my code?
Yes, with MCP(url=..., native=True). Pydantic AI's docs say it falls back to running the server locally when the model doesn't support native MCP. We tested only the local mode.
Is there a Pydantic AI MCP client without an agent?
Yes. MCPToolset works on its own inside async with. Call list_tools() to see what the server offers and direct_call_tool() to run one. Our MCP Python client guide shows the same calls with the bare mcp SDK.
Sources
- Pydantic AI docs, MCP overview (checked 22 October 2026): https://pydantic.dev/docs/ai/mcp/overview/
- Pydantic AI docs, MCP client (checked 22 October 2026): https://pydantic.dev/docs/ai/mcp/client/
- Pydantic AI docs, V1 to V2 migration (checked 22 October 2026): https://pydantic.dev/docs/ai/overview/migration/
- pydantic-ai-slim on PyPI, version 2.59.0, and its source (checked 22 October 2026): https://pypi.org/project/pydantic-ai-slim/
- Claude docs, models overview (checked 22 October 2026): https://platform.claude.com/docs/en/about-claude/models/overview
- TwitterAPI.io pricing (checked 22 October 2026): https://twitterapi.io/pricing
- Weir docs, MCP: https://docs.weirapp.io/mcp
- Weir docs, APIs and frameworks: https://docs.weirapp.io/mcp-frameworks
- Weir billing: https://docs.weirapp.io/billing
- Weir search_x call, run 22 October 2026 (request aa9c0a28-b7a2-445f-beab-58efbc3650b2)
- Our runs with pydantic-ai-slim 2.59.0 against https://api.weirapp.io/mcp and a local stub, 22 October 2026