foolfuuka-mcp-server
by dynmie
README.md
# foolfuuka-mcp-server
MCP server for querying 4chan archives (Desuarchive, 4plebs, b4k, archived.moe) via the [FoolFuuka](https://github.com/FoolCode/FoolFuuka) API. Enables AI agents to search and retrieve historical archived posts through the [Model Context Protocol](https://modelcontextprotocol.io).
## Quick start
```sh
# Run directly (no install needed)
npx foolfuuka-mcp-server
# Or install globally
npm install -g foolfuuka-mcp-server
foolfuuka-mcp-server
```
Add to your MCP client config (Claude Desktop, VS Code, etc.):
```json
{
"mcpServers": {
"foolfuuka": {
"command": "npx",
"args": ["foolfuuka-mcp-server"]
}
}
}
```
## Configuration
| Environment variable | Default | Description |
|---|---|---|
| `FOOLFUUKA_BASE_URL` | `https://desuarchive.org` | Root URL of a FoolFuuka archive |
| `FOOLFUUKA_USER_AGENT` | `foolfuuka-mcp-server/1.0` | User-Agent header sent with API requests |
| `FOOLFUUKA_BOARDS` | none | Comma-separated board shortnames to display (e.g. `"a,g,vr"`). Overrides the default board list. When unset, desuarchive uses a curated subset matching its mirrors; other archives attempt the API then fall back to a full hardcoded list. |
> [!TIP]
> Desuarchive works out of the box. For Cloudflare-protected archives (4plebs, archived.moe), you may need to run the server on a machine with the archive whitelisted, or use a different base URL.
## Tools
### `search_archive`
Full-text search across archived posts with filters.
**Parameters:** `text`, `boards`, `subject`, `username`, `tripcode`, `capcode`, `filename`, `image`, `uid`, `country`, `deleted`, `ghost`, `filter`, `type`, `start`, `end`, `results`, `order`, `page`
Returns a markdown table with **Board**, **Thread**, **Post**, **Date**, **Author**, **Excerpt** columns. OP posts are marked with **(OP)**. Use single-board or multi-board mode depending on the `boards` parameter.
### `get_thread`
Retrieve all posts in a thread.
**Parameters:** `board`, `num`, `latest_doc_id` (incremental), `last_limit` (default 100, pass 0 for all)
Returns the OP post and all replies in formatted markdown with author, timestamp, subject, content, and media attachments.
### `get_post`
Retrieve a single post.
**Parameters:** `board`, `num` (supports `_` suffix for ghost posts, e.g. `"676_1"`)
Returns post details including author, date, board, thread number, subject, content, media (filename, dimensions, size), and image link when present.
### `list_boards`
List available boards for the configured archive.
**Parameters:** none
Returns a markdown table of board shortnames and names, plus site name and search-enabled board count. The board list comes from `FOOLFUUKA_BOARDS` if set, otherwise a desuarchive-curated subset or API response depending on the archive. Boards not in the list still work for search and post lookups.
## Examples
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_archive",
"arguments": { "boards": "a", "text": "kamiina botan", "page": 1 }
}
}
```
Response (single-board):
```markdown
## Search: "kamiina botan" on /a/
Found 25 of 330 matching posts (page 1 of 200, 25 per page)
| Board | Thread | Post | Date | Author | Excerpt |
|-------|--------|------|------|--------|---------|
| /a/ | #288811815 | #288821283 | 2026-06-20 | Anonymous | They say in /au/ that Japanese otakus don't like Kamiina Botan... |
| /a/ | #288749749 | #288763277 | 2026-06-17 | Anonymous | So uh... How about that erm, K-Kamiina Botan? |
| /a/ | #288735782 | #288744910 | 2026-06-16 | Anonymous | Kamiina Botan is the best romance anime of the decade. |
| /a/ | #288692733 | #288705032 | 2026-06-14 | Anonymous | Kamiina Botan the best yuri anime adaptation of all time... |
```
```json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_thread",
"arguments": { "board": "a", "num": 288342508 }
}
}
```
Response:
```markdown
## Thread #288342508 on /a/
**OP** by Anonymous ā 2026-05-26 14:38:49 UTC
**Subject:** Marriagetoxin
> Best girl is here.
>
> Sorry Kinosaki.
š [SubsPlease] MARRIAGETOXIN - 08 (720p) [50718D73].mkv-2026-05-26-10h38m13s978.jpg (1280Ć720, 234 KB)
---
**#288342579** by Anonymous ā 2026-05-26 14:42:24 UTC
> why is Gero spending so much time with Mei on the weekend?
š [SubsPlease] MARRIAGETOXIN - 08 (720p) [50718D73].mkv-2026-05-26-10h42m06s075.jpg (1280Ć720, 244 KB)
---
**#288344069** by Anonymous ā 2026-05-26 16:06:53 UTC
> Genuinely best girl.
---
**#288345985** by Anonymous ā 2026-05-26 17:40:31 UTC
> >>288342508
> In a series of Best Girls, Hamster Lady is absolutely Best Best Girl.
>
> Her main 'attack' is putting on a Carnivale costume and dancing with hamsters!
```
## How it works
The server runs over **stdio transport** ā it reads JSON-RPC messages from stdin and writes responses to stdout. There is no HTTP server.
```
LLM <--MCP stdio--> foolfuuka-mcp-server <--HTTP--> FoolFuuka Archive
```
All responses are formatted as markdown rather than raw JSON, making them natural for LLMs to consume without extra parsing.
## Rate limits
FoolFuuka archives enforce rate limits (e.g., ~5 requests/minute on 4plebs). The server respects `Retry-After` headers on 429 responses and surfaces the wait time to the caller.
## Development
```sh
git clone https://github.com/dynmie/foolfuuka-mcp-server.git
cd foolfuuka-mcp-server
npm install
npm run build
npm test
```
Tests are written with [Vitest](https://vitest.dev) and live in `tests/`.
## License
MIT
TDQS
A4.1/5.0
Scored across 4 tools
Disambiguation5/5
Each tool serves a distinct purpose: global search, thread retrieval, single post retrieval, and board listing, with no functional overlap.
Naming Consistency5/5
All tools follow a consistent verb_noun pattern (search_archive, get_thread, get_post, list_boards), making them predictable.
Tool Count4/5
With only 4 tools, the set is minimal but well-scoped for a read-only archive viewer; slightly underpopulated but not insufficient.
Completeness4/5
Covers all basic read operations (search, thread, post, board list) for the domain; no obvious missing operations for the intended use case.