Skip to main content
Glama

zentao-mcp-server(自建)

目标

  • 提供一个可运行的 MCP Server(stdio),连接你的禅道 RESTful API v1。

  • 最小功能:自动获取/缓存 Token + 常用 bug 工具。

Related MCP server: 禅道 MCP Server

非目标

  • 不在仓库内存任何密钥/Token。

  • 不暴露无边界的通用 REST 写接口。

  • 不保证覆盖你禅道的全部 API;优先支持高频 bug 流程,再按你的流程补工具。

依赖

  • Node.js 18+(需要内置 fetch

License

MIT - 详见 LICENSE 文件

配置

复制 .env.example.env 并填写:

  • ZENTAO_BASE_URL

  • ZENTAO_ACCOUNT

  • ZENTAO_PASSWORD

  • (可选)ZENTAO_PRODUCT_ID:你的禅道实例若报 Need product id 时设置

  • (可选)ZENTAO_PROJECT_ID:按项目查 bug 时设置(直接 /projects/{id}/bugs

  • (可选)ZENTAO_PROJECT_SET_ID:你的 bug 若在项目集视角,设置项目集 ID

  • (可选)ZENTAO_DEFAULT_RESOLVED_BUILD:解决 bug 时的默认「解决版本」,默认 trunk(很多实例必填)

  • (可选)ZENTAO_MY_BUGS_PATH:我的 bug 专用接口路径(如 /my/bug

  • (可选)ZENTAO_BUGS_FALLBACK_PATHS:bug 列表回退路径(逗号分隔)

  • (可选)ZENTAO_PROJECT_SET_BUGS_PATHS:项目集 bug 路径模板(支持 {projectSetId}

注意:不同禅道版本/部署方式的 token 端点与返回结构可能不同;可通过 ZENTAO_TOKEN_PATH/ZENTAO_API_PREFIX 调整。

默认情况下不需要配置 ZENTAO_API_PREFIX(默认值是 /api.php/v1)。

安全约束:ZENTAO_API_PREFIX / ZENTAO_TOKEN_PATH 只支持相对路径;默认要求 ZENTAO_BASE_URL 使用 HTTPS。ZENTAO_BASE_URL 可为根路径或子目录部署地址(如 https://zentao.example.com/zentao)。

安装与运行

npm i
cp .env.example .env
npm start

npm 安装后的运行

发布到 npm 后,推荐用 npx 启动(适合 MCP 客户端配置):

npx -y @aipper/zentao-mcp-server

验证(不依赖 MCP 客户端)

npm i
cp .env.example .env
set -a; source .env; set +a
npm run smoke

期望结果:

  • 输出一行 token: xxxx…yyyy source: ...

  • 输出 GET /projects status: 200(或你的禅道实际返回码)

Claude Desktop / Cursor 示例(stdio)

优先使用 npx(npm 发布版):

{
  "mcpServers": {
    "zentao": {
      "command": "npx",
      "args": ["-y", "@aipper/zentao-mcp-server"],
      "env": {
        "ZENTAO_BASE_URL": "https://zentao.example.com",
        "ZENTAO_ACCOUNT": "your_account",
        "ZENTAO_PASSWORD": "your_password"
      }
    }
  }
}

本地源码调试可继续用 node src/index.js

示例(Claude Desktop 的 mcpServers 风格,按你的客户端实际字段为准):

{
  "mcpServers": {
    "zentao": {
      "command": "node",
      "args": ["src/index.js"],
      "cwd": "/ABS/PATH/TO/zentao",
      "env": {
        "ZENTAO_BASE_URL": "https://zentao.example.com",
        "ZENTAO_ACCOUNT": "your_account",
        "ZENTAO_PASSWORD": "your_password"
      }
    }
  }
}

常见错误(-32000

-32000 通常是客户端侧“通用 MCP 调用失败”映射码,优先检查:

  • env 是否完整传入(尤其是 ZENTAO_BASE_URL/ZENTAO_ACCOUNT/ZENTAO_PASSWORD)。

  • 默认要求 HTTPS;如果你的实例只能走 HTTP,必须显式设置 ZENTAO_ALLOW_INSECURE_HTTP=true,且只建议临时内网调试使用。

  • 若报 Need product id,请设置 ZENTAO_PRODUCT_ID,或在 get_my_bugsproductId

  • 若你的 bug 在“项目集/我的视角”而非产品,建议设置 ZENTAO_PROJECT_SET_ID,并配置 ZENTAO_MY_BUGS_PATH=/my/bug

  • 项目集场景下,优先直接调用 get_my_bugs 并传 projectSetId,必要时再显式传 path="/my/bug";不要先依赖 list_my_projects 找项目。

  • 有些项目集本身没有创建实际项目,但仍然存在“我的 bug”;这类数据可能不会出现在 list_my_projects 结果里。

  • get_my_bugs 会按候选路径回退(包含项目集路径);即使首个路径返回空列表也会继续尝试,并会把多端点结果合并去重。

  • get_my_bugs.total 表示最终“我的 bug”总数;若需排查底层一共扫描了多少条,可看 raw.scannedTotal

  • 排查时看工具返回里的 raw.triedPaths / raw.paths,可确认每条路径的返回码与命中数量。

  • ZENTAO_API_PREFIX/ZENTAO_TOKEN_PATH 是否和你的禅道实例一致,且使用相对路径。

  • MCP 客户端是否真的在执行 npx -y @aipper/zentao-mcp-server(而不是旧的本地命令)。

  • 客户端日志中是否有启动报错(如找不到命令、401、超时)。

已实现工具

  • get_token:获取/刷新 token(始终只回显脱敏后的 token 摘要)

  • list_my_projects:示例:列出“我参与的项目”(字段匹配基于常见返回结构,可能需按你的实例微调;不适合作为项目集 bug 的唯一发现入口)

  • get_my_bugs:获取“指派给我”的 bug(支持 status/keyword/limit/page/productId/projectSetId,默认路径 /bugspath 仅允许 /bugs/my/bug/my/bugs

  • get_bug_detail:按 id 获取 bug 详情(固定读取 /bugs/{id};返回安全裁剪后的 bug 摘要与同源图片链接,不直接透传外部图片地址或原始附件外链)。当 bug 被激活过时,额外返回 activation 摘要 {count, lastActor, lastDate, lastComment},其中 lastComment 是最近一次激活时测试人员填写的评论(已去除 HTML)。bug 摘要现包含 activatedCount/activatedDate

  • get_bug_actions:按 id 获取 bug 的动作历史(激活/解决/关闭/评论等)。同一 /bugs/{id} 端点,返回 actions:[{id, actor, action, date, comment, history:[{field, old, new}]}]comment 已去 HTML)和 activation 摘要。当 bug 被激活、需要拿到激活评论/字段变更明细时使用;get_bug_detailactivation.lastComment 已覆盖"只看最近一次激活评论"的常见场景,需完整历史再用本工具。

  • resolve_bug:按 id 调用真正的解决接口 POST /bugs/{id}/resolve(默认 resolution=fixedresolvedBuild 默认取 ZENTAO_DEFAULT_RESOLVED_BUILD/trunk;优先 solutionModules,兼容纯文本 solution

  • batch_resolve_my_bugs:批量解决“我的 bug”(同上 resolve API;默认筛选 status=active,支持 productId/projectSetId/resolvedBuild,默认遇错即停,maxItems 上限 100;优先共享 solutionModules

  • close_bug:按 id 关闭 bug

  • verify_bug:验证结果处理(pass=关闭,fail=激活)

  • comment_bug:按 id 添加备注

结构化解决说明 solutionModules(推荐)

字段:

  • rootCause:【根因】触发条件 + 错误行为

  • fixApproach:【修复思路】策略说明

  • logicChange:【改动逻辑】关键分支/校验/流程变化

  • impact:【影响范围】受影响场景 + 结果型回归点

服务端会格式化为多行文本写入禅道,例如:

【根因】
...

【修复思路】
...

【改动逻辑】
...

【影响范围】
...

优先级:solutionModules(任一非空字段)> 纯文本 solution > comment 兜底。

解决版本 resolvedBuild:很多禅道实例校验「解决版本不能为空」。请传工具参数 resolvedBuild,或配置 ZENTAO_DEFAULT_RESOLVED_BUILD(默认 trunk)。无版本列表时 trunk 通常可用。

不要用 HTTP 编辑冒充解决PUT /bugs/{id} 或网页表单“编辑”只可能改字段/状态,不会走 resolve 动作,也不会把 MCP 的 solutionModules 模板写进解决说明。必须用 resolve_bug / batch_resolve_my_bugs

示例参数:

  • resolve_bug(推荐):

{
  "id": 123,
  "resolution": "fixed",
  "resolvedBuild": "trunk",
  "solutionModules": {
    "rootCause": "分页参数为空时仍进入查询构造,导致列表请求异常。",
    "fixApproach": "为空参数补默认值,并在构造前做兜底校验。",
    "logicChange": "page/size 为空时回落默认值;非法值改为明确错误提示,避免前端重复提交。",
    "impact": "列表查询与分页切换;重点回归空参进入与异常提示是否收敛。"
  }
}
  • resolve_bug(兼容纯文本):{"id":123,"resolution":"fixed","resolvedBuild":"trunk","solution":"补齐分页参数为空时的默认值分支,避免空值继续进入查询构造;同时收敛异常提示,防止前端重复触发提交"}

  • batch_resolve_my_bugs(推荐共享模块):

{
  "status": "active",
  "maxItems": 20,
  "resolvedBuild": "trunk",
  "solutionModules": {
    "rootCause": "状态切换时旧数据判空顺序错误,触发空指针。",
    "fixApproach": "统一状态切换的判空与分支顺序。",
    "logicChange": "保存前增加兜底校验;异常改为明确提示而非静默失败。",
    "impact": "状态流转相关保存与切换场景。"
  }
}
  • get_my_bugs(项目集):{"status":"active","projectSetId":1001,"limit":50}

  • get_my_bugs(我的):{"status":"active","path":"/my/bug","limit":50}

  • get_my_bugs(项目集 + 我的):{"status":"active","projectSetId":1001,"path":"/my/bug","limit":50}

  • get_my_bugs(按产品):{"status":"active","productId":1,"limit":50}

  • close_bug{"id":123,"comment":"验证通过,关闭"}

  • verify_bug{"id":123,"result":"pass","comment":"验证通过"}

  • comment_bug{"id":123,"comment":"已复现,正在定位根因"}

solutionModules / solution / comment 不要写 Evidence:Verify:、文件路径、编译命令或“已修复并自测”这类无法说明改动内容的表述。

使用建议:如果用户提到“项目集”“我的 bug”“项目列表里找不到但禅道里能看到 bug”,优先走项目集视角的 get_my_bugs,不要先让用户证明项目已创建。

安全建议

  • 默认要求使用 HTTPS:HTTP 会明文传输账号密码和数据,存在安全风险;如确需兼容老旧实例,需显式设置 ZENTAO_ALLOW_INSECURE_HTTP=true

  • 使用最小权限账号(仅需要的项目权限),避免使用管理员账号。

  • get_token 不再支持回显完整 token。

  • 调试日志会自动脱敏 querybodycommentsolution 等敏感字段,但仍建议仅在排查问题时临时开启。

调试

如需查看详细日志,可设置环境变量:

ZENTAO_DEBUG=true npx -y @aipper/zentao-mcp-server

日志会输出到 stderr,不影响 MCP 协议通信。

发布到 npm

脚本:scripts/release-npm.sh(参考 aiws 的发布流程,默认 dry-run)。

常用命令:

# dry-run:只检查 + npm pack --dry-run,不会发布
npm run release:npm

# 自动递增版本(patch/minor/major)+ commit + tag(不发布)
npm run release:npm -- --bump patch

# 发布(会二次确认;默认自动 patch 递增)
npm run release:npm -- --publish

# 版本对齐 + commit + tag(不发布)
npm run release:npm -- --release v0.1.0

注意:

  • package.jsonprivate: true,发布前请改成 false 并确认包名可用。

  • 可加 --require-tag 要求 HEAD 上有匹配版本的 tag。

  • 若发布时报 403,通常是包名归属问题;建议改为 scoped 包名(如 @yourname/zentao-mcp-server)。

Install Server
A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…

  • MCP server for AI access to SmartBear tools, including BugSnag, Reflect, Swagger, PactFlow, QTM4J.

  • A MCP server built for developers enabling Git based project management with project and personal…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aipper/zentao-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server