内容
# 🦎 Agama — Redmine MCP 服务器
[MCP服务器](https://modelcontextprotocol.io/),适用于Redmine。使AI代理能够使用简单的自然语言命令处理问题。
与单个开发人员使用的个人工具一样好,也可以一次部署并由整个团队共享。
```plaintext
┌──────────┐ MCP(标准输入/输出) ┌─────────────────────┐ REST/JSON ┌──────────┐
│ 代理 │ ──────────────▶ │ Redmine MCP 服务器 │ ────────────▶ │ Redmine │
│ (客户端)│ ◀────────────── │ (此项目) │ ◀──────────── │ 服务器 │
└──────────┘ 工具结果 └─────────────────────┘ HTTP └──────────┘
```
## 💬 直接提问
> "有哪些问题被分配给我?按优先级排序。"
> "在Web项目中创建一个bug:登录按钮在移动设备上无响应,标记为紧急。"
> "总结问题#456及其所有子任务。"
> "我本周记录了多少小时,按项目分类?"
## 要求
- Node.js 20+
- 一个启用了REST API的Redmine实例(_管理 → 设置 → API_)
- 一个Redmine API密钥 — 登录后前往 **我的账户 → API访问密钥**
## 快速开始
大多数MCP客户端(例如Claude Desktop)为您启动服务器 — 配置一次即可忘记:
```json
{
"mcpServers": {
"redmine": {
"command": "npx",
"args": ["-y", "@0xkillaflow/agama-redmine-mcp"],
"env": {
"REDMINE_URL": "https://redmine.example.com",
"REDMINE_API_KEY": "your-redmine-api-key"
}
}
}
}
```
对于Claude Desktop,这将放入 `claude_desktop_config.json`(**设置 → 开发者 → 编辑配置**)。重启客户端,Redmine工具将出现在其工具列表中。
要从shell独立运行:
```bash
REDMINE_URL=https://redmine.example.com REDMINE_API_KEY=your-redmine-api-key \
npx -y @0xkillaflow/agama-redmine-mcp
```
服务器通过标准输入/输出进行MCP通信,并将日志记录到标准错误流中,因此标准输出流保持干净以便进行协议通信。
## 配置
通过环境变量设置,在启动时验证。参见 [`.env.example`](./.env.example) 获取模板。
| 变量 | 是否必需 | 默认值 | 目的 |
| -------------------- | -------- | ------- | -------------------------------------- |
| `REDMINE_URL` | 是 | — | Redmine实例的基本URL |
| `REDMINE_API_KEY` | 是 | — | 活动用户的API密钥 |
| `REDMINE_TIMEOUT_MS` | 否 | `30000` | 每个请求的超时时间(毫秒) |
| `LOG_LEVEL` | 否 | `info` | `debug` \| `info` \| `warn` \| `error` |
| `MCP_TRANSPORT` | 否 | `stdio` | `stdio` (目前唯一支持的模式) |
## 工具
十种意图明确的工具,每个工具都带有MCP安全注释。完整参考:
[`docs/tools.md`](./docs/tools.md)。
| 工具 | 类型 | 描述 |
| --------------------------- | ----- | ----------------------------------------------------------- |
| `redmine_list_issues` | 读取 | 按状态、分配者、跟踪器、日期等搜索/筛选问题 |
| `redmine_get_issue` | 读取 | 完整的issue详情,可选地包含日志和附件 |
| `redmine_create_issue` | 写入 | 创建一个问题 |
| `redmine_update_issue` | 写入 | 编辑问题的状态、分配者、备注… |
| `redmine_search` | 读取 | 对问题、wiki、新闻、项目进行全文搜索 |
| `redmine_list_projects` | 读取 | 列出可见的项目 |
| `redmine_get_project` | 读取 | 完整的项目详情,包括跟踪器/类别/活动 |
| `redmine_list_time_entries` | 读取 | 查询已记录的时间 |
| `redmine_create_time_entry` | 写入 | 记录问题或项目的小时数 |
| `redmine_get_current_user` | 读取 | "我是谁" — API密钥的用户、成员资格、组 |
> **注意:** 在写入时,Redmine会静默忽略未知的`tracker_id`、`status_id`或
> `fixed_version_id`,而不是报错 — 始终检查返回的问题。同样,如果您的角色缺乏“设置公开/私有”的权限,
> `is_private`将被静默丢弃。
## 安全
服务器在本地运行,并作为单个用户:您的`REDMINE_API_KEY`不会离开您的机器,
除了作为请求头发送到您自己的Redmine实例,服务器可以做的任何事情都是您的账户已经可以做的。
多用户HTTP传输计划正在实施,但尚未实现 —
选择`MCP_TRANSPORT=http`将以明确的错误退出。
## 故障排除
| 症状 | 可能原因 |
| ---------------------------- | -------------------------------------------------------------------- |
| 客户端显示没有工具 | 除了JSON-RPC以外,其他内容正在写入标准输出 — 检查任何包装器 |
| 启动后立即退出 | 缺少或无效的env变量;错误名称 |
| `401 Unauthorized` | API密钥缺失/错误,或Redmine侧禁用REST API |
| `403 Forbidden` | 密钥的用户缺乏该操作的权限 |
| `404 Not Found` | ID不存在或对密钥不可见 |
| `422 Unprocessable Entity` | Redmine拒绝写入 — 检查返回的字段级消息 |
## 文档
- [`docs/architecture.md`](./docs/architecture.md) — 设计和请求生命周期
- [`docs/tools.md`](./docs/tools.md) — 按工具生成的参考
- [`docs/adding-a-tool.md`](./docs/adding-a-tool.md) — 添加新工具的配方
- [`CONTRIBUTING.md`](./CONTRIBUTING.md) — 开发设置和贡献指南
## 开发
```bash
npm install # 安装依赖
npm run dev # 监视并运行stdio服务器
npm test # 运行测试套件
npm run build # 打包到dist/
```
## License
[MIT](./LICENSE)