Skip to main content
Glama
x-readonly

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.