twikit-mcp¶
Twitter/X MCP server + CLI — no API key needed.
An MCP server that lets Claude (or any MCP-compatible AI agent) interact with Twitter/X using browser cookies. The same twikit-mcp binary doubles as a CLI for shell scripts and debugging.
What's new in 0.1.45¶
- CI: an unreachable review API no longer fails the PR —
pr-review.ymlhad a warn-and-skip handler for a bad LLM response, but GitHub runsrun:blocks underbash -e, so a non-zerocurlexit (timeout, DNS, connection refused) killed the step before the handler ran. Run #141 died that way and turned an already-approved PR red. All three call sites now capture curl's status and degrade as intended. A test extracts the real shell out of the workflow and runs it against a stubcurl, so it can't drift from what CI executes — and it immediately found the same latent bug inissue-triage.yml. (closes #124) - No more duplicate review on a draft→ready flip — reviews now record which commit they covered, and a second run on the same SHA skips instead of spending another LLM call.
ready_for_reviewstays a trigger, since a contributor marking a draft ready genuinely wants a review then.
CI only — no change to the package. Upgrade is optional.
What's new in 0.1.44¶
- Listed in the official MCP registry — a
server.jsonmanifest now declares this server toregistry.modelcontextprotocol.ioasio.github.tangivis/twitter-mcp: PyPI package, stdio transport, and every environment variable with a description you can act on. A sentinel test keeps it in sync withpyproject.tomland cross-checks the declared variables against the ones the code actually reads — in both directions, so the manifest can't advertise a knob that does nothing or omit one that matters. (closes #122) - DeepSeek Harness card completed — documents the
reconnectkeys and the fact that a duplicateserverNameacross live instances fails the later plugin at load.
What's new in 0.1.43¶
- README's client list is no longer stale — Pi (documented in 0.1.34) and DeepSeek Harness (0.1.40) were missing from the one-line "Works with" summary in all three languages, because nothing connected that line to the Install page. Both are now listed, and a sentinel test asserts every client card on the Install page appears in every README summary, so the next one can't quietly go missing. Docs + test only.
What's new in 0.1.42¶
get_retweetersno longer dies on a suspended account — when one of a tweet's retweeters has been suspended or deleted, X returns__typename: UserUnavailablefor that entry, which carries norest_id. twikit'sUser.__init__reads that key unconditionally, so a single dead account killed the entire call withKeyError: 'rest_id'. Unparseable entries are now skipped and the rest are returned.get_favoritersshares the same code path and the same fix. Caught by live-smoke against real X on 2026-08-17. (issue #37)- Also hardened one line away in the same function: cursor extraction assumed the last two timeline entries are always cursors, which
KeyError'd on gated responses that omit them. Missing cursors now yieldNone.
Upgrade with uv tool upgrade twikit-mcp (or pip install --upgrade twikit-mcp).
What's new in 0.1.41¶
- Read XChat (encrypted DMs) locally — three new tools take the registry to 62:
xchat_status,xchat_list_conversations,xchat_get_history. X's web client already decrypts your conversations and stores the plaintext in a local SQLite file; these read it. No new dependencies, no network, no credentials, no write path — the database is openedmode=ro&immutable=1, every statement is a SELECT, encryption keys are never read, and reading here does not mark anything read on X. Configure withXCHAT_BROWSER(chrome/chromium/edge/brave/aside),XCHAT_BROWSER_PROFILE, orXCHAT_DATABASE_PATH; with none set the tools stay dormant and the rest of the server is unaffected. See the XChat page. (closes #118) - Thanks to @DJNgoma — the SQLite reading and browser-profile discovery are derived from his work in PR #107.
Upgrade with uv tool upgrade twikit-mcp (or pip install --upgrade twikit-mcp).
What's new in 0.1.40¶
- DeepSeek Harness (dsh) setup guide — the Install page now covers DeepSeek Harness. Unlike Pi, dsh has a first-party MCP client (
@deepseek-ai/dsh-mcp-client), so no community extension is needed — but its config is a plugin entry incordis.ymlrather than the usualmcpServersmap, and it has no tool allowlist, so all 59 tools register. The card covers both, plus thefailOnStartupErrorandtoolCallTimeoutMskeys worth knowing. Docs only — no code changes;twikit-mcpis a standard stdio MCP server and needs nothing special.
What's new in 0.1.39¶
- Migrated to MCP Python SDK v2 — the server is now built on
MCPServer(mcp.server.mcpserver) instead of the removedFastMCP, and the dependency moved frommcp[cli]>=1.27,<2to>=2,<3. Nothing changes for you at the protocol level: the fulltools/listpayload — negotiated protocol version, capabilities, and all 59 tools with their complete input/output schemas — is byte-for-byte identical to 0.1.38 (58,843 bytes, diffed across both SDKs over a real stdio handshake). Upgrading pulls SDK 2.x; if you pinmcp<2yourself, stay on 0.1.38. (closes #109) serverInfo.versionnow reports the actual package version — SDK v1 filled this field with its own version, and v2 leaves it empty unless set. Clients now seetwikit-mcp's real version in the initialize response.
Upgrade with uv tool upgrade twikit-mcp (or pip install --upgrade twikit-mcp).
What's new in 0.1.38¶
- Groundwork for the MCP 2026-07-28 spec — the MCP Python SDK 2.0.0 is now stable, and it renames the class this server is built on (
FastMCP→MCPServer). Your install is unaffected: the dependency has been pinned to SDK 1.x since 0.1.35. This release funnels every read of the SDK's private tool registry through a single internal accessor, which turns the upcoming v2 migration from a ~70-site sweep into a one-line change. Pure internal refactor — no behavior change, byte-identical generated docs and CLI output. (issue #109 phase 2)
Upgrade with uv tool upgrade twikit-mcp (or pip install --upgrade twikit-mcp).
What's new in 0.1.37¶
get_dm_historyno longer crashes on message requests — accepting a stranger's message request makes X inject atrust_conversationsystem entry into the conversation timeline, which crashed the tool withKeyError: 'message'. Non-message entries are now skipped and surfaced in a newtimeline_eventsfield, and awarningsfield flags that history may be incomplete for end-to-end encrypted (X Chat) conversations — the legacy DM API cannot return encrypted bodies, so agents should not conclude "no reply was sent". Clean conversations keep the exact same JSON shape as before. (closes #104)- First-time DM reads no longer misreport "User not found" — reading a conversation right after sending a first DM can transiently 404 on X's side; the tool now retries up to 3 times with short backoff and reports the conversation (not the user) as unavailable if it persists. (closes #102)
- Thanks to @DJNgoma for the live diagnosis and both patches (PRs #103, #105).
Upgrade with uv tool upgrade twikit-mcp (or pip install --upgrade twikit-mcp).
What's new in 0.1.36¶
- Integer IDs accepted everywhere — X serializes tweet/user/list IDs as JSON numbers (
"id": 2087887408440164663next to"id_str"). Any client that echoed the numericidback —{"tweet_id": id}without astr()— used to be rejected by validation before the tool even ran (Input should be a valid string). Every snowflake-shaped parameter (37 sites across the 59 tools:tweet_id,user_id,list_id,media_ids, …) now accepts int or string and coerces losslessly to string. Floats stay rejected: these IDs exceed 2^53, so a float is already precision-corrupted and would silently target the wrong tweet. (closes #111)
Upgrade with uv tool upgrade twikit-mcp (or pip install --upgrade twikit-mcp).
What's new in 0.1.35¶
- Pinned the MCP SDK below v2 —
mcp[cli]had no upper bound, so a freshuv tool install twikit-mcpwould have pulled SDK v2 the day 2.0.0 leaves pre-release. v2 (implementing the 2026-07-28 spec) renamesFastMCP→MCPServerand movesmcp.server.fastmcp.*tomcp.server.mcpserver.*, which breaks this server at import. Now>=1.27,<2, guarded by a sentinel test. No behavior change on an existing install. Migration tracked in issue #109.
What's new in 0.1.34¶
- Pi setup guide — the Install page now covers Pi. Pi has no built-in MCP, so the card walks through installing a community MCP extension (
pi-mcp-adapter) and using itsdirectToolsallowlist to keep this server's 59 tools from crowding a coding session's context. Docs only — no code changes;twikit-mcpis a standard stdio MCP server and needs nothing special.
What's new in 0.1.33¶
- Drop the 200-char text truncation —
get_timeline/search_tweets/get_user_tweets/get_bookmarks/get_list_tweets/get_scheduled_tweets/get_community_tweets/get_communities_timeline/search_community_tweetno longer cut tweet text at 200 characters.get_tweetandget_tweet_repliesalso switch toTweet.full_text, which returns the long-form text (up to 4000 chars) for X note tweets. Compact responses are user-controlled viacount. (closes #97) get_article_previewdistinguishes quote tweets — when the input is a quote tweet, the error now says "this is a quote tweet, not an article. Use get_tweet to read the quoted tweet content" instead of the generic "does not embed an article".
What's new in 0.1.32¶
- Read tweet replies — new
get_tweet_replies(tweet_id, cursor=None)tool fetches the comments / discussion under a tweet. Uses X's TweetDetail GraphQL via vendored twikit; one page per call withnext_cursorfor more. Returns the same compact reply shape asget_user_tweets/get_timeline. (closes #94)
What's new in 0.1.31¶
- Per-client install matrix in docs — new Install page walks through registering
twikit-mcpwith Claude Code / Claude Desktop / Cursor / Windsurf / Cline / opencode (config file path + JSON snippet, ≤ 12 lines per client). Single canonical install command (uv tool install twikit-mcp); JSON shape is universal across clients. (closes #92)
What's new in 0.1.30¶
- Localized API docs page —
/zh/api/and/ja/api/now show Chinese / Japanese chrome (title, intro, table headers, section labels) instead of falling back to English. Tool docstrings stay native (Python source) — same trade-offmkdocstringsmakes. (closes #90)
What's new in 0.1.29¶
- Community + article-preview reliability —
get_community/get_community_tweets/get_community_members/get_community_moderators/search_community_tweetno longer crash withKeyError: 'rest_id'/IndexError.get_article_previewnow surfaces a cleanToolErrorinstead of leakingHTTPStatusErrorwhen the syndication endpoint returns 404 for a stale article. Defensive.get()parsing in_vendor/twikit/community.py+client.py. Closes issue #76 —T_DRIFTis now empty inlive-smoke.yml. (issue #76 parts 2 + 3)
What's new in 0.1.28¶
- List-tool reliability —
get_list/get_list_tweets/get_list_members/get_list_subscribersno longer crash withKeyError: 'created_at'/IndexError/Invalid list idon burner-gated responses. Defensive parsing in_vendor/twikit/list.py+client.py: missing fields returnNone/""/0, empty entries return emptyResult. Live-smoke now catches future regressions of these classes (no moreT_DRIFTtolerance for the list path). (issue #76 part 1)
What's new in 0.1.27¶
- Download tweet videos via yt-dlp — new
download_tweet_videoMCP tool +twikit-mcp video <id>CLI subcommand. Saves to~/Downloads/twikit-mcp/by default. Authenticated via your existingcookies.json. Requiresyt-dlpon PATH (uv tool install yt-dlp);ffmpegonly needed if you pass a separate-stream format likebestvideo+bestaudio. (closes #84)
What's new in 0.1.26¶
- Quote tweet visibility on
get_tweet— the response now includesis_quote_status,quoted_id,quoted_author, andquoted_textwhen the tweet quote-retweets another. Agents can now show the quoted text inline without an extraget_tweetround-trip — the data is already in the same GraphQL response, we just expose it. (closes #82)
What's new in 0.1.25¶
- Conversation context on
get_tweet— the response now includesin_reply_to(parent tweet ID when the tweet is a reply) andconversation_id(root tweet ID of the thread). Agents can now reconstruct thread context from a single tweet without needing the user to paste the parent link. (closes #77)
What's new in 0.1.24¶
- Rich-rendered cards — the terminal cards from 0.1.23 are now produced by Rich, giving correct cell-width math for emoji + CJK (no more right-border drift on
❤ 🔁lines), and OSC 8 clickable hyperlinks for tweet / profile / bio URLs in iTerm2, kitty, WezTerm, Windows Terminal, gnome-terminal ≥ 3.36, etc. The trends list is now a proper table. - Plain (non-TTY) output unchanged:
| jq/> file/NO_COLOR=1consumers stay byte-stable.
What's new in 0.1.23¶
- ASCII Twitter-card UI —
twikit-mcp tweet,user,tl,search,trendsnow render box-drawing cards in your terminal (bold author, dim timestamps, separators between body / counts / URL). Piping to a file or another command, or settingNO_COLOR=1, auto-falls-back to the previous byte-stable plain text. See CLI mode for samples.
What's new in 0.1.22¶
- Human-friendly CLI subcommands — read tweets / profiles / timeline / search / trends straight from your terminal:
Plain text output, native unicode, sensible defaults. See the CLI mode page.
- UTF-8 outputs end-to-end — no more \uXXXX escapes. Greek / 中文 / 日本語 / emoji all flow through tools as readable text.
- Tri-lingual docs site — this very page; switch language in the top bar.
What you get¶
- 57 tools covering tweets, users, lists, communities, scheduled tweets + polls, DMs, articles, search, trends, notifications.
- Browser-cookie auth — copy
ct0+auth_tokenfrom your X session, you're authenticated. - Two transports, one binary — MCP server (default) for AI agents;
twikit-mcp call <tool>CLI for shells. - Vendored twikit with project-specific defensive patches.
Where to go¶
- CLI mode — subcommands, type coercion, exit codes, examples.
- MCP Tools API — auto-generated reference: every tool's signature + docstring + CLI example, kept in sync with code.
- Technical design — internals (currently 中文 only — translation welcome).
- Vendoring twikit — every patch and the issue that motivated it (currently 中文 only).
- GitHub repo — README has full install / quickstart in three languages.
Quick install¶
# 1. Drop your X cookies into ~/.config/twitter-mcp/cookies.json
mkdir -p ~/.config/twitter-mcp
cat > ~/.config/twitter-mcp/cookies.json <<'EOF'
{"ct0": "...", "auth_token": "..."}
EOF
chmod 600 ~/.config/twitter-mcp/cookies.json
# 2. Install (recommended for daily use)
uv tool install twikit-mcp
# 3. Register with Claude Code
claude mcp add twitter -s user \
-e "TWITTER_COOKIES=$HOME/.config/twitter-mcp/cookies.json" \
-- twikit-mcp
Use uv tool upgrade twikit-mcp to update; full alternatives (uvx / pip / pipx) on the GitHub README.