内容
# mattermost-mcp
一个基于 **stdio** 的 Node.js 20 / TypeScript MCP 服务器,封装了官方的 [`@mattermost/client`](https://github.com/mattermost/mattermost/tree/master/webapp/packages/client) Client4(REST v4)。它可以与自托管的 Mattermost 实例进行身份验证,并提供了 **34 种工具**,涵盖消息、频道/团队、用户/存在和文件操作等。默认情况下是安全的,通过可配置的防护层;所有输出都发送到 stdout(MCP 通道),所有日志都发送到 stderr。
> **仅限自托管。** Mattermost Cloud 不暴露此处使用的 REST v4 端点;您需要一个自我管理的 Mattermost 服务器(任何支持 REST v4 的近期版本)。
## 功能
- **3 种身份验证模式** — 个人访问令牌(默认)、用户名/密码(+MFA)、OAuth2(授权码 + PKCE S256,透明令牌刷新)。
- **34 种工具**,涵盖 4 个领域 — 消息(13)、频道和团队(12)、用户和存在(6)、文件(3)。
- **默认安全** — 只读模式(`MM_READ_ONLY`)、破坏性操作防护(`MM_ALLOW_DESTRUCTIVE`)、团队/频道允许列表,以及每个调用的 `confirm: true` 要求,适用于破坏性工具。
- **弹性** — 可配置的请求超时、重试次数,带有指数退避 + 抖动的 `429` / `5xx` / 网络错误。
- **严格验证** — 每个工具输入都使用 Zod 模式验证,然后再进行任何 API 调用。 Mattermost 错误原样显示(状态码 + 消息)。
## 要求
- Node.js ≥ 20
- 一个具有用户账户和凭证(PAT、登录/密码或 OAuth2 应用程序)的自托管 Mattermost 服务器
## 安装
### 全局安装(推荐)
```bash
npm i -g @bryanberger/mattermost-mcp
mattermost-mcp login # 交互式:服务器 URL + 身份验证,保存到配置文件目录
mattermost-mcp status # 验证:打印已验证的身份
```
`login` 验证服务器的凭证并将它们(0600)写入 `$XDG_CONFIG_HOME/mattermost-mcp`(或 `~/.config/mattermost-mcp`)。然后,MCP 服务器会自动获取它们 — 无需环境变量。参见 [CLI](#cli) 和 [使用 `login` 身份验证](#authenticate-with-login)。
### 从源码
```bash
npm install
npm run build
# 二进制文件现在位于 dist/index.js(也可在 bin 字段中作为 mattermost-mcp 使用)
```
## CLI
`mattermost-mcp` 二进制文件既是 MCP 服务器,也是小型管理 CLI:
| 命令 | 描述 |
| ------------------------------- | ----------------------------------------------------------------------- |
| `mattermost-mcp` | 在 stdio 上启动 MCP 服务器(默认 — 这是 MCP 客户端运行的内容)。 |
| `mattermost-mcp login` | 交互式身份验证向导;验证并保存凭证。 |
| `mattermost-mcp login --gitlab` | 浏览器 SSO 登录(GitLab/SAML)— 无需管理员或 PAT。 |
| `mattermost-mcp status` | 使用已解析的配置文件进行身份验证并打印当前身份。 |
| `mattermost-mcp logout` | 删除保存的凭证(和匹配的 OAuth 令牌缓存)。 |
| `mattermost-mcp --help` | 用法。`--version` 打印版本。 |
## 使用 `login` 身份验证
```text
$ mattermost-mcp login
Mattermost 服务器 URL(例如 https://mm.example.com):https://mattermost.example.com
身份验证模式(↑/↓ 移动,Enter 选择):
› pat 粘贴个人访问令牌
password 用户名/电子邮件 + 密码(+ MFA)
oauth2 OAuth2 应用程序 + 浏览器同意
gitlab / SSO 浏览器登录 via GitLab/SAML — 无需管理员
个人访问令牌: ********
✓ 以 @alice 身份登录 https://mattermost.example.com
保存到 ~/.config/mattermost-mcp/credentials.json(模式:pat,0600)
```
模式选择器可使用键盘导航(箭头键 / `j`·`k`,数字跳转,Enter 确认)。当输入不是 TTY 时,它会回退到编号提示。
- **pat** — 保存令牌原样。
- **password** — 交换密码为 **会话令牌** 并保存(永不写入磁盘);重新运行 `login` 时会话过期。
- **oauth2** — 运行浏览器同意流程并缓存 OAuth 令牌(透明刷新)。
- **gitlab / SSO** — 参见下文;也可直接使用 `mattermost-mcp login --gitlab` 选择。
### 浏览器 SSO 登录(GitLab / SAML)
如果服务器的唯一登录是外部 IdP(例如 GitLab),**且您不是管理员**,则 PAT 和 OAuth2 应用程序可能不可用 — 它们需要管理员才能启用的服务器设置。使用浏览器 SSO 登录代替:
```text
$ mattermost-mcp login --gitlab
Mattermost 服务器 URL:https://mattermost.example.com
打开浏览器窗口。 在那里完成 GitLab(或其他 SSO)登录。
✓ 以 @alice 身份登录 https://mattermost.example.com
保存到 ~/.config/mattermost-mcp/credentials.json(模式:pat — 浏览器 SSO 会话令牌,0600)
```
它在 `{server}/login` 处打开浏览器,等待您在该窗口中完成 SSO 登录,然后读取生成的 `MMAUTHTOKEN` 会话 cookie 并将其保存为令牌。标志是提供者无关的(`--sso` 是别名),`gitlab / SSO` 也在 `login` 菜单中提供。
- 使用 **默认浏览器** 当它是基于 Chromium 的(Chrome、Chromium、Brave、Edge、Opera、Vivaldi、Arc、Dia…);否则,它会找到第一个安装的 Chromium 引擎。 使用 `MM_CHROME_PATH=/path/to/browser` 覆盖(puppeteer-core 只能驱动 Chromium 引擎 — 而不是 Safari 或 Firefox)。
- 捕获的令牌是 **会话令牌** — 它在服务器的 SSO 会话长度后过期。 重新运行 `mattermost-mcp login --gitlab` 当调用开始返回 `401`。
- 最干净的长期解决方案:请管理员启用个人访问令牌,然后使用 `login`(pat)。
## 配置
凭证来自两个来源,按优先级顺序:
1. **环境变量** (`MM_*`) — 始终优先;适用于 CI 和 `examples/` MCP 客户端配置文件。
2. **保存的 `login` 凭证** — 匹配的 env 变量缺失时的基准。
在开发过程中,您可以将 env 变量放在项目根目录的 `.env` 文件中,并在运行前导出它们;在生产环境中,直接将它们传递给进程。带有注释的 `.env.example` 示例存放在存储库中。下面每个设置也可以通过 env 配置。
### 环境变量
#### 连接
| 变量 | 必需 | 默认值 | 描述 |
| -------- | -------- | ------- | ----------------------------------------------------------------------------------------- |
| `MM_URL` | **是** | — | 服务器根 URL,无尾随斜杠,无 `/api/v4`(例如 `https://mattermost.example.com`)。 |
#### 身份验证
| 变量 | 必需 | 默认值 | 描述 |
| ------------------- | --------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `MM_AUTH_MODE` | 否 | `pat` | `pat \| password \| oauth2` 之一。 |
| `MM_TOKEN` | 当 `pat` | — | 个人访问令牌(Bearer;无过期)。在系统控制台中启用 → 集成 → 个人访问令牌。 |
| `MM_LOGIN_ID` | 当 `password` | — | 用户名或电子邮件。 |
| `MM_PASSWORD` | 当 `password` | — | 密码。 |
| `MM_MFA_TOKEN` | 否 | — | MFA 一次性代码(仅当帐户强制执行 MFA 时)。 |
| `MM_CLIENT_ID` | 当 `oauth2` | — | OAuth2 应用程序客户端 ID(在系统控制台中注册 → 集成 → OAuth 2.0 应用程序)。 |
| `MM_CLIENT_SECRET` | 当 `oauth2` | — | OAuth2 应用程序客户端密钥。 |
| `MM_OAUTH_REDIRECT` | 否 | `http://127.0.0.1:7000/callback` | 环回重定向 URI(必须以 `http://` 或 `https://` 开头)。 |
#### 防护栏
| 变量 | 必需 | 默认值 | 描述 |
| ---------------------- | -------- | ---------------- | ----------------------------------------------------------------------------------------------------------- |
| `MM_READ_ONLY` | 否 | `false` | `true` 禁用每个写/破坏性工具(它们在调用时硬拒绝;仍在 `tools/list` 中列出)。 |
| `MM_ALLOW_DESTRUCTIVE` | 否 | `false` | 防护破坏性工具;它们还需要每个调用的 `confirm: true`。 |
| `MM_TEAM_ALLOWLIST` | 否 | _(无限制)_ | 团队 ID 的 CSV;拒绝针对团队列表以外的团队的操作。 |
| `MM_CHANNEL_ALLOWLIST` | 否 | _(无限制)_ | 频道 ID 的 CSV;拒绝针对频道列表以外的频道的操作。 |
| `MM_MAX_MESSAGE_LEN` | 否 | `16383` | 在发送之前拒绝超过此长度的消息(Unicode 代码点)。 |
#### 弹性
| 变量 | 必需 | 默认值 | 描述 |
| ----------------------- | -------- | ------- | ----------------------------------------------------------------------------- |
| `MM_REQUEST_TIMEOUT_MS` | 否 | `30000` | 请求超时,单位为毫秒(`0` 禁用)。 |
| `MM_MAX_RETRIES` | 否 | `3` | `429` / `5xx` / 网络错误时的重试次数,带有指数退避 + 抖动。 |
| `MM_RETRY_BASE_MS` | 否 | `500` | 退避基数延迟,单位为毫秒。 |
## 身份验证模式
### pat(默认,推荐)
在 **系统控制台 → 集成 → 个人访问令牌** 中创建个人访问令牌,然后:
```bash
MM_AUTH_MODE=pat
MM_TOKEN=your-personal-access-token
```
无过期;可在任何时候撤销;设置最简单。
### password
```bash
MM_AUTH_MODE=password
MM_LOGIN_ID=your-username-or-email
MM_PASSWORD=your-password
# MM_MFA_TOKEN=123456 # 仅当帐户强制执行 MFA 时
```
服务器调用 `POST /users/login`,捕获响应头中的 `Token` 会话令牌,并自动在 `401` 时重新身份验证。
### oauth2
在 **系统控制台 → 集成 → OAuth 2.0 应用程序** 中注册一个 **机密** OAuth2 应用程序,并使用环回重定向 URI(默认为 `http://127.0.0.1:7000/callback`),然后:
```bash
MM_AUTH_MODE=oauth2
MM_CLIENT_ID=your-client-id
MM_CLIENT_SECRET=your-client-secret
# MM_OAUTH_REDIRECT=http://127.0.0.1:7000/callback # 可选覆盖
```
首次运行时,服务器会打开浏览器进行授权码 + PKCE S256 流。令牌缓存在 `$XDG_CONFIG_HOME/mattermost-mcp`(或 `~/.config/mattermost-mcp`)下,权限为 `0600`,并在之后透明地刷新。
> **注意:** Mattermost OAuth2 没有粒度范围 — 令牌继承授权用户的完全访问权限。
## 工具目录
图例:⚠️ = 写(被 `MM_READ_ONLY=true` 阻止)· 💥 = 破坏性(需要 `MM_ALLOW_DESTRUCTIVE=true` **和** 每个调用的 `confirm: true`)
### 消息(13)
| 工具 | 描述 |
| -------------------- | ----------------------------------------------------------------------------------- |
| `post_message` ⚠️ | 向频道发布消息(可选 `root_id`、`file_ids`、`props`)。 |
| `reply_thread` ⚠️ | 在线程中回复(`root_id`)。 |
| `get_channel_posts` | 分页频道历史记录(`page`/`per_page`,或 `since`/`before`/`after` 游标)。 |
| `get_thread` | 根帖子和所有回复。 |
| `get_post` | 按 ID 获取单个帖子。 |
| `search_posts` | 在团队内全文搜索(`terms`、`is_or_search`)。 |
| `edit_post` ⚠️ | 更新帖子的消息(补丁 — 仅消息字段)。 |
| `delete_post` 💥 | 删除帖子。 |
| `send_dm` ⚠️ | 打开/获取 DM(2 用户)或群 DM(3-8 用户)并发布消息。 |
| `pin_post` ⚠️ | 置顶帖子。 |
| `unpin_post` ⚠️ | 取消置顶帖子。 |
| `add_reaction` ⚠️ | 添加表情反应(作为经过身份验证的用户)。 |
| `remove_reaction` ⚠️ | 删除表情反应。 |
### 频道和团队(12)
| 工具 | 描述 |
| ---------------------- | ----------------------------------------------- |
| `list_teams` | 用户所属的团队。 |
| `list_channels` | 团队中的用户频道。 |
| `get_channel` | 频道元数据。 |
| `create_channel` ⚠️ | 创建公共(`O`)或私有(`P`)频道。 |
| `join_channel` ⚠️ | 加入频道(自己)。 |
| `leave_channel` ⚠️ | 离开频道(自己)。 |
| `archive_channel` 💥 | 存档(软删除)频道。 |
| `list_channel_members` | 频道的成员(分页)。 |
| `add_member` ⚠️ | 将另一个用户添加到频道。 |
| `remove_member` 💥 | 从频道中删除另一个用户。 |
| `get_unreads` | 团队的每个频道的未读/提及计数。 |
| `mark_channel_read` ⚠️ | 将频道标记为已查看。 |
### 用户和存在(6)
| 工具 | 描述 |
| ---------------------- | ---------------------------------------------------- |
| `get_me` | 已认证的用户。 |
| `get_user` | 按 ID 或用户名获取用户(只需一个)。 |
| `search_users` | 按术语搜索用户。 |
| `get_user_status` | 用户的状态(`online`/`away`/`dnd`/`offline`)。 |
| `set_status` ⚠️ | 设置自己的状态(`online \| away \| offline \| dnd`)。 |
| `set_custom_status` ⚠️ | 设置自己的自定义状态(表情 + 文本)。 |
### 文件(3)
| 工具 | 描述 |
| ------------------- | ---------------------------------------------------------------------------------------------------- |
| `upload_file` ⚠️ | 上传文件到频道(base64 内容);返回文件 ID 以通过 `post_message.file_ids` 附加。 |
| `get_file` | 以 base64 格式下载文件内容(可配置的 `max_bytes` 限制,默认为 8 MiB)。 |
| `get_file_metadata` | 文件信息(`GET /files/{id}/info`)。 |
## 防护栏
### 防护栏变量
| 变量 | 影响 |
| --------------------------- | ------------------------------------------------------------------------------------- |
| `MM_READ_ONLY=true` | 每个 ⚠️ 和 💥 工具在调用时硬拒绝。工具仍在 `tools/list` 中可见。 |
| `MM_ALLOW_DESTRUCTIVE=true` | 解锁 💥 工具。 |
| `MM_TEAM_ALLOWLIST` | 允许的团队 ID 的 CSV;拒绝针对团队列表以外的团队的操作。 |
| `MM_CHANNEL_ALLOWLIST` | 允许的频道 ID 的 CSV;拒绝针对频道列表以外的频道的操作。 |
| `MM_MAX_MESSAGE_LEN` | 消息超过此长度(Unicode 代码点)时拒绝发送。 |
### 规则
- 破坏性工具(`delete_post`、`archive_channel`、`remove_member`)需要 **同时满足**
`MM_ALLOW_DESTRUCTIVE=true` 在环境中 **和** 工具调用中显式 `confirm: true` 参数。
- `MM_READ_ONLY=true` 优先级高于 `MM_ALLOW_DESTRUCTIVE`;所有 ⚠️/💥 工具都拒绝。
- 允许列表针对调用的解析团队/频道 ID 进行检查,而不是显示名称。
- Mattermost API 错误(状态码 + 消息)原样显示 — 绝不被抑制。
## 在 MCP 客户端中注册
服务器通过 **stdio** 讲话 MCP。 将您的 MCP 客户端指向二进制文件。 `examples/` 目录中有两个现成的配置示例。
### 全局安装 + `login` 后
如果您已全局安装并运行了 `mattermost-mcp login`,则凭证已经在磁盘上 — 客户端配置根本不需要 `env` 块:
```json
{
"mcpServers": {
"mattermost": {
"command": "mattermost-mcp"
}
}
}
```
### 通用配置(`examples/mcp.json`)
适用于任何遵循标准 `mcpServers` 模式的 MCP 客户端(Cursor、Continue 等)。复制到项目根目录的 `.mcp.json` 文件中,并调整路径和凭证:
```json
{
"mcpServers": {
"mattermost": {
"command": "node",
"args": ["/绝对路径/to/mattermost-mcp/dist/index.js"],
"env": {
"MM_URL": "https://mattermost.example.com",
"MM_AUTH_MODE": "pat",
"MM_TOKEN": "你的个人访问令牌"
}
}
}
}
```
### 克劳德桌面版配置(`examples/claude_desktop_config.json`)
合并到 `~/Library/Application Support/Claude/claude_desktop_config.json`(macOS)或等效路径(Windows/Linux)。**始终使用绝对路径**。保存后重启克劳德桌面版。
```json
{
"mcpServers": {
"mattermost": {
"command": "node",
"args": ["/绝对路径/to/mattermost-mcp/dist/index.js"],
"env": {
"MM_URL": "https://mattermost.example.com",
"MM_AUTH_MODE": "pat",
"MM_TOKEN": "你的个人访问令牌"
}
}
}
}
```
## 集成测试
存储库中提供了一个 `docker-compose.yml` 文件。它启动一个可丢弃的 Mattermost 预览实例:
```bash
docker compose up -d
# Mattermost 现在运行在 http://localhost:8065
# 创建帐户 + 团队,然后生成个人访问令牌。
```
实时集成测试**默认跳过**(因此 `npm test` 保持在线和绿色)。设置 `MM_INTEGRATION=1` 以启用它们:
```bash
MM_INTEGRATION=1 \
MM_URL=http://localhost:8065 \
MM_AUTH_MODE=pat \
MM_TOKEN=你的令牌 \
MM_TEST_CHANNEL_ID=<频道ID> \
npm test
```
`MM_TEST_CHANNEL_ID` 是可选的;它仅启用发布 → 获取 → 删除写入循环测试。
## 开发
### 脚本
| 脚本 | 目的 |
| ---------------- | --------------------------------------------------------------------------- |
| `npm run build` | 编译 TypeScript → `dist/` |
| `npm run dev` | 从源代码运行服务器(tsx,无需构建) |
| `npm start` | 运行编译后的服务器(`node dist/index.js`) |
| `npm test` | 运行 vitest 套件(集成测试在没有 `MM_INTEGRATION=1` 时跳过) |
| `npm run lint` | ESLint + Prettier 检查 |
| `npm run format` | Prettier 写入(自动修复格式) |
## 许可证
MIT
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器