@zzp123/mcp-zentao
v1.18.15
Published
禅道项目管理系统的高级API集成包 - 完整版,包含所有94个工具。另有产品经理、测试工程师、开发工程师专用精简版本可选
Maintainers
Readme
MCP-Zentao
禅道项目管理系统的高级API集成包,提供任务管理、Bug跟踪等功能的完整封装,专为Cursor IDE设计的MCP扩展。支持产品经理、测试工程师、开发工程师三种角色的精简版本,大幅减少上下文占用。
📦 安装
npm install @zzp123/mcp-zentao -g🎭 角色版本选择
从 v1.17.0 开始,提供了三个角色专用的精简版本,每个版本只包含对应角色常用的工具,可显著减少 LLM 上下文占用 30-45%:
| 版本 | 命令 | 工具数量 | 文件大小 | 适用角色 |
|------|------|---------|---------|---------|
| 完整版 | zentao | 91个 | 67 KB | 需要使用全部功能 |
| 产品经理版 | zentao-pm | 39个 | 39 KB (-57%) | 需求、产品、计划管理 |
| 测试工程师版 | zentao-qa | 26个 | 25 KB (-71%) | Bug、测试用例管理 |
| 开发工程师版 | zentao-dev | 38个 | 35 KB (-58%) | 任务、项目、Bug解决 |
如何选择版本?
在 Claude Desktop 配置文件中,将 command 字段改为对应的命令即可:
{
"mcpServers": {
"zentao-pm": {
"command": "zentao-pm",
"args": []
}
}
}各版本包含的功能
- ✅ 初始化配置
- ✅ 需求管理(创建、查看、修改、删除)
- ✅ 产品管理
- ✅ 计划管理
- ✅ 项目集管理
- ✅ Bug查看(只读)
- ✅ 任务查看(只读)
- ✅ 评论功能
- ✅ 文件上传
- ✅ 初始化配置
- ✅ Bug管理(创建、查看、修改、解决、删除)
- ✅ 测试用例管理
- ✅ 需求查看(只读)
- ✅ 任务查看(只读)
- ✅ 评论功能
- ✅ 文件上传
- ✅ 初始化配置
- ✅ 任务管理(创建、查看、更新、完成、删除)
- ✅ Bug解决(查看、解决、评论)
- ✅ 项目管理
- ✅ 执行管理
- ✅ 构建版本管理
- ✅ 需求查看(只读)
- ✅ 评论功能
- ✅ 文件上传
🎯 Claude Code Skills
新功能! 现在提供 Claude Code Skills 支持,让你通过自然语言更便捷地使用禅道功能。
什么是 Skills?
Skills 是 Claude Code 的功能扩展,通过它你可以:
- 用自然语言描述需求,无需记住命令
- 智能化的任务管理和状态更新
- 更友好的交互体验
可用的 Skills
目前提供以下 Skills:
| Skill | 适用角色 | 功能 | 文档 | |-------|---------|-----|------| | zentao-dev | 开发工程师 | 任务管理、Bug解决、项目管理 | 文档 |
如何使用 Skills?
安装 MCP 服务器(如果还没安装):
npm install -g @zzp123/mcp-zentao配置 Claude Desktop(参考下方 MCP 配置)
在 Claude Code 中使用:
你:查看我今天的任务 AI:[显示任务列表] 你:开始处理任务 #123 AI:✓ 任务已更新为"进行中"状态
详细使用指南请查看 Skills 文档
📋 版本历史
查看完整的版本更新历史,请访问 CHANGELOG.md
最新版本: v1.17.6 - 2025-11-10
- 💬 评论工具完全统一(移除所有便捷工具,统一使用 addComment)
- 📊 完整版 91个工具,PM版 39个,QA版 26个,Dev版 38个
- 🎯 累计减少约 106行重复代码,完全统一评论API
近期版本:
- v1.17.5 - 评论工具简化(移除 addBugComment 和 addTaskComment)
- v1.17.4 - 产品经理版移除工单管理(42个工具)
- v1.17.3 - 测试工程师版移除构建和工单管理(29个工具)
使用方法
首次使用(配置禅道信息)
首次使用时,需要提供禅道的配置信息:
zentao '{"config":{"url":"https://your-zentao-url","username":"your-username","password":"your-password","apiVersion":"v1"},"name":"张三","age":25,"skills":["编程","设计"]}'配置信息会被保存在用户目录下的 .zentao/config.json 文件中,后续使用时无需再次提供。
后续使用
配置完成后,只需要提供任务相关的信息即可:
zentao '{"name":"张三","age":25,"skills":["编程","设计"]}'更新配置
如果需要更新禅道配置信息,只需要再次提供 config 参数即可:
zentao '{"config":{"url":"https://new-zentao-url","username":"new-username","password":"new-password","apiVersion":"v1"},"name":"张三","age":25,"skills":["编程","设计"]}'配置文件位置
配置文件保存在用户目录下的 .zentao/config.json 文件中:
- Windows:
C:\Users\你的用户名\.zentao\config.json - macOS/Linux:
~/.zentao/config.json
功能特性
- 支持配置信息的持久化存储
- 自动管理禅道API的认证信息
- 提供任务创建、更新、完成等功能
- 支持Bug跟踪和处理
- 完整的类型定义支持
注意事项
- 配置文件中包含敏感信息,请确保文件权限设置正确
- 建议定期更新密码,以确保安全性
- 如遇到问题,可以删除配置文件重新配置
许可证
MIT
特点
- 完整的禅道API封装
- 简单易用的接口设计
- 类型安全(TypeScript支持)
- 完善的错误处理
- 自动化的认证管理
与其他项目的区别
不同于通用的数据库操作工具(如 mcp-mysql-server),本项目专注于提供:
- 禅道系统特定的业务功能
- 高级别的API抽象
- 完整的禅道工作流支持
- 开箱即用的禅道集成方案
本地开发
- 克隆仓库
git clone https://github.com/bigtian/mcp-zentao.git
cd mcp-zentao- 安装依赖
npm install- 运行测试
npm test- 构建项目
npm run buildDocker 使用
使用 docker-compose(推荐)
- 复制环境变量模板并修改配置
cp .env.example .env
# 编辑 .env 文件,填入你的禅道系统配置- 启动服务
docker-compose up -d- 查看日志
docker-compose logs -f手动使用 Docker
- 构建镜像
docker build -t mcp-zentao .- 运行容器
docker run -d \
--name mcp-zentao \
-p 3000:3000 \
-e ZENTAO_URL=your-zentao-url \
-e ZENTAO_USERNAME=your-username \
-e ZENTAO_PASSWORD=your-password \
-e ZENTAO_API_VERSION=v1 \
-v $(pwd)/logs:/app/logs \
mcp-zentao在 Cursor IDE 中配置
在 Cursor IDE 的配置文件中添加以下配置:
{
"mcpServers": {
"zentao": {
"url": "http://localhost:3000"
}
}
}🚦 传输方式:STDIO 与 HTTP 双支持
默认使用 STDIO 传输(适合本地/CLI 场景)。如果需要通过 URL 与 MCP 客户端通信,可启用 HTTP 传输。两种配置方式任选其一:
方式 1:环境变量
MCP_TRANSPORT=http启用 HTTP(默认stdio)MCP_HTTP_PORT(或MCP_PORT):端口,默认 3000MCP_HTTP_HOST(或MCP_HOST):监听地址,默认0.0.0.0MCP_HTTP_PATH:路由前缀,默认/mcp- 安全可选:
MCP_ALLOWED_HOSTS、MCP_ALLOWED_ORIGINS(逗号分隔),MCP_DNS_PROTECTION=true
示例:
MCP_TRANSPORT=http MCP_HTTP_PORT=3000 MCP_HTTP_PATH=/mcp zentao --config "{\"url\":\"http://your-zentao\",\"username\":\"u\",\"password\":\"p\",\"apiVersion\":\"v1\"}"方式 2:CLI 参数
--transport http--http-port 3000(或--port)--http-host 0.0.0.0(或--host)--http-path /mcp- 安全可选:
--allowed-hosts host1,host2,--allowed-origins http://a,http://b,--dns-protection true
示例:
zentao --transport http --http-port 3000 --http-path /mcp --config "{\"url\":\"http://your-zentao\",\"username\":\"u\",\"password\":\"p\",\"apiVersion\":\"v1\"}"HTTP 模式下客户端需要连接到 http://<host>:<port><path>(默认 http://localhost:3000/mcp)。
方式 3:交互式初始化(最便捷)
运行一次交互式向导,选择 STDIO/HTTP 并保存到 ~/.zentao/transport.json,后续无需再带参数:
zentao --init-transport
# 或 zentao-dev / zentao-pm / zentao-qa 均可交互式示例:
=== MCP 传输方式初始化 ===
选择传输方式 (1) stdio (2) http [1]: 2
HTTP 端口 [3000]: 4000
HTTP 路径前缀 (如 /mcp) [/mcp]: /zentao
监听地址 [0.0.0.0]: 127.0.0.1
允许的 Host 列表(逗号分隔,可留空): localhost:4000
允许的 Origin 列表(逗号分隔,可留空): https://example.com
启用 DNS Rebinding 防护? (y/N): y最终配置会写入 ~/.zentao/transport.json,示例:
{
"transport": "http",
"host": "127.0.0.1",
"port": 4000,
"path": "/zentao",
"allowedHosts": ["localhost:4000"],
"allowedOrigins": ["https://example.com"],
"dnsProtection": true
}该文件优先级低于环境变量/CLI 参数,因此仍可通过临时参数覆盖。
基本使用
import { ZentaoAPI } from '@zzp123/mcp-zentao';
// 创建API实例
const api = new ZentaoAPI({
url: 'https://your-zentao-url', // 你的禅道系统URL
username: 'your-username', // 用户名
password: 'your-password', // 密码
apiVersion: 'v1' // API版本,默认为v1
});
// 获取我的任务列表
async function getMyTasks() {
try {
const tasks = await api.getMyTasks();
console.log('我的任务:', tasks);
} catch (error) {
console.error('获取任务失败:', error);
}
}
// 获取我的Bug列表
async function getMyBugs() {
try {
const bugs = await api.getMyBugs();
console.log('我的Bug:', bugs);
} catch (error) {
console.error('获取Bug失败:', error);
}
}
// 完成任务
async function finishTask(taskId: number) {
try {
await api.finishTask(taskId);
console.log('任务已完成');
} catch (error) {
console.error('完成任务失败:', error);
}
}
// 解决Bug (v1.4.0+)
async function resolveBug(bugId: number) {
try {
const result = await api.resolveBug(bugId, {
resolution: 'fixed',
resolvedBuild: 'trunk',
assignedTo: 'admin',
comment: '问题已修复'
});
console.log('Bug已解决:', result);
} catch (error) {
console.error('解决Bug失败:', error);
}
}
// 上传剪贴板图片 (v1.3.1+)
async function uploadClipboardImage() {
try {
// 注意:需要先复制图片到系统剪贴板
const result = await api.uploadFile({
filename: 'screenshot.png',
uid: 'optional-uid'
});
console.log('图片已上传:', result);
} catch (error) {
console.error('上传失败:', error);
}
}API文档
ZentaoAPI 类
构造函数
constructor(config: {
url: string; // 禅道系统URL
username: string; // 用户名
password: string; // 密码
apiVersion?: string; // API版本,默认为v1
})方法
getMyTasks(): Promise<Task[]>- 获取当前用户的任务列表
- 返回: Promise<Task[]>
getMyBugs(): Promise<Bug[]>- 获取当前用户的Bug列表
- 返回: Promise<Bug[]>
finishTask(taskId: number): Promise<void>- 完成指定ID的任务
- 参数: taskId - 任务ID
- 返回: Promise
resolveBug(bugId: number, resolution: ResolveBugRequest): Promise<Bug>(v1.4.0+)- 解决指定ID的Bug
- 参数:
- bugId - Bug ID
- resolution - Bug解决方案
- 返回: Promise - 返回更新后的Bug对象
uploadFile(request: UploadFileRequest): Promise<FileUploadResponse>(v1.2.0+)- 上传文件到禅道
- 参数: UploadFileRequest - 文件上传请求
- 返回: Promise - 包含文件ID和访问URL
downloadFile(fileId: number): Promise<Buffer>(v1.2.0+)- 从禅道下载文件
- 参数: fileId - 文件ID
- 返回: Promise - 文件的二进制数据
类型定义
interface Task {
id: number;
name: string;
status: string;
pri: number;
assignedTo: string;
deadline: string;
// ... 其他任务属性
}
interface Bug {
id: number;
title: string;
status: string;
severity: number;
resolvedBy: string;
resolution: string;
// ... 其他Bug属性
}
// v1.4.0+
type ResolutionType = 'fixed' | 'bydesign' | 'duplicate' | 'external' | 'notrepro' | 'postponed' | 'willnotfix';
interface ResolveBugRequest {
resolution: ResolutionType; // 解决方案(必填)
resolvedBuild?: string; // 解决版本(resolution='fixed'时必填)
assignedTo?: string; // 指派给
comment?: string; // 备注
duplicateBug?: number; // 重复Bug的ID(resolution='duplicate'时必填)
}
// v1.2.0+
interface UploadFileRequest {
file: Buffer; // 文件数据
filename: string; // 文件名
uid?: string; // 唯一标识符(可选)
}
interface FileUploadResponse {
id: number; // 文件ID
url: string; // 文件访问URL
}注意事项
- 确保提供正确的禅道系统URL和API版本
- 用户名和密码需要有相应的API访问权限
- 所有API调用都是异步的,需要使用async/await或Promise处理
- 错误处理建议使用try/catch进行捕获
开发环境
- Node.js >= 14.0.0
- TypeScript >= 4.0.0
贡献
欢迎提交Issue和Pull Request!
