{"_id":"@0x50b/mcp-twitterapi","_rev":"4-6c855d88ecdb62a3b97efedebe740a02","name":"@0x50b/mcp-twitterapi","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@0x50b/mcp-twitterapi","version":"0.1.0","keywords":["mcp","model-context-protocol","claude","anthropic","twitter","x","tweets","twitterapi","twitterapi.io"],"author":{"name":"0x50b","email":"0x50b@proton.me"},"license":"MIT","_id":"@0x50b/mcp-twitterapi@0.1.0","maintainers":[{"name":"0x50b","email":"ryowa@boom.haus"}],"homepage":"https://github.com/designoor/mcp-twitterapi#readme","bugs":{"url":"https://github.com/designoor/mcp-twitterapi/issues"},"bin":{"mcp-twitterapi":"dist/index.js"},"dist":{"shasum":"a1ea9cbef799e6e6733fb74b05cc3717cae73322","tarball":"https://registry.npmjs.org/@0x50b/mcp-twitterapi/-/mcp-twitterapi-0.1.0.tgz","fileCount":9,"integrity":"sha512-LBhCTSbW+tZHUEYegYeisg7Wyz5qb7tK2uLoDfsNv0zin7qORJEfIceW2PdGP66kz9KeUf0KCrvL0rhaIwilaw==","signatures":[{"sig":"MEUCIC4fJ8cUdZMppbkOKhZwcHqohshHzc/XgiGpd9uiZL0/AiEArc9B28rF/dVMv6a1gOb/jlqqoviuxp07247u2Ixguko=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39179},"type":"module","_from":"file:0x50b-mcp-twitterapi-0.1.0.tgz","engines":{"node":">=20"},"scripts":{"dev":"tsx src/index.ts","test":"vitest run","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"0x50b","email":"ryowa@boom.haus"},"_resolved":"/private/var/folders/5h/18f8dgm14y31rrtxn2t93m_w0000gn/T/139dc9e009edbc1447ba4d05e86bc3fb/0x50b-mcp-twitterapi-0.1.0.tgz","_integrity":"sha512-LBhCTSbW+tZHUEYegYeisg7Wyz5qb7tK2uLoDfsNv0zin7qORJEfIceW2PdGP66kz9KeUf0KCrvL0rhaIwilaw==","repository":{"url":"git+https://github.com/designoor/mcp-twitterapi.git","type":"git"},"_npmVersion":"11.2.0","description":"MCP server for fetching tweets from a specific X (Twitter) user via twitterapi.io.","directories":{},"_nodeVersion":"22.11.0","dependencies":{"zod":"^3.23.8","@modelcontextprotocol/sdk":"^1.0.4"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.0","vitest":"^2.1.0","typescript":"^5.5.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-twitterapi_0.1.0_1777046275271_0.7878078693404929","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@0x50b/mcp-twitterapi","version":"0.1.1","keywords":["mcp","model-context-protocol","claude","anthropic","twitter","x","tweets","twitterapi","twitterapi.io"],"author":{"name":"0x50b","email":"0x50b@proton.me"},"license":"MIT","_id":"@0x50b/mcp-twitterapi@0.1.1","maintainers":[{"name":"0x50b","email":"ryowa@boom.haus"}],"homepage":"https://github.com/designoor/mcp-twitterapi#readme","bugs":{"url":"https://github.com/designoor/mcp-twitterapi/issues"},"bin":{"mcp-twitterapi":"dist/index.js"},"dist":{"shasum":"5d46aee32274166850497cd4df1ccb132e91063e","tarball":"https://registry.npmjs.org/@0x50b/mcp-twitterapi/-/mcp-twitterapi-0.1.1.tgz","fileCount":9,"integrity":"sha512-0rDj7eK4T8R7ZSJr/IS8CcTx1lUWNZoGGXwL7hb40Zg9wxxo3pxBpk2DkB4tESQim6enHUWzdLbjreCRjvVX1A==","signatures":[{"sig":"MEUCIQDBpGTpH2f5MPHV+K/syjcHZfyBlAr3aFGpc+9XIHS/bAIgXzFgZoKeaaqxsaGsRAjXY08tButgJsQ/eDzLi/ov1EU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38966},"type":"module","_from":"file:0x50b-mcp-twitterapi-0.1.1.tgz","engines":{"node":">=20"},"scripts":{"dev":"tsx src/index.ts","test":"vitest run","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"0x50b","email":"ryowa@boom.haus"},"_resolved":"/private/var/folders/5h/18f8dgm14y31rrtxn2t93m_w0000gn/T/e0b39ea6f6c17379364da031ffa02570/0x50b-mcp-twitterapi-0.1.1.tgz","_integrity":"sha512-0rDj7eK4T8R7ZSJr/IS8CcTx1lUWNZoGGXwL7hb40Zg9wxxo3pxBpk2DkB4tESQim6enHUWzdLbjreCRjvVX1A==","repository":{"url":"git+https://github.com/designoor/mcp-twitterapi.git","type":"git"},"_npmVersion":"11.2.0","description":"MCP server for fetching tweets from a specific X (Twitter) user via twitterapi.io.","directories":{},"_nodeVersion":"22.11.0","dependencies":{"zod":"^3.23.8","@modelcontextprotocol/sdk":"^1.0.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.0","vitest":"^2.1.0","typescript":"^5.5.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-twitterapi_0.1.1_1777101930870_0.4856315140992069","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@0x50b/mcp-twitterapi","version":"0.2.0","keywords":["mcp","model-context-protocol","claude","anthropic","twitter","x","tweets","twitterapi","twitterapi.io"],"author":{"name":"0x50b","email":"0x50b@proton.me"},"license":"MIT","_id":"@0x50b/mcp-twitterapi@0.2.0","maintainers":[{"name":"0x50b","email":"ryowa@boom.haus"}],"homepage":"https://github.com/designoor/mcp-twitterapi#readme","bugs":{"url":"https://github.com/designoor/mcp-twitterapi/issues"},"bin":{"mcp-twitterapi":"dist/index.js"},"dist":{"shasum":"369c80004ed41845ad7f61676ca7879802d693a0","tarball":"https://registry.npmjs.org/@0x50b/mcp-twitterapi/-/mcp-twitterapi-0.2.0.tgz","fileCount":9,"integrity":"sha512-inlHnopx3RHf2aKt52zoh4p6VyhPC3u2OQOecSeW8EUpe4kMBI7oUqz0riJanoV70ITTJsE4kbVvNSIJnOF4yg==","signatures":[{"sig":"MEYCIQDP3EDpNwKsqoZGbSRv0frYgek9Gy/HVTUH0Nf/M3vtIQIhAJfRHZKd+QqvZF8zvrOGmMSysxYQnjfzVN/XjXnEI6Z8","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42772},"type":"module","_from":"file:0x50b-mcp-twitterapi-0.2.0.tgz","engines":{"node":">=20"},"scripts":{"dev":"tsx src/index.ts","test":"vitest run","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"0x50b","email":"ryowa@boom.haus"},"_resolved":"/private/var/folders/5h/18f8dgm14y31rrtxn2t93m_w0000gn/T/c9db3d5a729a76a53229a86d89bb9f48/0x50b-mcp-twitterapi-0.2.0.tgz","_integrity":"sha512-inlHnopx3RHf2aKt52zoh4p6VyhPC3u2OQOecSeW8EUpe4kMBI7oUqz0riJanoV70ITTJsE4kbVvNSIJnOF4yg==","repository":{"url":"git+https://github.com/designoor/mcp-twitterapi.git","type":"git"},"_npmVersion":"11.2.0","description":"MCP server for fetching tweets from a specific X (Twitter) user via twitterapi.io.","directories":{},"_nodeVersion":"22.11.0","dependencies":{"zod":"^3.23.8","@modelcontextprotocol/sdk":"^1.0.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.0","vitest":"^2.1.0","typescript":"^5.5.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-twitterapi_0.2.0_1777196818342_0.18630916166243772","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@0x50b/mcp-twitterapi","version":"0.3.0","description":"MCP server for fetching tweets from a specific X (Twitter) user via twitterapi.io.","license":"MIT","author":{"name":"0x50b","email":"0x50b@proton.me"},"repository":{"type":"git","url":"git+https://github.com/designoor/mcp-twitterapi.git"},"homepage":"https://github.com/designoor/mcp-twitterapi#readme","bugs":{"url":"https://github.com/designoor/mcp-twitterapi/issues"},"keywords":["mcp","model-context-protocol","claude","anthropic","twitter","x","tweets","twitterapi","twitterapi.io"],"type":"module","bin":{"mcp-twitterapi":"dist/index.js"},"publishConfig":{"access":"public"},"engines":{"node":">=20"},"dependencies":{"@modelcontextprotocol/sdk":"^1.0.4","zod":"^3.23.8"},"devDependencies":{"@types/node":"^22.0.0","tsx":"^4.19.0","typescript":"^5.5.0","vitest":"^2.1.0"},"scripts":{"build":"tsc","dev":"tsx src/index.ts","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","start":"node dist/index.js"},"_id":"@0x50b/mcp-twitterapi@0.3.0","_integrity":"sha512-FfURmAV/eUQZiAtSW/JUfmCl3pu54hP+rLOWEnPm+LTolVCSqpSPRidwkIo1MnLFqFL/suevtcpy/6nTKelAtQ==","_resolved":"/private/var/folders/5h/18f8dgm14y31rrtxn2t93m_w0000gn/T/9cbd81846efe1c54521b48ec92305892/0x50b-mcp-twitterapi-0.3.0.tgz","_from":"file:0x50b-mcp-twitterapi-0.3.0.tgz","_nodeVersion":"22.11.0","_npmVersion":"11.2.0","dist":{"integrity":"sha512-FfURmAV/eUQZiAtSW/JUfmCl3pu54hP+rLOWEnPm+LTolVCSqpSPRidwkIo1MnLFqFL/suevtcpy/6nTKelAtQ==","shasum":"a4a28e1adfa2e7a8486ba1b9874cc145b5df1527","tarball":"https://registry.npmjs.org/@0x50b/mcp-twitterapi/-/mcp-twitterapi-0.3.0.tgz","fileCount":9,"unpackedSize":48826,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHs/NX3REH53Dtgi37QQNpJ0hPfiKGE45q4oCvLWS+sNAiB5LQc8g6fn+bfgr0k0HHKl9HSzPkPl1+TKRIBncKxmuA=="}]},"_npmUser":{"name":"0x50b","email":"ryowa@boom.haus"},"directories":{},"maintainers":[{"name":"0x50b","email":"ryowa@boom.haus"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-twitterapi_0.3.0_1779536142265_0.04925672769989409"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-24T15:57:55.155Z","modified":"2026-05-23T11:35:42.556Z","0.1.0":"2026-04-24T15:57:55.493Z","0.1.1":"2026-04-25T07:25:31.033Z","0.2.0":"2026-04-26T09:46:58.532Z","0.3.0":"2026-05-23T11:35:42.449Z"},"bugs":{"url":"https://github.com/designoor/mcp-twitterapi/issues"},"author":{"name":"0x50b","email":"0x50b@proton.me"},"license":"MIT","homepage":"https://github.com/designoor/mcp-twitterapi#readme","keywords":["mcp","model-context-protocol","claude","anthropic","twitter","x","tweets","twitterapi","twitterapi.io"],"repository":{"type":"git","url":"git+https://github.com/designoor/mcp-twitterapi.git"},"description":"MCP server for fetching tweets from a specific X (Twitter) user via twitterapi.io.","maintainers":[{"name":"0x50b","email":"ryowa@boom.haus"}],"readme":"# mcp-twitterapi\n\nA local [MCP](https://modelcontextprotocol.io) server that fetches tweets from a specific X (Twitter) user via [twitterapi.io](https://twitterapi.io).\n\nBuild with \n\n```\n░█░█░█░█░█▀▀░█▀█░█▀▄░▀█▀░░░█▀█░█░░░█░█░█▀▀░▀█▀░█▀█░█▀▀\n░█▀▄░█░█░▀▀█░█▀█░█▀▄░░█░░░░█▀▀░█░░░█░█░█░█░░█░░█░█░▀▀█\n░▀░▀░▀▀▀░▀▀▀░▀░▀░▀░▀░▀▀▀░░░▀░░░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀▀▀\n```\nBuild with [create-mcp@kusari-plugin](https://github.com/kusarixyz/kusari-plugins) skill.\n\n## Requirements\n\n- Node.js 22+\n- A twitterapi.io API key ([get one here](https://twitterapi.io/dashboard))\n\n## Install\n\nThe package is on [npm](https://www.npmjs.com/package/@0x50b/mcp-twitterapi) but you don't have to install it. Using npx is perfectly fine.\n\nAdd to your Claude Desktop config:\n\n| Platform | Config path |\n|---|---|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Claude Code | project-local `.mcp.json` (also set `enableAllProjectMcpServers: true` in `.claude/settings.local.json`) |\n\n```json\n{\n  \"mcpServers\": {\n    \"twitter\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@0x50b/mcp-twitterapi\"],\n      \"env\": {\n        \"TWITTERAPI_IO_API_KEY\": \"your-key-here\"\n      }\n    }\n  }\n}\n```\n\nRestart Claude Desktop fully (⌘Q on macOS, not just close the window).\n\n### Run from a local clone\n\nIf you'd rather run your own checkout (e.g. for a forked version, an unpublished change), build the server first:\n\n```sh\ngit clone https://github.com/designoor/mcp-twitterapi.git\ncd mcp-twitterapi\npnpm install\npnpm build\n```\n\nThen point your client config at the built `dist/index.js` using an **absolute path**:\n\n```json\n{\n  \"mcpServers\": {\n    \"twitter\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/mcp-twitterapi/dist/index.js\"],\n      \"env\": {\n        \"TWITTERAPI_IO_API_KEY\": \"your-key-here\"\n      }\n    }\n  }\n}\n```\n\nRe-run `pnpm build` after any source change, then restart the client.\n\n## Tools\n\n### `fetch_tweets`\n\nFetch tweets from a specific X (Twitter) user via twitterapi.io's advanced search. Combines `from:{username}` with optional time bounds, extra query terms, and content filters. Returns up to `limit` tweets in reverse-chronological order, trimmed to high-signal fields (text, counts, author, quoted/retweeted content, attached media).\n\n#### Parameters\n\n| Param | Type | Default | Description |\n|---|---|---|---|\n| `username` | string | **required** | X handle without `@` |\n| `since` | string | — | ISO 8601 or relative (`30s`, `45m`, `6h`, `2d`, `1w`) |\n| `until` | string | now | ISO 8601 or relative |\n| `limit` | int 1–2000 | `200` | max tweets returned in this call |\n| `query` | string | — | extra terms AND-combined with `from:{username}`; supports quoted phrases and `OR` |\n| `include_retweets` | bool | `true` | when false, appends `-filter:retweets` |\n| `include_quotes` | bool | `true` | when false, appends `-filter:quote` |\n| `include_replies` | bool | `true` | when false, appends `-filter:replies` |\n| `query_type` | `Latest` \\| `Top` | `Latest` | sort order |\n| `lang` | ISO 639-1 | — | e.g. `en`, `es` |\n| `min_faves` | int ≥ 0 | — | minimum like count |\n\n#### Response\n\n| Field | Type | Meaning |\n|---|---|---|\n| `tweets` | array | Trimmed tweet objects in reverse-chronological order |\n| `count` | int | Number of tweets returned |\n| `window` | `{ since, until }` | Resolved absolute bounds of the requested window |\n| `fetched` | `{ newest, oldest }` \\| `null` | Oldest/newest returned tweet timestamps; `null` when `count === 0` |\n| `hasMore` | bool | `false` = window fully fetched. `true` = more exist earlier |\n| `nextCall` | `{ since, until }` \\| `null` | Exact params for the follow-up call when `hasMore: true` |\n| `hint` | string | Human-readable guidance (what was returned, what to do next) |\n| `queryString` | string | Echo of the query sent to twitterapi.io — for debugging |\n\nEach tweet includes `hasMedia` (only when true) and `media[]` with `{type, url, videoUrl?, altText?}`:\n\n| Field | Type | Meaning |\n|---|---|---|\n| `type` | `photo` \\| `video` \\| `animated_gif` | media kind |\n| `url` | string | image URL (photo) or thumbnail/poster (video, gif) |\n| `videoUrl` | string | highest-bitrate mp4 — video and gif only |\n| `altText` | string | author-provided accessibility description, when present |\n\nQuoted and retweeted tweets surface only `hasMedia` (not the full media array) to keep nesting cheap.\n\n#### Response size cap\n\nResponses are capped at ~450KB per call. The server declares `anthropic/maxResultSizeChars: 500000` in its tool metadata so Claude Code honors the 500K-character hard ceiling instead of the default 25K-token cap. When the byte budget trims a call mid-fetch, two extra fields appear:\n\n| Field | Type | Meaning |\n|---|---|---|\n| `fetchedTotal` | int | Tweets fetched before trimming |\n| `droppedForSize` | int | `fetchedTotal − count` (tweets discarded to fit under the cap) |\n\nThe `hint` then spells out the covered timespan and drop count — so you can continue with `nextCall` or lower `limit`.\n\n#### Continuation pattern\n\nWhen a window contains more than `limit` tweets, iterate:\n\n```\nfetch_tweets({ username: \"elonmusk\", since: \"30d\", limit: 200 })\n  → hasMore: true, nextCall: { since: \"...\", until: \"2026-04-15T10:23:00Z\" }\n\nfetch_tweets({ username: \"elonmusk\", since: \"...\", until: \"2026-04-15T10:23:00Z\", limit: 200 })\n  → hasMore: true, nextCall: { ... }\n\n... until hasMore: false.\n```\n\n<details>\n<summary>How pagination works internally</summary>\n\nEach call paginates by **walking the `until` bound backward** — per twitterapi.io's own guidance (their cursor is documented as unreliable). After each API page, the tool narrows `until` to one second before the oldest tweet it just received, queries again, and stops when the API reports no more tweets, when a page yields zero new IDs, or when the caller's `limit` / byte budget is reached. Duplicates are filtered by tweet ID as a safety net for boundary tweets. A pagination safety ceiling of 110 API calls per invocation prevents runaway cost on pathological windows; if it fires, `hasMore` stays `true` and the returned `nextCall` lets you resume from the oldest fetched tweet.\n\n</details>\n\n## Skills\n\nThis repo also ships an optional Claude Code skill, [`fetch-tweets`](skills/fetch-tweets/SKILL.md), that wraps `fetch_tweets` with a `[since, until]` pagination loop and prompt-injection guidance for tweet content. It is not bundled with the MCP server — see [`skills/`](skills/) for what's available and how to copy it into your own skills directory.\n\n## Local development (contributors only)\n\n```bash\ngit clone https://github.com/designoor/mcp-twitterapi.git\ncd mcp-twitterapi\npnpm install\n\npnpm typecheck       # tsc --noEmit\npnpm test            # vitest run\npnpm build           # compiles to dist/\npnpm dev             # runs via tsx without a build step\nTWITTERAPI_IO_API_KEY=... node dist/index.js   # manual stdio run\n```\n\nTo test changes against Claude Desktop locally, point the config at your built `dist/index.js` via its absolute path instead of `npx`.\n","readmeFilename":"README.md"}