@bangdao-ai/zentao-mcp
v6.1.0
Published
禅道 MCP Server v3 — 27 个 canonical 工具,一功能一接口,纯 HTTP API,零 MySQL/LLM/Zenbot 依赖。设置 ZENTAO_MCP_LEGACY=1 可回退到 v2 旧版 35+ 工具
Readme
禅道 MCP v3 — 34 个 canonical 工具
一功能一接口 | 纯 HTTP API | 零 MySQL/LLM/Zenbot 依赖 | 108+ 用例对抗性契约测试覆盖
v3.0 升级要点
- 工具数从 51 → 32(降 37%+),
*_bug/*_story/*_task等幻觉工具退场;新增 Testtask 提测域 5 工具。 - 一功能一接口:
transition_bug一个工具替代resolve_bug + close_bug + activate_bug + confirm_bug + assign_bug + 3 个 batch_*(9 → 1)。Story / Task 同样合并。 - 纯 HTTP API:
src/zentao_mcp/全包零 importzenbot、零 MySQL 连接、零 LLM 调用,只用requests。 - 真实禅道契约测试:在
productID=419上验证,发现并修复了多处docs/zentao-native-api.md与禅道真实行为的偏差。 - 零影响 Zenbot:
src/zenbot/一行没改;旧版入口src/mcp/server.py保留,通过ZENTAO_MCP_LEGACY=1环境变量回退。
快速开始
前置要求
- Node.js: >= 14.0.0
- Python: >= 3.10
MCP 配置(v3 默认)
{
"mcpServers": {
"zentao": {
"command": "npx",
"args": ["-y", "@bangdao-ai/zentao-mcp@latest"],
"env": {
"ZENTAO_OPENED_BY": "your-user-id",
"ZENTAO_KEY": "your-api-key"
}
}
}
}回退到 v2 (legacy)
如果你依赖 v2 的 Zenbot 业务工具(playbook_* / bug_source_alias_* / ai_query / thumb_* / confirm/revoke_memory),加 ZENTAO_MCP_LEGACY=1:
"env": {
"ZENTAO_MCP_LEGACY": "1",
"ZENTAO_OPENED_BY": "...",
"ZENTAO_KEY": "..."
}注意 legacy 入口需要 MySQL 连接和钉钉密钥,见 .env.example。
工具清单(34 个)
Bug 域 (6)
| 工具 | 取代 | 说明 |
|---|---|---|
| get_bug | get_bug_detail | Bug 详情;自动导出附件与 steps/备注内嵌图到本地包 |
| list_bugs | get_bug_list + query_bugs + get_my_bug | 三种查询模式合一(产品/我的/默认) |
| create_bug | create_bug | 创建 Bug |
| edit_bug | edit_bug | 编辑字段(不含状态转移) |
| transition_bug | resolve+close+activate+confirm+assign + 3 batch (9→1) | 状态转移单接口 |
| upload_bug_attachment | upload_image_to_bug | 上传附件 |
get_bug_enums已从 v3 通用 MCP 下线:allneedlist/createbugbyapikeys只授给101 自动化测试平台等特定组,不是通用禅道能力。
Story 域 (5)
| 工具 | 取代 |
|---|---|
| get_story, list_stories, create_story, edit_story, transition_story | get_story_detail / get_story_list / query_stories / get_my_story / close_story / activate_story / update_story_status (7→5) |
get_story查看详情时自动导出附件、spec/verify/备注内嵌图片到本地目录,并生成story_{id}.md。
Task 域 (5)
| 工具 | 取代 |
|---|---|
| get_task, list_tasks, create_task, edit_task, transition_task | get_task_detail / get_my_task / create_task / assign_task / start_task / finish_task / close_task (7→5) |
get_task查看详情时自动导出附件、desc/备注内嵌图片到本地目录,并生成task_{id}.md。
⚠️ 禅道原生
task.create不返回 taskID,executor 会通过project.task按 name 反查;反查失败时需手动list_tasks/get_task拿 ID。
Testtask 域 (5)
| 工具 | 说明 |
|---|---|
| list_project_builds | 项目下可选版本(build);提交测试前选版本,走 ajaxGetProjectBuilds |
| list_testtasks | 产品下提测单列表 |
| get_testtask | 提测单详情(返回 testtask_id,非开发任务) |
| create_testtask | 发起提测;必填 name/product_id;项目/版本/日期可自动补全 |
| close_testtask | 关闭提测单(标记通过);须带 comment |
⚠️
testtask.create成功时常不返 ID,client 会list_testtasks按 name 反查。close_testtask空 comment 在禅道侧 silent fail。
Product/Project 域 (6)
| 工具 | 说明 |
|---|---|
| list_products | 所有可访问产品(扁平 dict 已规范化为数组) |
| get_product | 产品详情 |
| list_modules | 模块树(story/bug/case 视图) |
| list_releases | 发布列表 |
| list_product_projects | 产品下项目;走 ajaxGetProjects(product&f=project 在 10.5.1 不可用) |
| get_project | 项目详情 |
My / User / Config (5)
| 工具 | 说明 |
|---|---|
| get_my_work | 待办概览(Bug+Story+Todo 计数) |
| get_my_todos | 我的 Todo |
| get_my_dynamic | 最近操作动态 |
| search_user | 按姓名搜索用户 |
| get_my_defaults / set_my_defaults | 读写本地 JSON 默认 product/project/build;任意工具显式传参也会自动合并 |
| get_config | 当前 MCP 配置 + defaults 文件路径 |
退场工具清单
以下旧工具在 v3 不再导出(原因:实现死代码 / 接口不可用 / Zenbot 专属):
- 全部 case 模块:
get_case_list,get_case_detail,create_case,create_cases_from_csv,submit_csv_cases_to_zentao(7 个,nexus mixin 未接入) - legacy v2 testtask/build 模块 (nexus mixin 未接入;v3 已用独立 HTTP 实现替代)
- 全部 build 模块及
link_story_to_build(5 个,死代码) - Zenbot 业务:
set_product,set_my_defaults,playbook_*,bug_source_alias_*,product_alias_*,ai_query,thumb_*,confirm/revoke_memory(15+ 个)
旧脚本如果调用了这些工具,请改走 v3 对应工具或显式加 ZENTAO_MCP_LEGACY=1。
使用示例
Bug 全生命周期
"帮我创建一个Bug,标题是'登录页面验证码不显示'" → create_bug
"查看Bug 121128的详情" → get_bug
"把Bug 121128指派给张三" → transition_bug(action=assign)
"解决Bug 121128,标记为已修复" → transition_bug(action=resolve)
"关闭Bug 121128" → transition_bug(action=close)
"重开Bug 121128" → transition_bug(action=activate)
"批量关闭 121128, 121129, 121130" → transition_bug(action=close, bug_ids=[...])任务全生命周期
"创建任务 '优化登录接口性能',项目 ID 833" → create_task
"开始任务 828221" → transition_task(action=start)
"完成任务 828221" → transition_task(action=finish)
"关闭任务 828221" → transition_task(action=close)提测全链路
"产品419项目425有哪些版本" → list_project_builds
"发起提测,名称222,版本5147" → create_testtask(begin/end 自动填今天~一周后)
"查看提测单6670" → get_testtask
"关闭提测单6670" → close_testtask
"产品419的提测单列表" → list_testtasks我的待办
"看看我有什么待办" → get_my_work
"查看指派给我的 Bug" → list_bugs(scope=mine, my_type=assigntome)
"我的任务列表" → list_tasks(scope=mine)项目结构
zentao-mcp/
├── index.js # Node 入口(默认 v3,可回退 v2)
├── src/
│ ├── zentao_mcp/ # ★ v3 canonical 包(本次新增,零 zenbot 依赖)
│ │ ├── registry.py # 32 个工具定义
│ │ ├── client.py # 纯 HTTP 客户端
│ │ ├── executors.py # 工具 dispatch + 业务规则
│ │ └── server.py # MCP server 入口
│ ├── mcp/ # ⚠ v2 legacy 入口(deprecated,仍可用)
│ │ └── server.py
│ ├── core/ # 旧版业务层(legacy 链路 + Zenbot 共用)
│ ├── shared/ # 旧 tool_registry(legacy 链路)
│ └── zenbot/ # 钉钉机器人(本次未修改)
├── tests/
│ └── zentao_mcp/ # ★ v3 契约测试(本次新增)
│ └── contract/ # 契约测试
├── docs/
│ └── zentao-native-api.md # API 文档(本次大幅修订,标真实差异)
└── README.md # 当前文件技术架构 (v3)
AI 编辑器 (Cursor/Claude Desktop)
↕ MCP 协议 (stdio)
ZenTaoMCPServer (src/zentao_mcp/server.py)
↕ 工具注册 + dispatch
EXECUTORS (src/zentao_mcp/executors.py) — 仅参数校验和默认值
↕
ZenTaoClient (src/zentao_mcp/client.py) — 纯 HTTP
↕ requests POST (api.php?m=...&f=... / allneedlist/*)
禅道服务器零 MySQL · 零 LLM · 零 Zenbot · 零 ACW 依赖。
测试
v3 契约测试(真实禅道,推荐)
全量入口(推荐):
./scripts/run_zentao_mcp_contract.sh
# 等价于: ZENTAO_API_TRACE=1 pytest tests/zentao_mcp/contract/ -v
# HTTP 明细: logs/zentao_mcp_contract_<YYYYMMDD_HHMMSS>.log (每次运行一个新文件)# 手动跑全部
pytest tests/zentao_mcp/contract/ -v
# 只跑某一域
pytest tests/zentao_mcp/contract/test_bug.py -v环境变量:
| 变量 | 用途 |
|------|------|
| ZENTAO_OPENED_BY / ZENTAO_KEY | 禅道 API(必备) |
| ZENTAO_BASE_URL | 可选;未设则用内置默认 https://zentao.bangdao-tech.com |
| MYSQL_ZENTAO_HOST / USER / PASSWORD / DATABASE | 写操作用例落库校验(必备,见 .env.example) |
| ZENTAO_API_TRACE=1 | HTTP trace(脚本默认开启) |
| ZENTAO_API_TRACE_FILE | trace 路径;未设则每次运行 logs/zentao_mcp_contract_<时间戳>.html |
| ZENTAO_API_TRACE_FORMAT | html(默认,浏览器可打开) / text(纯文本 .log) |
| ZENTAO_API_TRACE_VIEW | case(默认,每用例卡片: 标题+入参+出参) / detail(HTTP+MCP 分层) |
| ZENTAO_API_TRACE_HTTP | case 视图下设为 1 才写入 HTTP 明细 |
| ZENTAO_API_TRACE_MCP | detail 视图: compact/full; case 视图固定入参/出参卡片 |
测试默认在 productID=419 上跑; create/edit/transition 类用例在 API 返回 success 后会查 zt_bug / zt_story / zt_task 验证落库。所有创建的资源在 teardown 阶段自动 close。
页面验证 (mini 默认开启): 整次 pytest session 共用一个浏览器;登录后窗口保持到全部用例结束(ZENTAO_UI_KEEP_BROWSER=1 默认),会话写入 logs/.zentao_ui_storage.json。未登录时打开工作台请你完成钉钉授权(等待期间不会自动刷新)。依赖: uv pip install -e ".[contract]" && playwright install chromium。关闭: ZENTAO_UI_VERIFY=0。
最小正向集合 (34 工具各 1 条):
./scripts/run_zentao_mcp_contract.sh tests/zentao_mcp/contract/test_positive_minimal.py -v对抗/负向用例仍在 test_bug.py 等文件 (约 107 条); 日常冒烟只跑 test_positive_minimal.py 即可。
旧版集成测试(legacy)
pytest tests/integration/test_zentao_api.py -v已知 6 fail 是 case 模块死代码 + get_my_task 未实现,v3 已直接退场,不再修复 legacy。
API 文档
docs/zentao-native-api.md 已在 v3.0.0 修订中标注以下 9 处与禅道真实行为的偏差:
bug.close必须传closedDate(否则 status=1 但状态不变)bug.activate必须传openedBuild + assignedTobug.edit对不存在 bugID 不报错(v3 在 executor 中预检)product.all真实返回扁平 dict 而非嵌套data.productstask.create不返回 taskIDm=product&f=project端点不可用story.create / edit强制公司自定义字段allneedlist/createtaskbyapi网关有"任务类型不得为空"实现缺陷allneedlist/createbugbyapikeys只授给特定自动化平台组,不是通用能力,不得重新加入 v3 MCPallneedlist/updateStoryByApi可改部分字段但不能改 status,不是通用状态转移能力,不得重新加入 v3 MCP
许可证
MIT
