Last updated: August 31, 2026

Give a Pydantic AI agent a Twitter tool

Attach the OpenTweet MCP server with MCPServerStreamableHTTP and your agent gets 43 tools for posting, scheduling, threads, and articles on X. Or write one typed tool over the REST endpoint when the agent should only ever publish. No X developer account.

Pydantic AI has native MCP support, so this is four lines rather than an integration project. One caveat worth knowing before you design around tool metadata is in the #6613 section below.

7-day free trial. No X developer account needed.

What your agent can do on X

The whole toolset over MCP, or exactly one action you define.

Post now

opentweet_create_tweet publishes the moment the model calls it.

Schedule

opentweet_schedule_tweet and opentweet_batch_schedule queue posts and let the process exit.

Threads and articles

opentweet_create_thread and opentweet_create_article for long-form.

43 tools

Schemas come from the server, so you write no tool definitions.

Analytics

The agent reads results and adapts the next run.

No X API

No developer account, no OAuth flow to implement.

Option 1: MCPServerStreamableHTTP

The server ships its own schemas, so you write no tool definitions and get scheduling, threads, articles, evergreen, and analytics for the same four lines.

x_agent.py
import asyncio
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStreamableHTTP

opentweet = MCPServerStreamableHTTP(
    "https://mcp.opentweet.io/mcp",
    headers={"Authorization": "Bearer ot_your_key"},
)

agent = Agent(
    "openai:gpt-4o",
    toolsets=[opentweet],
    instructions="You publish and schedule on X. Prefer scheduling unless told to post now.",
)

async def main():
    async with agent:
        result = await agent.run(
            "Write a 3-post thread about the 2.0 release and schedule it for 9am UTC tomorrow."
        )
        print(result.output)

asyncio.run(main())

Version gotcha

Current releases take toolsets=[server] and async with agent:. Older ones used mcp_servers=[server] and async with agent.run_mcp_servers():. A TypeError on the Agent constructor almost always means you are reading a guide written for the other one.

Every tool name and argument is in the MCP docs.

What issue #6613 changes about your design

The open issue pydantic/pydantic-ai#6613 tracks gaps in the MCP Apps client surface. Three things are dropped rather than surfaced: _meta on tool results, mimeType on resources, and capabilities.extensions.

The practical rule that follows: do not build anything that depends on metadata travelling next to a tool result. If a server hides the important part of its answer in _meta, your agent will not see it, and you will spend an afternoon deciding whether the bug is yours.

The OpenTweet tools return the status, the post id, and the URL in the result text, which is the format the model reads anyway. Nothing you need to act on rides in _meta, so this gap does not affect posting or scheduling.

Option 2: one typed tool over REST

For an unattended agent, narrow the surface. A function with a docstring and typed arguments is the whole tool definition, and the key never leaves the process environment.

x_tool.py
import os
import httpx
from pydantic_ai import Agent

agent = Agent("openai:gpt-4o", instructions="You write and publish short posts on X.")

@agent.tool_plain
async def post_to_x(text: str, scheduled_date: str | None = None) -> str:
    """Publish a post to X, or schedule it. scheduled_date is ISO 8601, for example 2026-09-02T09:00:00Z."""
    body = {"text": text}
    if scheduled_date:
        body["scheduled_date"] = scheduled_date
    else:
        body["publish_now"] = True

    async with httpx.AsyncClient(timeout=30) as client:
        res = await client.post(
            "https://opentweet.io/api/v1/posts",
            headers={"Authorization": f"Bearer {os.environ['OPENTWEET_API_KEY']}"},
            json=body,
        )
    res.raise_for_status()
    return res.text

And the same call outside Python, for a cron job or a deploy hook:

post.sh
curl -X POST https://opentweet.io/api/v1/posts \
  -H "Authorization: Bearer ot_your_key" \
  -H "Content-Type: application/json" \
  -d '{"text":"The agent wrote this in Python and the scheduler sent it.","scheduled_date":"2026-09-02T09:00:00Z"}'

The route is /api/v1/posts, not /api/v1/tweets. Fields and error codes in the API docs, and post to Twitter from Python covers the non-agent version.

Good fits

Research agents that publish findings

The agent finishes a run, writes the summary, and schedules it rather than dumping it at 3am.

Data and ML teams already on Pydantic

The tool contract is a Pydantic model like everything else in the codebase.

Typed, testable posting logic

A narrow tool is easy to unit test against a mock, unlike a prompt that hopefully picks the right tool.

