flarum-mcp
by ReverserID
README.md
# flarum-mcp
An [MCP](https://modelcontextprotocol.io) server for **Flarum** forums. It lets
any MCP client (Claude Code, Claude Desktop, …) search, read, and post
discussions through Flarum's REST/JSON:API. Read tools need no auth; write tools
use a personal access token. Ships preconfigured for [reverser.id](https://reverser.id).
## Tools
| Tool | Auth | What it does |
| --- | --- | --- |
| `list_tags` | – | List categories/labels with id, slug, description, count |
| `search_discussions` | – | Full-text search discussions |
| `recent_discussions` | – | Most recently active discussions |
| `discussions_by_tag` | – | Discussions under a tag slug (e.g. `malware-analysis`) |
| `get_discussion` | – | Read a discussion + its posts as plain text |
| `create_discussion` | token | Start a new discussion (needs ≥1 tag id); optional `attachments` |
| `reply_to_discussion` | token | Reply to an existing discussion; optional `attachments` |
| `upload_file` | token | Upload an image/file (local path or URL) → embed snippet |
| `get_post` | – | Read a single post + permalink |
| `whoami` | token | Show which user the credentials authenticate as |
| `search_users` | token | Find users by username/name |
| `like_post` | token | Like / unlike a post |
| `subscribe_discussion` | token | Follow / ignore a discussion |
| `edit_post` | token | Replace a post's content |
| `rename_discussion` | token | Change a discussion's title |
| `set_tags` | token | Replace a discussion's tags |
| `sticky_discussion` | token | Pin / unpin a discussion |
| `lock_discussion` | token | Lock / unlock a discussion |
| `delete_discussion` | token | Delete a discussion (irreversible) |
| `delete_post` | token | Delete a post (irreversible) |
`create_discussion` and `reply_to_discussion` accept an optional `attachments`
array of local file paths or `http(s)` URLs — each is uploaded and embedded in
the post (images render inline, other files as download links). Uploading
requires the [`fof/upload`](https://github.com/FriendsOfFlarum/upload) extension
enabled on the forum.
## Configuration
| Env var | Required | Default |
| --- | --- | --- |
| `FLARUM_BASE_URL` | no | `https://reverser.id` |
| `FLARUM_USERNAME` (or `FLARUM_EMAIL`) | write tools | – |
| `FLARUM_PASSWORD` | write tools | – |
| `FLARUM_API_TOKEN` | optional alternative to the above | – |
Auth is only needed for the **write** tools (`create_discussion`,
`reply_to_discussion`); read tools work anonymously.
The recommended way is to just give it a **username/email + password** — the
server logs in for you via `POST /api/token` and caches the token for the life
of the process, so you never mint one by hand:
```json
"env": {
"FLARUM_BASE_URL": "https://reverser.id",
"FLARUM_USERNAME": "your-username",
"FLARUM_PASSWORD": "your-password"
}
```
Prefer not to store a password? Supply a ready-made token instead (takes
precedence if set):
```bash
curl -s https://reverser.id/api/token -H 'Content-Type: application/json' \
-d '{"identification":"USERNAME_OR_EMAIL","password":"PASSWORD"}'
# -> {"token":"xxxxxxxxxxxx...","userId":1}
# then set FLARUM_API_TOKEN to that value
```
> Legacy `REVERSER_*` names (`REVERSER_BASE_URL`, `REVERSER_USERNAME`,
> `REVERSER_PASSWORD`, `REVERSER_API_TOKEN`) are still read as fallbacks.
## Use with Claude Code
Once published, no install needed — run it with `npx`:
```bash
claude mcp add flarum-mcp \
--env FLARUM_BASE_URL=https://reverser.id \
--env FLARUM_USERNAME=your-username \
--env FLARUM_PASSWORD=your-password \
-- npx -y flarum-mcp
```
Or a project-local `.mcp.json`:
```json
{
"mcpServers": {
"flarum-mcp": {
"command": "npx",
"args": ["-y", "flarum-mcp"],
"env": {
"FLARUM_BASE_URL": "https://reverser.id",
"FLARUM_USERNAME": "your-username",
"FLARUM_PASSWORD": "your-password"
}
}
}
}
```
## Use with Claude Desktop
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"flarum-mcp": {
"command": "npx",
"args": ["-y", "flarum-mcp"],
"env": {
"FLARUM_BASE_URL": "https://reverser.id",
"FLARUM_USERNAME": "your-username",
"FLARUM_PASSWORD": "your-password"
}
}
}
}
```
## Local development
```bash
git clone https://github.com/ReverserID/flarum-mcp.git
cd flarum-mcp
npm install # runs the build via the "prepare" script
npm start # node build/index.js
```
Quick manual test — handshake + `list_tags` over stdio, no client needed:
```bash
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"t","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_tags","arguments":{}}}' \
| node build/index.js
```
## Layout
```
flarum-mcp/
├── src/
│ ├── index.ts # MCP server + tool definitions
│ └── flarum.ts # tiny Flarum JSON:API client + helpers
├── package.json
├── tsconfig.json
├── .env.example
└── LICENSE
```
## Notes
- stdio transport uses stdout for the protocol — the server only ever logs to
**stderr**. Keep it that way if you extend it.
- Extend with more tools (likes, flags, user lookup, notifications) by following
the same `server.registerTool(...)` pattern.
## License
MIT © ReverserID
TDQS
A3.8/5.0
Scored across 7 tools
Disambiguation5/5
Each tool targets a distinct action or query (create, list-by-tag, get, list-tags, recent, reply, search) with no overlap in functionality.
Naming Consistency4/5
Most tools follow verb_noun pattern with snake_case, but 'discussions_by_tag' and 'recent_discussions' deviate slightly (preposition, adjective-first) from the dominant pattern.
Tool Count4/5
7 tools is a reasonable count for a forum MCP, covering essential operations without being too sparse or bloated.
Completeness4/5
Covers create, read (by ID, by tag, recent, search), and reply; missing update and delete capabilities, but core read/write workflows are present.
Maintenance
ActivityStale
ResponsivenessNo issues