@xihe-lab/tapd-mcp-server 1.3.0 → 1.4.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.
Files changed (97) hide show
  1. package/README.md +56 -7
  2. package/dist/integration-test.d.ts +10 -0
  3. package/dist/integration-test.d.ts.map +1 -0
  4. package/dist/integration-test.js +117 -0
  5. package/dist/integration-test.js.map +1 -0
  6. package/dist/tapd-client.d.ts +32 -1
  7. package/dist/tapd-client.d.ts.map +1 -1
  8. package/dist/tapd-client.js +96 -19
  9. package/dist/tapd-client.js.map +1 -1
  10. package/dist/tools/attachment.d.ts.map +1 -1
  11. package/dist/tools/attachment.js +35 -10
  12. package/dist/tools/attachment.js.map +1 -1
  13. package/dist/tools/board.d.ts +3 -0
  14. package/dist/tools/board.d.ts.map +1 -0
  15. package/dist/tools/board.js +98 -0
  16. package/dist/tools/board.js.map +1 -0
  17. package/dist/tools/bug.d.ts.map +1 -1
  18. package/dist/tools/bug.js +382 -7
  19. package/dist/tools/bug.js.map +1 -1
  20. package/dist/tools/changes.d.ts.map +1 -1
  21. package/dist/tools/changes.js +25 -34
  22. package/dist/tools/changes.js.map +1 -1
  23. package/dist/tools/comment.d.ts.map +1 -1
  24. package/dist/tools/comment.js +53 -3
  25. package/dist/tools/comment.js.map +1 -1
  26. package/dist/tools/custom-fields.d.ts.map +1 -1
  27. package/dist/tools/custom-fields.js +43 -36
  28. package/dist/tools/custom-fields.js.map +1 -1
  29. package/dist/tools/image.d.ts +3 -0
  30. package/dist/tools/image.d.ts.map +1 -0
  31. package/dist/tools/image.js +23 -0
  32. package/dist/tools/image.js.map +1 -0
  33. package/dist/tools/index.d.ts.map +1 -1
  34. package/dist/tools/index.js +12 -0
  35. package/dist/tools/index.js.map +1 -1
  36. package/dist/tools/iteration.d.ts.map +1 -1
  37. package/dist/tools/iteration.js +95 -6
  38. package/dist/tools/iteration.js.map +1 -1
  39. package/dist/tools/mini-comment.d.ts.map +1 -1
  40. package/dist/tools/mini-comment.js +18 -5
  41. package/dist/tools/mini-comment.js.map +1 -1
  42. package/dist/tools/mini-item.d.ts.map +1 -1
  43. package/dist/tools/mini-item.js +36 -11
  44. package/dist/tools/mini-item.js.map +1 -1
  45. package/dist/tools/mini-workspace.d.ts.map +1 -1
  46. package/dist/tools/mini-workspace.js +13 -4
  47. package/dist/tools/mini-workspace.js.map +1 -1
  48. package/dist/tools/program.d.ts +3 -0
  49. package/dist/tools/program.d.ts.map +1 -0
  50. package/dist/tools/program.js +27 -0
  51. package/dist/tools/program.js.map +1 -0
  52. package/dist/tools/relations.d.ts.map +1 -1
  53. package/dist/tools/relations.js +25 -30
  54. package/dist/tools/relations.js.map +1 -1
  55. package/dist/tools/release.d.ts.map +1 -1
  56. package/dist/tools/release.js +228 -2
  57. package/dist/tools/release.js.map +1 -1
  58. package/dist/tools/report.d.ts +3 -0
  59. package/dist/tools/report.d.ts.map +1 -0
  60. package/dist/tools/report.js +38 -0
  61. package/dist/tools/report.js.map +1 -0
  62. package/dist/tools/settings.d.ts.map +1 -1
  63. package/dist/tools/settings.js +379 -31
  64. package/dist/tools/settings.js.map +1 -1
  65. package/dist/tools/source.d.ts +3 -0
  66. package/dist/tools/source.d.ts.map +1 -0
  67. package/dist/tools/source.js +69 -0
  68. package/dist/tools/source.js.map +1 -0
  69. package/dist/tools/story.d.ts.map +1 -1
  70. package/dist/tools/story.js +650 -160
  71. package/dist/tools/story.js.map +1 -1
  72. package/dist/tools/task.d.ts.map +1 -1
  73. package/dist/tools/task.js +104 -11
  74. package/dist/tools/task.js.map +1 -1
  75. package/dist/tools/test.d.ts.map +1 -1
  76. package/dist/tools/test.js +505 -75
  77. package/dist/tools/test.js.map +1 -1
  78. package/dist/tools/timesheet.d.ts.map +1 -1
  79. package/dist/tools/timesheet.js +72 -11
  80. package/dist/tools/timesheet.js.map +1 -1
  81. package/dist/tools/user.d.ts.map +1 -1
  82. package/dist/tools/user.js +36 -4
  83. package/dist/tools/user.js.map +1 -1
  84. package/dist/tools/utility.d.ts +3 -0
  85. package/dist/tools/utility.d.ts.map +1 -0
  86. package/dist/tools/utility.js +132 -0
  87. package/dist/tools/utility.js.map +1 -0
  88. package/dist/tools/wiki.d.ts.map +1 -1
  89. package/dist/tools/wiki.js +75 -20
  90. package/dist/tools/wiki.js.map +1 -1
  91. package/dist/tools/workflow.d.ts.map +1 -1
  92. package/dist/tools/workflow.js +78 -6
  93. package/dist/tools/workflow.js.map +1 -1
  94. package/dist/tools/workspace.d.ts.map +1 -1
  95. package/dist/tools/workspace.js +93 -4
  96. package/dist/tools/workspace.js.map +1 -1
  97. package/package.json +2 -1
