twitter-mcp
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
twitter-mcp + xdata
X (Twitter) data access for Claude Code, split across two front ends over one set of adapters:
xdataCLI — all content reads. This is the entry point you want.MCP server — writes, post-volume counts, and usage only.
Zero compilation — edit and run instantly with Bun.
Why reads live in the CLI, not in MCP
Both data providers bill per returned record, and an MCP tool result lands in the model's
context in full. One 20-post search is 20–40k tokens of JSON. From a shell the same call can be
trimmed, piped through jq, or written straight to disk with only a summary coming back.
Measured, not estimated:
tools | schema in context | a 20-post search in context | |
before (reads in MCP) | 21 | ~1,898 tok | 20,000–40,000 tok |
now (reads in CLI) | 9 | ~986 tok | ~600 tok ( |
The 900-token schema saving is the small half. The point is that large payloads no longer have a path into the conversation at all.
Related MCP server: X (Twitter) MCP Server - Enhanced Edition
Architecture
┌───────────────────────────┐ ┌──────────────────────────────────────┐
│ xdata CLI │ │ MCP server (twitter-mcp v2.0) │
│ all content reads │ │ writes · counts · usage · feeds │
└─────────────┬─────────────┘ └──────────────┬───────────────────────┘
│ │
▼ ▼
┌──────────────────────┐ ┌────────────────────┐
│ ReaderClient (port) │ │ WriterClient │ OAuth 1.0a
├──────────────────────┤ │ CookieClient │ ct0 + auth_token
│ primary │ │ CountsClient │ OAuth2 app-only
│ twitterapi.io │ └────────────────────┘
│ $0.00015/post │
│ │ on 401/402/429/5xx or an HTTP-200 `status:error`
│ ▼ │
│ fallback │ every fallback is tagged in the response —
│ official X API v2 │ a silent switch would hide a 33x price jump
│ $0.005/post │
└──────────────────────┘Which channel for what
Need | Channel | Cost shape |
Content (search, timelines, replies, profiles, graph) | twitterapi.io | $0.00015/post, $0.00018/profile |
Same, when the primary is out of credits or down | official v2 (auto, tagged) | $0.005/post, $0.010/user — 33x |
Volume over time (trends, ranking, spotting peaks) | official | $0.005 per request — any match volume, and it does not consume the 3M post-read cap |
Writes (post/like/retweet/delete) | official OAuth 1.0a | $0.015/post ($0.20 with a link) |
Replies the Free tier blocks (403) | cookie GraphQL | free |
The cheap pattern is two-stage: counts first to find which query and which window matter
(effectively free), then pull posts for only that window. Large blind searches are the expensive
mistake.
Setup
git clone https://github.com/armatrix/twitter-mcp.git && cd twitter-mcp && bun install
mkdir -p ~/.twitter-mcp && cp config.example.json ~/.twitter-mcp/config.json && chmod 600 ~/.twitter-mcp/config.json~/.twitter-mcp/config.json is the single source of truth for every credential:
{
"reader": { "provider": "twitterapi.io", "api_key": "new1_..." },
"writer": { "provider": "twitter-official", "api_key": "...", "api_secret_key": "...",
"access_token": "...", "access_token_secret": "..." },
"official": { "bearer": "AAAA..." },
"cookie": { "ct0": "...", "auth_token": "..." },
"defaults": { "timeline_count": 20, "search_count": 20 }
}reader.api_key— twitterapi.io. Optional: without it every read falls back to the official API and is tagged as such (33x the price, same capability).writer.*— X Developer Portal → your App → Keys and Tokens.official.bearer— derive it, don't go hunting for it. OAuth 1.0a is rejected bycounts, location trends,usageand filtered stream; an app-only bearer is one call away from the consumer key/secret you already have:curl -s -u "<consumer_key>:<consumer_secret>" \ -d 'grant_type=client_credentials' https://api.x.com/oauth2/tokencookie.*— DevTools → Application → Cookies →x.com→ copyct0andauth_token. Optional; only powers the reply fallback.ct0rotates every few hours.
Install the CLI and register the MCP server:
ln -sf "$PWD/bin/xdata" ~/.local/bin/xdata # or point a wrapper at src/cli.ts
claude mcp add twitter -- bun run "$PWD/src/index.ts" -config ~/.twitter-mcp/config.jsonCLI
xdata usage # both providers: balance, spend, cap
xdata counts '<query>' --day|--hour [--all] # per-request billing → trends & ranking
xdata search '<q> min_faves:30' --top -n 20 # min_faves is server-side (official v2 lacks it)
xdata user|about|timeline|mentions <handle>
xdata replies|quotes|thread|retweeters <tweetId>
xdata tweets <id,id,...> # batch by id
xdata batch-users <id,id,...> # bulk profiles, cheaper per user
xdata followers|followings <handle>
xdata follower-ids <handle> # IDs only: 0.45cr vs 18cr per profile — 40x cheaper
xdata verified-followers <handle> # $0.3/1000
xdata usersearch <query> # no official equivalent exists
xdata follows <a> <b> # mutual-follow check (100cr)
xdata article <tweetId> # long-form body (no official equivalent)
xdata trends [woeid]Output control — this is where the token savings are:
--out FILE full JSON to disk, one summary line to stdout
--json raw --jsonl one record per line (pipe to jq)
-n N max records -w N text column width -q no summary lineEvery command prints cost≈, because both providers bill per record and it is otherwise invisible
until the dashboard catches up.
MCP tools (9)
Tool | Channel | Notes |
| OAuth 1.0a → cookie | Up to 4 images; auto-falls back to cookie auth on a reply 403 |
| OAuth 1.0a | |
| official app-only | Per-request billing; counts only (no text/authors) |
| official app-only | Post reads against the monthly cap + estimated spend |
| cookie | The authenticated account's own timelines |
There are deliberately no content-read tools here. The server says so on startup.
Reply fallback
post_tweet(text, reply_to_tweet_id) → OAuth 1.0a POST /2/tweets
├─ 200 → done (method: "oauth")
└─ 403 (Free tier reply restriction) → cookie GraphQL CreateTweet (method: "cookie")
→ or an error if no cookie is configuredEndpoint index
docs/endpoint-index.md — 264 endpoints across both providers, generated from their machine-readable
specs (api.x.com/2/openapi.json v2.168 / 157 paths + twitterapi.io / 76 paths), grouped by function
with auth requirements and billing per row. Consult it before assuming a capability is missing.
⚠️ A spec is a lead, not a fact. /twitter/user/tweet_timeline is documented with a top-level
tweets array but actually answers data.tweets; the adapter accepts both, because reading only one
shape yields an empty array indistinguishable from "no results".
Known limitations
Issue | Reality |
| It isn't a route — the path is |
| No such parameter; a page is always ~20 and you are billed per returned tweet. Narrow with |
Official | They reject OAuth 1.0a. Use |
Official v2 has no user search, and no long-form article body | Only twitterapi.io has these |
| 403 — Enterprise tier |
Filtered stream billing | Not in the pricing page; rule slots are visible ( |
Free-tier OAuth blocks replies to non-interacted posts | Cookie fallback handles it |
| Re-copy from the browser when cookie auth starts failing |
Project structure
src/
├── cli.ts # xdata — all content reads
├── index.ts # MCP server — writes, counts, usage, feeds
├── config.ts
├── clients/
│ ├── reader.ts # port + router (primary → tagged fallback)
│ ├── reader-twitterapi.ts # primary adapter
│ ├── reader-official.ts # fallback adapter (X API v2, OAuth 1.0a)
│ ├── counts.ts # app-only bearer: counts / trends / usage
│ ├── writer.ts # OAuth 1.0a writes + media upload
│ └── cookie.ts # GraphQL via browser session
├── lib/
│ ├── normalize-tweet.ts # GraphQL → NormalizedTweet
│ └── v2-to-normalized.ts # X API v2 → NormalizedTweet
└── tools/
├── discovery.ts # get_tweet_counts, get_api_usage, cookie feeds
└── write.ts # post/like/unlike/retweet/delete
docs/
├── endpoint-index.md # both providers, generated from specs
PATCH-reader-dual-channel.md # why it is built this way + what was learned the hard wayDevelopment
No build step. Edit and restart the server (stdio servers do not hot-reload — /mcp reconnect
after changing anything the server loads).
bun run src/index.ts -config ~/.twitter-mcp/config.json
bunx tsc --noEmitTech stack
Bun · @modelcontextprotocol/sdk ·
oauth-1.0a · bun:sqlite · X internal GraphQL (no deps)
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Twitter/X read-only MCP server — 12 tools: search, users, tweets, followers, timelines, trends.
Hosted X (Twitter) MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
Official twitterapi.io hosted MCP: Twitter/X tweets, users, followers, trends. OAuth or API key.
Official MCP server for twitterapis.com. Read and write Twitter/X: search, users, tweets, DMs.
Related MCP Servers
- AlicenseBqualityDmaintenanceAn MCP server that enables Claude to interact with Twitter, allowing for posting tweets and searching Twitter content.2280 npm407MIT
- AlicenseNot gradedqualityDmaintenanceAn enhanced Model Context Protocol server that enables Claude to interact with Twitter/X, supporting tweet posting, searching, and deletion with both OAuth 1.0a and OAuth 2.0 authentication methods.109 npm24MIT
- AlicenseNot gradedqualityDmaintenanceModel Context Protocol server that enables programmatic interaction with Twitter API, allowing users to post tweets, search for content, and retrieve user timelines through standardized MCP tools.5 npmMIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server for interacting with the Twitter/X API v2, enabling AI assistants to retrieve tweets, post content, reply, quote, and more programmatically.3,240 npm13MIT