Scheduled content pipelines

Queue a week with batch scheduling in one run and let the process exit.

Other frameworks: Mastra, LangGraph, CrewAI, Google ADK.

Frequently asked questions

How does a Pydantic AI agent post to X?

Create an MCPServerStreamableHTTP pointed at https://mcp.opentweet.io/mcp with an Authorization header, pass it to your Agent in toolsets, and open the agent as an async context manager. The model then has all 43 OpenTweet tools for posting, scheduling, threads, articles, and analytics.

Is it toolsets or mcp_servers?

Current Pydantic AI takes toolsets=[server] and you enter the agent with async with agent:. Older releases used mcp_servers=[server] with async with agent.run_mcp_servers():. If a tutorial you are following uses the older names and your code raises a TypeError on the Agent constructor, that version difference is why.

What does issue #6613 mean for me?

The open issue pydantic/pydantic-ai#6613 tracks MCP Apps client gaps: tool-result _meta, resource mimeType, and capabilities.extensions are dropped rather than surfaced. In practice, do not design an integration that depends on metadata riding alongside a tool result. The OpenTweet tools return the post id, status, and URL in the result text itself, so nothing you need is carried in _meta.

Do I need an X developer account?

No. OpenTweet holds the X connection, OAuth, and token refresh. Your agent carries one ot_ bearer key. You never register an X developer app and you never pay the X pay-per-use rates.

Can the agent schedule instead of posting immediately?

Yes. opentweet_schedule_tweet takes an ISO 8601 time and opentweet_batch_schedule queues many posts in one call. Over REST, send scheduled_date instead of publish_now. The queue lives on OpenTweet servers, so the Python process can exit.

Should I give the model all 43 tools?

For a supervised agent, yes, it is less code and the model picks well. For an unattended one, write a narrow tool instead. A typed function with a Pydantic model for its arguments is easier to reason about than a system prompt telling the model which of 43 tools it must not touch.

What does it cost?

Pro is $19.99/month with the API, 1 link post a day and a 7-day free trial. The X API charges $0.015 per post and $0.20 per post containing a link. Advanced ($29/month) includes 10 link posts a day, and an agent that posts links crosses its break-even around 145 link posts a month, about 5 a day.

Wire any agent to X

One hosted MCP server, every framework that speaks the protocol.

OpenTweet vs the X API

Post, schedule, and automate X without a developer account or the $200/mo minimum.

X DM outreach, human-approved

Find and qualify leads, AI-draft DMs, approve each one, and drip-send from your own account via API or MCP.

Post to X without an API

The clean, account-safe way to post to X from your code or an AI agent.

Twitter MCP Server

Give Claude, Cursor, and OpenClaw the ability to post to X. 43 tools included.

Developer docs

Quickstart, API keys, MCP setup, and the REST reference for posting to X from code or an agent.

Cross-posting reference

One call posts to X, Bluesky and LinkedIn. The platforms field, per-network results, and why a network gets skipped.

Social media API for AI agents

Three ways an agent can post to X, Bluesky and LinkedIn, and the trade-offs of each.

LinkedIn MCP server

Post and schedule to a LinkedIn profile from Claude or Cursor through the official LinkedIn API.

XMCP vs OpenTweet

X's official MCP server bills per API call and cannot schedule. Compare it with the flat-fee hosted MCP.

MCP for AI agents

Connect your AI client to X in under two minutes, no X developer account.

Developer API and keys

REST endpoints, one bearer key, and usage tracking. Build on OpenTweet.

OpenTweet for AI agents

The posting layer for autonomous agents and automations that live on X.

Build an AI Twitter persona

Give your AI agent its own X account. Setup, cadence, and the rules that keep it safe.

Best MCP servers for social media

The 2026 ranked list. How the hosted OpenTweet MCP compares with the official X MCP and others.

Cheapest way to post to X via code

Flat fee vs pay-per-use. Why the $0.20 per-link fee flips the math past ~145 link posts a month.

X API pricing 2026

Every pay-per-use X API endpoint price from docs.x.com in one searchable table.

Bluesky posting API

Post and schedule to Bluesky with one REST call and OAuth, and cross-post to X and LinkedIn in the same request.

Automate LinkedIn posts

Post to LinkedIn from an AI agent, n8n or a script through the official Posts API, with one REST or MCP call.

Ship a Python agent that posts to X

Four lines for the full toolset, or one function for a narrow one.

$19.99/month, API included. Cancel anytime.