@cqjjb/zentao-mcp-server
v2.0.0
Published
MCP server for ZenTao 12.x: auto-login (zentaosid session + form submission) and full bug lifecycle (list/detail/edit/assign/resolve/close/activate/comment) + attachments
Maintainers
Readme
禅道 MCP Server
让 AI(Claude / Cursor / Codex 等)自动管理禅道 Bug:读取列表与详情、创建、编辑、指派、解决、关闭、激活、评论——全流程自动化,无需人工操作浏览器。
本项目针对 禅道 12.x(开源版 12.3.1) 真机开发与验证。 禅道 16.0+ 才提供 RESTful token 接口;本实现采用禅道官方推荐的
zentaosid会话 + 表单提交 方式,12.x 全兼容。
✨ 功能特性
- 自动登录:
zentaosid 会话 + md5(md5(密码)+盐) 加密,与浏览器登录完全一致,无需验证码交互 - 会话自管理:内存缓存会话,掉线/过期自动重登并重试,AI 全程无感
- 12 个工具:覆盖 Bug 全生命周期
- 写操作安全校验:指派/解决后自动回读校验状态,防止"假成功"
- 人员解析:支持中文姓名 ↔ 禅道账号自动互转,指派对象必须在用户列表中校验存在
- 自检工具:
zentao_self_test一键验证连接与权限
📦 安装与构建
npm install
npm run build # 编译到 dist/
npm run dev # tsx 直接运行(开发)🔧 配置(环境变量)
| 变量 | 默认值 | 说明 |
|---|---|---|
| ZENTAO_BASE_URL | http://192.168.1.252/zentao | 禅道地址(注意带 /zentao 前缀) |
| ZENTAO_ACCOUNT | 无 | 禅道账号(必填) |
| ZENTAO_PASSWORD | 无 | 禅道密码(必填) |
| ZENTAO_TIMEOUT_MS | 15000 | 请求超时毫秒 |
# .env(或直接 export / 客户端配置 env)
ZENTAO_BASE_URL=http://192.168.1.252/zentao
ZENTAO_ACCOUNT=你的账号
ZENTAO_PASSWORD=你的密码🚀 接入 MCP 客户端
Claude Desktop(claude_desktop_config.json):
{
"mcpServers": {
"zentao": {
"command": "node",
"args": ["D:\\workspace\\mcp\\zentao-mcp-server\\dist\\index.js"],
"env": {
"ZENTAO_BASE_URL": "http://192.168.1.252/zentao",
"ZENTAO_ACCOUNT": "这里填账号",
"ZENTAO_PASSWORD": "这里填密码"
}
}
}
}Cursor(.cursor/mcp.json):
{
"mcpServers": {
"zentao": {
"command": "node",
"args": ["/path/to/zentao-mcp-server/dist/index.js"],
"env": { "ZENTAO_BASE_URL": "http://192.168.1.252/zentao", "ZENTAO_ACCOUNT": "...", "ZENTAO_PASSWORD": "..." }
}
}
}🔨 工具清单(暴露给 AI)
| 工具 | 作用 |
|---|---|
| zentao_self_test | 连接自检(登录、产品、bug 列表) |
| zentao_list_products | 产品列表 |
| zentao_list_users | 可指派人员列表(账号+姓名) |
| zentao_my_bugs | 「我的地盘」bug 列表(默认指派给我,可切我创建/解决/关闭;跨产品,与 my-bug.html 一致) |
| zentao_product_bugs | 按产品查 bug(必填 productId;支持标题关键字检索,产品内全量翻页) |
| zentao_get_bug | Bug 详情(含历史记录 + 附件清单与可读性标注) |
| zentao_list_attachments | 列出 Bug 全部附件(步骤/评论内嵌图 + 附件区正式附件),逐条标注类型与可读性 |
| zentao_download_attachment | 下载附件到本地(白名单见下;白名单外明确拒绝并告知 AI 处理建议) |
| zentao_update_bug | 编辑 Bug |
| zentao_assign_bug | 指派 Bug |
| zentao_resolve_bug | 解决 Bug |
| zentao_close_bug | 关闭 Bug |
| zentao_activate_bug | 激活(重新打开)Bug |
| zentao_add_comment | 添加评论 |
📎 附件读取边界(重要)
MCP 只能读取以下类型的附件,其余类型会显式告知 AI 不可读取并拒绝下载(不会静默失败):
| 类型 | 扩展名 | 读取方式 |
|---|---|---|
| 🖼️ 图片 | png / jpg / jpeg / gif / webp / bmp | zentao_download_attachment 下载 → read_image 查看 |
| 📄 文本 | md / txt / csv / log / json / xml / svg | zentao_download_attachment 下载 → read 查看 |
| 🚫 其他 | docx / xlsx / pdf / zip / rar / 音视频… | 不可读取:清单标注"🚫 不可读取+原因+建议",下载工具直接拒绝 |
- 附件提取来源:复现步骤内嵌图、历史/评论富文本内嵌图、附件区正式附件(
file-read-{id}.{ext}/file-download-{id}全量扫描) - 单文件 > 10MB 拒绝下载
- 遇白名单外附件,AI 应告知用户("该附件类型不支持读取,请人工查看或转成图片/文本后重新上传"),而不是猜测内容
⚠️ 安全规则(重要)
- 指派必须询问用户:AI 调用
zentao_assign_bug前,必须先用zentao_list_users获取候选,并向用户明确询问指派给谁;用户未明确指定时禁止执行。 - 解决 Bug 默认把 bug 指派给当前指派人;如需改派必须先经用户确认。
- 所有写操作后自动回读校验,失败即报错,不静默。
- 无创建/删除功能:创建与删除 Bug 由人工在禅道页面上完成,MCP 不暴露(避免 AI 误建/误删)。
🔄 完整工作流示例
用户:「把我创建的未关闭 bug 都列出来」
→ zentao_my_bugs(browseType=openedbyme)
用户:「查一下产品 81 全员培训里标题带『题库』的 bug」
→ zentao_product_bugs(productId=81, keywords=题库)
用户:「#37813 解决掉,指派给陈春位」
→ AI 调用 zentao_list_users(37813) 确认候选 → 向用户确认「确认指派给陈春位?」→ 用户确认
→ zentao_resolve_bug(37813, resolution=fixed, assignedTo=陈春位, comment=...)🧪 真机验证(本项目已对 192.168.1.252 完成验证)
# 只读链路
ZENTAO_ACCOUNT=xxx ZENTAO_PASSWORD=xxx node scripts/e2e.mjs
# 写操作链路(会在测试 bug 上真实执行)
ZENTAO_ACCOUNT=xxx ZENTAO_PASSWORD=xxx TEST_BUG_ID=37813 node scripts/e2e-write.mjs📝 已知限制(禅道 12.3.1)
- 无 RESTful API,采用会话+表单方式(已稳定验证)
action-comment独立评论接口受账号权限控制;被拒时自动降级为「无改动编辑 + 备注」方式记录评论(同样进入历史记录)- 部分账号(如本测试账号)无用户管理权限,人员列表从指派表单动态获取
📁 项目结构
src/
├── index.ts # MCP Server 入口
├── config.ts # 环境变量配置
├── zentao-client.ts # 核心客户端(登录/会话/请求/重登)
└── tools/bug-tools.ts # 12 个工具实现
scripts/
├── e2e.mjs # 读链路端到端测试
└── e2e-write.mjs # 写链路端到端测试