{"_id":"x-api-mcp","_rev":"3-662d95e848f4321d1805e459be170ea6","name":"x-api-mcp","dist-tags":{"latest":"0.2.1"},"versions":{"0.0.0-stage":{"name":"x-api-mcp","version":"0.0.0-stage","_id":"x-api-mcp@0.0.0-stage","stub":true,"maintainers":[{"name":"fatwang2","email":"wangding0798@gmail.com"}],"dist":{"shasum":"c0198bc54d864a24dbbf6c89e803a2af64b747e1","tarball":"https://registry.npmjs.org/x-api-mcp/-/x-api-mcp-0.0.0-stage.tgz","fileCount":2,"integrity":"sha512-1SyuQKeMEZTgUFyAsJCBplJRXEPFVvEjEHc+GLExLJcVrNyjvKGqW9lchfO+cD5636s2Hrdg/CVXBY5LpdGNlw==","signatures":[{"sig":"MEYCIQD0nlkKUd1oZJVUXiFcpmI06xtKGnmDH/Ah5oRUeUjalAIhAMSiVcXFGA/8mgqhHSP6/hVHPlZc/Fzeg7Al3r6CIkGU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":331},"_npmUser":{"name":"fatwang2","email":"wangding0798@gmail.com"},"description":"Temporary package placeholder for staged publishing","directories":{}},"0.2.0":{"name":"x-api-mcp","version":"0.2.0","keywords":["mcp","x","twitter","x-api","oauth2","model-context-protocol"],"author":{"name":"fatwang2"},"license":"MIT","_id":"x-api-mcp@0.2.0","maintainers":[{"name":"fatwang2","email":"wangding0798@gmail.com"}],"homepage":"https://github.com/fatwang2/x-api-mcp#readme","bugs":{"url":"https://github.com/fatwang2/x-api-mcp/issues"},"bin":{"x-api-mcp":"dist/index.js"},"dist":{"shasum":"eda9c6df9d205a5f372b2264d1160e6edf24b082","tarball":"https://registry.npmjs.org/x-api-mcp/-/x-api-mcp-0.2.0.tgz","fileCount":16,"integrity":"sha512-1Z1odfMVUNpM5T/FYdQTbPEkX2tQAzI5DVF/pHK9KzV9gzCsRgNpiOa4fHMjmStphP/En9EY++W5FmkW+ez41A==","signatures":[{"sig":"MEYCIQCpDCG5WNXvZzm3+rkLpnai8j+xYH2rzXl1xe8w6YViZAIhAPRYQ6690h9wT9EIqbpyKlB2Bq71YW/tPhhv08V3sD7M","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQD5HBElLcmdHmGbC/m+o/QnPZE+yuQBxLb+yNHfoChz1AIhANT3r16F+lVnl0Z/Koz9iGSCeq48YEqHXpwr7I/eBqQE","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90136},"type":"module","engines":{"node":">=20"},"gitHead":"b2ffee14c5c4592393b5946c1fb4bfb029e08dc4","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"npm run build && node --test --test-timeout=30000 test/*.test.mjs","build":"tsc -p tsconfig.json && chmod +x dist/index.js","start":"node dist/index.js","version":"node scripts/sync-version.mjs && git add src/version.ts plugin.json .claude-plugin/plugin.json mcp.json .mcp.json","prepublishOnly":"npm test"},"_npmUser":{"name":"fatwang2","email":"wangding0798@gmail.com"},"repository":{"url":"git+https://github.com/fatwang2/x-api-mcp.git","type":"git"},"_npmVersion":"10.9.3","description":"Local stdio MCP server for the official X API: multi-account posting, threads, media upload. Tokens never leave your machine.","directories":{},"_nodeVersion":"22.19.0","dependencies":{"zod":"^3.25.76","@modelcontextprotocol/sdk":"^1.32.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/x-api-mcp_0.2.0_1792034089739_0.5151082894521655","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"_id":"x-api-mcp@0.2.1","bin":{"x-api-mcp":"dist/index.js"},"bugs":{"url":"https://github.com/fatwang2/x-api-mcp/issues"},"dist":{"shasum":"129812f112da49d09cc286de206ab8b6e6f595c9","tarball":"https://registry.npmjs.org/x-api-mcp/-/x-api-mcp-0.2.1.tgz","fileCount":16,"integrity":"sha512-sZmEs5Z9suiu4FAnxapIlIPV+e2FgisP/kFvMSex9qUMqGIPBcqFLSYLnVz9CXJsvqVgQrvyDX58aVFq1iZUtg==","signatures":[{"sig":"MEYCIQDEtWUB5i9iidG27SRqHT/rR5vg5loRq+JOAr1pAQwWUAIhAK+tU00CGRYeVV6xpxLZ+71LA/1Jc/OuWhU53fYUfL++","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDmXU8jlr6/A9e0WLqDIPh9EjrnrHw0xWBCQGD7Z4gaQQIhAKBOsycEkYEQptOjo1cpto4HSm0/SahzBJmnj9ZM8APc"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/x-api-mcp@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":90136},"name":"x-api-mcp","type":"module","author":{"name":"fatwang2"},"engines":{"node":">=20"},"gitHead":"a630896a13cfffeda8da0b2340f2800f7106fc26","license":"MIT","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"npm run build && node --test --test-timeout=30000 test/*.test.mjs","build":"tsc -p tsconfig.json && chmod +x dist/index.js","start":"node dist/index.js","version":"node scripts/sync-version.mjs && git add src/version.ts plugin.json .claude-plugin/plugin.json mcp.json .mcp.json","prepublishOnly":"npm test"},"version":"0.2.1","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"5e3cc801-c725-484b-bd05-431f03b2109b"}},"homepage":"https://github.com/fatwang2/x-api-mcp#readme","keywords":["mcp","x","twitter","x-api","oauth2","model-context-protocol"],"repository":{"url":"git+https://github.com/fatwang2/x-api-mcp.git","type":"git"},"_npmVersion":"11.19.0","description":"Local stdio MCP server for the official X API: multi-account posting, threads, media upload. Tokens never leave your machine.","directories":{},"maintainers":[{"name":"fatwang2","email":"wangding0798@gmail.com"}],"_nodeVersion":"24.21.0","dependencies":{"zod":"^3.25.76","@modelcontextprotocol/sdk":"^1.32.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^22.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/x-api-mcp_0.2.1_1792034759501_0.13350322743768062"}}},"time":{"created":"2026-10-15T03:13:54.378Z","modified":"2026-10-15T03:25:59.958Z","0.0.0-stage":"2026-10-15T03:13:54.378Z","0.2.0":"2026-10-15T03:14:49.822Z","0.2.1":"2026-10-15T03:25:59.594Z"},"bugs":{"url":"https://github.com/fatwang2/x-api-mcp/issues"},"author":{"name":"fatwang2"},"license":"MIT","homepage":"https://github.com/fatwang2/x-api-mcp#readme","keywords":["mcp","x","twitter","x-api","oauth2","model-context-protocol"],"repository":{"url":"git+https://github.com/fatwang2/x-api-mcp.git","type":"git"},"description":"Local stdio MCP server for the official X API: multi-account posting, threads, media upload. Tokens never leave your machine.","maintainers":[{"name":"fatwang2","email":"wangding0798@gmail.com"}],"readme":"# x-api-mcp\n\nA **local stdio MCP server** for the official X API v2, built around multi-account posting: posts, replies, threads, deletes, and image/GIF/video uploads (including chunked upload). It also covers likes, reposts, bookmarks, follows, timelines, search, DMs, Lists and trends.\n\nX's official remote MCP server can't post. This project fills that gap.\n\n## Why stdio\n\nThe server runs on your own machine, launched by your MCP client (Claude Desktop, Claude Code, Cursor, ...) as a child process. OAuth and access/refresh tokens stay in `~/.x-api-mcp/tokens.json` (mode 0600) and never pass through a third-party server.\n\n## Create an X App\n\nEach user brings their own X App, and API usage is billed to that App's credits.\n\n1. Create an App at [console.x.com](https://console.x.com) and add pay-per-use credits.\n2. Under **User authentication settings**:\n   - App permissions: **Read and write** (add **Direct Messages** if you want DM tools)\n   - Type of App: **Native App** (public client, no secret needed, recommended). A Web App also works; set `X_CLIENT_SECRET` as well.\n   - Callback URI: `http://127.0.0.1:8765/callback` (must exactly match `X_REDIRECT_URI`)\n3. Copy the OAuth 2.0 **Client ID**.\n\n## Install\n\n### As a Claude plugin\n\n```\n/plugin install x-api-mcp --marketplace fatwang2/x-api-mcp\n```\n\nThe plugin bundles the MCP server and a skill that tells the agent how to use it safely (confirm before acting, always name the account, mind the costs, how to authorize). It asks for your Client ID and a few options when enabled. Hosts that don't prompt for plugin settings can call `set_client_id` instead.\n\n### As a plain MCP server\n\nClaude Desktop / Cursor (`claude_desktop_config.json` / `.cursor/mcp.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"x\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"x-api-mcp\"],\n      \"env\": { \"X_CLIENT_ID\": \"your-client-id\", \"X_REQUIRE_ACCOUNT\": \"1\" }\n    }\n  }\n}\n```\n\nClaude Code:\n\n```bash\nclaude mcp add x -e X_CLIENT_ID=your-client-id -- npx -y x-api-mcp\n```\n\nThe Client ID can also be saved once with `npx x-api-mcp config --client-id your-client-id` or from chat with the `set_client_id` tool. It is stored in `~/.x-api-mcp/app.json`, and `X_CLIENT_ID` wins when both are set.\n\nThe agent guidance lives in [`skills/x-api-mcp/SKILL.md`](skills/x-api-mcp/SKILL.md). The `plugin.json` and `mcp.json` at the repository root describe the same bundle for hosts that use the agent-plugins format.\n\n## Authorize accounts\n\nCall `add_account` from chat (or run `npx x-api-mcp login` in a terminal) and open the returned URL. Repeat to add more accounts. How the callback comes back depends on where the browser is:\n\n- **Loopback** (browser on the same computer as the server): a listener on `127.0.0.1:8765` saves the token automatically.\n- **Paste** (browser on another device, as with chat bots, remote agents or SSH): after approving, the browser lands on an error page at `http://127.0.0.1:8765/callback?...`. Copy that full URL and paste it back right away; the agent passes it to `complete_authorization`. X codes expire about 30 seconds after approval.\n\n`X_AUTH_MODE=auto` (the default) uses paste over SSH and loopback otherwise. Set `X_AUTH_MODE=paste` explicitly for chat-bot hosts.\n\nThe first authorized account becomes the default. Set `X_REQUIRE_ACCOUNT=1` to make every write name its account, which is recommended with several accounts. Access tokens are refreshed automatically. X rotates refresh tokens, so concurrent refreshes from several MCP processes are serialized with a file lock.\n\n## Tools\n\nEndpoints are grouped by action rather than one tool per endpoint, so agents can choose easily. `X_TOOLS=write` registers only the account and write tools; DM tools appear only with `X_ENABLE_DM=1`. Every tool takes an optional `account` (defaults to the default account). Users can be given as `@username`, `username` or a numeric ID.\n\n| Group | Tool | What it does |\n| --- | --- | --- |\n| Accounts | `set_client_id` `list_accounts` `add_account` `auth_status` `complete_authorization` `set_default_account` `remove_account` | App setup, multi-account OAuth and management; local except for the OAuth exchange |\n| | `get_me` | Profile of the authorized account (read) |\n| Posting | `create_post` | Post, reply, quote, poll, attach media (local files can be passed directly) |\n| | `create_thread` | Publish a thread in order; stops at the first failure and returns what was posted |\n| | `delete_post` | Delete a post |\n| | `post_action` | like / unlike / repost / unrepost / bookmark / unbookmark / hide_reply / unhide_reply |\n| Media | `upload_media` `get_media_status` | Images up to 5 MB in one request; GIFs, videos and large files via chunked upload, waiting for processing; optional alt text |\n| Reading | `search` | `type=posts` searches the last 7 days, `type=users` searches accounts |\n| | `get_posts` | Look up posts by ID |\n| | `get_timeline` | home / posts / mentions / liked / bookmarks |\n| | `get_post_engagement` | Liking users / reposted by / quote posts |\n| Users | `get_users` | Look up profiles by username or ID |\n| | `get_user_relations` | followers / following, plus your own muting / blocking lists |\n| | `user_action` | follow / unfollow / mute / unmute / block / unblock |\n| DMs | `send_dm` `get_dm_events` | Send a DM to a user or conversation (with media) / read DMs. Only with `X_ENABLE_DM=1` |\n| Lists | `list_action` `get_lists` | Create, update, delete Lists and manage members / read owned Lists, List info, members and posts |\n| Trends | `get_trends` | Personalized trends |\n\nAlmost every call is billed per use; see the [pricing page](https://docs.x.com/x-api/getting-started/pricing) and your console for current rates. Posts containing a URL cost noticeably more. X documents `quote_post_id` and blocking as Enterprise-only.\n\nBy default authorization requests every scope these tools use except DM scopes, because an App without Direct Messages permission rejects the whole request when they are asked for. If an account was authorized with fewer scopes, calls that need a missing scope fail before reaching X with a hint to run `add_account` again.\n\nNot covered: Spaces, bookmark folders, DM deletion, streaming endpoints, Ads and compliance endpoints.\n\n## Environment variables\n\n| Variable | Default | Notes |\n| --- | --- | --- |\n| `X_CLIENT_ID` | none | Your App's Client ID. Can be saved with `set_client_id` instead |\n| `X_CLIENT_SECRET` | none | Only for Web Apps (confidential clients) |\n| `X_AUTH_MODE` | `auto` | `loopback`, `paste`, or `auto` (paste over SSH) |\n| `X_TOOLS` | `all` | `write` registers only account and write tools; `read` only account and read tools |\n| `X_REQUIRE_ACCOUNT` | off | `1` makes write tools refuse calls without `account` |\n| `X_ENABLE_DM` | off | `1` requests `dm.read dm.write` and registers the DM tools. The App needs Direct Messages permission |\n| `X_REDIRECT_URI` | `http://127.0.0.1:8765/callback` | Must match the App settings |\n| `X_SCOPES` | All non-DM scopes the tools use (see `src/config.ts`) | Set to narrow permissions |\n| `X_API_MCP_HOME` | `~/.x-api-mcp` | Storage directory for tokens and the saved Client ID |\n| `X_DEFAULT_ACCOUNT` | none | Used when no default account is set locally |\n\n## CLI\n\n```\nx-api-mcp                       Run the MCP server on stdio\nx-api-mcp config --client-id <id> [--client-secret <s>]\n                                Save your App's Client ID locally\nx-api-mcp login                 Authorize a new account in the browser\nx-api-mcp accounts              List accounts (* marks the default)\nx-api-mcp default <username>    Set the default account\nx-api-mcp logout <username>     Remove an account and revoke its tokens\nx-api-mcp post [--account a] <text>   Publish a quick test post\n```\n\n## Development\n\n```bash\nnpm install\nnpm test   # builds, then runs end-to-end tests against a local mock of the X API\n```\n\nThe tests cover OAuth (loopback and paste), refresh-token rotation, the concurrency lock, threads, chunked upload, interactions, DMs, tool-group switches and the stdio protocol. Validate the plugin bundle with `claude plugin validate .`.\n\nLayout: `src/oauth.ts` (PKCE and token endpoint), `src/auth.ts` (authorization flow and loopback callback), `src/store.ts` (token file and lock), `src/client.ts` (API client with auto refresh and scope checks), `src/posts.ts` (posting), `src/social.ts` (interactions, relationships, timelines, DMs, Lists), `src/shape.ts` (response trimming), `src/media.ts`, `src/server.ts` (MCP tool registration), `src/index.ts` (entry point and CLI).\n\n## Releasing\n\nReleases are published by GitHub Actions when a version tag is pushed:\n\n```bash\nnpm version patch          # or minor / major; also updates the version pinned in the plugin files\ngit push --follow-tags\n```\n\n`.github/workflows/release.yml` checks that the tag matches `package.json`, runs the tests, publishes to npm with provenance and creates a GitHub release. It runs in the `npm` GitHub environment and authenticates with [npm trusted publishing](https://docs.npmjs.com/trusted-publishers) (GitHub repository `fatwang2/x-api-mcp`, workflow `release.yml`, environment `npm`), so no npm token is stored. A version that is already on npm is skipped.\n\n## Privacy Policy\n\nx-api-mcp runs entirely on your computer. It has no server of its own and the author collects no data.\n\n- **What it stores:** your X App's Client ID (and secret, if you use one) in `~/.x-api-mcp/app.json`, and OAuth access and refresh tokens plus basic account details (username, user ID, display name, granted scopes) in `~/.x-api-mcp/tokens.json`. Both files are readable only by your user account (mode 0600). Nothing else is stored.\n- **Where data goes:** requests go directly from your computer to the X API (`api.x.com`) and X's OAuth pages, using your own App. Post text, media files, DMs and other content you ask the agent to send are transmitted only to X. No analytics or telemetry are collected.\n- **Third parties:** your use of the X API is governed by the [X Developer Agreement and Policy](https://developer.x.com/en/developer-terms) and [X's Privacy Policy](https://x.com/en/privacy). Content returned by the tools is passed to the AI agent you run them in, under that agent provider's terms.\n- **Removal:** `remove_account` (or `x-api-mcp logout <username>`) revokes an account's tokens at X and deletes them locally. Deleting `~/.x-api-mcp` removes everything.\n- **Contact:** open an issue at https://github.com/fatwang2/x-api-mcp/issues.\n\n## References\n\n- [OAuth 2.0 PKCE](https://docs.x.com/fundamentals/authentication/oauth-2-0/authorization-code), [Create Post](https://docs.x.com/x-api/posts/create-post), [Chunked media upload](https://docs.x.com/x-api/media/quickstart/media-upload-chunked)\n- [xdevplatform/xurl](https://github.com/xdevplatform/xurl), [xdevplatform/xmcp](https://github.com/xdevplatform/xmcp)\n- [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)\n\n## License\n\nMIT\n","readmeFilename":"README.md"}