内容
# MCP for Flarum
一个适用于 [Flarum](https://flarum.org) 的 [模型上下文协议](https://modelcontextprotocol.io) 服务器。
它为任何与MCP兼容的AI客户端(Claude Code、Claude Desktop、Cursor、VS Code、Windsurf、Zed等)提供对Flarum论坛API的完全访问权限:读取和搜索讨论和帖子,创建主题和回复,管理用户、标签和分组,审核内容,修改设置,以及调用任何第三方扩展的端点。
> Flarum的整个API都是统一的 [JSON:API](https://jsonapi.org),因此一组小型通用工具涵盖了**全部**表面,包括扩展,而不是数百个手工编写的工具。
## 工具列表
**通用工具(全API覆盖):**
| 工具 | 功能 |
| --- | --- |
| `flarum_list` | 列出/搜索任意资源类型,支持过滤、包含、排序和分页 |
| `flarum_get` | 通过类型和ID获取单个资源 |
| `flarum_create` | 创建任意资源 |
| `flarum_update` | 更新任意资源(也包括锁定/置顶/审核通过) |
| `flarum_delete` | 删除任意资源 |
| `flarum_request` | 任意端点的原始请求入口 |
**便捷工具:**
| 工具 | 功能 |
| --- | --- |
| `flarum_whoami` | 论坛信息 + API密钥所属用户 |
| `flarum_search` | 全文讨论搜索 |
| `flarum_create_discussion` | 创建主题(标题 + 内容 + 可选标签) |
| `flarum_reply` | 回复讨论 |
**官方文档(默认开启):**
搜索和阅读Flarum官方 [2.0 文档](https://docs.flarum.org/2.x/),以便AI可以检查设置、权限、扩展或REST端点的用法。 这些文档仅读取公共文档,不会读取您的论坛或其密钥,因此它们在任何模式下都有效,包括只读模式和无API密钥模式。 它们读取实时文档,因此结果始终反映当前的2.0文档。 可以通过设置`FLARUM_DOCS=0`关闭。
| 工具 | 功能 |
| --- | --- |
| `flarum_docs_search` | 搜索2.0文档;返回带有摘要的排名页面 |
| `flarum_docs_get` | 读取完整的文档页面(按slug、路径或URL) |
| `flarum_docs_list` | 列出/浏览可用的2.0文档页面 |
**扩展管理(需启用,默认关闭):**
仅在设置`FLARUM_EXTENSIONS=1`且论坛安装了官方 [`flarum/extension-manager`](https://github.com/flarum/extension-manager) 时注册。 这些工具驱动服务器上的Composer,因此需要管理员密钥和写入模式。 参见 [管理扩展](#managing-extensions)。
| 工具 | 功能 |
| --- | --- |
| `flarum_ext_search` | 在Packagist上搜索可安装的扩展、语言包或主题 |
| `flarum_ext_why_not` | 对软件包进行兼容性检查(不更改任何内容) |
| `flarum_ext_install` | 安装扩展(可选启用) |
| `flarum_ext_update` | 更新扩展(`soft` 在范围内,或 `hard` 到最新版本) |
| `flarum_ext_remove` | 卸载扩展 |
| `flarum_ext_toggle` | 启用/禁用已安装的扩展(无Composer;即时) |
| `flarum_ext_check_updates` | 检查Packagist上的更新可用性 |
| `flarum_ext_bulk_update` | 批量更新:`minor`、`major`(带有 `dryRun`),或 `global` |
| `flarum_ext_configure_composer` | 读取/设置 `minimum-stability`、存储库或私有注册表身份验证 |
| `flarum_ext_tasks` | 列出安装/更新作业历史和Composer输出(轮询异步作业) |
## 配置
| 变量 | 是否必需 | 描述 |
| --- | --- | --- |
| `FLARUM_URL` | 是 | 论坛基准URL,例如 `https://discuss.example.com` |
| `FLARUM_API_KEY` | 写入/私有数据 | Flarum API密钥(来自 `api_keys` 表)。 没有它,只提供公共读取访问。 |
| `FLARUM_USER_ID` | 可选 | 使用主API密钥时,模拟此用户ID |
| `FLARUM_MODE` | 可选 | `write`(默认)或 `read`。 在 `read` 模式下,服务器拒绝所有变更请求(创建/更新/删除和非GET `flarum_request`)并且隐藏写入工具。 `READ_ONLY=1` 具有相同的效果。 使用它指向一个真实的论坛而不冒修改的风险。 |
| `FLARUM_EXTENSIONS` | 可选 | `1`/`true` 注册扩展管理工具(通过 `flarum/extension-manager` 安装/更新/删除扩展)。 默认关闭;需要写入模式和管理密钥。 参见 [管理扩展](#managing-extensions)。 |
| `FLARUM_DOCS` | 可选 | 默认开启。 设置 `0`/`false`/`off` 以隐藏官方文档工具(`flarum_docs_search`/`get`/`list`)。 它们仅读取公共文档,不会读取您的论坛。 |
| `FLARUM_TIMEOUT` | 可选 | 请求超时(毫秒,默认30000) |
| `FLARUM_USER_AGENT` | 可选 | 重写发送到论坛的 `User-Agent`。 默认值为 `mcp-for-flarum/<version> (+repo url)`。 参见 [Cloudflare或WAF后面](#behind-cloudflare-or-a-waf)。 |
### Cloudflare或WAF后面
许多Flarum论坛位于Cloudflare后面。 一些WAF配置阻止请求,其 `User-Agent` 看起来是脚本化的或空的,返回 **Cloudflare错误1010** (`browser_signature_banned`) 在请求到达Flarum之前。 服务器默认发送一个描述性的、可识别的User-Agent,以解决这个问题,因此常见情况可以直接使用。
如果您的论坛仍然阻止它,请允许列出该工具,而不是放松防火墙:
- **允许列出User-Agent。** 在Cloudflare中,添加一个WAF规则,例如 `User-Agent contains "mcp-for-flarum"` → *跳过* / *允许*。 默认UA是 `mcp-for-flarum/<version> (+https://github.com/linkrobins/mcp-for-flarum)`。
- **或者允许列出服务器IP** (适用于托管/单源部署的最佳做法)。
- **或者设置自定义UA** 为 `FLARUM_USER_AGENT` 以匹配现有的允许规则。
不要通过伪造浏览器User-Agent来解决这个问题:它很脆弱,并且使得流量无法被允许或审计。
### 获取API密钥
Flarum目前没有API密钥的管理员界面。 直接在数据库中创建一个:
```sql
INSERT INTO api_keys (`key`, user_id, created_at)
VALUES (REPLACE(UUID(), '-', ''), 1, NOW());
```
将生成的 `key` 作为 `FLARUM_API_KEY`。 设置 `user_id`(或 `FLARUM_USER_ID`)使密钥模拟该用户,因此其权限与该用户的权限完全相同。
### 管理扩展
设置 `FLARUM_EXTENSIONS=1` 以允许AI安装、更新、删除、启用和禁用扩展。 默认情况下**关闭**,因为它在服务器上运行Composer,可以更改论坛运行的代码,远比编辑内容更强大。 它需要以下所有条件:
- 官方的 [`flarum/extension-manager`](https://github.com/flarum/extension-manager) 已安装并启用在论坛上。
- 写入模式(不是 `FLARUM_MODE=read`)和管理密钥,其用户是**管理员**。
- 服务器可以实际运行Composer:PHP函数 `proc_open` 和 `escapeshellarg` 可用,并且 `vendor/`、`storage/`、`composer.json` 和 `composer.lock` 可写。
长期安装的报告取决于论坛的队列:
- **后台队列** (Redis、数据库等,带有正在运行的工作进程):调用在作业完成时返回。 工具为您轮询管理器的任务列表并返回Composer输出。 如果没有工作进程消耗作业,调用超时并说明,而不是挂起。
- **同步** (`sync` 队列,或管理器的“在后台运行作业”设置关闭):请求阻塞,直到Composer完成并内联返回结果。 非常大的更新可能会导致PHP/网关超时,尽管Composer继续运行。
`flarum_ext_install` 除非您传递 `enable: true`,否则不会启用扩展。 使用 `flarum_ext_why_not` 首先确认软件包与您的Flarum版本兼容。 对于批量或重大更新,请先备份。
**启用可能会破坏论坛。** 管理器拒绝安装扩展程序,其发布的Flarum兼容性与您的版本不匹配,但检查是尽力而为的:它读取最新的稳定版本声明的 `flarum/core` 约束,当Packagist不可达或软件包声明无约束时跳过,并且Composer实际安装的版本可能与检查的版本不同。 因此,扩展程序可能会通过检查,但启用后仍会失败,导致整个站点崩溃(每个页面,包括管理面板和此工具的API,都开始返回500)。 管理器无法为您禁用它:恢复意味着从 `extensions_enabled` 设置中删除扩展程序并手动 `composer remove` 它。 这就是为什么安装默认不启用,为什么在启用不熟悉的扩展程序之前备份值得。
## 安装和运行
使用官方Docker镜像自行托管,或从源代码构建。 (它故意**不**发布到npm。)
### 选项1:Docker(推荐)
对于本地Claude客户端(stdio):
```bash
docker run -i --rm \
-e FLARUM_URL=https://discuss.example.com \
-e FLARUM_API_KEY=xxxxx \
ghcr.io/linkrobins/mcp-for-flarum
```
Claude Code:
```bash
claude mcp add flarum -- docker run -i --rm -e FLARUM_URL=https://discuss.example.com -e FLARUM_API_KEY=xxxxx ghcr.io/linkrobins/mcp-for-flarum
```
Claude Desktop / Cursor / Windsurf(JSON配置):
```json
{
"mcpServers": {
"flarum": {
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "FLARUM_URL", "-e", "FLARUM_API_KEY", "ghcr.io/linkrobins/mcp-for-flarum"],
"env": {
"FLARUM_URL": "https://discuss.example.com",
"FLARUM_API_KEY": "xxxxx"
}
}
}
}
```
### 选项2:从源代码(无Docker)
```bash
git clone https://github.com/linkrobins/mcp-for-flarum.git
cd mcp-for-flarum
npm install && npm run build
FLARUM_URL=https://discuss.example.com FLARUM_API_KEY=xxxxx node dist/index.js
```
然后将客户端的 `command` 指向 `node /absolute/path/to/mcp-for-flarum/dist/index.js`。
### 不想运行任何东西?
Link Robins提供了一个托管的托管版本,无需安装,无需密钥管理,可从Web客户端使用。 参见 [linkrobins.com](https://linkrobins.com)。
## 主机(HTTP传输)
相同的二进制文件可以作为长-lived的Web服务运行在 **Streamable HTTP** 上,因此您可以托管它而不是本地运行。 这就是基于Web的客户端(无法启动本地进程)连接到的内容。
使用 `--http` (或 `MCP_TRANSPORT=http`)以HTTP模式启动:
```bash
FLARUM_URL=https://discuss.example.com \
FLARUM_API_KEY=xxxxx \
MCP_AUTH_TOKEN=a-long-random-secret \
PORT=3000 \
node dist/index.js --http
```
它提供:
- `POST /mcp` — MCP端点(Streamable HTTP,无状态)
- `GET /health` — 负载均衡器/正常运行时间监视器的健康检查
主机特定配置:
| 变量 | 默认值 | 描述 |
| --- | --- | --- |
| `MCP_TRANSPORT` | `stdio` | 设置为 `http` 以运行Web服务(或传递 `--http`) |
| `PORT` | `3000` | HTTP端口 |
| `HOST` | `127.0.0.1` | 绑定地址。 失败关闭:**它拒绝绑定非本地主机地址,除非设置了 `MCP_AUTH_TOKEN`**。 要公开它(例如在Docker中),请设置 `HOST=0.0.0.0` 和令牌。 |
| `MCP_AUTH_TOKEN` | _(无)_ | 如果设置,请求必须发送 `Authorization: Bearer <token>`。 暴露非本地主机接口时需要。 |
| `SNAPSHOT_URL` | _(无)_ | 可选的托管托管钩子。 设置后,服务器在会话中的**第一个写入**之前会发出一个尽力而为的 `POST` 请求,以便可以拍摄恢复点。 失败永远不会阻止写入;对于自托管者,取消设置。 |
| `SNAPSHOT_TOKEN` | `MCP_AUTH_TOKEN` | 发送到 `SNAPSHOT_URL` 的Bearer令牌。 默认值为 `MCP_AUTH_TOKEN`。 |
> 安全:托管实例可以读取、写入和删除其目标论坛的内容。 始终在TLS后面运行它,设置 `MCP_AUTH_TOKEN`(或用自己的身份验证/OAuth代理前端),并为API密钥的用户提供所需的最小权限。 Flarum API密钥保留在服务器端,客户端永远不会暴露。
### Docker(托管模式)
```bash
docker run -p 3000:3000 \
-e MCP_TRANSPORT=http \
-e HOST=0.0.0.0 \
-e FLARUM_URL=https://discuss.example.com \
-e FLARUM_API_KEY=xxxxx \
-e MCP_AUTH_TOKEN=a-long-random-secret \
ghcr.io/linkrobins/mcp-for-flarum
```
`HOST=0.0.0.0` 是必需的,以便发布的端口可访问;服务器仅允许它,因为设置了 `MCP_AUTH_TOKEN`。
或者使用附带的 [`docker-compose.yml`](docker-compose.yml):设置您的值并 `docker compose up -d`。
## 开发
```bash
npm install
npm run build
FLARUM_URL=... FLARUM_API_KEY=... node dist/index.js
```
## 许可证
源代码可用且专有。 版权所有 (c) 2026 Link Robins。 您可以自行托管并为自己的使用而运行;您不得重新分发它或为他人提供托管服务作为托管服务。 Link Robins是唯一允许提供它作为托管服务的实体。 有关完整条款,请参见 [LICENSE](LICENSE)。
## 商标
Flarum是Flarum基金会的商标。 本项目是一个独立项目,它通过API与Flarum合作;它不隶属于Flarum基金会,不受其认可、赞助或支持。