Connect Claude to Twitter/X — without paying $100/month for the official API. Uses Playwright to control a managed Chromium session, wrapped as an MCP server.
Claude ──MCP──▶ x-mcp-server ──Playwright──▶ Chromium (logged in) ──▶ Twitter/X
No API key required. No manual browser setup. Login once, works forever.
What's trending on my timeline right now?
Search for recent tweets about the AI funding landscape
Post a tweet: "Just shipped a new feature 🚀"
Show me my unread DMs and summarize them
| Tool | Method | Status |
|---|---|---|
twitter_post |
GraphQL API | Working |
twitter_reply |
GraphQL API | Working |
twitter_like |
GraphQL API | Working |
twitter_retweet |
GraphQL API | Working |
twitter_quote |
Browser automation | Working |
twitter_follow |
Browser automation | Working |
twitter_unfollow |
Browser automation | Working |
twitter_undo |
GraphQL API | Working |
twitter_search |
Browser DOM parsing | Working |
twitter_timeline |
Browser DOM parsing | Working |
twitter_bookmarks |
Browser DOM parsing | Working |
twitter_tweets |
Browser DOM parsing | Working |
twitter_notifications |
Browser DOM parsing | Working |
twitter_user |
Browser DOM parsing | Working |
twitter_view_tweet |
Browser DOM parsing | Working |
twitter_mentions |
Browser DOM parsing | Working |
twitter_my_replies |
Browser DOM parsing | Working |
twitter_dm_read |
Browser automation | Working |
twitter_screenshot |
Playwright screenshot | Working |
browser_open |
Playwright navigation | Working |
browser_snapshot |
Page text content | Working |
Note
DM reading works but Twitter's E2E encryption may limit what's visible via browser automation.
Prerequisites: Node.js 18+.
Claude Desktop configuration:
{
"mcpServers": {
"twitter": {
"command": "npx",
"args": ["-y", "x-mcp-bridge", "--stdio"]
}
}
}On first use, Playwright Chromium is downloaded automatically (~100MB, one-time). A browser window then opens for you to log in to Twitter/X. The session is saved to ~/.x-mcp-bridge/profile/ — no login needed on subsequent runs.
Note
Early tool calls may return an error while the browser is still setting up. If that happens, retry after a few seconds.
🔧 Configuration
Session management:
npx x-mcp-bridge --login # open browser, log in, save session, exit
npx x-mcp-bridge --logout # delete saved browser profile
npx x-mcp-bridge --status # check if session is valid and exitHTTP mode (for Claude.ai remote or MCP Inspector):
npx x-mcp-bridge # starts HTTP server on :8080Environment variables:
| Variable | Default | Description |
|---|---|---|
PORT |
8080 |
HTTP server port |
BASE_URL |
http://localhost:8080 |
Public URL for OAuth discovery |
TWITTER_MCP_PROFILE |
~/.x-mcp-bridge/profile |
Browser profile directory |
HEADLESS |
true |
Set false to show the browser window |
DM_PIN |
(empty) | Twitter DM encryption PIN (4 digits, if set up) |
❗ Troubleshooting
Login loop on every start:
- The browser profile isn't saving. Check that the
TWITTER_MCP_PROFILEpath is writable.
Tools time out or are slow:
- Headless mode can trigger bot detection. Run
npx x-mcp-bridge --no-headlessto open a visible browser and debug.
Playwright Chromium not found:
- Run
npx playwright install chromium.
Prerequisites: Claude Desktop.
One-click installation for Claude Desktop users:
- Download the latest
.mcpbfrom Releases - Drag it into Claude Desktop, or go to File → Install Extension...
- On the first tool call, a browser window opens — log in to Twitter/X
- The session is saved to
~/.x-mcp-bridge/profile/. No login needed on subsequent runs.
❗ Troubleshooting
First-time setup:
- A browser window opens automatically on the first tool call that requires authentication
- Log in to Twitter/X normally; the session is saved to disk automatically
Session issues:
- Browser profile is stored at
~/.x-mcp-bridge/profile/ - If Twitter invalidates your session, call any tool — a login window will reopen
- To force a fresh login: delete the profile directory and restart
Playwright Chromium not found:
- Run
npx playwright install chromiumin the server directory
Prerequisites: Node.js 18+ and Git.
git clone https://github.com/trendfluence-org/x-mcp-bridge.git
cd x-mcp-server
npm install # also downloads Playwright Chromium (~100MB, one-time)
node server.mjs # starts HTTP server on :8080Expose with any HTTPS reverse proxy (Cloudflare Tunnel, ngrok, etc.) and add the URL to Claude.ai → Settings → Connected Tools.
🔧 Configuration
Environment variables (or .env file):
| Variable | Default | Description |
|---|---|---|
PORT |
8080 |
HTTP server port |
BASE_URL |
http://localhost:8080 |
Public URL for OAuth discovery |
TWITTER_MCP_PROFILE |
~/.x-mcp-bridge/profile |
Browser profile directory |
HEADLESS |
true |
Set false to show the browser window |
DM_PIN |
(empty) | Twitter DM encryption PIN (4 digits, if set up) |
OAUTH_CLIENT_ID |
twitter-mcp-client |
OAuth client ID |
OAUTH_CLIENT_SECRET |
(auto-generated) | OAuth client secret |
Session management:
node server.mjs --login # open browser, log in, save session, exit
node server.mjs --logout # delete saved browser profile
node server.mjs --status # check if session is valid and exitTest with curl:
# Register a client
curl -s -X POST http://localhost:8080/register \
-H "Content-Type: application/json" \
-d '{"redirect_uris":["http://localhost:9999/callback"],"client_name":"test"}'
# Authorize — grab the `code` from the redirect Location header
CODE=$(curl -si "http://localhost:8080/authorize?response_type=code&client_id=twitter-mcp-client&redirect_uri=http://localhost:9999/callback&code_challenge=abc&code_challenge_method=plain&state=x" \
| grep -i location | sed 's/.*code=\([^&]*\).*/\1/' | tr -d '\r')
# Exchange for a token
TOKEN=$(curl -s -X POST http://localhost:8080/token \
-d "grant_type=authorization_code&code=$CODE&redirect_uri=http://localhost:9999/callback&code_verifier=abc&client_id=twitter-mcp-client" \
| node -e "process.stdin.resume();var d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>console.log(JSON.parse(d).access_token))")
# Initialize MCP session
curl -s -D /tmp/mcp-headers -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $TOKEN" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
SESSION_ID=$(grep -i 'mcp-session-id' /tmp/mcp-headers | awk '{print $2}' | tr -d '\r')
# Call a tool
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $TOKEN" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"twitter_timeline","arguments":{"count":5}}}'❗ Troubleshooting
twitter_timeline returns []:
- Twitter returned a "Something went wrong" page. The server auto-retries once; if persistent, run
node server.mjs --status.
Login loop on every start:
- The browser profile isn't saving. Check that the
TWITTER_MCP_PROFILEpath is writable.
Tools time out or are slow:
- Headless mode can trigger bot detection. Run
node server.mjs --no-headlessto open a visible browser and debug.
Playwright Chromium not found:
- Run
npx playwright install chromium.
Prerequisites: Node.js 18+ and Git.
# 1. Clone repository
git clone https://github.com/trendfluence-org/x-mcp-bridge.git
cd x-mcp-server
# 2. Install dependencies (also downloads Playwright Chromium ~100MB)
npm install
# 3. Start with visible browser for debugging
node server.mjs --no-headless🔧 Configuration
CLI flags:
--stdio— stdio transport (used by Claude Desktop / mcpb)--no-headless— show browser window (debugging)--login— open browser, log in, save session, exit--logout— delete saved browser profile--status— check if session is valid and exit
stdio mode (direct JSON-RPC):
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"twitter_timeline","arguments":{"count":3}}}' \
| node server.mjs --stdio 2>/dev/null❗ Troubleshooting
Scraping issues:
- Use
--no-headlessto watch every navigation in real time.
Session issues:
- Profile is stored at
~/.x-mcp-bridge/profile/. Delete it and run--loginto start fresh.
Playwright Chromium not found:
- Run
npx playwright install chromium.
- Managed browser — Playwright launches and manages a persistent Chromium profile stored at
~/.x-mcp-bridge/profile/. No external Chrome instance needed. - Auto login — On first run with no session, the browser opens visibly so you can log in. After login it switches to headless. Session is saved to disk automatically.
- MCP transports —
--stdioflag for Claude Desktop (mcpb); HTTP + OAuth 2.0 PKCE for Claude.ai remote. - Tool implementations — Browser automation (open page → wait → parse DOM) for most tools; Twitter's internal GraphQL API for lightweight mutations (like, retweet, undo).
- React contenteditable — Twitter's compose box is a
contenteditablediv. The server usesClipboardEvent pastefor reliable text input. - GraphQL mutations — Like, retweet, and undo use Twitter's internal GraphQL API via in-page
fetch()(nox-client-transaction-idneeded for these endpoints). - Session persistence — Playwright's persistent context writes cookies and localStorage to disk automatically. Re-login is only needed if Twitter invalidates the session.
- DM PIN auto-entry — If
DM_PINis set, the server auto-enters it using React-compatible input simulation.
MIT