OpenAI Agents SDK MCP: Build an X (Twitter) Research Agent
Connect the OpenAI Agents SDK to a remote MCP server with MCPServerStreamableHttp: a 30-line X research agent, a tool filter, caching and real output.
Tarun Khatri
Published · Updated · 7 min read
The OpenAI Agents SDK connects to an MCP server through MCPServerStreamableHttp: give it a URL and headers, then pass it to your Agent.
This guide builds a short X (Twitter) research agent on Weir's MCP server, with a bearer key and a filter that keeps only X tools. We run Weir.
The connection is this one object:
import os
from agents.mcp import MCPServerStreamableHttp
weir = MCPServerStreamableHttp(
name="weir",
params={
"url": "https://api.weirapp.io/mcp",
"headers": {"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"},
"timeout": 30,
},
)
How to connect the OpenAI Agents SDK to an MCP server
Weir is a remote server, so your Python process connects to it over Streamable HTTP with an API key.
The key rides in the Authorization header of every request, so there's no sign-in step. That suits scripts, CI jobs and servers, where nobody sits at a browser.
- Get a Weir keyCreate one under API keys in your Weir dashboard. Keep it in WEIR_API_KEY.
- Install the SDKRun pip install openai-agents. Version 0.24.0 came out on 15 October 2026 and needs Python 3.10 or later.
- Set your OpenAI keyThe SDK's README says to set OPENAI_API_KEY before you run an agent.
- Connect and runPass the server to an Agent and call Runner.run, as in the script below.
Three settings matter more than the rest:
- Raise the timeouts. The SDK waits five seconds by default, for the request and for the session. A search can take longer, so Weir's docs use 30.
- Cache the tool list. OpenAI's docs say every agent run calls
list_tools()on each server. Callinvalidate_tools_cache()if you ever need a fresh list. - Stay on Streamable HTTP. Weir doesn't serve the older SSE transport, which the MCP project has deprecated. So
MCPServerSsewon't connect.
OpenAI Agents SDK MCP example: an X research agent
The full script is 29 lines, shown here in two parts. Part one holds the settings and the tool filter:
import asyncio, os
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp
WEIR = {
"url": "https://api.weirapp.io/mcp",
"headers": {"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"},
"timeout": 30,
}
def x_tools_only(context, tool) -> bool:
# Keep search_x, search_x_users and every get_x_* tool. Drop Reddit.
return tool.name.startswith(("search_x", "get_x_"))
The SDK calls the filter once for each tool, with a context, and keeps the ones where it returns True. Ours keeps 25 of the 44 tools a default Weir key or sign-in gets: every X tool, and none of the Reddit or account ones.
Why filter at all? Every tool you pass adds its description to the model's prompt, and Weir also serves Reddit tools. A shorter list costs fewer tokens and leaves fewer wrong picks.
Prefer a fixed list? create_static_tool_filter(allowed_tool_names=[...]) does the same job with names you pick.
Part two connects, builds the agent and asks the question:
async def main(question: str) -> None:
async with MCPServerStreamableHttp(
name="weir", params=WEIR, client_session_timeout_seconds=30,
cache_tools_list=True, tool_filter=x_tools_only,
) as weir:
agent = Agent(
name="x-researcher",
instructions="Research X with the Weir tools. Use limit 10 or less, put "
"filters in the call, link every post you cite, never retry a 402.",
mcp_servers=[weir],
)
result = await Runner.run(agent, question)
print(result.final_output)
asyncio.run(main("What has @OpenAIDevs posted about the Agents SDK?"))
The async with block connects to Weir and closes the session when the run ends. The instructions carry Weir's own advice to agents: small limits, filters in the call, no retry on 402.
What does the agent get back?
To answer, the model needs search_x with fromUsers and a query. We ran that call through Weir's MCP server on 22 October 2026, at limit: 3:
→ search_x {"fromUsers": ["OpenAIDevs"], "query": "\"Agents SDK\"", "limit": 3}
← 3 posts · 4 credits (1 + 3 × 1) · nextCursor set
322 likes 2026-07-02 X Article: "June for OpenAI Developers"
1,219 likes 2026-06-23 Over the past six months, we shipped 30+ models... Agents SDK harness & sandbox
371 likes 2026-06-08 X Article: "May for OpenAI Developers"
Two of the three were X Articles. Their post text is only a link, yet X's search still matched them.
The title comes back in each post's article field. To read the whole piece, the agent calls get_x_article, which the filter keeps. Our guide to reading X Articles through an API covers that call.
Weir bills a credit per call plus a credit per X post, and failed calls are free:
Budget per run, not per call, because one question can take a few searches. Three 10-post searches come to 33 credits.
Paid packs start at $5 for 25,000 credits and never expire, as of October 2026. OpenAI bills your model tokens on its own. Every Weir rate is on our pricing page.
Hosted MCP tool or MCPServerStreamableHttp?
Pick by where you want the tool calls to run. OpenAI's docs list both options for a remote server like Weir.
| MCPServerStreamableHttp | HostedMCPTool | |
|---|---|---|
| Who calls Weir | Your Python process | OpenAI's Responses API |
| Models | Any the SDK runs | OpenAI models with hosted MCP |
| Tool filter | tool_filter, any code |
allowed_tools |
| Calls your code | On every tool call | No round trip |
Our pick for research agents is MCPServerStreamableHttp, because the filter is plain Python and the calls show up in your own logs.
The hosted route uses the Responses API's MCP tool shape, with the key in headers, as Weir's docs show:
import os
from agents import Agent, HostedMCPTool
weir_hosted = HostedMCPTool(tool_config={
"type": "mcp",
"server_label": "weir",
"server_url": "https://api.weirapp.io/mcp",
"headers": {"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"},
"allowed_tools": ["search_x", "get_x_post", "get_x_thread", "get_x_article"],
"require_approval": {"never": {"read_only": True}},
})
agent = Agent(name="x-researcher", tools=[weir_hosted])
That require_approval setting lets tools marked read-only run without a stop. Every Weir data tool is marked read-only.
If it doesn't work
KeyError: 'WEIR_API_KEY'. Export the key in the shell that runs the script.- Searches time out. Raise
timeoutandclient_session_timeout_seconds, as the script does. MCPServerSsewon't connect. Weir serves Streamable HTTP only, so switch the class.- "run_context and agent are required for dynamic tool filtering". You called
list_tools()yourself with a function filter. Pass both, or use a static filter. - The model still sees Reddit tools. Put
tool_filteron the server, not on theAgent. - A tool returns
402. Your Weir credits ran out, and retrying won't help. Add credits or wait for next month's grant.
When not to use Weir
- Your agent has to post or DM on X. Weir is read-only, so pick a tool with write access to your account.
- You want your private data. Weir reads public posts, not your bookmarks, DMs or home timeline.
- Price per post matters most. TwitterAPI.io lists $0.15 per 1,000 tweets as of October 2026, less than we charge.
- You need a guarantee. Weir isn't licensed by X or affiliated with it, so access can change.
FAQ
Does the OpenAI Agents SDK support MCP?
Yes. OpenAI's docs list four ways in: hosted MCP tools, Streamable HTTP servers, SSE servers and local stdio servers. For a remote server like Weir, use MCPServerStreamableHttp or HostedMCPTool.
What is MCPServerStreamableHttp?
It's the SDK's class for MCP servers that speak Streamable HTTP. You pass params with a url, optional headers and a timeout. Use it as an async context manager, then hand it to Agent(mcp_servers=[...]).
How do I filter MCP tools in the OpenAI Agents SDK?
Pass tool_filter to the server. Use create_static_tool_filter with allowed or blocked names, or a function that gets a context and a tool and returns True to keep it. OpenAI's docs say the allow list applies first.
Can the agent post to X through Weir?
No. Weir only reads public X data, so nothing can post, like or follow through it. To post, you need a tool that holds your own X account's access.
Sources
- OpenAI Agents SDK docs, MCP (checked 22 October 2026): https://openai.github.io/openai-agents-python/mcp/
- openai-agents on PyPI, version 0.24.0 (checked 22 October 2026): https://pypi.org/project/openai-agents/
- openai-agents-python v0.24.0, MCP server classes (checked 22 October 2026): https://github.com/openai/openai-agents-python/blob/v0.24.0/src/agents/mcp/server.py
- openai-agents-python v0.24.0, tool filters (checked 22 October 2026): https://github.com/openai/openai-agents-python/blob/v0.24.0/src/agents/mcp/util.py
- openai-agents-python v0.24.0, HostedMCPTool (checked 22 October 2026): https://github.com/openai/openai-agents-python/blob/v0.24.0/src/agents/tool.py
- OpenAI docs, MCP and connectors (checked 22 October 2026): https://developers.openai.com/api/docs/guides/tools-connectors-mcp
- OpenAI Python SDK, Responses MCP tool type (checked 22 October 2026): https://github.com/openai/openai-python/blob/main/src/openai/types/responses/tool.py
- TwitterAPI.io pricing (checked 22 October 2026): https://twitterapi.io/pricing
- Weir docs, APIs and frameworks: https://docs.weirapp.io/mcp-frameworks
- Weir docs, MCP: https://docs.weirapp.io/mcp
- Weir billing: https://docs.weirapp.io/billing
- Weir search_x call, run 22 October 2026 (request 3463037a-a03d-41a5-bc4d-eab22e68d48c)