@twitterapis/mcp
MCP serverSearchLets your agent search Twitter/X and read or post tweets, user info, and direct messages.
Use @twitterapis/mcp in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add @twitterapis/mcp and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use @twitterapis/mcp
Needs your own @twitterapis/mcp account. You sign in to it and approve access when you connect.
Details
Available today. Use it from your connected AI after setup.
Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
About this server
Official MCP server for twitterapis.com. Read and write Twitter/X: search, users, tweets, DMs.
Install @twitterapis/mcp
The server’s own address, for the clients that take one directly. Or connect ahel once and every client you use reads it from one address, with the account kept on ahel rather than in each client’s config.
Claude Code
claude mcp add --transport http --scope user twitterapis-mcp 'https://api.twitterapis.com/mcp'Run it once in your project, then open /mcp to approve any sign-in the server asks for.
Claude Desktop
https://api.twitterapis.com/mcpAdd a custom connector in Settings, paste this address, and approve the sign-in.
Cursor
cursor://anysphere.cursor-deeplink/mcp/install?name=twitterapis-mcp&config=eyJ1cmwiOiJodHRwczovL2FwaS50d2l0dGVyYXBpcy5jb20vbWNwIn0=Open the link and Cursor adds the server at that address.
ChatGPT
https://api.twitterapis.com/mcpIn Settings, enable Developer mode, create an MCP app, and paste this address. Your plan and workspace must allow custom apps.
Codex
codex mcp add twitterapis-mcp --url 'https://api.twitterapis.com/mcp'Run it once, then sign in with codex mcp login twitterapis-mcp if the server asks for an account.
From the project's README
As published by twitterapis/twitterapis-mcp in README.md.
Official Model Context Protocol server for twitterapis.com, the Twitter / X API as native tools for Claude, Cursor, Windsurf, and any MCP client. Reads (search, profiles, timelines, followers, DMs) plus write actions (post, like, retweet, follow).
Ask your agent to search tweets, pull a user's profile or timeline, list followers/following, fetch thread context, or enumerate list members and it calls the API directly. Every tool maps to a REST endpoint at https://api.twitterapis.com; the server holds no state and forwards your API key on each call.
Quick start
No install needed. Run with npx. You need one thing: an API key (free $0.50 in credits, no card required): twitterapis.com/signup.
Setup
Claude Desktop
Edit claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"twitterapis": {
"command": "npx",
"args": ["-y", "@twitterapis/mcp@latest"],
"env": { "TWITTERAPIS_KEY": "YOUR_API_KEY" }
}
}
}
Restart Claude Desktop. The twitter_* tools appear in the tool picker.
Cursor
~/.cursor/mcp.json (or Settings → MCP → Add New Server):
{
"mcpServers": {
"twitterapis": {
"command": "npx",
"args": ["-y", "@twitterapis/mcp@latest"],
"env": { "TWITTERAPIS_KEY": "YOUR_API_KEY" }
}
}
}
Windsurf
~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"twitterapis": {
"command": "npx",
"args": ["-y", "@twitterapis/mcp@latest"],
"env": { "TWITTERAPIS_KEY": "YOUR_API_KEY" }
}
}
}
VS Code (Copilot / agent mode)
.vscode/mcp.json in your workspace, or the user-level MCP settings:
{
"servers": {
"twitterapis": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@twitterapis/mcp@latest"],
"env": { "TWITTERAPIS_KEY": "YOUR_API_KEY" }
}
}
}
Configuration
| Env var | Required | Default | Purpose |
|---|---|---|---|
TWITTERAPIS_KEY | Yes | (none) | API key from dashboard |
TWITTERAPIS_BASE_URL | No | https://api.twitterapis.com | Override the API host |
TWITTERAPIS_TIMEOUT_MS | No | 30000 | Per-request timeout in milliseconds |
Tools
109 tools: 65 reads and 44 write actions. Most user endpoints accept username (handle without @) or user_id (twitter_user_likes and twitter_user_tweets_complete require user_id); tweet endpoints accept id or url; paginated endpoints return a cursor you pass back to get the next page. Every data read also takes fields (comma-separated dotted paths to keep, e.g. id,text,author.username; pagination and envelope keys always survive) and compact ("1" for a built-in preset of ids, text, counts and author basics), so a model paying per token can trim a page to what it will read. Four of the reads are free account lookups (twitter_account_me, twitter_account_payments, twitter_feedback_get, twitter_feedback_list); the 14 monitoring tools and twitter_feedback_send are also free (account administration, not metered reads).
Public reads (search, profiles, tweets, followers, likes) work with just your API key. The account-only reads (bookmarks, DMs, home timeline, followers-you-know) and most write actions act AS an authenticated X account, so they need a session linked to your key first (returns HTTP 409 until then). Link a session either by registering your x.com cookies (twitter_customer_session) or by logging in with a username/password (twitter_user_login). Alternatively, pass per-call inline credentials on any of those tools (auth_token + ct0, with optional proxy_url / user_agent) to act AS that account for a single call without pre-registering a session, so one API key can act as many accounts. For write actions, set proxy_url to a residential proxy, since X soft-blocks writes that egress from datacenter IPs. Each write tool is annotated readOnlyHint: false; reversing actions (delete, unfollow, unlike, unretweet, unbookmark, monitor/webhook delete) are annotated destructiveHint: true so MCP clients can prompt before running them. The monitoring and feedback tools (see below) are the exception: they administer your twitterapis.com account, not an X session, so they need only your API key, no linked session and no inline credentials.
Reads
| Tool | What it does |
|---|---|
twitter_advanced_search | Search tweets with X operators (from:, min_faves:, since:, filter:links, etc.) |
twitter_user_search | Find user accounts by name or keyword |
twitter_user_info | Full profile by handle (bio, counts, verification, location) |
twitter_user_info_by_id | Full profile by numeric user id |
twitter_user_status | Is an account alive, suspended, or deleted |
twitter_user_about | A user's structured About object (category, professional/business labels, verification + identity-verification flags, joined date, and X's 'About this account' transparency panel) |
twitter_user_affiliates | Accounts affiliated with an organization profile |
twitter_check_follow_relationship | Follow relationship between two user ids (who follows whom) |
twitter_user_tweets | A user's recent original tweets (replies excluded) |
twitter_user_tweets_and_replies | A user's full timeline (tweets + replies) |
twitter_user_tweets_complete | A large batch of a user's tweet history per call (see paging note) |
twitter_user_media | Images and videos a user has posted |
twitter_user_mentions | Recent public tweets mentioning a user |
twitter_user_likes | Tweets a user has liked (public Likes tab) |
twitter_user_followers | Accounts that follow a user |
twitter_user_following | Accounts a user follows |
twitter_user_followers_v2 | Followers with the v2 response shape (richer fields, deeper cursoring) |
twitter_user_following_v2 | Following with the v2 response shape (richer fields, deeper cursoring) |
twitter_user_verified_followers | A user's verified followers only |
twitter_followers_you_know | Followers of a target that your authenticated account also follows |
twitter_tweet_detail | Single tweet: text, author, metrics, media, quoted/reply context |
twitter_tweet_replies | Replies to a tweet |
twitter_tweet_thread | Full author thread (connected tweet chain by same author) |
twitter_tweet_retweeters | Accounts that retweeted a tweet |
twitter_tweet_quotes | Tweets that quote a tweet, with their text. Search-backed, so count is what search returned, not the tweet's true quote_count |
twitter_list_members | Members of a Twitter/X List |
twitter_list_followers | Accounts that follow a public List (a different set from its members) |
twitter_list_tweets | Posts by a List's members, search-backed: filterable by since / until date, include_replies, and product (Latest / Top), no retweets |
twitter_list_timeline | A List's native X feed: retweets and X's own ordering included, no filters, paging only |
twitter_home_timeline | Your authenticated account's Home timeline (session) |
twitter_bookmarks | Your authenticated account's bookmarks (session) |
twitter_blocking | Accounts your authenticated account has blocked (your own list only) (session) |
twitter_muting | Accounts your authenticated account has muted (your own list only) (session) |
twitter_bookmark_search | Full-text search within your bookmarks (session) |
twitter_bookmark_folders | Your authenticated account's bookmark folders (session) |
twitter_bookmark_folder_timeline | Tweets inside one of your bookmark folders, by folder_id (session) |
twitter_dm_list | Your DM conversations (inbox), read-only (session) |
twitter_dm_conversation | Messages in one DM conversation, read-only; pass the previous page's min_entry_id as max_id to page back (session) |
twitter_spaces_info | Metadata and participant roster for one X Space, live or ended (by Space id) |
twitter_community_search | Find X Communities by keyword; the discovery step that produces the numeric id the rest of the community family needs |
twitter_community_info | One X Community by numeric id: name, counts, join policy, rules, topic, banners, admin |
twitter_community_about | A community's moderators and a member preview, each returned as a full user profile, not the reduced row _members/_moderators return |
twitter_community_members | A community's member roster, each row carrying that member's Admin / Moderator / Member role |
twitter_community_moderators | A community's moderators and admins, from its own upstream operation (not a filter over the roster) |
twitter_community_tweets | A community's post timeline, with the pinned post returned as its own pinned field |
twitter_community_memberships | The inverse lookup: every community a given numeric user_id belongs to |
twitter_grok_chat | Ask X's own Grok, grounded in live X data, and get the answer plus the sources it cited |
twitter_grok_config | Whether the authenticated account can use Grok, and which models it may pick |
twitter_trends | Current top trends for a location (by country or woeid) |
twitter_trends_locations | Every location X has trends for, each with its WOEID |
twitter_account_me | Your twitterapis.com account: credits, usage, email (free) |
twitter_account_payments | Your twitterapis.com payment history (free) |
twitter_media_status | Processing state of an uploaded media_id; poll until succeeded before attaching video or GIF (session) |
twitter_article_get | Read a published article's full content via its announcement tweet id/url (public, no session) |
twitter_article_list | List your own articles, filtered by lifecycle (draft or published) (session) |
Write actions (require a linked X session)
| Tool | What it does |
|---|---|
twitter_create_tweet | Post a tweet; set reply_to to reply or quote to quote-tweet |
twitter_delete_tweet | Delete one of your tweets (irreversible) |
twitter_favorite_tweet / twitter_unfavorite_tweet | Like / unlike a tweet |
twitter_retweet / twitter_unretweet | Retweet / undo retweet |
twitter_bookmark_tweet / twitter_unbookmark_tweet | Bookmark / remove bookmark |
twitter_follow_user / twitter_unfollow_user | Follow / unfollow a user by user_id or username (exactly one) |
twitter_dm_send | Send a Direct Message to a user by their numeric recipient_id |
twitter_list_create | Create a Twitter/X List owned by your session (name, optional description / is_private) |
twitter_list_add_member / twitter_list_remove_member | Add / remove one account on a List you own; member_count comes back as proof the write landed |
twitter_media_upload | Upload a base64 image, returns a media_id for twitter_create_tweet |
twitter_update_profile | Change your own name, bio, location or link. A PARTIAL update: omitted fields keep their values, an empty string clears one |
twitter_update_avatar | Replace your own profile picture. Takes base64 image bytes in image, not a URL and not a media_id. No undo, and X keeps no history |
twitter_update_banner | Replace your own header image. Takes base64 image bytes in banner, not a URL and not a media_id. No undo, and X keeps no history |
Drafts and scheduled posts (require a linked X session)
A draft is private and never posts. A scheduled post will publish publicly at its execute_at unless you cancel it first. Both lists read only your own account.
| Tool | What it does |
|---|---|
twitter_draft_create | Save a private draft on your account; nothing is posted |
twitter_draft_edit | Replace one draft's contents by id; the fields you send become the draft |
twitter_draft_delete | Delete a draft by id; it was never public, so nothing is retracted |
twitter_draft_list | List your drafts, each with text and thread_truncated |
twitter_scheduled_create | Schedule a post for a future execute_at in epoch seconds, not milliseconds |
twitter_scheduled_delete | Cancel a pending scheduled post before it sends |
twitter_scheduled_list | List your pending queue; execute_at comes back in epoch seconds |
Both list tools can return partial: true, which means X's answer was read but not fully understood. It is not the same as an empty list: on a clean read the flag is absent entirely, so an empty array with no partial means you genuinely have nothing queued or drafted.
Articles (X's long-form "Notes" feature; writes require a linked X session)
| Tool | What it does |
|---|---|
twitter_article_create | Start a new draft article, returns its id |
twitter_article_update_title | Set a draft or published article's title |
twitter_article_update_cover_media | Attach an already-uploaded image as an article's cover (media_id from twitter_media_upload) |
twitter_article_update_content | Replace a draft or published article's body (Draft.js content_state you build) |
twitter_article_publish | Publish a draft, posting a real public announcement tweet (not fully reversible) |
twitter_article_unpublish | Revert a published article to draft (leaves the announcement tweet up) |
twitter_article_delete | Delete an article (draft: hard delete; published: unpublish + delete the announcement tweet), irreversible |
See also twitter_article_get and twitter_article_list above.
Monitoring (webhook delivery of new posts; free, not metered)
Watch an X account for new posts and get them pushed to your own HTTPS endpoint, HMAC-signed, instead of polling. Register a webhook first, then create a monitor; every new post from a watched handle is delivered to every active webhook on your account (or a restricted subset via webhook_ids). Monitor/webhook CRUD is account administration, not a metered Twitter read, so every tool below is free.
| Tool | What it does |
|---|---|
twitter_monitor_create | Start watching an X account (handle) for new posts |
twitter_monitor_list | List every monitor on your account |
twitter_monitor_update | Pause/resume a monitor or change its webhook_ids restriction |
twitter_monitor_delete | Stop and remove a monitor (irreversible) |
twitter_monitor_health | One monitor's status, degradation flag, poll interval, cursor position |
twitter_monitor_account_health | Account-wide rollup: service status, active/paused monitor counts, 24h delivery outcome counts, one call |
twitter_monitor_deliveries | Recent delivery events across every monitor, with detection + delivery latency |
twitter_x_user_stream_add_user | Compat drop-in for twitter_monitor_create using an x_user_stream-shaped envelope |
twitter_x_user_stream_remove_user | Compat drop-in for twitter_monitor_delete using an x_user_stream-shaped envelope |
twitter_x_user_stream_list_users | Compat drop-in for twitter_monitor_list using an x_user_stream-shaped envelope |
twitter_monitor_webhook_create | Register an HTTPS delivery URL; returns the HMAC signing secret once |
twitter_monitor_webhook_list | List every webhook registered on your account |
twitter_monitor_webhook_delete | Soft-delete a webhook by id (irreversible from the caller's side) |
twitter_monitor_webhook_test | Send one signed test event to a webhook right now, synchronously |
twitter_monitor_webhook_redrive | Replay deliveries that dead-lettered while your endpoint was down, oldest first |
Feedback (report a bug or a gap to the twitterapis.com team without leaving your session; free)
Modelled on Claude Code's own feedback tool. When a call fails in a way that is not your key, credits, session or a rate limit, when you ask for something no tool covers, or when a result is plainly wrong, the model can draft a report into a local queue (~/.twitterapis/feedback-queue.json, at most 10 drafts, override the directory with TWITTERAPIS_FEEDBACK_DIR). Nothing is sent until you ask to review the queue and name the drafts to send. Each report carries the last failing call's endpoint, status and request id, your client name and this package's version, so the team can act on it without a follow-up. Use twitter_feedback_get with the returned server id to see whether it was triaged, shipped or declined.
| Tool | What it does |
|---|---|
twitter_feedback_send | action: "draft" (default) queues a report locally and sends nothing; "list" shows the queue; "send" posts only the drafts you name to POST /feedback; "discard" drops them |
twitter_feedback_get | Read a sent report's status (new, triaged, shipped, declined) and the team's response |
twitter_feedback_list | List the reports this account has already sent, newest first, with status/type filters and a cursor to page |
Session setup
Link an X account to your key once, so the account-only reads and write actions act as it (or pass per-call auth_token/ct0 instead).
| Tool | What it does |
|---|---|
twitter_customer_session | Register your x.com session cookies (auth_token + ct0) against your key |
twitter_customer_session_status | Read back the registered session without changing it: resolved account, live/dead status, timestamps, and which egress tier a write would use. Never returns the cookies. Free |
twitter_customer_session_delete | Revoke that stored session, deleting your auth_token + ct0 from the service. Idempotent and free |
twitter_user_login | Log in with username + password (+ totp_secret for 2FA); stores the session against your key. Returns a confirmation, never the cookies |
Usage examples
Search for trending AI tweets
"Find the most popular tweets about AI agents posted this week"
The agent calls twitter_advanced_search with:
query: "AI agents min_faves:200 since:2024-01-01"
product: "Top"
count: 20
Pull a user's recent posts
"Get the last 10 tweets from @sama"
The agent calls twitter_user_tweets with:
username: "sama"
count: 10
Read a full thread
"Get the full thread for this tweet: https://x.com/karpathy/status/1849....."
The agent calls twitter_tweet_thread with:
url: "https://x.com/karpathy/status/1849....."
Paginate through followers
"List the first 100 followers of @openai, then the next 100"
First call, twitter_user_followers: { username: "openai", count: 100 }
Second call, pass back the cursor from the first response: { username: "openai", count: 100, cursor: "<cursor from response>" }
Paging twitter_user_tweets_complete
"Pull @elonmusk's whole tweet history"
twitter_user_tweets_complete auto-paginates server-side and returns a large batch per call, but it does not guarantee the full history in one call. Read the result like this:
next_cursoris the completion signal, notcount. Non-null means the history is truncated and more remains. Null means it is genuinely exhausted. The response also carrieshas_more, the same signal as a boolean.maxis a minimum target, not a cap. Pages arrive in whole chunks, so a response may hold up to one page (<=100) more than requested. Live behaviour:max=10returned 20,max=50returned 60,max=150returned 161, and omittingmax(server default 200) returned 201. Never assumecount === max.- Each call also has a server-side wall-clock budget, so a response can be truncated even when it returned fewer tweets than requested. That is the second reason
countcannot tell you whether you are done. - Billing is a flat $0.0024 per call, regardless of how many tweets come back, so fewer large calls cost less than many small ones.
To resume, pass the next_cursor straight back in as cursor and repeat until it comes back null:
First call, twitter_user_tweets_complete: { user_id: "44196397", max: 800 }
Then, while next_cursor is non-null: { user_id: "44196397", max: 800, cursor: "<next_cursor from previous response>" }
Monitor brand mentions
"Show me recent tweets mentioning @twitterapis"
The agent calls twitter_user_mentions with:
username: "twitterapis"
count: 50
Troubleshooting
HTTP 401 (invalid or missing API key) Check that TWITTERAPIS_KEY is set correctly in your MCP client config and matches the key shown in your dashboard.
HTTP 402 (insufficient credits) Top up at twitterapis.com/dashboard. Your first $0.50 is free at signup.
HTTP 403 (access forbidden) The account or tweet may be private/protected, or your plan does not include this endpoint.
HTTP 404 (not found) The user, tweet, or list may have been deleted, suspended, or the id/handle is wrong.
HTTP 429 (rate limited) Wait a few seconds and retry. If you hit this frequently, add "TWITTERAPIS_TIMEOUT_MS": "60000" to your env config and space out bulk requests.
Request failed: timed out after 30000ms The default timeout is 30 s. For large paginated fetches set TWITTERAPIS_TIMEOUT_MS to a higher value (e.g. 60000).
Tools do not appear in Claude / Cursor Ensure npx is on your PATH and Node.js 18+ is installed (node --version). Check MCP client logs for startup errors.
Pricing
Calls are billed to your twitterapis.com account. Most endpoints are $0.0008/call: nearly every read (search, profiles, tweets, followers, likes) plus the simple write actions (like, retweet, bookmark, follow and their undos, delete). At the read rate that works out to $0.04 per 1,000 tweets, since each call returns about 20 tweets. The premium endpoints cost a little more: tweet creation, sending a DM (twitter_dm_send), and DM reads (twitter_dm_list, twitter_dm_conversation) at $0.0016/call, full tweet history (twitter_user_tweets_complete) at $0.0024/call, a full tweet thread (twitter_tweet_thread) and a Grok answer (twitter_grok_chat) at $0.004/call, and the article-editing writes (twitter_article_create, twitter_article_update_title, twitter_article_update_cover_media, twitter_article_update_content, twitter_article_publish, twitter_article_unpublish) at $0.0016. The compose surface is $0.0016 for twitter_draft_create, twitter_draft_edit, twitter_scheduled_create and, note, BOTH LIST READS (twitter_draft_list, twitter_scheduled_list), which are the two reads that are not at the read rate; twitter_draft_delete and twitter_scheduled_delete are $0.0008/call, while twitter_article_get, twitter_article_list and twitter_article_delete stay at the standard $0.0008/call. The three profile writes (twitter_update_profile, twitter_update_avatar, twitter_update_banner) are $0.0016/call each. Your first $0.50 is free. See twitterapis.com/pricing.
Links
- Docs: docs.twitterapis.com
- Dashboard / API keys: twitterapis.com/dashboard
- Pricing: twitterapis.com/pricing
- REST API base URL (call it directly, without MCP):
https://api.twitterapis.com
FAQ
Shortened here. Read the whole README on GitHub.
Signals
- Forks
- 1
- Last commit
- Oct 2026
- Weekly_downloads
- 1k weekly_downloads
Advanced
- Delivery
- twitterapis-mcp MCP server → your ahel connector (mcp.ahel.ai) → your AI.
- Item type
- mcp-server
- Key
io-github-twitterapis-twitterapis-mcp- Source
- github.com/twitterapis/twitterapis-mcp
- Hosted endpoint
https://api.twitterapis.com/mcp
github.com/twitterapis/twitterapis-mcp