WEIR

smolagents MCP: Connect a Remote Server with MCPClient

Load smolagents MCP tools from a remote server: MCPClient with a bearer header, the mcp<2 install fix, structured output, ToolCallingAgent and real output.


Published · Updated · 6 min read

Cover image: MCP tools in a smolagents agent

smolagents MCP support comes from MCPClient: pass it a dict with the server's url, the streamable-http transport and headers, and it returns tools.

This guide is for Python developers building a smolagents agent. It connects Weir's remote MCP server for public X (Twitter) data with an API key, fixes today's broken install and shows a real call. We run Weir.

import os
from smolagents import MCPClient

weir = {
    "url": "https://api.weirapp.io/mcp",
    "transport": "streamable-http",
    "headers": {"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"},
}
with MCPClient(weir, structured_output=True) as tools:
    print([tool.name for tool in tools])

How to connect a smolagents MCP client to a remote server

You need Python 3.10 or later, a Weir key and a model.

We tested smolagents 1.26.0, released 29 May 2026, with mcpadapt 0.1.20 and mcp 1.30.0.

  1. Installpip install "smolagents[mcp]" "mcp<2" in a virtual environment.
  2. Get a Weir keyCreate one under API keys in your Weir dashboard. Keep it in WEIR_API_KEY.
  3. Pick a modelInferenceClientModel reads HF_TOKEN. Any smolagents model works.
  4. Run the agentOpen MCPClient in a with block and pass its tools to a CodeAgent.
pip install "smolagents[mcp]" "mcp<2"

Why the pin? The mcp extra sets no upper bound on the MCP SDK. On 24 October 2026, pip picked mcp 2.3.0, and importing mcpadapt 0.1.20 failed:

ImportError: cannot import name 'streamablehttp_client' from 'mcp.client.streamable_http'

The mcp 2.0 release renamed that client. A smolagents pull request to cap the version closed without merging, and mcpadapt's issue #88 is still open. ToolCollection.from_mcp reports the same failure as "Please install 'mcp' extra", even when it's installed.

smolagents MCP example: a CodeAgent that searches X

The script is 18 lines, in two parts. Part one sets up the server and the tools to keep:

import os
from smolagents import CodeAgent, InferenceClientModel, MCPClient

weir = {
    "url": "https://api.weirapp.io/mcp",
    "transport": "streamable-http",
    "headers": {"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"},
}
keep = {"search_x", "get_x_post", "get_usage"}

Part two opens the connection, builds the agent and asks:

with MCPClient(weir, structured_output=True) as tools:
    agent = CodeAgent(
        tools=[tool for tool in tools if tool.name in keep],
        model=InferenceClientModel(),
        instructions="Search X with limit 5 or less. Link every post you cite.",
        max_steps=6,
    )
    print(agent.run("What has @huggingface posted about MCP?"))

Here's what the source does with it:

  • MCPClient(...) connects at once. mcpadapt runs the session on a background thread and waits up to 30 seconds.
  • Tools work only inside the block. Leaving it closes the session. Without a with, call disconnect() in a finally.
  • The model writes Python. A CodeAgent calls search_x(fromUsers=["huggingface"], limit=3) like a function and reads the dict it gets.

InferenceClientModel() uses Hugging Face Inference Providers, with Qwen3-Next-80B-A3B-Thinking as its default model in 1.26.0.

What does the agent get back?

To answer, the model calls search_x on @huggingface. We made that call through Weir's MCP server on 24 October 2026:

→ search_x {"fromUsers": ["huggingface"], "query": "MCP -filter:nativeretweets",
            "onlyOriginal": true, "limit": 1}
← 1 post · 2 credits (1 + 1 × 1) · nextCursor set
  2025-06-04  75 likes  28,311 views  "Killer app ideas for the Gradio x Agents x MCP Hackathon"

The newest match was a June 2025 thread quoting @Gradio. A good agent widens the search, say to "smolagents".

What reaches your code depends on one flag:

structured_output search_x returns
True A dict with data and meta
False, the default The same JSON as a string
Either, on a 402 The error, not an exception

Weir sends its JSON twice, as text and as structuredContent, plus a credit line. With False, smolagents keeps the first text block and drops the credit line.

Leave the flag out and 1.26.0 warns that the default changes "in version 1.25". It hasn't, so set it. Weir publishes no output schema, so name the fields in your instructions: posts sit in data, and meta.nextCursor pages.

2credits for the search above
11credits for a 10-post search
1credit for a search that finds nothing
5,000free Weir credits every month

Weir bills 1 credit per call plus 1 per X post, and failed calls are free. Packs start at $5 for 25,000 credits, as of October 2026. Every rate is on our pricing page.

How to use smolagents MCP tools with ToolCallingAgent

ToolCallingAgent checks each call against the tool's inputs, and smolagents 1.26.0 marks every MCP input as required.

In our test, a search_x call without query failed with "Argument query is required". This loop fixes it. Run it inside the with block, before you build the agent:

for tool in tools:
    for spec in tool.inputs.values():
        spec["nullable"] = True

Weir still rejects a call that misses a field it truly needs, and the model reads why. An mcpadapt pull request to restore optional inputs, #90, is open.

A CodeAgent doesn't run that check, so it works without the loop.

If it doesn't work

This is what MCPClient printed when we connected with no key:

httpx INFO HTTP Request: POST https://api.weirapp.io/mcp "HTTP/1.1 401 Unauthorized"
httpx.HTTPStatusError: Client error '401 Unauthorized' for url 'https://api.weirapp.io/mcp'
TimeoutError: Couldn't connect to the MCP server after 30 seconds

The 401 prints from the background thread. Your code only sees the TimeoutError, 30 seconds later. The fixes:

  • TimeoutError after 30 seconds. Look above it for a 401. The header must read Bearer weir_live_...; test the key with Weir's free GET /v1/whoami.
  • "cannot import name 'streamablehttp_client'". Reinstall with "mcp<2".
  • "Argument ... is required". Add the nullable loop for ToolCallingAgent.
  • A tool returns 402. Your Weir credits ran out. smolagents hands the agent the error instead of raising it, so tell it not to retry.

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 smolagents support MCP?

Yes. MCPClient and ToolCollection.from_mcp load tools from stdio, Streamable HTTP or older SSE servers through mcpadapt. Both come with the mcp extra. For a dict without transport, smolagents 1.26.0 picks Streamable HTTP.

What is the difference between MCPClient and ToolCollection.from_mcp?

ToolCollection.from_mcp is a context manager that needs trust_remote_code=True, or it raises a ValueError. Its tools sit in .tools. MCPClient skips that flag, returns a plain list and also works without a with block.

Can smolagents be an MCP server?

Not by itself: smolagents is the client side. To serve your own tools over MCP, Hugging Face's docs point to Gradio, where demo.launch(mcp_server=True) turns an app into an MCP server.

Can a smolagents agent post to X through Weir?

No. Weir only reads public X data, so nothing can post, like or follow through it.

Sources

All checked on 24 October 2026.