The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the X (read Only) listing page.
An MCP server that reads X (Twitter): posts, threads, replies, quotes, and search. It wraps twscrape and uses your own logged-in session, so there's no paid X API and no developer account. Tools return clean markdown shaped for an agent to read, including image, video, and GIF URLs and any external links in a post.
Works with any MCP client over the two standard transports — local stdio and hosted Streamable HTTP.
| Tool | Returns |
|---|---|
read_tweet(url_or_id) | One post as markdown. |
read_thread(url_or_id, max_replies=50) | Root post + the author's self-thread + top replies. |
read_replies(url_or_id, limit=50) | Replies to a post. |
read_quotes(url_or_id, limit=30) | Quote-tweets (best-effort, search-based). |
user_timeline(username, limit=40, include_replies=False) | A user's recent posts, newest first. Set include_replies=True to include replies. |
search(query, limit=20, product="Latest") | Search results. Supports from:, has:media, min_faves:, etc. |
user_profile(username) | A user's profile as markdown: bio, location, follower/following/tweet counts, join date. |
Then authenticate once (next section) and verify:
Reads run against your own X session. Pick one path:
1. Launch a dedicated browser (recommended). Opens a separate Chrome/Brave profile with a DevTools port, you sign in to X once, and the session is captured. It does not touch your daily browser or automate X's login flow.
2. Attach to a dedicated browser profile. Only use this when you already run an isolated Chromium profile with a debug port. Browser debugging exposes browser data, and recent Chrome versions do not enable it for the default profile.
3. Headless / CI (raw cookies). A server can't open your desktop browser, so
add a session from auth_token + ct0 cookies. Run this without cookie flags to
enter values through hidden prompts, rather than leaving secrets in shell history:
The captured session is reused across restarts. Run login --launch-browser chrome again when it expires,
or to add burner sessions for rate-limit rotation. twscrape-twitter-mcp accounts
lists the pool.
Use burner accounts, not your main — see Legal.
The server runs locally over stdio. Most MCP clients take a JSON block like this:
Client-specific equivalents:
Add the JSON block above to claude_desktop_config.json
(Settings → Developer → Edit Config).
~/.codex/config.toml~/.cursor/mcp.json.vscode/mcp.jsonFor a hosted private instance (see Deploy), point a preconfigured client at the HTTP endpoint with a bearer token. This is static bearer auth, not an OAuth sign-in flow.
Then ask, e.g. "read this thread: <url>".
Run the server always-on and reachable over HTTP (POST /mcp). It ships as a
container; Cloudflare Workers won't work because twscrape is Python with native
deps.
A headless container can't open your desktop browser, so authenticate locally
first (login --attach writes storage_state.json under
TWSCRAPE_TWITTER_MCP_HOME), then ship that session to the host — copy the file to
the mounted volume, or run the cookie-based init over SSH. The server reloads a
persisted session on boot.
Always set a token when exposing HTTP — anyone who can reach the endpoint can use your X session:
Point Railway at this repo (it reads railway.json + Dockerfile), add a volume
mounted at /data, set TWSCRAPE_TWITTER_MCP_AUTH_TOKEN, and seed a session via
the Railway shell with twscrape-twitter-mcp init.
Clients send Authorization: Bearer <token>.
| Env var | Default | Purpose |
|---|---|---|
TWSCRAPE_TWITTER_MCP_HOME | ~/.config/twscrape-twitter-mcp | Where the sqlite account pool lives. Point at a volume in prod. |
TWSCRAPE_TWITTER_MCP_DB | $TWSCRAPE_TWITTER_MCP_HOME/accounts.db | Override the pool path directly. |
TWSCRAPE_TWITTER_MCP_AUTH_TOKEN | (unset) | Required bearer token for HTTP transport. |
TWSCRAPE_TWITTER_MCP_PROXY | (unset) | Global proxy for every account. |
TWSCRAPE_TWITTER_MCP_CDP_URL | http://127.0.0.1:9222 | Browser DevTools endpoint for login --attach. |
TWSCRAPE_TWITTER_MCP_DEFAULT_LIMIT | 40 | Default timeline and search result count (1–100). |
PORT | 8080 | HTTP port (Railway injects this). |
The hard part of reading X — GraphQL signing, the x-client-transaction-id
header, TLS fingerprinting — lives entirely in twscrape, which is pinned.
This package is a read-only MCP layer on top and never
touches that machinery. When X changes something and reads break, the fix is a
version bump, not reverse-engineering.
init.Reading X with your own logged-in session may violate X's Terms of Service, and accounts used for scraping can be rate-limited or suspended. Use burner accounts, not your main. Provided as-is for research and personal use; you are responsible for how you use it.
MIT.
The hard scraping work is twscrape by
vladkens. This is a read-only MCP layer on top — go star it.