@zzp123/mcp-zentao 1.18.2 → 1.18.3

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 CHANGED
@@ -5,6 +5,20 @@ 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.18.3] - 2025-01-12
9
+
10
+ ### Fixed
11
+ - **修复MCP协议兼容性问题** 🔧
12
+ - 修复 `changeStory` 和 `changeRequirement` 工具的参数类型错误
13
+ - 移除 `z.union([z.object({...}), z.string()])` 改为纯对象类型
14
+ - 解决 "Expected object, received string" 错误
15
+ - 同时修复完整版和产品经理版本
16
+
17
+ ### Technical
18
+ - 更新 `src/index.ts` 中的 `changeStory` 和 `changeRequirement` 工具定义
19
+ - 更新 `src/index-pm.ts` 中的 `changeStory` 工具定义
20
+ - 符合MCP协议规范,所有参数必须是对象类型
21
+
8
22
  ## [1.17.6] - 2025-11-10
9
23
 
10
24
  ### Changed
package/dist/index-pm.js CHANGED
@@ -375,76 +375,58 @@ server.tool("createPlan", {
375
375
  content: [{ type: "text", text: JSON.stringify(plan, null, 2) }]
376
376
  };
377
377
  });
378
- server.tool("changeStory", "需求变更 - 支持软件需求(story)和用户需求(requirement),自动识别类型。支持对象或JSON字符串格式", {
378
+ server.tool("changeStory", "需求变更 - 支持软件需求(story)和用户需求(requirement),自动识别类型", {
379
379
  storyId: z.number().describe("需求ID(可以是story或requirement类型)"),
380
- update: z.union([
381
- z.object({
382
- // 基本信息
383
- title: z.string().optional(),
384
- product: z.number().optional(),
385
- parent: z.number().optional(),
386
- module: z.number().optional(),
387
- branch: z.number().optional(),
388
- plan: z.union([z.number(), z.array(z.number())]).optional(),
389
- type: z.string().optional(),
390
- // 来源信息
391
- source: z.string().optional(),
392
- sourceNote: z.string().optional(),
393
- // 分类与优先级
394
- category: z.string().optional(),
395
- pri: z.number().optional(),
396
- estimate: z.number().optional(),
397
- // 状态与阶段
398
- stage: z.string().optional(),
399
- status: z.string().optional(),
400
- // 关键词与标识
401
- keywords: z.string().optional(),
402
- color: z.string().optional(),
403
- grade: z.number().optional(),
404
- // 人员相关
405
- mailto: z.array(z.string()).optional(),
406
- reviewer: z.array(z.string()).optional().describe("评审人员列表(通常为必填,除非设置needNotReview=true跳过评审)"),
407
- assignedTo: z.string().optional(),
408
- closedBy: z.string().optional(),
409
- feedbackBy: z.string().optional(),
410
- // 关闭相关
411
- closedReason: z.enum(['done', 'subdivided', 'duplicate', 'postponed', 'willnotdo', 'cancel', 'bydesign']).optional(),
412
- duplicateStory: z.number().optional(),
413
- // 评审相关
414
- needNotReview: z.boolean().optional().describe("是否跳过评审,如果不提供reviewer则应设置为true"),
415
- // 通知相关
416
- notifyEmail: z.string().optional(),
417
- // 描述内容
418
- spec: z.string().optional(),
419
- verify: z.string().optional(),
420
- // 备注
421
- comment: z.string().optional()
422
- }),
423
- z.string()
424
- ]).describe(`更新需求(使用 PUT 接口)
380
+ update: z.object({
381
+ // 基本信息
382
+ title: z.string().optional(),
383
+ product: z.number().optional(),
384
+ parent: z.number().optional(),
385
+ module: z.number().optional(),
386
+ branch: z.number().optional(),
387
+ plan: z.union([z.number(), z.array(z.number())]).optional(),
388
+ type: z.string().optional(),
389
+ // 来源信息
390
+ source: z.string().optional(),
391
+ sourceNote: z.string().optional(),
392
+ // 分类与优先级
393
+ category: z.string().optional(),
394
+ pri: z.number().optional(),
395
+ estimate: z.number().optional(),
396
+ // 状态与阶段
397
+ stage: z.string().optional(),
398
+ status: z.string().optional(),
399
+ // 关键词与标识
400
+ keywords: z.string().optional(),
401
+ color: z.string().optional(),
402
+ grade: z.number().optional(),
403
+ // 人员相关
404
+ mailto: z.array(z.string()).optional(),
405
+ reviewer: z.array(z.string()).optional().describe("评审人员列表(通常为必填,除非设置needNotReview=true跳过评审)"),
406
+ assignedTo: z.string().optional(),
407
+ closedBy: z.string().optional(),
408
+ feedbackBy: z.string().optional(),
409
+ // 关闭相关
410
+ closedReason: z.enum(['done', 'subdivided', 'duplicate', 'postponed', 'willnotdo', 'cancel', 'bydesign']).optional(),
411
+ duplicateStory: z.number().optional(),
412
+ // 评审相关
413
+ needNotReview: z.boolean().optional().describe("是否跳过评审,如果不提供reviewer则应设置为true"),
414
+ // 通知相关
415
+ notifyEmail: z.string().optional(),
416
+ // 描述内容
417
+ spec: z.string().optional(),
418
+ verify: z.string().optional(),
419
+ // 备注
420
+ comment: z.string().optional()
421
+ }).describe(`更新需求(使用 PUT 接口)
425
422
 
426
423
  此工具使用标准的"修改需求其他字段"接口(PUT /stories/:id),支持修改29个字段。
427
424
  自动处理评审人问题,无需手动设置 needNotReview。
428
-
429
- 支持对象或JSON字符串格式。
430
425
  `.trim())
431
426
  }, async ({ storyId, update }) => {
432
427
  if (!zentaoApi)
433
428
  throw new Error("Please initialize Zentao API first");
434
- // 如果 update 是字符串,尝试解析为对象
435
- let updateData;
436
- if (typeof update === 'string') {
437
- try {
438
- updateData = JSON.parse(update);
439
- }
440
- catch (error) {
441
- throw new Error(`Invalid JSON string: ${error instanceof Error ? error.message : 'Unknown error'}`);
442
- }
443
- }
444
- else {
445
- updateData = update;
446
- }
447
- const story = await zentaoApi.changeStory(storyId, updateData);
429
+ const story = await zentaoApi.changeStory(storyId, update);
448
430
  return {
449
431
  content: [{ type: "text", text: JSON.stringify(story, null, 2) }]
450
432
  };
package/dist/index.js CHANGED
@@ -564,76 +564,58 @@ server.tool("getProjects", {
564
564
  };
565
565
  });
566
566
  // Add changeStory tool
567
- server.tool("changeStory", "需求变更 - 支持软件需求(story)和用户需求(requirement),自动识别类型。支持对象或JSON字符串格式", {
567
+ server.tool("changeStory", "需求变更 - 支持软件需求(story)和用户需求(requirement),自动识别类型", {
568
568
  storyId: z.number().describe("需求ID(可以是story或requirement类型)"),
569
- update: z.union([
570
- z.object({
571
- // 基本信息
572
- title: z.string().optional(),
573
- product: z.number().optional(),
574
- parent: z.number().optional(),
575
- module: z.number().optional(),
576
- branch: z.number().optional(),
577
- plan: z.union([z.number(), z.array(z.number())]).optional(),
578
- type: z.string().optional(),
579
- // 来源信息
580
- source: z.string().optional(),
581
- sourceNote: z.string().optional(),
582
- // 分类与优先级
583
- category: z.string().optional(),
584
- pri: z.number().optional(),
585
- estimate: z.number().optional(),
586
- // 状态与阶段
587
- stage: z.string().optional(),
588
- status: z.string().optional(),
589
- // 关键词与标识
590
- keywords: z.string().optional(),
591
- color: z.string().optional(),
592
- grade: z.number().optional(),
593
- // 人员相关
594
- mailto: z.array(z.string()).optional(),
595
- reviewer: z.array(z.string()).optional().describe("评审人员列表(通常为必填,除非设置needNotReview=true跳过评审)"),
596
- assignedTo: z.string().optional(),
597
- closedBy: z.string().optional(),
598
- feedbackBy: z.string().optional(),
599
- // 关闭相关
600
- closedReason: z.enum(['done', 'subdivided', 'duplicate', 'postponed', 'willnotdo', 'cancel', 'bydesign']).optional(),
601
- duplicateStory: z.number().optional(),
602
- // 评审相关
603
- needNotReview: z.boolean().optional().describe("是否跳过评审,如果不提供reviewer则应设置为true"),
604
- // 通知相关
605
- notifyEmail: z.string().optional(),
606
- // 描述内容
607
- spec: z.string().optional(),
608
- verify: z.string().optional(),
609
- // 备注
610
- comment: z.string().optional()
611
- }),
612
- z.string()
613
- ]).describe(`更新需求(使用 PUT 接口)
569
+ update: z.object({
570
+ // 基本信息
571
+ title: z.string().optional(),
572
+ product: z.number().optional(),
573
+ parent: z.number().optional(),
574
+ module: z.number().optional(),
575
+ branch: z.number().optional(),
576
+ plan: z.union([z.number(), z.array(z.number())]).optional(),
577
+ type: z.string().optional(),
578
+ // 来源信息
579
+ source: z.string().optional(),
580
+ sourceNote: z.string().optional(),
581
+ // 分类与优先级
582
+ category: z.string().optional(),
583
+ pri: z.number().optional(),
584
+ estimate: z.number().optional(),
585
+ // 状态与阶段
586
+ stage: z.string().optional(),
587
+ status: z.string().optional(),
588
+ // 关键词与标识
589
+ keywords: z.string().optional(),
590
+ color: z.string().optional(),
591
+ grade: z.number().optional(),
592
+ // 人员相关
593
+ mailto: z.array(z.string()).optional(),
594
+ reviewer: z.array(z.string()).optional().describe("评审人员列表(通常为必填,除非设置needNotReview=true跳过评审)"),
595
+ assignedTo: z.string().optional(),
596
+ closedBy: z.string().optional(),
597
+ feedbackBy: z.string().optional(),
598
+ // 关闭相关
599
+ closedReason: z.enum(['done', 'subdivided', 'duplicate', 'postponed', 'willnotdo', 'cancel', 'bydesign']).optional(),
600
+ duplicateStory: z.number().optional(),
601
+ // 评审相关
602
+ needNotReview: z.boolean().optional().describe("是否跳过评审,如果不提供reviewer则应设置为true"),
603
+ // 通知相关
604
+ notifyEmail: z.string().optional(),
605
+ // 描述内容
606
+ spec: z.string().optional(),
607
+ verify: z.string().optional(),
608
+ // 备注
609
+ comment: z.string().optional()
610
+ }).describe(`更新需求(使用 PUT 接口)
614
611
 
615
612
  此工具使用标准的"修改需求其他字段"接口(PUT /stories/:id),支持修改29个字段。
616
613
  自动处理评审人问题,无需手动设置 needNotReview。
617
-
618
- 支持对象或JSON字符串格式。
619
614
  `.trim())
620
615
  }, async ({ storyId, update }) => {
621
616
  if (!zentaoApi)
622
617
  throw new Error("Please initialize Zentao API first");
623
- // 如果 update 是字符串,尝试解析为对象
624
- let updateData;
625
- if (typeof update === 'string') {
626
- try {
627
- updateData = JSON.parse(update);
628
- }
629
- catch (error) {
630
- throw new Error(`Invalid JSON string: ${error instanceof Error ? error.message : 'Unknown error'}`);
631
- }
632
- }
633
- else {
634
- updateData = update;
635
- }
636
- const story = await zentaoApi.changeStory(storyId, updateData);
618
+ const story = await zentaoApi.changeStory(storyId, update);
637
619
  return {
638
620
  content: [{ type: "text", text: JSON.stringify(story, null, 2) }]
639
621
  };
@@ -878,49 +860,32 @@ server.tool("getRequirementDetail", "获取用户需求详情 - 用户需求的
878
860
  });
879
861
  server.tool("changeRequirement", "用户需求变更 - 用户需求的专用接口,提供更好的语义化", {
880
862
  requirementId: z.number().describe("用户需求ID"),
881
- update: z.union([
882
- z.object({
883
- title: z.string().optional(),
884
- product: z.number().optional(),
885
- parent: z.number().optional(),
886
- module: z.number().optional(),
887
- pri: z.number().optional(),
888
- category: z.string().optional(),
889
- spec: z.string().optional(),
890
- verify: z.string().optional(),
891
- source: z.string().optional(),
892
- sourceNote: z.string().optional(),
893
- estimate: z.number().optional(),
894
- keywords: z.string().optional(),
895
- assignedTo: z.string().optional(),
896
- reviewer: z.array(z.string()).optional(),
897
- comment: z.string().optional()
898
- }),
899
- z.string().describe("JSON字符串格式的更新内容")
900
- ]).describe(`
863
+ update: z.object({
864
+ title: z.string().optional(),
865
+ product: z.number().optional(),
866
+ parent: z.number().optional(),
867
+ module: z.number().optional(),
868
+ pri: z.number().optional(),
869
+ category: z.string().optional(),
870
+ spec: z.string().optional(),
871
+ verify: z.string().optional(),
872
+ source: z.string().optional(),
873
+ sourceNote: z.string().optional(),
874
+ estimate: z.number().optional(),
875
+ keywords: z.string().optional(),
876
+ assignedTo: z.string().optional(),
877
+ reviewer: z.array(z.string()).optional(),
878
+ comment: z.string().optional()
879
+ }).describe(`
901
880
  更新用户需求(使用 PUT /stories/:id 接口)
902
881
 
903
882
  此工具使用标准的"修改需求其他字段"接口(PUT /stories/:id),支持修改多个字段。
904
883
  自动处理评审人问题,无需手动设置 needNotReview。
905
-
906
- 支持对象或JSON字符串格式。
907
884
  `.trim())
908
885
  }, async ({ requirementId, update }) => {
909
886
  if (!zentaoApi)
910
887
  throw new Error("Please initialize Zentao API first");
911
- let updateData;
912
- if (typeof update === 'string') {
913
- try {
914
- updateData = JSON.parse(update);
915
- }
916
- catch (e) {
917
- throw new Error('Invalid JSON string for update parameter');
918
- }
919
- }
920
- else {
921
- updateData = update;
922
- }
923
- const requirement = await zentaoApi.changeStory(requirementId, updateData);
888
+ const requirement = await zentaoApi.changeStory(requirementId, update);
924
889
  return {
925
890
  content: [{ type: "text", text: JSON.stringify(requirement, null, 2) }]
926
891
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zzp123/mcp-zentao",
3
- "version": "1.18.2",
3
+ "version": "1.18.3",
4
4
  "description": "禅道项目管理系统的高级API集成包 - 完整版,包含所有94个工具。另有产品经理、测试工程师、开发工程师专用精简版本可选",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",