xctl-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@xctl-mcpPost a thread: "Shipping v2 today" then "Changelog in the replies.""
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
xctl
A terminal control plane for your own X account: a CLI, a typed SDK layer, and an MCP server generated from one operation registry.
60 operations · 49 official-API · 11 unofficial (opt-in) · 51 MCP tools by default
X's official API lost most account-control features in 2026.
xctlcovers what remains officially, and puts the rest behind a clearly labeled, opt-in unofficial transport that the user must explicitly enable.
Install
npm (Node.js ≥ 24):
npm install -g x-mcp-automation
xctl --helpWithout a global install:
npx -y x-mcp-automation --helpPyPI / pipx (same binary, Node.js ≥ 24 required):
pipx install x-mcp-automation
xctl --helpClaude Code plugin:
npx -y x-mcp-automation install --agent claudeor manually:
/plugin marketplace add FiredMosquito831/TwitterXApiMcp
/plugin install xctl@xctl-marketplaceThe plugin ships its own server bundle, so it does not need a global npm install. Its settings (spend cap, profile, config directory) are asked for in Claude Code's plugin settings.
Detailed channels, updating, uninstalling and troubleshooting: docs/INSTALL.md.
Related MCP server: X API FastMCP Server
What works
Surface | Official API |
|
Post, thread, poll, edit, delete | ✅ |
|
Media upload (image/GIF/video, alt text) | ✅ |
|
Home / user / mentions timelines | ✅ |
|
Search recent + full archive | ✅ |
|
Post metrics, own-account analytics | ✅ |
|
Quote-post reads | ✅ |
|
Liked posts, blocked/muted lists | ✅ |
|
Trends, Spaces (read), Communities (read), News | ✅ |
|
DMs send/read | ✅ |
|
Bookmarks | ✅ |
|
Lists CRUD + members | ✅ |
|
Repost / undo | ✅ |
|
Block, mute | ✅ |
|
Long-form Articles draft/publish | ✅ |
|
Usage / credit balance | ✅ |
|
Reply | ⚠️ summoned only | submits; X returns 403 unless allowed |
Quote post | ❌ Enterprise |
|
Like / follow | ❌ removed + rule-prohibited when automated |
|
Profile bio/name/location/url | ❌ no endpoint |
|
Avatar / banner | ❌ no endpoint |
|
Pinned post | ❌ no endpoint |
|
Requirements
Node.js ≥ 24
An X developer app with OAuth 2.0 enabled (for official operations)
Build from source
npm install
npm run build
npm testRun the CLI directly:
node packages/cli/dist/index.js --helpOr link the binaries:
(cd packages/cli && npm link)
(cd packages/mcp && npm link)
x --help
x-mcp --helpAuthentication
OAuth 2.0 PKCE (official operations)
Create an app at https://console.x.com, enable OAuth 2.0, and register a redirect URI (default http://localhost:8080/callback).
export X_CLIENT_ID="..."
export X_CLIENT_SECRET="..." # optional for public clients
x auth loginThe browser opens, the loopback server exchanges the code immediately (X's codes live 30 seconds), and tokens are stored in the OS keychain. Access tokens last 2 hours and refresh automatically; the refresh token rotates.
Headless or remote:
x auth login --manual # prints the URL, stores PKCE state
x auth complete --callback "http://localhost:8080/callback?code=...&state=..."Other auth commands:
x auth status [--live]
x auth logout [--profile work]
x auth import-cookies --file cookies.jsonCLI
# account and cost
x account status
x usage get --kind all
# posting
x posts create --text "hello from the terminal"
x posts create --text "with media" --media-ids 1234567890
x posts create --text "poll" --poll '{"options":["a","b"],"duration_minutes":1440}'
x posts thread --segments "first" "second" "third"
x posts delete --id 1234567890
# reads
x posts timeline --kind home --max-results 20
x posts search-recent --query "from:jack mcp" --max-results 10
x users get --username jack
x analytics account --max-posts 50
# DMs
x dms send --to-user-id 42 --text "hello"
x dms list --max-results 20Every write supports --dry-run where it makes sense (posts.create, posts.thread, media.upload) and prints the USD cost first.
Global flags: --json, --profile <name>, --spend-cap <usd>.
Scheduling
xctl schedules locally; it does not use X's web scheduler.
x queue add --op posts.create --input '{"text":"later"}' --in 2h
x queue list
x queue run --once # or without --once to poll every 30s
x queue remove 1MCP server
claude mcp add --transport stdio x --scope user -- xctl-mcpWithout a global install:
claude mcp add --transport stdio x --scope user -- npx -y --package x-mcp-automation xctl-mcpManual config:
{
"mcpServers": {
"x": {
"type": "stdio",
"command": "node",
"args": ["D:/Projects2/TwitterXApiMcp/packages/mcp/dist/index.js"],
"env": { "X_USER_TOKEN": "…", "XCTL_SPEND_CAP": "5" }
}
}
}The server exposes one tool per operation plus two meta-tools:
operations_search— find an operation and its input schema without loading every schema.operations_invoke— run any operation by id with validated input.
Use one entry per profile (X_PROFILE=work, X_PROFILE=personal).
The unofficial transport
This uses your logged-in browser session against X's private web endpoints. X's automation rules prohibit non-API automation and state it may result in permanent suspension. It is off by default, lives in a separate package, and every operation is prefixed UNOFFICIAL in its description.
Enable it deliberately:
# 1. export cookies from a logged-in x.com session
# (Cookie-Editor JSON, Playwright storageState, or a Cookie header)
x auth import-cookies --file cookies.json
# 2. acknowledge the risk
x config set-unofficial on --i-understandThen unofficial commands appear, and each requires --confirm:
x likes add --id 1234567890 --confirm
x follows add --username jack --confirm
x profile update --description "new bio" --confirm
x posts pin --id 1234567890 --confirmDesign constraints, enforced in code:
One target per invocation. No batch or loop verbs exist.
Every unofficial op is marked destructive and non-idempotent in MCP.
The unofficial transport never runs without the config flag and stored cookies.
Rate budgets are conservative; X's own
x-rate-limit-*headers seed the buckets.No anti-detection engineering: it uses a real session, not fingerprint spoofing.
If X changes its bundle layout, x unofficial refresh re-scans the operation table; x unofficial operations shows what was discovered.
Safety and cost
A spend meter refuses operations that would cross
XCTL_SPEND_CAP(default$5), persisted per profile per month.Posts containing a URL cost $0.20 instead of $0.015 and say so before running.
Writes are never retried automatically — a retried post can duplicate.
A 30-second dedupe window blocks accidental double submission.
Reads use the cheaper Owned Reads endpoints where possible.
Layout
packages/core transport, OAuth, credentials, config, state, rate limiter, spend meter
packages/ops the operation registry — the single source of truth (49 official ops)
packages/unofficial cookie session, bundle parser, transaction-id generator (11 ops)
packages/cli commander front-end over the registry
packages/mcp MCP v2 server over the registry
npm/ publishable package (bundled CLI + MCP, bins xctl/xctl-mcp)
pip/ PyPI launcher (vendors the same bundles)
plugins/xctl/ Claude Code plugin (manifest, vendored server, skill, commands)
.claude-plugin/ marketplace catalogue
.github/workflows/ npm and PyPI trusted-publishing workflows
scripts/ tests, structural checks, package builder
docs/research/ six dated research reports with sources
docs/PLAN.md decision record, capability matrix, roadmap, risk registerTests
npm testRuns, in order:
test-core.mjs— PKCE vector, pricing, spend cap, limiter seeding, SQLite state, cookie parsing, transaction materialstest-ops.mjs— request shapes, dry runs, thread rollback, search params, analytics aggregationverify-registry.mjs— unique names, annotations, cost functions, unofficial warningsmcp-smoke.mjs— real stdio handshake andtools/listtest-mcp.mjs—operations_search,operations_invoke, oversized-input rejection
Environment
Variable | Purpose |
| OAuth app credentials |
| Override the redirect URI |
| Skip the store and use a fixed token |
| App-only bearer; public reads only |
| Profile name for multi-account setups |
| Hard USD cap per month/profile (default |
| Override config/cache directory |
Limits worth knowing
Official replies only work when the author summoned you.
DM reads are capped at 15 per 15 minutes; use the Activity API for chat-scale polling.
X Chat (E2E DMs) is not implemented; legacy DM endpoints are.
Media processing can take minutes for video;
media.uploadwaits up to ~60s.Articles require a DraftJS
content_state; the built-in paragraph builder is a convenience and may need adjustment for rich content.
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted X (Twitter) MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
Twitter/X read-only MCP server — 12 tools: search, users, tweets, followers, timelines, trends.
Official MCP server for twitterapis.com. Read and write Twitter/X: search, users, tweets, DMs.
Official twitterapi.io hosted MCP: Twitter/X tweets, users, followers, trends. OAuth or API key.
Related MCP Servers
- AlicenseAqualityDmaintenanceAn MCP server that provides AI agents with full access to the X (Twitter) API for posting, searching, and managing engagement through natural language. It supports comprehensive tools for tweet management, media uploads, and account analytics across multiple MCP-compatible clients.1556MIT

X API FastMCP Serverofficial
FlicenseNot gradedqualityFmaintenanceA local MCP server that exposes the X API (formerly Twitter API) as tools, enabling operations like posting, searching, user management, and more via natural language commands.864-- AlicenseBqualityDmaintenanceMCP server for interacting with the X platform (Twitter) via MCP clients like Claude, Cursor AI, and Windsurf AI.201 npm6MIT
- AlicenseBqualityCmaintenanceAn MCP server that enables AI assistants to interact with Twitter/X through a single authenticated session without an official API key, providing 27 tools for reading and writing tweets, user management, timeline access, trends, and direct messages.2722 PyPI2MIT