Skip to main content
Glama
XcrapCC

@xcrap/mcp

Official
by XcrapCC
README.md
# @xcrap/mcp

**Twitter / X tools for LLM agents.** An [MCP](https://modelcontextprotocol.io) server that lets Claude, Cursor, or any other MCP client search posts, read posts and their replies, unroll threads, extract profiles, timelines, account histories and follower lists, list media and check trends on X — **without an X account, an API key, or a login**.

It wraps the public [XCrap](https://xcrap.cc) API. Twelve tools, one per endpoint, stdio transport, no credentials to configure.

---

## Quick start

```bash
npx -y @xcrap/mcp
```

That is the whole installation. The server talks to `https://xcrap.cc`, and there is nothing to configure.

### Claude Code

```bash
claude mcp add xcrap -- npx -y @xcrap/mcp
```

Make it available in every project rather than just this one:

```bash
claude mcp add xcrap --scope user -- npx -y @xcrap/mcp
```

Then check it connected:

```bash
claude mcp list
```

### Claude Desktop

Edit `claude_desktop_config.json` — **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`, **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`, **Linux**: `~/.config/Claude/claude_desktop_config.json` — and add:

```json
{
  "mcpServers": {
    "xcrap": {
      "command": "npx",
      "args": ["-y", "@xcrap/mcp"]
    }
  }
}
```

Restart Claude Desktop. The tools appear under the connectors icon in the prompt box.

### Cursor

Create `.cursor/mcp.json` in the project (or `~/.cursor/mcp.json` for every project):

```json
{
  "mcpServers": {
    "xcrap": {
      "command": "npx",
      "args": ["-y", "@xcrap/mcp"]
    }
  }
}
```

Then enable **xcrap** in *Settings → Tools & Integrations → MCP*.

### Any other MCP client

The server speaks MCP over stdio. Run `npx -y @xcrap/mcp`, or `node /path/to/mcp/src/index.js` from a checkout.

---

## Tools

| Tool | What it does |
| --- | --- |
| `xcrap_get_tweet` | One post by URL or id: text, author, timestamp, metrics, media, poll, quote, community note. |
| `xcrap_get_thread` | Unrolls a whole thread from any post in it, in order, author's posts only. |
| `xcrap_get_user` | A public profile: bio, location, website, join date, verification, follower counts. |
| `xcrap_get_user_tweets` | A page of an account's posts, newest first, cursor-paginated. |
| `xcrap_search` | Full-text search over X posts with X's own operators, latest, top, photos or videos. |
| `xcrap_get_user_history` | Up to 200 of an account's posts in one call, optionally inside a date window. |
| `xcrap_get_replies` | The replies to a post, most liked or newest first (one page, no paging). |
| `xcrap_get_followers` | One page of the accounts following an account, as profiles, cursor-paginated. |
| `xcrap_get_following` | One page of the accounts an account follows, as profiles, cursor-paginated. |
| `xcrap_get_trends` | What is trending on X right now, with post volumes. |
| `xcrap_list_media` | Every image, video and GIF on a post, with dimensions, alt text and direct download URLs. |
| `xcrap_bulk` | Up to 50 posts in a single call — the right tool for a list of links. |

Every tool is read-only. Nothing here posts, likes, follows, or modifies anything on X.

### Examples

Ask your client in plain language — it picks the tool:

- *"Unroll this thread and summarise the argument: https://x.com/jack/status/20"* → `xcrap_get_thread`
- *"What has @NASA posted this week, images only?"* → `xcrap_get_user_tweets` with `media_only: true`
- *"Get me the video from this post"* → `xcrap_list_media`, then hand over the `download_url`
- *"Pull all 30 of these links into one summary"* → `xcrap_bulk` (one call, not thirty)
- *"How many followers does @jack have?"* → `xcrap_get_user`
- *"What are people on X saying about the Starship launch?"* → `xcrap_search` with `feed: "top"`
- *"What are the replies saying about this post?"* → `xcrap_get_replies`
- *"Everything @naval posted in March"* → `xcrap_get_user_history` with `since` and `until`

---

## Configuration

| Variable | Default | Purpose |
| --- | --- | --- |
| `XCRAP_BASE_URL` | `https://xcrap.cc` | API origin. Leave it unset; change it only to route requests through a proxy you control. |

There is no API key. XCrap is free and unauthenticated.

---

## Design notes

**Markdown by default, not JSON.** Every tool that renders posts defaults to `format: "markdown"`, because a tool result is spent directly out of the model's context window and XCrap's markdown rendering of a post is roughly a tenth the size of the same post as JSON — the JSON carries every null metric, every media variant and every entity offset, none of which a summarising model reads. Pass `format: "json"` when you genuinely need field-level access: numeric ids, media URLs, per-metric values. `xcrap_list_media` always returns JSON, because file URLs *are* field-level data.

**Hard 25,000-character cap.** No tool result can exceed it. When a response is cut, the model is told so explicitly, with the reason and the argument to change — a truncated answer that looks complete is worse than an error. Pagination cursors are lifted out before the cut so a truncated timeline can still be continued.

**Errors are instructions, not status codes.** A 404 says the post is deleted, private, or never existed *and that retrying will not help*. A 429 reports the retry-after window and which endpoint budget was hit. A 451 explains that the account opted out of extraction and must not be worked around. A 502 says every upstream source failed and is usually transient.

**Provenance.** XCrap reads from four upstream sources in a cascade and caches for five days. Each result carries a one-line footer saying which source answered and whether it came from cache, so the model knows whether it is looking at live data.

---

## Rate limits

Per IP, enforced by the XCrap instance:

| Endpoint | Budget |
| --- | --- |
| `xcrap_get_tweet`, `xcrap_get_user` | 60 / minute |
| `xcrap_get_thread`, `xcrap_get_user_tweets` | 20 / minute |
| `xcrap_list_media` | 30 / minute |
| `xcrap_bulk` | 10 / 5 minutes (up to 50 posts each) |
| `xcrap_get_replies`, `xcrap_get_followers`, `xcrap_get_following` | 20 / minute |
| `xcrap_get_user_history` | 5 / 5 minutes |
| `xcrap_search` | 15 / 15 minutes |
| `xcrap_get_trends` | 120 / minute |

Prefer one `xcrap_bulk` call over many `xcrap_get_tweet` calls: it is one request instead of N, and it runs them concurrently.

---

## Development

```bash
cd mcp
npm install
npm start                                              # run over stdio
npm run inspect                                        # MCP Inspector UI
npm run check                                          # syntax check
```

Raw stdio round-trip, no client required:

```bash
printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"cli","version":"1.0.0"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
  | node src/index.js
```

Requires Node 20 or newer (built-in `fetch`, no HTTP dependency).

---

## Ethics and limits

XCrap reads only public data, honours account opt-outs (a `451` is final and this server will not route around it), and stores nothing beyond a short cache. It cannot read protected accounts, direct messages, or anything behind a login — and neither can this server.

---

## Links

- XCrap: <https://xcrap.cc> · API docs: <https://xcrap.cc/docs>
- Model Context Protocol: <https://modelcontextprotocol.io>

MIT licensed.

TDQS

A4.6/5.0

Scored across 12 tools

Disambiguation5/5

Every tool targets a distinct retrieval mode: single post, bulk, thread, replies, user timeline/history, profile, followers/following, search, trends, and media. The 'when to use this instead of the alternatives' notes explicitly resolve the few overlapping surfaces, so an agent should not misselect.

Naming Consistency4/5

Nine tools follow the xcrap_get_<resource> pattern and all are lowercase snake_case with the xcrap_ prefix. The exceptions are xcrap_search, xcrap_bulk, and xcrap_list_media, which use bare verbs or list_ instead of get_. Overall the pattern is predictable, just slightly imperfect.

Tool Count5/5

12 tools is squarely in the well-scoped range for a read-only X/Twitter API. Each tool covers a distinct workflow and none feel like filler; the count supports both quick single-post lookups and bulk/history jobs.

Completeness5/5

For its stated purpose of reading X/Twitter public data, the surface is remarkably complete: posts (single, bulk, thread, replies), profiles, timelines, history, followers/following, search, trends, and media. There are no dead ends, and paging/error behavior is described consistently. Optional read surfaces like likes or list timelines are absent but are outside the apparent core scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues