@zzp123/mcp-zentao 1.17.0 → 1.17.2
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/CHANGELOG.md +26 -0
- package/README.md +2 -4
- package/dist/index-dev.js +0 -44
- package/dist/index-pm.js +0 -70
- package/dist/roleConfig.js +1 -3
- package/package.json +1 -1
- package/scripts/generate-role-versions.cjs +2 -4
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.17.2] - 2025-11-10
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **产品经理版优化** 📊
|
|
12
|
+
- 从产品经理版 (mcp-zentao-pm) 移除反馈管理工具(7个工具)
|
|
13
|
+
- 工具数量从 54 个减少到 47 个
|
|
14
|
+
- 包大小从 25 KB 减少到约 22 KB
|
|
15
|
+
- 更专注于产品规划和需求管理核心功能
|
|
16
|
+
|
|
17
|
+
### Technical
|
|
18
|
+
- 更新 `roleConfig.ts` 中的 pm 角色配置
|
|
19
|
+
- 重新生成产品经理版源文件 (`src/index-pm.ts`)
|
|
20
|
+
|
|
21
|
+
## [1.17.1] - 2025-11-10
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- **开发工程师版优化** 🔧
|
|
25
|
+
- 从开发工程师版 (mcp-zentao-dev) 移除工单管理工具(5个工具)
|
|
26
|
+
- 工具数量从 46 个减少到 41 个
|
|
27
|
+
- 包大小从 24 KB 减少到约 22 KB
|
|
28
|
+
- 更专注于核心开发工作流
|
|
29
|
+
|
|
30
|
+
### Technical
|
|
31
|
+
- 更新 `roleConfig.ts` 中的 dev 角色配置
|
|
32
|
+
- 重新生成开发工程师版源文件 (`src/index-dev.ts`)
|
|
33
|
+
|
|
8
34
|
## [1.17.0] - 2025-11-10
|
|
9
35
|
|
|
10
36
|
### Added
|
package/README.md
CHANGED
|
@@ -18,9 +18,9 @@ npm install @zzp123/mcp-zentao -g
|
|
|
18
18
|
| 版本 | 命令 | 工具数量 | 文件大小 | 适用角色 |
|
|
19
19
|
|------|------|---------|---------|---------|
|
|
20
20
|
| **完整版** | `zentao` | 94个 | 69 KB | 需要使用全部功能 |
|
|
21
|
-
| **产品经理版** | `zentao-pm` |
|
|
21
|
+
| **产品经理版** | `zentao-pm` | 47个 | 44 KB (-36%) | 需求、产品、计划管理 |
|
|
22
22
|
| **测试工程师版** | `zentao-qa` | 38个 | 38 KB (-45%) | Bug、测试用例、构建 |
|
|
23
|
-
| **开发工程师版** | `zentao-dev` |
|
|
23
|
+
| **开发工程师版** | `zentao-dev` | 41个 | 37 KB (-46%) | 任务、项目、Bug解决 |
|
|
24
24
|
|
|
25
25
|
### 如何选择版本?
|
|
26
26
|
|
|
@@ -47,7 +47,6 @@ npm install @zzp123/mcp-zentao -g
|
|
|
47
47
|
- ✅ 产品管理
|
|
48
48
|
- ✅ 计划管理
|
|
49
49
|
- ✅ 项目集管理
|
|
50
|
-
- ✅ 反馈管理
|
|
51
50
|
- ✅ Bug查看(只读)
|
|
52
51
|
- ✅ 任务查看(只读)
|
|
53
52
|
- ✅ 评论功能
|
|
@@ -80,7 +79,6 @@ npm install @zzp123/mcp-zentao -g
|
|
|
80
79
|
- ✅ 构建版本管理
|
|
81
80
|
- ✅ 需求查看(只读)
|
|
82
81
|
- ✅ 评论功能
|
|
83
|
-
- ✅ 工单管理
|
|
84
82
|
- ✅ 文件上传
|
|
85
83
|
</details>
|
|
86
84
|
|
package/dist/index-dev.js
CHANGED
|
@@ -447,50 +447,6 @@ server.tool("deleteBuild", { buildId: z.number() }, async ({ buildId }) => {
|
|
|
447
447
|
throw new Error("Please initialize Zentao API first");
|
|
448
448
|
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.deleteBuild(buildId), null, 2) }] };
|
|
449
449
|
});
|
|
450
|
-
server.tool("getTickets", {
|
|
451
|
-
browseType: z.string().optional(),
|
|
452
|
-
param: z.string().optional(),
|
|
453
|
-
orderBy: z.string().optional(),
|
|
454
|
-
page: z.number().optional(),
|
|
455
|
-
limit: z.number().optional()
|
|
456
|
-
}, async (params) => {
|
|
457
|
-
if (!zentaoApi)
|
|
458
|
-
throw new Error("Please initialize Zentao API first");
|
|
459
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.getTickets(params), null, 2) }] };
|
|
460
|
-
});
|
|
461
|
-
server.tool("getTicketDetail", { ticketId: z.number() }, async ({ ticketId }) => {
|
|
462
|
-
if (!zentaoApi)
|
|
463
|
-
throw new Error("Please initialize Zentao API first");
|
|
464
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.getTicketDetail(ticketId), null, 2) }] };
|
|
465
|
-
});
|
|
466
|
-
server.tool("createTicket", {
|
|
467
|
-
product: z.number(),
|
|
468
|
-
module: z.number(),
|
|
469
|
-
title: z.string(),
|
|
470
|
-
type: z.string().optional(),
|
|
471
|
-
desc: z.string().optional()
|
|
472
|
-
}, async (params) => {
|
|
473
|
-
if (!zentaoApi)
|
|
474
|
-
throw new Error("Please initialize Zentao API first");
|
|
475
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.createTicket(params), null, 2) }] };
|
|
476
|
-
});
|
|
477
|
-
server.tool("updateTicket", {
|
|
478
|
-
ticketId: z.number(),
|
|
479
|
-
product: z.number().optional(),
|
|
480
|
-
module: z.number().optional(),
|
|
481
|
-
title: z.string().optional(),
|
|
482
|
-
type: z.string().optional(),
|
|
483
|
-
desc: z.string().optional()
|
|
484
|
-
}, async ({ ticketId, ...params }) => {
|
|
485
|
-
if (!zentaoApi)
|
|
486
|
-
throw new Error("Please initialize Zentao API first");
|
|
487
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.updateTicket(ticketId, params), null, 2) }] };
|
|
488
|
-
});
|
|
489
|
-
server.tool("deleteTicket", { ticketId: z.number() }, async ({ ticketId }) => {
|
|
490
|
-
if (!zentaoApi)
|
|
491
|
-
throw new Error("Please initialize Zentao API first");
|
|
492
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.deleteTicket(ticketId), null, 2) }] };
|
|
493
|
-
});
|
|
494
450
|
server.tool("getModules", {
|
|
495
451
|
type: z.enum(['story', 'task', 'bug', 'case', 'feedback', 'product']),
|
|
496
452
|
id: z.number(),
|
package/dist/index-pm.js
CHANGED
|
@@ -568,76 +568,6 @@ server.tool("deleteStory", "删除需求 - 支持软件需求(story)和用户需
|
|
|
568
568
|
throw new Error("Please initialize Zentao API first");
|
|
569
569
|
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.deleteStory(storyId), null, 2) }] };
|
|
570
570
|
});
|
|
571
|
-
server.tool("getFeedbacks", {
|
|
572
|
-
solution: z.string().optional(),
|
|
573
|
-
orderBy: z.string().optional(),
|
|
574
|
-
page: z.number().optional(),
|
|
575
|
-
limit: z.number().optional()
|
|
576
|
-
}, async (params) => {
|
|
577
|
-
if (!zentaoApi)
|
|
578
|
-
throw new Error("Please initialize Zentao API first");
|
|
579
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.getFeedbacks(params), null, 2) }] };
|
|
580
|
-
});
|
|
581
|
-
server.tool("getFeedbackDetail", { feedbackId: z.number() }, async ({ feedbackId }) => {
|
|
582
|
-
if (!zentaoApi)
|
|
583
|
-
throw new Error("Please initialize Zentao API first");
|
|
584
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.getFeedbackDetail(feedbackId), null, 2) }] };
|
|
585
|
-
});
|
|
586
|
-
server.tool("createFeedback", {
|
|
587
|
-
product: z.number(),
|
|
588
|
-
module: z.number().optional(),
|
|
589
|
-
title: z.string(),
|
|
590
|
-
type: z.string().optional(),
|
|
591
|
-
desc: z.string().optional(),
|
|
592
|
-
public: z.number().optional(),
|
|
593
|
-
notify: z.number().optional(),
|
|
594
|
-
notifyEmail: z.string().optional(),
|
|
595
|
-
feedbackBy: z.string().optional()
|
|
596
|
-
}, async (params) => {
|
|
597
|
-
if (!zentaoApi)
|
|
598
|
-
throw new Error("Please initialize Zentao API first");
|
|
599
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.createFeedback(params), null, 2) }] };
|
|
600
|
-
});
|
|
601
|
-
server.tool("updateFeedback", {
|
|
602
|
-
feedbackId: z.number(),
|
|
603
|
-
product: z.number().optional(),
|
|
604
|
-
module: z.number().optional(),
|
|
605
|
-
title: z.string().optional(),
|
|
606
|
-
type: z.string().optional(),
|
|
607
|
-
desc: z.string().optional(),
|
|
608
|
-
public: z.number().optional(),
|
|
609
|
-
notify: z.number().optional(),
|
|
610
|
-
notifyEmail: z.string().optional(),
|
|
611
|
-
feedbackBy: z.string().optional()
|
|
612
|
-
}, async ({ feedbackId, ...params }) => {
|
|
613
|
-
if (!zentaoApi)
|
|
614
|
-
throw new Error("Please initialize Zentao API first");
|
|
615
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.updateFeedback(feedbackId, params), null, 2) }] };
|
|
616
|
-
});
|
|
617
|
-
server.tool("deleteFeedback", { feedbackId: z.number() }, async ({ feedbackId }) => {
|
|
618
|
-
if (!zentaoApi)
|
|
619
|
-
throw new Error("Please initialize Zentao API first");
|
|
620
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.deleteFeedback(feedbackId), null, 2) }] };
|
|
621
|
-
});
|
|
622
|
-
server.tool("assignFeedback", {
|
|
623
|
-
feedbackId: z.number(),
|
|
624
|
-
assignedTo: z.string().optional(),
|
|
625
|
-
comment: z.string().optional(),
|
|
626
|
-
mailto: z.string().optional()
|
|
627
|
-
}, async ({ feedbackId, ...params }) => {
|
|
628
|
-
if (!zentaoApi)
|
|
629
|
-
throw new Error("Please initialize Zentao API first");
|
|
630
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.assignFeedback(feedbackId, params), null, 2) }] };
|
|
631
|
-
});
|
|
632
|
-
server.tool("closeFeedback", {
|
|
633
|
-
feedbackId: z.number(),
|
|
634
|
-
closedReason: z.string().optional(),
|
|
635
|
-
comment: z.string().optional()
|
|
636
|
-
}, async ({ feedbackId, ...params }) => {
|
|
637
|
-
if (!zentaoApi)
|
|
638
|
-
throw new Error("Please initialize Zentao API first");
|
|
639
|
-
return { content: [{ type: "text", text: JSON.stringify(await zentaoApi.closeFeedback(feedbackId, params), null, 2) }] };
|
|
640
|
-
});
|
|
641
571
|
server.tool("getTickets", {
|
|
642
572
|
browseType: z.string().optional(),
|
|
643
573
|
param: z.string().optional(),
|
package/dist/roleConfig.js
CHANGED
|
@@ -86,14 +86,13 @@ export const TOOL_CATEGORIES = {
|
|
|
86
86
|
};
|
|
87
87
|
// 角色权限配置
|
|
88
88
|
export const ROLE_PERMISSIONS = {
|
|
89
|
-
//
|
|
89
|
+
// 产品经理:需求、产品、计划、项目集、评论
|
|
90
90
|
pm: [
|
|
91
91
|
...TOOL_CATEGORIES.init,
|
|
92
92
|
...TOOL_CATEGORIES.story,
|
|
93
93
|
...TOOL_CATEGORIES.product,
|
|
94
94
|
...TOOL_CATEGORIES.plan,
|
|
95
95
|
...TOOL_CATEGORIES.program,
|
|
96
|
-
...TOOL_CATEGORIES.feedback,
|
|
97
96
|
...TOOL_CATEGORIES.bugReadonly,
|
|
98
97
|
...TOOL_CATEGORIES.taskReadonly,
|
|
99
98
|
...TOOL_CATEGORIES.comment,
|
|
@@ -122,7 +121,6 @@ export const ROLE_PERMISSIONS = {
|
|
|
122
121
|
...TOOL_CATEGORIES.build,
|
|
123
122
|
...TOOL_CATEGORIES.storyReadonly,
|
|
124
123
|
...TOOL_CATEGORIES.comment,
|
|
125
|
-
...TOOL_CATEGORIES.ticket,
|
|
126
124
|
...TOOL_CATEGORIES.utility
|
|
127
125
|
],
|
|
128
126
|
// 管理员:所有工具
|
package/package.json
CHANGED
|
@@ -32,7 +32,6 @@ const ROLE_PERMISSIONS = {
|
|
|
32
32
|
...TOOL_CATEGORIES.product,
|
|
33
33
|
...TOOL_CATEGORIES.plan,
|
|
34
34
|
...TOOL_CATEGORIES.program,
|
|
35
|
-
...TOOL_CATEGORIES.feedback,
|
|
36
35
|
...TOOL_CATEGORIES.bugReadonly,
|
|
37
36
|
...TOOL_CATEGORIES.taskReadonly,
|
|
38
37
|
...TOOL_CATEGORIES.comment,
|
|
@@ -59,7 +58,6 @@ const ROLE_PERMISSIONS = {
|
|
|
59
58
|
...TOOL_CATEGORIES.build,
|
|
60
59
|
...TOOL_CATEGORIES.storyReadonly,
|
|
61
60
|
...TOOL_CATEGORIES.comment,
|
|
62
|
-
...TOOL_CATEGORIES.ticket,
|
|
63
61
|
...TOOL_CATEGORIES.utility
|
|
64
62
|
]
|
|
65
63
|
};
|
|
@@ -71,7 +69,7 @@ const ROLE_NAMES = {
|
|
|
71
69
|
};
|
|
72
70
|
|
|
73
71
|
// 读取完整的 index.ts
|
|
74
|
-
const indexPath = path.join(__dirname, 'src', 'index.ts');
|
|
72
|
+
const indexPath = path.join(__dirname, '..', 'src', 'index.ts');
|
|
75
73
|
const indexContent = fs.readFileSync(indexPath, 'utf8');
|
|
76
74
|
|
|
77
75
|
// 提取工具注册块的函数
|
|
@@ -195,7 +193,7 @@ function extractToolBlocks(content) {
|
|
|
195
193
|
|
|
196
194
|
// 写入文件
|
|
197
195
|
const output = finalLines.join('\n');
|
|
198
|
-
const outputPath = path.join(__dirname, 'src', `index-${role}.ts`);
|
|
196
|
+
const outputPath = path.join(__dirname, '..', 'src', `index-${role}.ts`);
|
|
199
197
|
fs.writeFileSync(outputPath, output, 'utf8');
|
|
200
198
|
|
|
201
199
|
console.log(` ✓ 已生成: ${outputPath}`);
|