@bangdao-ai/zentao-mcp 1.1.13 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +31 -0
- package/README.md +156 -273
- package/index.js +2 -2
- package/main.py +44 -0
- package/package.json +13 -3
- package/requirements.txt +3 -1
- package/src/__init__.py +0 -0
- package/src/core/__init__.py +0 -0
- package/src/core/bug_classifier.py +436 -0
- package/src/core/zentao_nexus.py +1764 -0
- package/src/mcp/server.py +711 -0
- package/src/mcp_server.py +639 -501
- package/src/zenbot/SOUL.md +104 -0
- package/src/zenbot/__init__.py +0 -0
- package/src/zenbot/bot_service.py +248 -0
- package/src/zenbot/config.py +140 -0
- package/src/zenbot/db_resolver.py +168 -0
- package/src/zenbot/dingtalk_api.py +77 -0
- package/src/zenbot/dingtalk_handler.py +124 -0
- package/src/zenbot/dingtalk_reply.py +53 -0
- package/src/zenbot/formatters.py +486 -0
- package/src/zenbot/handlers/__init__.py +72 -0
- package/src/zenbot/handlers/bug_handlers.py +267 -0
- package/src/zenbot/handlers/case_handlers.py +114 -0
- package/src/zenbot/handlers/help_handler.py +63 -0
- package/src/zenbot/handlers/my_handlers.py +45 -0
- package/src/zenbot/handlers/product_handlers.py +47 -0
- package/src/zenbot/handlers/story_handlers.py +104 -0
- package/src/zenbot/handlers/task_handlers.py +105 -0
- package/src/zenbot/handlers/user_handlers.py +21 -0
- package/src/zenbot/intent_parser.py +278 -0
- package/src/zenbot/keyword_extractor.py +32 -0
- package/src/zenbot/llm_client.py +67 -0
- package/src/zenbot/session_manager.py +90 -0
- package/src/zenbot/zentao_client.py +51 -0
- package/src/zentao_nexus.py +1464 -977
package/.env.example
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# ═══════════════ MCP 通用 ═══════════════
|
|
2
|
+
ZENTAO_BASE_URL=https://zentao.example.com
|
|
3
|
+
ZENTAO_PRODUCT_ID=365
|
|
4
|
+
ZENTAO_OPENED_BY=your_account
|
|
5
|
+
ZENTAO_KEY=your_api_key
|
|
6
|
+
ZENTAO_USE_TEST_ENV=false
|
|
7
|
+
|
|
8
|
+
# ═══════════════ ZenBot 专属 ═══════════════
|
|
9
|
+
# 钉钉应用
|
|
10
|
+
DINGTALK_APP_KEY=your_app_key
|
|
11
|
+
DINGTALK_APP_SECRET=your_app_secret
|
|
12
|
+
|
|
13
|
+
# LLM(百炼/通义千问)
|
|
14
|
+
OPENAI_API_KEY=your_openai_api_key
|
|
15
|
+
OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
16
|
+
LLM_MODEL=qwen-plus
|
|
17
|
+
|
|
18
|
+
# 禅道 MySQL(用于用户/产品自动映射)
|
|
19
|
+
MYSQL_ZENTAO_HOST=127.0.0.1
|
|
20
|
+
MYSQL_ZENTAO_PORT=3306
|
|
21
|
+
MYSQL_ZENTAO_USER=root
|
|
22
|
+
MYSQL_ZENTAO_PASSWORD=your_password
|
|
23
|
+
MYSQL_ZENTAO_DATABASE=zentao
|
|
24
|
+
|
|
25
|
+
# 会话
|
|
26
|
+
SESSION_TIMEOUT_MINUTES=5
|
|
27
|
+
|
|
28
|
+
# 用户映射(可选,MySQL 查不到时 fallback)
|
|
29
|
+
# USER_MAPPING={"staff_id":"zentao_account"}
|
|
30
|
+
# USER_NAME_MAPPING={"staff_id":"display_name"}
|
|
31
|
+
# PRODUCT_MAPPING={"product_name":"product_id"}
|
package/README.md
CHANGED
|
@@ -1,336 +1,219 @@
|
|
|
1
|
-
# 禅道 MCP
|
|
1
|
+
# 禅道 MCP v2.0 — 项目管理AI中枢(原生API版)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **35+ MCP 工具** | 需求·任务·Bug·用例·发布·我的地盘全生命周期 | 禅道原生API | Bug 智能分类引擎 | 一句话驱动禅道
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## v2.0 核心升级
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- **原生 API 模式**:全部切换为禅道原生 `m=module&f=action` 端点,移除 `allneedlist` 自定义接口依赖
|
|
8
|
+
- **工具数从 20 → 36**:新增 Bug 确认/指派/编辑、任务开始/完成/关闭、需求编辑/关闭/激活、用例列表/详情、发布列表、我的地盘概览、用户搜索等
|
|
9
|
+
- **响应数据更丰富**:原生 API 返回 50+ 字段(vs 自定义 API 的 10-20 字段)
|
|
10
|
+
- **严格测试基线**:40 条 Pytest 用例,全部严格断言(仅 `status=1/success` 通过),不容忍任何异常
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
- "帮我创建一个Bug,标题是'登录页面验证码不显示',重现步骤是:1. 打开登录页面 2. 点击验证码区域 3. 验证码未显示"
|
|
11
|
-
- "创建一个Bug,标题'支付接口超时',步骤:调用支付接口后等待30秒无响应,截图路径是 /path/to/screenshot.png"
|
|
12
|
-
- "在禅道创建一个Bug,标题'数据导出功能异常',重现步骤:进入数据管理页面,点击导出按钮,提示错误"
|
|
13
|
-
|
|
14
|
-
### 场景二:获取需求详情
|
|
15
|
-
|
|
16
|
-
**话术示例**:
|
|
17
|
-
- "帮我获取需求ID为12345的需求详情"
|
|
18
|
-
- "查询一下需求12345的详细信息,包括标题、描述、验收标准等"
|
|
19
|
-
- "获取需求12345的完整信息"
|
|
20
|
-
|
|
21
|
-
### 场景三:创建任务
|
|
22
|
-
|
|
23
|
-
**话术示例**:
|
|
24
|
-
- "帮我创建一个任务,任务名称是'优化登录接口性能',分配给张三"
|
|
25
|
-
- "创建一个开发任务,名称'修复支付bug',优先级高,分配给李四"
|
|
26
|
-
- "在禅道创建一个任务,标题'重构用户模块',分配给王五,预计3天完成"
|
|
27
|
-
|
|
28
|
-
### 场景四:指派任务
|
|
29
|
-
|
|
30
|
-
**话术示例**:
|
|
31
|
-
- "把任务ID为67890的任务指派给张三"
|
|
32
|
-
- "将任务67890重新指派给李四,备注'需要紧急处理'"
|
|
33
|
-
- "指派任务67890给王五,备注说明'这个任务需要前端配合'"
|
|
34
|
-
|
|
35
|
-
### 场景五:查询BUG列表
|
|
36
|
-
|
|
37
|
-
**话术示例**:
|
|
38
|
-
- "帮我查询产品365下所有已确认的BUG"
|
|
39
|
-
- "查询产品365中分配给张三的未解决BUG"
|
|
40
|
-
- "获取产品365在2024-01-01到2024-01-31期间创建的BUG列表"
|
|
41
|
-
- "查询产品365中状态为'激活'的BUG,创建人是李四"
|
|
42
|
-
- "帮我拉取产品365下所有已确认但未解决的BUG"
|
|
43
|
-
|
|
44
|
-
### 场景六:批量解决BUG
|
|
45
|
-
|
|
46
|
-
**话术示例**:
|
|
47
|
-
- "批量解决产品365下的BUG,BUG ID是[76016, 75241],解决方案是fixed,解决人是68249,解决版本是2700"
|
|
48
|
-
- "将产品365的BUG [76016, 75241] 标记为'设计如此',解决人是张三"
|
|
49
|
-
- "批量解决BUG,产品ID 365,BUG列表[76016, 75241],解决方案duplicate(重复上报),解决人李四"
|
|
50
|
-
|
|
51
|
-
### 场景七:创建测试用例
|
|
52
|
-
|
|
53
|
-
**话术示例**:
|
|
54
|
-
- "帮我创建一个接口测试用例,名称'用户登录接口测试',接口地址是 /api/login,请求方法是POST"
|
|
55
|
-
- "创建一个功能测试用例,名称'用户注册流程测试',步骤包括:1. 打开注册页面 2. 填写信息 3. 提交注册"
|
|
56
|
-
- "在禅道创建一个测试用例,类型是接口测试,名称'订单查询接口'"
|
|
57
|
-
|
|
58
|
-
### 场景八:批量创建测试用例
|
|
59
|
-
|
|
60
|
-
**话术示例**:
|
|
61
|
-
- "从CSV文件 /path/to/cases.csv 批量创建测试用例"
|
|
62
|
-
- "帮我将CSV文件中的测试用例批量提交到禅道,文件路径是 /path/to/test_cases.csv"
|
|
63
|
-
- "从CSV文件批量创建接口测试用例,文件路径 /path/to/api_cases.csv"
|
|
64
|
-
|
|
65
|
-
### 场景九:上传截图到BUG
|
|
66
|
-
|
|
67
|
-
**话术示例**:
|
|
68
|
-
- "把截图 /path/to/screenshot.png 上传到BUG 12345"
|
|
69
|
-
- "上传图片到BUG 12345,图片路径是 /path/to/image.jpg,文件名改为'错误截图'"
|
|
70
|
-
- "帮我把截图上传到BUG 12345的附件中"
|
|
71
|
-
|
|
72
|
-
### 场景十:查看配置
|
|
73
|
-
|
|
74
|
-
**话术示例**:
|
|
75
|
-
- "查看一下当前的禅道配置信息"
|
|
76
|
-
- "显示当前的配置"
|
|
77
|
-
- "获取配置信息"
|
|
78
|
-
|
|
79
|
-
## 功能特性
|
|
80
|
-
|
|
81
|
-
- ✅ 创建Bug(支持截图上传)
|
|
82
|
-
- ✅ 获取需求详情
|
|
83
|
-
- ✅ 创建任务
|
|
84
|
-
- ✅ 指派任务
|
|
85
|
-
- ✅ 查询BUG列表(支持多条件筛选)
|
|
86
|
-
- ✅ 批量解决BUG
|
|
87
|
-
- ✅ 创建测试用例
|
|
88
|
-
- ✅ 批量从CSV文件创建测试用例
|
|
89
|
-
- ✅ 上传图片到Bug附件
|
|
90
|
-
- ✅ 支持配置文件(支持JSON注释)
|
|
91
|
-
- ✅ 自动格式化步骤为HTML
|
|
92
|
-
|
|
93
|
-
## 安装
|
|
12
|
+
## 快速开始
|
|
94
13
|
|
|
95
14
|
### 前置要求
|
|
96
15
|
|
|
97
16
|
- **Node.js**: >= 14.0.0
|
|
98
|
-
- **Python**: >= 3.10
|
|
99
|
-
|
|
100
|
-
### 安装方式
|
|
101
|
-
|
|
102
|
-
#### 方式一:通过 npx 使用(推荐,无需安装)
|
|
103
|
-
|
|
104
|
-
直接在 Cursor 配置中使用,无需手动安装:
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
npx -y @bangdao-ai/zentao-mcp@latest
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
#### 方式二:全局安装
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
npm install -g @bangdao-ai/zentao-mcp@latest
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
#### 方式三:本地安装(开发模式)
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
git clone https://github.com/bangdao-ai/zentao-mcp.git
|
|
120
|
-
cd zentao-mcp
|
|
121
|
-
pip3 install -r requirements.txt
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
**详细安装指南请参考**:[docs/INSTALL.md](docs/INSTALL.md)
|
|
125
|
-
|
|
126
|
-
## 配置
|
|
17
|
+
- **Python**: >= 3.10
|
|
18
|
+
- **Cursor 编辑器**(或其他支持 MCP 的编辑器)
|
|
127
19
|
|
|
128
|
-
###
|
|
129
|
-
|
|
130
|
-
在 Cursor 的 MCP 配置文件中添加:
|
|
20
|
+
### MCP 配置
|
|
131
21
|
|
|
132
22
|
```json
|
|
133
23
|
{
|
|
134
24
|
"mcpServers": {
|
|
135
25
|
"zentao": {
|
|
136
26
|
"command": "npx",
|
|
137
|
-
"args": [
|
|
138
|
-
"-y",
|
|
139
|
-
"@bangdao-ai/zentao-mcp@latest"
|
|
140
|
-
],
|
|
27
|
+
"args": ["-y", "@bangdao-ai/zentao-mcp@latest"],
|
|
141
28
|
"env": {
|
|
142
29
|
"ZENTAO_PRODUCT_ID": "your-product-id",
|
|
143
30
|
"ZENTAO_OPENED_BY": "your-user-id",
|
|
144
|
-
"
|
|
145
|
-
"ZENTAO_KEYWORDS": "AI",
|
|
146
|
-
"ZENTAO_TITLE_PREFIX": "",
|
|
147
|
-
"ZENTAO_ROLE_TYPE": "test"
|
|
31
|
+
"ZENTAO_KEY": "your-api-key"
|
|
148
32
|
}
|
|
149
33
|
}
|
|
150
34
|
}
|
|
151
35
|
}
|
|
152
36
|
```
|
|
153
37
|
|
|
154
|
-
|
|
155
|
-
- `ZENTAO_PRODUCT_ID`(必需):产品ID
|
|
156
|
-
- `ZENTAO_OPENED_BY`(必需):创建人和指派人ID(同一个人),作为API认证的code参数
|
|
157
|
-
- `KEY`(必需):API认证密钥,作为API认证的key参数
|
|
158
|
-
- `ZENTAO_KEYWORDS`(可选):关键词,默认为空
|
|
159
|
-
- `ZENTAO_TITLE_PREFIX`(可选):标题前缀,默认为空
|
|
160
|
-
- `ZENTAO_ROLE_TYPE`(可选):角色类型,默认为"test"
|
|
161
|
-
|
|
162
|
-
### 兜底配置(可选)
|
|
163
|
-
|
|
164
|
-
如果未在环境变量中配置,可以使用配置文件 `bug_config.json`。配置文件路径可通过环境变量 `ZENTAO_CONFIG_PATH` 指定。
|
|
165
|
-
|
|
166
|
-
## MCP 工具
|
|
167
|
-
|
|
168
|
-
### 1. create_bug
|
|
169
|
-
|
|
170
|
-
创建Bug到禅道系统。
|
|
171
|
-
|
|
172
|
-
**参数**:
|
|
173
|
-
- `title` (必需): Bug标题
|
|
174
|
-
- `steps` (必需): 重现步骤(支持换行,会自动转换为HTML格式)
|
|
175
|
-
- `product_id` (可选): 产品ID
|
|
176
|
-
- `opened_by` (可选): 创建人和指派人
|
|
177
|
-
- `screenshot_path` (可选): 截图文件路径
|
|
178
|
-
- `severity` (可选): 严重程度(默认3)
|
|
179
|
-
- `pri` (可选): 优先级(默认3)
|
|
180
|
-
- `type` (可选): Bug类型(默认codeissue)
|
|
181
|
-
- `environment` (可选): 环境(默认测试环境)
|
|
182
|
-
- `story` (可选): 相关需求id
|
|
183
|
-
- `task` (可选): 相关任务id
|
|
184
|
-
- `mailto` (可选): 抄送人账号
|
|
185
|
-
- `keywords` (可选): 关键词
|
|
38
|
+
### 配置项说明
|
|
186
39
|
|
|
187
|
-
|
|
40
|
+
| 配置项 | 必需 | 说明 |
|
|
41
|
+
|--------|------|------|
|
|
42
|
+
| `ZENTAO_PRODUCT_ID` | 是 | 默认产品 ID |
|
|
43
|
+
| `ZENTAO_OPENED_BY` | 是 | 用户工号(同时作为 API 认证的 code) |
|
|
44
|
+
| `ZENTAO_KEY` | 是 | 禅道 API 密钥 |
|
|
188
45
|
|
|
189
|
-
|
|
46
|
+
## MCP 工具一览
|
|
190
47
|
|
|
191
|
-
|
|
192
|
-
- `bug_id` (必需): Bug ID
|
|
193
|
-
- `image_path` (必需): 图片文件路径
|
|
194
|
-
- `custom_filename` (可选): 自定义文件名
|
|
48
|
+
### Bug 管理(10个)
|
|
195
49
|
|
|
196
|
-
|
|
50
|
+
| 工具 | 说明 |
|
|
51
|
+
|------|------|
|
|
52
|
+
| `create_bug` | 创建Bug,支持截图上传,自动分类严重程度和优先级 |
|
|
53
|
+
| `get_bug_detail` | 获取Bug详情并导出到本地(50+字段、附件、截图、操作历史) |
|
|
54
|
+
| `get_bug_list` | 获取Bug列表,支持状态筛选 |
|
|
55
|
+
| `edit_bug` | 编辑Bug字段(自动补全 `openedBuild` 等必填项) |
|
|
56
|
+
| `resolve_bug` | 解决Bug(支持批量) |
|
|
57
|
+
| `close_bug` | 关闭Bug |
|
|
58
|
+
| `activate_bug` | 激活/重开Bug |
|
|
59
|
+
| `confirm_bug` | 确认Bug |
|
|
60
|
+
| `assign_bug` | 指派/转指派Bug |
|
|
61
|
+
| `upload_image_to_bug` | 上传图片到Bug附件 |
|
|
197
62
|
|
|
198
|
-
|
|
63
|
+
### 需求管理(6个)
|
|
199
64
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
- `keywords` (可选): 关键词
|
|
209
|
-
- `steps` (可选): 测试步骤数组
|
|
210
|
-
- `expects` (可选): 预期结果数组
|
|
65
|
+
| 工具 | 说明 |
|
|
66
|
+
|------|------|
|
|
67
|
+
| `get_story_detail` | 获取需求详情 |
|
|
68
|
+
| `get_story_list` | 获取需求列表 |
|
|
69
|
+
| `create_story` | 创建需求 |
|
|
70
|
+
| `edit_story` | 编辑需求(自动补全技术定级等环境必填项) |
|
|
71
|
+
| `close_story` | 关闭需求 |
|
|
72
|
+
| `activate_story` | 激活需求 |
|
|
211
73
|
|
|
212
|
-
###
|
|
74
|
+
### 任务管理(6个)
|
|
213
75
|
|
|
214
|
-
|
|
76
|
+
| 工具 | 说明 |
|
|
77
|
+
|------|------|
|
|
78
|
+
| `get_task_detail` | 获取任务详情 |
|
|
79
|
+
| `create_task` | 创建任务(自动填充类型/时间/优先级) |
|
|
80
|
+
| `assign_task` | 指派任务(自动补全 `projectID`) |
|
|
81
|
+
| `start_task` | 开始任务 |
|
|
82
|
+
| `finish_task` | 完成任务(自动补全 `consumed` 等必填项) |
|
|
83
|
+
| `close_task` | 关闭任务 |
|
|
215
84
|
|
|
216
|
-
|
|
217
|
-
- `csv_file_path` (必需): CSV文件路径
|
|
218
|
-
- `case_type` (可选): 用例类型(interface、feature、接口测试、功能测试,会自动识别)
|
|
219
|
-
- `product_id` (可选): 产品ID
|
|
220
|
-
- `opened_by` (可选): 创建人
|
|
221
|
-
- `keywords` (可选): 关键词
|
|
85
|
+
### 产品 & 模块(2个)
|
|
222
86
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
87
|
+
| 工具 | 说明 |
|
|
88
|
+
|------|------|
|
|
89
|
+
| `get_product_list` | 获取所有产品列表 |
|
|
90
|
+
| `get_module_list` | 获取模块树(需求/Bug/用例视图) |
|
|
226
91
|
|
|
227
|
-
### 5
|
|
92
|
+
### 测试用例(5个)
|
|
228
93
|
|
|
229
|
-
|
|
94
|
+
| 工具 | 说明 |
|
|
95
|
+
|------|------|
|
|
96
|
+
| `get_case_list` | 获取用例列表 |
|
|
97
|
+
| `get_case_detail` | 获取用例详情 |
|
|
98
|
+
| `create_case` | 创建用例(原生+网关双通道确保获取 caseID) |
|
|
99
|
+
| `create_cases_from_csv` | CSV批量创建用例 |
|
|
100
|
+
| `submit_csv_cases_to_zentao` | CSV批量提交用例(带备份) |
|
|
230
101
|
|
|
231
|
-
|
|
232
|
-
- `csv_file_path` (必需): CSV文件路径
|
|
233
|
-
- `case_type` (可选): 用例类型(interface、feature、接口测试、功能测试,会自动识别)
|
|
234
|
-
- `product_id` (可选): 产品ID
|
|
235
|
-
- `opened_by` (可选): 创建人
|
|
236
|
-
- `keywords` (可选): 关键词
|
|
102
|
+
### 发布管理(1个)
|
|
237
103
|
|
|
238
|
-
|
|
104
|
+
| 工具 | 说明 |
|
|
105
|
+
|------|------|
|
|
106
|
+
| `get_release_list` | 获取发布列表 |
|
|
239
107
|
|
|
240
|
-
|
|
108
|
+
### 我的地盘(4个)
|
|
241
109
|
|
|
242
|
-
|
|
110
|
+
| 工具 | 说明 |
|
|
111
|
+
|------|------|
|
|
112
|
+
| `get_my_work` | 获取待办概览(Bug+任务+需求+Todo 一次全返回) |
|
|
113
|
+
| `get_my_bug` | 获取我的Bug |
|
|
114
|
+
| `get_my_task` | 获取我的任务 |
|
|
115
|
+
| `get_my_todo` | 获取我的待办 |
|
|
243
116
|
|
|
244
|
-
|
|
117
|
+
### 用户(1个)
|
|
245
118
|
|
|
246
|
-
|
|
247
|
-
|
|
119
|
+
| 工具 | 说明 |
|
|
120
|
+
|------|------|
|
|
121
|
+
| `search_user` | 按姓名或工号模糊搜索用户 |
|
|
248
122
|
|
|
249
|
-
|
|
123
|
+
### 配置(1个)
|
|
250
124
|
|
|
251
|
-
|
|
125
|
+
| 工具 | 说明 |
|
|
126
|
+
|------|------|
|
|
127
|
+
| `get_config` | 获取当前配置和API版本信息 |
|
|
252
128
|
|
|
253
|
-
|
|
129
|
+
## 使用示例
|
|
254
130
|
|
|
255
|
-
|
|
256
|
-
- `task_data` (必需): 任务数据对象,包含任务相关字段(form-data格式)
|
|
131
|
+
### Bug 全生命周期
|
|
257
132
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
### 9. assign_task
|
|
267
|
-
|
|
268
|
-
指派任务。
|
|
133
|
+
```
|
|
134
|
+
"帮我创建一个Bug,标题是'登录页面验证码不显示',步骤:1.打开登录页 2.验证码区域空白"
|
|
135
|
+
"查看Bug 121128的详情"
|
|
136
|
+
"把Bug 121128指派给张三"
|
|
137
|
+
"解决Bug 121128,标记为已修复"
|
|
138
|
+
"关闭Bug 121128"
|
|
139
|
+
"重新激活Bug 121128"
|
|
140
|
+
```
|
|
269
141
|
|
|
270
|
-
|
|
271
|
-
- `task_id` (必需): 任务ID
|
|
272
|
-
- `assigned_to` (必需): 新的指派人(姓名或工号)
|
|
273
|
-
- `comment` (可选): 指派备注
|
|
274
|
-
|
|
275
|
-
### 10. get_bug_list
|
|
142
|
+
### 任务全生命周期
|
|
276
143
|
|
|
277
|
-
|
|
144
|
+
```
|
|
145
|
+
"创建一个任务,名称'优化登录接口性能',分配给张三"
|
|
146
|
+
"开始任务 828221"
|
|
147
|
+
"完成任务 828221"
|
|
148
|
+
"关闭任务 828221"
|
|
149
|
+
```
|
|
278
150
|
|
|
279
|
-
|
|
280
|
-
- `product_id` (必需): 产品ID
|
|
281
|
-
- `assigned_to` (可选): 指派人(姓名或工号)
|
|
282
|
-
- `opened_by` (可选): 创建人(姓名或工号)
|
|
283
|
-
- `resolved_by` (可选): 解决人(姓名或工号)
|
|
284
|
-
- `confirmed` (可选): 是否确认(2=已确认,1=未确认,0或不传=所有)
|
|
285
|
-
- `status` (可选): 状态(激活/已解决/已关闭)
|
|
286
|
-
- `start_date` (可选): 创建开始日期(格式:YYYY-MM-DD)
|
|
287
|
-
- `end_date` (可选): 创建截止日期(格式:YYYY-MM-DD)
|
|
151
|
+
### 我的待办
|
|
288
152
|
|
|
289
|
-
|
|
153
|
+
```
|
|
154
|
+
"看看我有什么待办" → 调用 get_my_work,一次返回所有 Bug/任务/需求/Todo
|
|
155
|
+
"查看指派给我的Bug" → 调用 get_my_bug
|
|
156
|
+
```
|
|
290
157
|
|
|
291
|
-
|
|
158
|
+
## 项目结构
|
|
292
159
|
|
|
293
|
-
|
|
294
|
-
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
160
|
+
```
|
|
161
|
+
zentao-mcp/
|
|
162
|
+
├── index.js # Node.js 入口(自动检测Python、安装依赖)
|
|
163
|
+
├── src/
|
|
164
|
+
│ ├── mcp_server.py # MCP 服务器(36 工具注册和路由)
|
|
165
|
+
│ ├── zentao_nexus.py # 禅道原生API客户端 + 业务层
|
|
166
|
+
│ └── bug_classifier.py # Bug 智能分类引擎
|
|
167
|
+
├── testing/
|
|
168
|
+
│ ├── test_zentao_api.py # Pytest 全能力测试(40 条,严格断言)
|
|
169
|
+
│ ├── TEST_README.md # 测试说明
|
|
170
|
+
│ └── mcp.json # 测试环境配置
|
|
171
|
+
├── docs/
|
|
172
|
+
│ ├── zentao-native-api.md # 原生 API 文档
|
|
173
|
+
│ └── RELEASE.md # 发布说明
|
|
174
|
+
├── package.json
|
|
175
|
+
├── requirements.txt
|
|
176
|
+
└── README.md
|
|
177
|
+
```
|
|
310
178
|
|
|
311
|
-
##
|
|
179
|
+
## 技术架构
|
|
312
180
|
|
|
313
181
|
```
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
├── index.js # npm 入口文件
|
|
324
|
-
├── package.json # npm 包配置
|
|
325
|
-
├── requirements.txt # Python 依赖
|
|
326
|
-
└── README.md # 项目说明
|
|
182
|
+
AI 编辑器 (Cursor/Claude)
|
|
183
|
+
↕ MCP 协议 (stdio)
|
|
184
|
+
MCP Server (mcp_server.py)
|
|
185
|
+
↕ 36 Tool 定义 & 路由
|
|
186
|
+
ZenTaoNexus (zentao_nexus.py) — 业务封装层
|
|
187
|
+
↕
|
|
188
|
+
ZenTaoNativeClient — 原生 API 客户端
|
|
189
|
+
↕ HTTP POST (api.php?m=module&f=action)
|
|
190
|
+
禅道服务器
|
|
327
191
|
```
|
|
328
192
|
|
|
329
|
-
|
|
193
|
+
## 测试
|
|
330
194
|
|
|
331
|
-
|
|
195
|
+
```bash
|
|
196
|
+
pytest -q testing/test_zentao_api.py -s
|
|
197
|
+
```
|
|
332
198
|
|
|
333
|
-
|
|
199
|
+
40 条 Pytest 用例,覆盖 A~G 七个分组,严格成功判定(详见 `testing/TEST_README.md`)。
|
|
200
|
+
|
|
201
|
+
## v2.0 vs v1.x 对比
|
|
202
|
+
|
|
203
|
+
| 维度 | v1.x | v2.0 |
|
|
204
|
+
|------|------|------|
|
|
205
|
+
| API 模式 | 混合(allneedlist + 部分原生) | 全部原生 |
|
|
206
|
+
| 工具数 | 20 | 36 |
|
|
207
|
+
| Bug 字段 | 10-20 | 50+ |
|
|
208
|
+
| Bug 操作 | 创建/查看/解决/关闭/激活 | +确认/指派/编辑 |
|
|
209
|
+
| 任务操作 | 创建/查看/指派 | +开始/完成/关闭 |
|
|
210
|
+
| 需求操作 | 创建/查看/列表 | +编辑/关闭/激活 |
|
|
211
|
+
| 用例操作 | 创建/CSV导入 | +列表/详情 |
|
|
212
|
+
| 我的地盘 | 无 | Bug/任务/需求/Todo |
|
|
213
|
+
| 发布管理 | 无 | 发布列表 |
|
|
214
|
+
| 用户搜索 | 无 | 按姓名/工号搜索 |
|
|
215
|
+
| ACW 依赖 | 有 | 无 |
|
|
216
|
+
| 测试 | 手工/unittest | 40 条 Pytest 严格断言 |
|
|
334
217
|
|
|
335
218
|
## 许可证
|
|
336
219
|
|
package/index.js
CHANGED
|
@@ -140,11 +140,11 @@ function checkPythonDependencies(python) {
|
|
|
140
140
|
function getScriptPath() {
|
|
141
141
|
// 获取当前包的目录
|
|
142
142
|
const packageDir = __dirname;
|
|
143
|
-
const scriptPath = path.join(packageDir, 'src', '
|
|
143
|
+
const scriptPath = path.join(packageDir, 'src', 'mcp', 'server.py');
|
|
144
144
|
|
|
145
145
|
if (!fs.existsSync(scriptPath)) {
|
|
146
146
|
// 尝试相对路径(开发环境)
|
|
147
|
-
const devPath = path.join(packageDir, '..', 'src', '
|
|
147
|
+
const devPath = path.join(packageDir, '..', 'src', 'mcp', 'server.py');
|
|
148
148
|
if (fs.existsSync(devPath)) {
|
|
149
149
|
return devPath;
|
|
150
150
|
}
|
package/main.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""ZenBot v2 入口:启动钉钉 Stream 客户端"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent / "src"))
|
|
11
|
+
|
|
12
|
+
from dotenv import load_dotenv
|
|
13
|
+
from dingtalk_stream import DingTalkStreamClient, Credential, ChatbotMessage
|
|
14
|
+
|
|
15
|
+
from zenbot.config import JsonFormatter
|
|
16
|
+
from zenbot.dingtalk_handler import ZentaoBotHandler
|
|
17
|
+
|
|
18
|
+
load_dotenv()
|
|
19
|
+
|
|
20
|
+
_stderr_handler = logging.StreamHandler(sys.stderr)
|
|
21
|
+
_stderr_handler.setFormatter(JsonFormatter())
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger("zentaoagent")
|
|
24
|
+
logger.addHandler(_stderr_handler)
|
|
25
|
+
logger.setLevel(logging.INFO)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def main():
|
|
29
|
+
client_id = os.getenv("DINGTALK_APP_KEY")
|
|
30
|
+
client_secret = os.getenv("DINGTALK_APP_SECRET")
|
|
31
|
+
if not client_id or not client_secret:
|
|
32
|
+
logger.error("缺少 DINGTALK_APP_KEY 或 DINGTALK_APP_SECRET")
|
|
33
|
+
sys.exit(1)
|
|
34
|
+
|
|
35
|
+
credential = Credential(client_id, client_secret)
|
|
36
|
+
bot_handler = ZentaoBotHandler()
|
|
37
|
+
client = DingTalkStreamClient(credential, logger)
|
|
38
|
+
client.register_callback_handler(ChatbotMessage.TOPIC, bot_handler)
|
|
39
|
+
logger.info("ZenBot v2 启动中...")
|
|
40
|
+
client.start_forever()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
if __name__ == "__main__":
|
|
44
|
+
main()
|
package/package.json
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bangdao-ai/zentao-mcp",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "禅道项目管理AI中枢 v2.0 — 35+MCP工具覆盖需求·任务·Bug·用例·发布·我的地盘全生命周期,原生API模式,Bug智能分类引擎+CSV批量用例导入+截图上传,一句话驱动禅道",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"zentao-mcp": "index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"start": "node index.js"
|
|
10
|
+
"start": "node index.js",
|
|
11
|
+
"prepublishOnly": "bash scripts/publish.sh --dry-run",
|
|
12
|
+
"build": "bash scripts/build.sh",
|
|
13
|
+
"publish:dry": "bash scripts/publish.sh --dry-run",
|
|
14
|
+
"publish:patch": "bash scripts/publish.sh patch",
|
|
15
|
+
"publish:minor": "bash scripts/publish.sh minor",
|
|
16
|
+
"publish:major": "bash scripts/publish.sh major",
|
|
17
|
+
"release": "bash scripts/publish.sh"
|
|
11
18
|
},
|
|
12
19
|
"keywords": [
|
|
13
20
|
"mcp",
|
|
@@ -19,8 +26,11 @@
|
|
|
19
26
|
"license": "MIT",
|
|
20
27
|
"files": [
|
|
21
28
|
"index.js",
|
|
29
|
+
"main.py",
|
|
22
30
|
"src/**/*.py",
|
|
31
|
+
"src/zenbot/SOUL.md",
|
|
23
32
|
"requirements.txt",
|
|
33
|
+
".env.example",
|
|
24
34
|
"README.md",
|
|
25
35
|
"package.json"
|
|
26
36
|
],
|
package/requirements.txt
CHANGED
package/src/__init__.py
ADDED
|
File without changes
|
|
File without changes
|