@@ -1,27 +1,35 @@
1
1
  import { z } from 'zod';
2
2
  import { TapdClient } from '../tapd-client.js';
3
3
  export const testTools = [
4
+ // 测试用例 CRUD
4
5
  {
5
6
  name: "tapd_create_test_case",
6
- description: "Create a new test case in TAPD",
7
- inputSchema: z.object({
8
- workspace_id: z.number().describe("Project ID (required)"),
9
- name: z.string().describe("Test case name (required)"),
10
- category_id: z.string().optional().describe("Category ID"),
11
- priority: z.string().optional().describe("Priority level"),
12
- creator: z.string().optional().describe("Creator (defaults to TAPD_NICK_NAME env)"),
13
- owner: z.string().optional().describe("Owner"),
14
- description: z.string().optional().describe("Test case description"),
15
- teststeps: z.string().optional().describe("Test steps"),
16
- expectresult: z.string().optional().describe("Expected result"),
17
- status: z.string().optional().describe("Status"),
18
- iteration_id: z.string().optional().describe("Iteration ID"),
19
- custom_field_one: z.string().optional().describe("Custom field 1 (supports 1-200)"),
7
+ description: "创建测试用例",
8
+ inputSchema: z.object({
9
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
10
+ name: z.string().describe("测试用例名称 (必填)"),
11
+ category_id: z.string().optional().describe("分类ID"),
12
+ priority: z.string().optional().describe("优先级"),
13
+ status: z.string().optional().describe("状态: updating/abandon/normal"),
14
+ description: z.string().optional().describe("描述"),
15
+ teststeps: z.string().optional().describe("测试步骤"),
16
+ expectresult: z.string().optional().describe("预期结果"),
17
+ precondition: z.string().optional().describe("前置条件"),
18
+ type: z.string().optional().describe("用例类型"),
19
+ iteration_id: z.string().optional().describe("迭代ID"),
20
+ owner: z.string().optional().describe("负责人"),
21
+ creator: z.string().optional().describe("创建人(默认当前用户)"),
22
+ custom_field_one: z.string().optional().describe("自定义字段 (支持 1-200)"),
20
23
  }),
21
24
  handler: async (client, params) => {
25
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
26
+ if (!workspaceId) {
27
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
28
+ }
22
29
  const nickName = TapdClient.getNickName();
23
30
  const finalParams = {
24
31
  ...params,
32
+ workspace_id: workspaceId,
25
33
  creator: params.creator ?? nickName,
26
34
  };
27
35
  return client.post("/tcases", finalParams);
@@ -29,67 +37,329 @@ export const testTools = [
29
37
  },
30
38
  {
31
39
  name: "tapd_get_test_cases",
32
- description: "Get test cases from TAPD",
40
+ description: "获取测试用例列表",
41
+ inputSchema: z.object({
42
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
43
+ id: z.string().optional().describe("测试用例ID,支持多ID查询"),
44
+ name: z.string().optional().describe("测试用例名称,支持模糊匹配"),
45
+ status: z.string().optional().describe("状态: updating/abandon/normal"),
46
+ priority: z.string().optional().describe("优先级"),
47
+ category_id: z.string().optional().describe("分类ID"),
48
+ iteration_id: z.string().optional().describe("迭代ID"),
49
+ creator: z.string().optional().describe("创建人"),
50
+ owner: z.string().optional().describe("负责人"),
51
+ created: z.string().optional().describe("创建时间,支持时间查询"),
52
+ modified: z.string().optional().describe("修改时间,支持时间查询"),
53
+ custom_field_one: z.string().optional().describe("自定义字段"),
54
+ limit: z.number().optional().describe("返回数量,默认30,最大200"),
55
+ page: z.number().optional().describe("页码,默认1"),
56
+ order: z.string().optional().describe("排序规则"),
57
+ fields: z.string().optional().describe("返回字段"),
58
+ }),
59
+ handler: async (client, params) => {
60
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
61
+ if (!workspaceId) {
62
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
63
+ }
64
+ return client.get("/tcases", { ...params, workspace_id: workspaceId });
65
+ },
66
+ },
67
+ {
68
+ name: "tapd_get_test_cases_count",
69
+ description: "获取测试用例数量",
70
+ inputSchema: z.object({
71
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
72
+ id: z.string().optional().describe("测试用例ID"),
73
+ name: z.string().optional().describe("测试用例名称"),
74
+ status: z.string().optional().describe("状态"),
75
+ priority: z.string().optional().describe("优先级"),
76
+ category_id: z.string().optional().describe("分类ID"),
77
+ iteration_id: z.string().optional().describe("迭代ID"),
78
+ creator: z.string().optional().describe("创建人"),
79
+ owner: z.string().optional().describe("负责人"),
80
+ }),
81
+ handler: async (client, params) => {
82
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
83
+ if (!workspaceId) {
84
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
85
+ }
86
+ return client.get("/tcases/count", { ...params, workspace_id: workspaceId });
87
+ },
88
+ },
89
+ {
90
+ name: "tapd_update_test_case",
91
+ description: "更新测试用例",
92
+ inputSchema: z.object({
93
+ id: z.string().describe("测试用例ID (必填)"),
94
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
95
+ name: z.string().optional().describe("测试用例名称"),
96
+ status: z.string().optional().describe("状态"),
97
+ priority: z.string().optional().describe("优先级"),
98
+ category_id: z.string().optional().describe("分类ID"),
99
+ description: z.string().optional().describe("描述"),
100
+ teststeps: z.string().optional().describe("测试步骤"),
101
+ expectresult: z.string().optional().describe("预期结果"),
102
+ precondition: z.string().optional().describe("前置条件"),
103
+ type: z.string().optional().describe("用例类型"),
104
+ iteration_id: z.string().optional().describe("迭代ID"),
105
+ owner: z.string().optional().describe("负责人"),
106
+ custom_field_one: z.string().optional().describe("自定义字段"),
107
+ }),
108
+ handler: async (client, params) => {
109
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
110
+ if (!workspaceId) {
111
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
112
+ }
113
+ return client.post("/tcases", { ...params, workspace_id: workspaceId });
114
+ },
115
+ },
116
+ // 测试用例分类
117
+ {
118
+ name: "tapd_get_tcase_categories",
119
+ description: "获取测试用例分类列表",
120
+ inputSchema: z.object({
121
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
122
+ id: z.string().optional().describe("分类ID,支持多ID查询"),
123
+ name: z.string().optional().describe("分类名称,支持模糊匹配"),
124
+ parent_id: z.number().optional().describe("父分类ID"),
125
+ created: z.string().optional().describe("创建时间"),
126
+ modified: z.string().optional().describe("修改时间"),
127
+ limit: z.number().optional().describe("返回数量"),
128
+ page: z.number().optional().describe("页码"),
129
+ order: z.string().optional().describe("排序"),
130
+ fields: z.string().optional().describe("返回字段"),
131
+ }),
132
+ handler: async (client, params) => {
133
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
134
+ if (!workspaceId) {
135
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
136
+ }
137
+ return client.get("/tcase_categories", { ...params, workspace_id: workspaceId });
138
+ },
139
+ },
140
+ {
141
+ name: "tapd_get_tcase_categories_count",
142
+ description: "获取测试用例分类数量",
143
+ inputSchema: z.object({
144
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
145
+ id: z.string().optional().describe("分类ID"),
146
+ name: z.string().optional().describe("分类名称"),
147
+ parent_id: z.number().optional().describe("父分类ID"),
148
+ }),
149
+ handler: async (client, params) => {
150
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
151
+ if (!workspaceId) {
152
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
153
+ }
154
+ return client.get("/tcase_categories/count", { ...params, workspace_id: workspaceId });
155
+ },
156
+ },
157
+ {
158
+ name: "tapd_add_tcase_category",
159
+ description: "创建测试用例分类",
160
+ inputSchema: z.object({
161
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
162
+ name: z.string().describe("分类名称 (必填)"),
163
+ parent_id: z.number().optional().describe("父分类ID(用于创建子分类)"),
164
+ }),
165
+ handler: async (client, params) => {
166
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
167
+ if (!workspaceId) {
168
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
169
+ }
170
+ return client.post("/tcase_categories", { ...params, workspace_id: workspaceId });
171
+ },
172
+ },
173
+ // 测试用例配置
174
+ {
175
+ name: "tapd_get_tcase_custom_fields_settings",
176
+ description: "获取测试用例自定义字段配置",
177
+ inputSchema: z.object({
178
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
179
+ }),
180
+ handler: async (client, params) => {
181
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
182
+ if (!workspaceId) {
183
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
184
+ }
185
+ return client.get("/tcases/custom_fields_settings", { ...params, workspace_id: workspaceId });
186
+ },
187
+ },
188
+ {
189
+ name: "tapd_get_tcase_fields_info",
190
+ description: "获取测试用例字段信息",
191
+ inputSchema: z.object({
192
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
193
+ }),
194
+ handler: async (client, params) => {
195
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
196
+ if (!workspaceId) {
197
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
198
+ }
199
+ return client.get("/tcases/get_fields_info", { ...params, workspace_id: workspaceId });
200
+ },
201
+ },
202
+ {
203
+ name: "tapd_get_story_by_tcase_id",
204
+ description: "获取测试用例关联的需求",
205
+ inputSchema: z.object({
206
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
207
+ tcase_id: z.string().describe("测试用例ID (必填)"),
208
+ }),
209
+ handler: async (client, params) => {
210
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
211
+ if (!workspaceId) {
212
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
213
+ }
214
+ return client.get("/tcases/get_story_by_tcase_id", { ...params, workspace_id: workspaceId });
215
+ },
216
+ },
217
+ // 测试用例执行
218
+ {
219
+ name: "tapd_assign_tcase_instance",
220
+ description: "分配测试用例执行人",
221
+ inputSchema: z.object({
222
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
223
+ test_plan_id: z.string().describe("测试计划ID (必填)"),
224
+ tcase_id: z.string().describe("测试用例ID (必填)"),
225
+ owner: z.string().describe("分配的执行人 (必填)"),
226
+ }),
227
+ handler: async (client, params) => {
228
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
229
+ if (!workspaceId) {
230
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
231
+ }
232
+ return client.post("/tcase_instance/assign", { ...params, workspace_id: workspaceId });
233
+ },
234
+ },
235
+ {
236
+ name: "tapd_execute_tcase_instance",
237
+ description: "执行测试用例",
238
+ inputSchema: z.object({
239
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
240
+ tcase_id: z.string().describe("测试用例ID (必填)"),
241
+ test_plan_id: z.string().describe("测试计划ID (必填)"),
242
+ result: z.string().describe("执行结果 (必填): pass/fail/block"),
243
+ run_step: z.string().optional().describe("执行步骤结果(JSON格式)"),
244
+ actual_result: z.string().optional().describe("实际结果"),
245
+ bug_id: z.string().optional().describe("关联缺陷ID"),
246
+ executed_by: z.string().optional().describe("执行人(默认当前用户)"),
247
+ }),
248
+ handler: async (client, params) => {
249
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
250
+ if (!workspaceId) {
251
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
252
+ }
253
+ return client.post("/tcase_instance/execute", { ...params, workspace_id: workspaceId });
254
+ },
255
+ },
256
+ {
257
+ name: "tapd_get_tcase_result",
258
+ description: "获取测试用例执行结果",
33
259
  inputSchema: z.object({
34
- workspace_id: z.number().describe("Project ID"),
35
- id: z.string().optional().describe("Test case ID, supports multiple IDs"),
36
- name: z.string().optional().describe("Test case name, supports fuzzy matching"),
37
- status: z.string().optional().describe("Status of the test case"),
38
- category_id: z.string().optional().describe("Category ID"),
39
- creator: z.string().optional().describe("Creator name"),
40
- owner: z.string().optional().describe("Owner"),
41
- priority: z.string().optional().describe("Priority level"),
42
- iteration_id: z.string().optional().describe("Iteration ID"),
43
- created: z.string().optional().describe("Creation time, supports time query"),
44
- modified: z.string().optional().describe("Modification time, supports time query"),
45
- custom_field_one: z.string().optional().describe("Custom field 1 (supports 1-200)"),
46
- limit: z.number().optional().describe("Number of results to return, max 200"),
47
- page: z.number().optional().describe("Page number, default 1"),
48
- order: z.string().optional().describe("Sort order, e.g., 'created desc'"),
49
- fields: z.string().optional().describe("Comma-separated list of fields to return"),
260
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
261
+ tcase_id: z.string().optional().describe("测试用例ID"),
262
+ test_plan_id: z.string().optional().describe("测试计划ID"),
263
+ result: z.string().optional().describe("执行结果: pass/fail/block"),
264
+ executed_by: z.string().optional().describe("执行人"),
265
+ executed: z.string().optional().describe("执行时间"),
266
+ limit: z.number().optional().describe("返回数量"),
267
+ page: z.number().optional().describe("页码"),
268
+ fields: z.string().optional().describe("返回字段"),
50
269
  }),
51
270
  handler: async (client, params) => {
52
- return client.get("/tcases", params);
271
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
272
+ if (!workspaceId) {
273
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
274
+ }
275
+ return client.get("/tcase_instance/result", { ...params, workspace_id: workspaceId });
53
276
  },
54
277
  },
278
+ {
279
+ name: "tapd_remove_tcase_instance",
280
+ description: "测试用例移出测试计划",
281
+ inputSchema: z.object({
282
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
283
+ test_plan_id: z.string().describe("测试计划ID (必填)"),
284
+ tcase_id: z.string().describe("测试用例ID (必填)"),
285
+ }),
286
+ handler: async (client, params) => {
287
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
288
+ if (!workspaceId) {
289
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
290
+ }
291
+ return client.post("/tcase_instance/remove_tcase", { ...params, workspace_id: workspaceId });
292
+ },
293
+ },
294
+ {
295
+ name: "tapd_delete_tcase_story_relation",
296
+ description: "解除测试用例与需求关联",
297
+ inputSchema: z.object({
298
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
299
+ tcase_id: z.string().describe("测试用例ID (必填)"),
300
+ story_id: z.string().describe("需求ID (必填)"),
301
+ }),
302
+ handler: async (client, params) => {
303
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
304
+ if (!workspaceId) {
305
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
306
+ }
307
+ return client.post("/tcase_instance/delete_tcase_story_relation", { ...params, workspace_id: workspaceId });
308
+ },
309
+ },
310
+ // 测试计划 CRUD
55
311
  {
56
312
  name: "tapd_get_test_plans",
57
- description: "Get test plans from TAPD",
313
+ description: "获取测试计划列表",
58
314
  inputSchema: z.object({
59
- workspace_id: z.number().describe("Project ID"),
60
- id: z.string().optional().describe("Test plan ID, supports multiple IDs"),
61
- name: z.string().optional().describe("Test plan name, supports fuzzy matching"),
62
- status: z.string().optional().describe("Status of the test plan"),
63
- creator: z.string().optional().describe("Creator name"),
64
- owner: z.string().optional().describe("Owner name"),
65
- limit: z.number().optional().describe("Number of results to return, max 200"),
66
- page: z.number().optional().describe("Page number, default 1"),
67
- order: z.string().optional().describe("Sort order, e.g., 'created desc'"),
68
- fields: z.string().optional().describe("Comma-separated list of fields to return"),
315
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
316
+ id: z.string().optional().describe("测试计划ID,支持多ID查询"),
317
+ name: z.string().optional().describe("测试计划名称,支持模糊匹配"),
318
+ status: z.string().optional().describe("状态"),
319
+ creator: z.string().optional().describe("创建人"),
320
+ owner: z.string().optional().describe("负责人"),
321
+ begin: z.string().optional().describe("开始日期"),
322
+ end: z.string().optional().describe("结束日期"),
323
+ created: z.string().optional().describe("创建时间"),
324
+ modified: z.string().optional().describe("修改时间"),
325
+ iteration_id: z.string().optional().describe("迭代ID"),
326
+ limit: z.number().optional().describe("返回数量,默认30,最大200"),
327
+ page: z.number().optional().describe("页码,默认1"),
328
+ order: z.string().optional().describe("排序"),
329
+ fields: z.string().optional().describe("返回字段"),
69
330
  }),
70
331
  handler: async (client, params) => {
71
- return client.get("/test_plans", params);
332
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
333
+ if (!workspaceId) {
334
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
335
+ }
336
+ return client.get("/test_plans", { ...params, workspace_id: workspaceId });
72
337
  },
73
338
  },
74
339
  {
75
340
  name: "tapd_create_test_plan",
76
- description: "Create a new test plan in TAPD",
341
+ description: "创建测试计划",
77
342
  inputSchema: z.object({
78
- workspace_id: z.number().describe("Project ID (required)"),
79
- name: z.string().describe("Test plan name (required)"),
80
- description: z.string().optional().describe("Test plan description"),
81
- owner: z.string().optional().describe("Owner (defaults to TAPD_NICK_NAME env)"),
82
- creator: z.string().optional().describe("Creator (defaults to TAPD_NICK_NAME env)"),
83
- begin: z.string().optional().describe("Start date (YYYY-MM-DD)"),
84
- end: z.string().optional().describe("End date (YYYY-MM-DD)"),
85
- status: z.string().optional().describe("Status"),
86
- category_id: z.string().optional().describe("Category ID"),
87
- iteration_id: z.string().optional().describe("Iteration ID"),
343
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
344
+ name: z.string().describe("测试计划名称 (必填)"),
345
+ description: z.string().optional().describe("描述"),
346
+ owner: z.string().optional().describe("负责人(默认当前用户)"),
347
+ creator: z.string().optional().describe("创建人(默认当前用户)"),
348
+ begin: z.string().optional().describe("开始日期 (YYYY-MM-DD)"),
349
+ end: z.string().optional().describe("结束日期 (YYYY-MM-DD)"),
350
+ status: z.string().optional().describe("状态"),
351
+ category_id: z.string().optional().describe("分类ID"),
352
+ iteration_id: z.string().optional().describe("迭代ID"),
88
353
  }),
89
354
  handler: async (client, params) => {
355
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
356
+ if (!workspaceId) {
357
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
358
+ }
90
359
  const nickName = TapdClient.getNickName();
91
360
  const finalParams = {
92
361
  ...params,
362
+ workspace_id: workspaceId,
93
363
  owner: params.owner ?? nickName,
94
364
  creator: params.creator ?? nickName,
95
365
  };
@@ -98,36 +368,196 @@ export const testTools = [
98
368
  },
99
369
  {
100
370
  name: "tapd_update_test_plan",
101
- description: "Update an existing test plan in TAPD",
371
+ description: "更新测试计划",
102
372
  inputSchema: z.object({
103
- workspace_id: z.number().describe("Project ID (required)"),
104
- id: z.string().describe("Test plan ID (required)"),
105
- name: z.string().optional().describe("Test plan name"),
106
- description: z.string().optional().describe("Test plan description"),
107
- owner: z.string().optional().describe("Owner"),
108
- begin: z.string().optional().describe("Start date (YYYY-MM-DD)"),
109
- end: z.string().optional().describe("End date (YYYY-MM-DD)"),
110
- status: z.string().optional().describe("Status"),
111
- category_id: z.string().optional().describe("Category ID"),
112
- iteration_id: z.string().optional().describe("Iteration ID"),
373
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
374
+ id: z.string().describe("测试计划ID (必填)"),
375
+ name: z.string().optional().describe("测试计划名称"),
376
+ description: z.string().optional().describe("描述"),
377
+ owner: z.string().optional().describe("负责人"),
378
+ begin: z.string().optional().describe("开始日期 (YYYY-MM-DD)"),
379
+ end: z.string().optional().describe("结束日期 (YYYY-MM-DD)"),
380
+ status: z.string().optional().describe("状态"),
381
+ category_id: z.string().optional().describe("分类ID"),
382
+ iteration_id: z.string().optional().describe("迭代ID"),
113
383
  }),
114
384
  handler: async (client, params) => {
115
- return client.post("/test_plans", params);
385
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
386
+ if (!workspaceId) {
387
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
388
+ }
389
+ return client.post("/test_plans", { ...params, workspace_id: workspaceId });
116
390
  },
117
391
  },
118
392
  {
119
393
  name: "tapd_get_test_plan_count",
120
- description: "Get the count of test plans",
394
+ description: "获取测试计划数量",
395
+ inputSchema: z.object({
396
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
397
+ id: z.string().optional().describe("测试计划ID"),
398
+ name: z.string().optional().describe("测试计划名称"),
399
+ status: z.string().optional().describe("状态"),
400
+ creator: z.string().optional().describe("创建人"),
401
+ owner: z.string().optional().describe("负责人"),
402
+ }),
403
+ handler: async (client, params) => {
404
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
405
+ if (!workspaceId) {
406
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
407
+ }
408
+ return client.get("/test_plans/count", { ...params, workspace_id: workspaceId });
409
+ },
410
+ },
411
+ // 测试计划详情
412
+ {
413
+ name: "tapd_get_test_plan_details",
414
+ description: "获取测试计划测试结果详情",
415
+ inputSchema: z.object({
416
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
417
+ test_plan_id: z.string().describe("测试计划ID (必填)"),
418
+ limit: z.number().optional().describe("返回数量"),
419
+ page: z.number().optional().describe("页码"),
420
+ fields: z.string().optional().describe("返回字段"),
421
+ }),
422
+ handler: async (client, params) => {
423
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
424
+ if (!workspaceId) {
425
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
426
+ }
427
+ return client.get("/test_plans/details", { ...params, workspace_id: workspaceId });
428
+ },
429
+ },
430
+ {
431
+ name: "tapd_get_test_plan_progress",
432
+ description: "获取测试计划执行进度",
433
+ inputSchema: z.object({
434
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
435
+ test_plan_id: z.string().describe("测试计划ID (必填)"),
436
+ }),
437
+ handler: async (client, params) => {
438
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
439
+ if (!workspaceId) {
440
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
441
+ }
442
+ return client.get("/test_plans/progress", { ...params, workspace_id: workspaceId });
443
+ },
444
+ },
445
+ {
446
+ name: "tapd_get_test_plan_fields_info",
447
+ description: "获取测试计划字段信息",
448
+ inputSchema: z.object({
449
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
450
+ }),
451
+ handler: async (client, params) => {
452
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
453
+ if (!workspaceId) {
454
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
455
+ }
456
+ return client.get("/test_plans/get_fields_info", { ...params, workspace_id: workspaceId });
457
+ },
458
+ },
459
+ // 测试计划关联
460
+ {
461
+ name: "tapd_get_test_plan_tcases",
462
+ description: "获取测试计划关联的测试用例",
463
+ inputSchema: z.object({
464
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
465
+ test_plan_id: z.string().describe("测试计划ID (必填)"),
466
+ tcase_id: z.string().optional().describe("测试用例ID"),
467
+ limit: z.number().optional().describe("返回数量"),
468
+ page: z.number().optional().describe("页码"),
469
+ fields: z.string().optional().describe("返回字段"),
470
+ }),
471
+ handler: async (client, params) => {
472
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
473
+ if (!workspaceId) {
474
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
475
+ }
476
+ return client.get("/test_plans/get_test_plan_tcase", { ...params, workspace_id: workspaceId });
477
+ },
478
+ },
479
+ {
480
+ name: "tapd_get_test_plan_relative_stories",
481
+ description: "获取测试计划关联的需求",
482
+ inputSchema: z.object({
483
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
484
+ test_plan_id: z.string().describe("测试计划ID (必填)"),
485
+ limit: z.number().optional().describe("返回数量"),
486
+ page: z.number().optional().describe("页码"),
487
+ fields: z.string().optional().describe("返回字段"),
488
+ }),
489
+ handler: async (client, params) => {
490
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
491
+ if (!workspaceId) {
492
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
493
+ }
494
+ return client.get("/test_plans/get_relative_stories", { ...params, workspace_id: workspaceId });
495
+ },
496
+ },
497
+ {
498
+ name: "tapd_get_test_plan_bugs",
499
+ description: "获取测试计划关联的缺陷",
500
+ inputSchema: z.object({
501
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
502
+ test_plan_id: z.string().describe("测试计划ID (必填)"),
503
+ limit: z.number().optional().describe("返回数量"),
504
+ page: z.number().optional().describe("页码"),
505
+ fields: z.string().optional().describe("返回字段"),
506
+ }),
507
+ handler: async (client, params) => {
508
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
509
+ if (!workspaceId) {
510
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
511
+ }
512
+ return client.get("/test_plans/result_relation_bugs", { ...params, workspace_id: workspaceId });
513
+ },
514
+ },
515
+ {
516
+ name: "tapd_create_story_relation",
517
+ description: "创建测试计划与需求关联",
518
+ inputSchema: z.object({
519
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
520
+ test_plan_id: z.string().describe("测试计划ID (必填)"),
521
+ story_id: z.string().describe("需求ID (必填)"),
522
+ }),
523
+ handler: async (client, params) => {
524
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
525
+ if (!workspaceId) {
526
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
527
+ }
528
+ return client.post("/test_plans/create_story_relation", { ...params, workspace_id: workspaceId });
529
+ },
530
+ },
531
+ {
532
+ name: "tapd_delete_story_relation",
533
+ description: "解除测试计划与需求关联",
534
+ inputSchema: z.object({
535
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
536
+ test_plan_id: z.string().describe("测试计划ID (必填)"),
537
+ story_id: z.string().describe("需求ID (必填)"),
538
+ }),
539
+ handler: async (client, params) => {
540
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
541
+ if (!workspaceId) {
542
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
543
+ }
544
+ return client.post("/test_plans/delete_story_relation", { ...params, workspace_id: workspaceId });
545
+ },
546
+ },
547
+ {
548
+ name: "tapd_create_tcase_relation",
549
+ description: "创建测试计划与测试用例关联",
121
550
  inputSchema: z.object({
122
- workspace_id: z.number().describe("Project ID (required)"),
123
- id: z.string().optional().describe("Test plan ID"),
124
- name: z.string().optional().describe("Test plan name"),
125
- status: z.string().optional().describe("Status"),
126
- creator: z.string().optional().describe("Creator"),
127
- owner: z.string().optional().describe("Owner"),
551
+ workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
552
+ test_plan_id: z.string().describe("测试计划ID (必填)"),
553
+ tcase_id: z.string().describe("测试用例ID (必填),支持多个ID逗号分隔"),
128
554
  }),
129
555
  handler: async (client, params) => {
130
- return client.get("/test_plans/count", params);
556
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
557
+ if (!workspaceId) {
558
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
559
+ }
560
+ return client.post("/test_plans/create_tcase_relation", { ...params, workspace_id: workspaceId });
131
561
  },
132
562
  },
133
563
  ];