x-readonly
by bonsko
README.md
# x-readonly
A tiny, read-only MCP server for X/Twitter. Built for feeding news, timelines and
opinions into a local agent without giving it the ability to post anything.
Seven tools, no writes: no `create`, no `like`, no `retweet`, no DMs. The code
only ever calls `search`, `users`, `tweets`, `trends` and `timelines` read paths.
- **One file, no MCP SDK.** `server.mjs` speaks JSON-RPC over stdio directly.
- **Works without an account.** No token → guest mode: profiles and user
timelines read fine. Search, trends and home timelines need a real
`auth_token` (X returns 404 for those GraphQL operations to guests).
- **Nothing is stored.** No database, no cache, no logs of posts.
Powered by [`emusks`](https://www.npmjs.com/package/emusks), a
reverse-engineered X API client. That means it impersonates a browser's TLS
fingerprint — read their caveats and X's terms before you use it, and use an
account you don't mind losing.
## Tools
| tool | what it does |
| --- | --- |
| `search` | search posts; `sort=top` or `latest` (chronological, best for news), cursors, full search operators |
| `user` | profile by `@username`: bio, followers, post count, join date |
| `user_tweets` | recent posts from one account: `tweets`, `replies`, `media`, `originals`, `reposts` |
| `tweet` | a single post by id, with engagement stats |
| `thread` | a post plus its reply thread |
| `trends` | current trending topics (needs auth) |
| `home` | your own Following/For You timeline, `latest` or `home` (needs auth) |
Results come back as compact text — author, timestamp, id, engagement, body
clipped at 600 chars, expanded links, permalink — so a 20-post search costs
about a screen of tokens instead of a wall of JSON.
## Install
```bash
git clone https://github.com/bonsko/x-readonly-mcp
cd x-readonly-mcp
npm install --no-audit --no-fund
```
`npm install` pulls ~142 MB, almost all of it `cycletls` (a bundled Go binary
that does the TLS impersonation). That is the price of the API answering at all.
## Authenticate (optional but needed for search)
The library wants the cookie, not OAuth:
1. sign in to x.com in a browser
2. DevTools → Application → Cookies → `https://x.com` → copy `auth_token`
3. save it:
```bash
umask 077
mkdir -p ~/.config/x-readonly-mcp
cat > ~/.config/x-readonly-mcp/auth.json <<'EOF'
{"auth_token": "PASTE_HERE"}
EOF
chmod 600 ~/.config/x-readonly-mcp/auth.json
```
`X_AUTH_TOKEN` in the environment overrides the file. Without either, the
server runs as a guest.
Note that an `auth_token` is a full-account credential — it can do everything
you can. Use an account you don't care about.
## Register with an MCP client
```json
{
"mcpServers": {
"x-readonly": {
"command": "node",
"args": ["/home/you/x-readonly-mcp/server.mjs"]
}
}
}
```
Claude Desktop, Cursor, Hermes and anything else that speaks stdio MCP take that
shape. Hermes: `hermes mcp add x-readonly --command node --args /path/server.mjs`.
## Limits
- Guest tokens are IP-bound and rate-limited hard; expect 429s on long sessions.
- `users.tweets` returns a full page (~100) regardless of the requested count;
the server trims and reports "showing N of M".
- Search and trends are plain GraphQL reads — X changes query ids without
warning, so a `404` on those means the emusks release needs updating, not that
your token is wrong.
## Licence
MIT. No warranty, no affiliation with X Corp.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues