Download Twitter Videos with an AI Agent
An agent that can read a tweet but can't get the video out of it is stuck at the worst possible moment — it found the thing you wanted and then hit a wall. The wall is usually the official API: OAuth, an app-review queue, media endpoints that change terms every few months. None of that fits inside an autonomous loop.
This tool is built to be called by software as much as by a person clicking a button. There are two ways to plug it into an agent — a Model Context Protocol (MCP) server for conversational clients, and a plain REST call for everything else — and the agent can even provision its own API key when it needs higher limits. This guide covers all three.
Short answer: point an MCP client at
https://download-twitter-video.drummerduck.com/api/mcp, or have the agent
GET /api/extract?url=<TWEET_URL> and read the direct MP4 link out of the JSON.
Try it now
Paste a Twitter/X link and download in seconds — free, no login.
Option 1 — MCP (Claude Desktop, Cursor, Claude Code)
The MCP server exposes the downloader as tools an assistant can call mid-conversation. Add it to your client's config:
{
"mcpServers": {
"twitter-video": {
"url": "https://download-twitter-video.drummerduck.com/api/mcp"
}
}
}
For a stdio-only client, wrap it with mcp-remote:
{
"mcpServers": {
"twitter-video": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://download-twitter-video.drummerduck.com/api/mcp"]
}
}
}
The server registers three tools:
| Tool | What it does |
| --- | --- |
| extract_twitter_video | Returns every media variant of a tweet with direct download URLs |
| get_tweet_info | Returns author, text, timestamp, and media metadata without the full URL list |
| get_free_api_key | Mints a free key so the agent can raise its own rate limits |
Then just ask: "Get the highest-quality video from this tweet: https://x.com/…" The
agent calls extract_twitter_video, gets structured JSON back, and hands you the
1080p link.
Option 2 — a plain API call (any agent framework)
For a LangChain / LlamaIndex / custom-loop agent, wrap one HTTP call as a tool. No SDK, no auth to start:
import requests
def download_tweet_video(url: str) -> str:
"""Return the highest-quality MP4 URL for a tweet."""
r = requests.get(
"https://download-twitter-video.drummerduck.com/api/extract",
params={"url": url},
timeout=30,
)
data = r.json()
if not data["ok"]:
raise RuntimeError(data["error"]["message"])
videos = [m for m in data["data"]["media"] if m["type"] == "video"]
return videos[0]["variants"][0]["url"] # variants are sorted best-first
Register that as a tool and the model can call it whenever a task needs the video behind a link. Full request/response shapes are on the developers page and in the REST API guide.
Let the agent get its own key
The whole flow stays autonomous because the agent can raise its own limits. When it
starts seeing 429s, it mints a key and switches to authenticated calls — no human in
the loop:
key = requests.post(
"https://download-twitter-video.drummerduck.com/api/keys",
json={"label": "my-agent"},
timeout=30,
).json()["data"]["apiKey"]
headers = {"Authorization": f"Bearer {key}"}
# reuse `headers` on every subsequent /api/extract and /api/download call
Over MCP, the equivalent is the get_free_api_key tool. Either way the free tier
takes you from 30 requests an hour to 300. See
Get a Free API Key for the details, and store the
key rather than minting a new one each run — creation is rate-limited on purpose.
Handle rate limits like a good citizen
Read X-RateLimit-Remaining off each response and back off as it approaches zero
instead of hammering into a 429. When you do get a 429, honour the Retry-After
header. Errors are structured — { "ok": false, "error": { "code", "message" } } —
so the agent can branch on code (RATE_LIMITED, NOT_FOUND, NO_MEDIA,
PROTECTED) without parsing prose.
Frequently asked questions
Which agents can use the MCP server?
Any MCP client — Claude Desktop, Claude Code, Cursor, and others. Clients that only
speak stdio connect through mcp-remote, shown above.
Do I need a key to start?
No. Everything works anonymously within the per-IP limits; a key only raises them, and the agent can fetch one itself.
Can it download GIFs and images too?
Yes. Check media[].type — "gif" items are silent MP4s and "image" items are
photos, both with direct URLs.
Is there a version for people, not agents?
Yes — the web downloader is a paste-a-link-and-click button, and the how-to guide walks through it.
Try it now
Paste a Twitter/X link and download in seconds — free, no login.
Only download public content you have the right to use, and respect copyright.