zwcad-mcp 0.2.2 → 0.2.4
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/README.md +4 -3
- package/lib/proxy.js +47 -35
- package/package.json +1 -1
- package/tools.json +2 -2
package/README.md
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
中望CAD(ZWCAD)MCP 服务,让大模型通过 [MCP 协议](https://modelcontextprotocol.io)直接操控中望CAD 平台与中望机械CAD,完成绘图、标注、图层/块/样式管理,以及图框、标题栏、明细表(BOM)等机械操作。
|
|
4
4
|
|
|
5
|
-
**共计
|
|
5
|
+
**共计 40 个工具**:平台 26 个(不依赖机械环境)+ 机械 11 个(需中望机械CAD)+ 诊断 2 个 + 启动器侧 1 个。
|
|
6
6
|
|
|
7
|
-
>
|
|
8
|
-
>
|
|
7
|
+
> 启动器侧的 `zwcad_wait_ready` 在 Python 运行时尚未就绪时也可用,用于等待初始化完成。
|
|
8
|
+
> 诊断统一走 `zwcad_diagnose`:Python 已就绪时返回完整诊断,
|
|
9
|
+
> 未就绪时自动降级为启动器视角(含错误日志与环境信息)并标注未检测项。
|
|
9
10
|
|
|
10
11
|
## 为什么需要 Node 启动器
|
|
11
12
|
|
package/lib/proxy.js
CHANGED
|
@@ -72,26 +72,6 @@ const PROXY_TOOLS = [
|
|
|
72
72
|
additionalProperties: false,
|
|
73
73
|
},
|
|
74
74
|
},
|
|
75
|
-
{
|
|
76
|
-
name: 'zwcad_launcher_diagnose',
|
|
77
|
-
description:
|
|
78
|
-
'诊断启动器与 Python 运行时的状态,并返回最近的错误记录。\n\n' +
|
|
79
|
-
'与 zwcad_diagnose 的区别:本工具由 JS 启动器实现,**在 Python 尚未就绪时也可用**,' +
|
|
80
|
-
'因此是排查「首次安装失败 / 一直停在初始化」的首选;' +
|
|
81
|
-
'zwcad_diagnose 依赖 Python 侧,只能在其就绪后调用。\n\n' +
|
|
82
|
-
'返回内容包括:运行时状态、Python 解释器路径与版本、虚拟环境状态、' +
|
|
83
|
-
'最近若干条错误日志(含事件名与诊断细节)。',
|
|
84
|
-
inputSchema: {
|
|
85
|
-
type: 'object',
|
|
86
|
-
properties: {
|
|
87
|
-
limit: {
|
|
88
|
-
type: 'number',
|
|
89
|
-
description: '返回最近多少条错误日志,默认 10,上限 50。',
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
additionalProperties: false,
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
75
|
];
|
|
96
76
|
|
|
97
77
|
/**
|
|
@@ -406,6 +386,15 @@ function createProxy(opts) {
|
|
|
406
386
|
handleProxyTool(msg);
|
|
407
387
|
return;
|
|
408
388
|
}
|
|
389
|
+
|
|
390
|
+
// zwcad_diagnose 是 Python 侧的主诊断工具,但它本身跑在 Python 里。
|
|
391
|
+
// Python 未就绪时它必然报「正在初始化」,而这恰恰是最需要诊断的时刻。
|
|
392
|
+
// 所以这里做一次兜底:未就绪时直接由代理层给出启动器视角的诊断,
|
|
393
|
+
// 让 AI 只需认准「一个诊断入口」。
|
|
394
|
+
if (toolName === 'zwcad_diagnose' && !childReady) {
|
|
395
|
+
handleDiagnoseFallback(msg);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
409
398
|
}
|
|
410
399
|
|
|
411
400
|
// tools/list 永远由本地静态清单应答,不受 childReady 影响。
|
|
@@ -514,14 +503,14 @@ function createProxy(opts) {
|
|
|
514
503
|
} else if (r.state === 'failed') {
|
|
515
504
|
text =
|
|
516
505
|
`服务初始化失败:${r.error}\n\n` +
|
|
517
|
-
`下一步:调用
|
|
506
|
+
`下一步:调用 zwcad_diagnose 获取完整的错误记录与运行环境信息,` +
|
|
518
507
|
`据此判断原因并告知用户具体怎么修。\n\n` +
|
|
519
508
|
`常见原因:未安装 Python 3.10+、网络无法访问 PyPI、磁盘空间不足。`;
|
|
520
509
|
} else {
|
|
521
510
|
text =
|
|
522
511
|
`已等待 ${seconds} 秒,初始化仍未完成,仍在安装依赖。\n\n` +
|
|
523
512
|
`下一步:可再调用一次本工具继续等待;若累计超过 2 分钟仍无进展,` +
|
|
524
|
-
`调用
|
|
513
|
+
`调用 zwcad_diagnose 查看错误记录。`;
|
|
525
514
|
}
|
|
526
515
|
|
|
527
516
|
writeJson({
|
|
@@ -535,19 +524,6 @@ function createProxy(opts) {
|
|
|
535
524
|
return;
|
|
536
525
|
}
|
|
537
526
|
|
|
538
|
-
if (name === 'zwcad_launcher_diagnose') {
|
|
539
|
-
let limit = Number(args.limit);
|
|
540
|
-
if (!Number.isFinite(limit) || limit <= 0) limit = 10;
|
|
541
|
-
limit = Math.min(limit, 50);
|
|
542
|
-
|
|
543
|
-
writeJson({
|
|
544
|
-
jsonrpc: '2.0',
|
|
545
|
-
id: msg.id,
|
|
546
|
-
result: { content: [{ type: 'text', text: buildDiagnosisReport(limit) }] },
|
|
547
|
-
});
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
527
|
writeJson({
|
|
552
528
|
jsonrpc: '2.0',
|
|
553
529
|
id: msg.id,
|
|
@@ -558,6 +534,42 @@ function createProxy(opts) {
|
|
|
558
534
|
});
|
|
559
535
|
}
|
|
560
536
|
|
|
537
|
+
/**
|
|
538
|
+
* Python 未就绪时,zwcad_diagnose 的兜底应答。
|
|
539
|
+
*
|
|
540
|
+
* 设计要点:对 AI 来说诊断入口始终是 zwcad_diagnose,不必记两个工具名。
|
|
541
|
+
* 这里返回启动器视角的诊断,并**明确标注哪些项目因 Python 未就绪而无法检测**,
|
|
542
|
+
* 避免 AI 把「未检测」误读成「正常」或「故障」。
|
|
543
|
+
*/
|
|
544
|
+
function handleDiagnoseFallback(msg) {
|
|
545
|
+
const report = buildDiagnosisReport(10);
|
|
546
|
+
|
|
547
|
+
const header =
|
|
548
|
+
'## 诊断来源\n' +
|
|
549
|
+
'Python 运行时尚未就绪,本次为**启动器视角**的诊断,' +
|
|
550
|
+
'无法检测 ZWCAD 连接状态、机械类型库等 Python 侧项目。\n' +
|
|
551
|
+
'待初始化完成后再次调用本工具,可获得完整诊断。\n\n';
|
|
552
|
+
|
|
553
|
+
const footer =
|
|
554
|
+
'\n\n## 本次未检测的项目\n' +
|
|
555
|
+
'- ZWCAD 是否已启动、是否打开了 DWG\n' +
|
|
556
|
+
'- 机械扩展(ZwmToolKit)类型库加载状态\n' +
|
|
557
|
+
'- 平台/机械 COM 连接可用性\n\n' +
|
|
558
|
+
'这些需要 Python 运行时就绪后才能探测。在此之前,' +
|
|
559
|
+
'如需了解 ZWCAD 侧的情况,请直接查看用户屏幕上是否打开了图纸。';
|
|
560
|
+
|
|
561
|
+
writeJson({
|
|
562
|
+
jsonrpc: '2.0',
|
|
563
|
+
id: msg.id,
|
|
564
|
+
result: {
|
|
565
|
+
content: [{ type: 'text', text: header + report + footer }],
|
|
566
|
+
// 这不是工具失败,而是「部分信息暂时不可得」,用 isError 会让 AI
|
|
567
|
+
// 误判为故障,所以按正常结果返回,把局限性写在正文里。
|
|
568
|
+
isError: false,
|
|
569
|
+
},
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
|
|
561
573
|
/**
|
|
562
574
|
* 生成诊断报告。
|
|
563
575
|
*
|
package/package.json
CHANGED
package/tools.json
CHANGED
|
@@ -1300,7 +1300,7 @@
|
|
|
1300
1300
|
},
|
|
1301
1301
|
{
|
|
1302
1302
|
"name": "zwcad_diagnose",
|
|
1303
|
-
"description": "
|
|
1303
|
+
"description": "诊断 MCP 服务的运行状态,并按需给出修复建议。\n\n分两种情形,工具名不变:\n- Python 运行时已就绪:返回完整诊断(平台 COM 可用性、活动图纸、机械扩展与 ZwmToolKit 类型库状态)。\n- Python 运行时未就绪:自动降级为启动器视角,返回运行时状态、Python 解释器路径与版本、最近错误记录(含 pip 镜像源、依赖清单、耗时),并明确标注哪些项目本次未检测。\n\n因此排查任何问题都从这里开始,无需另找工具。",
|
|
1304
1304
|
"inputSchema": {
|
|
1305
1305
|
"properties": {
|
|
1306
1306
|
"probe_cad": {
|
|
@@ -1320,4 +1320,4 @@
|
|
|
1320
1320
|
}
|
|
1321
1321
|
}
|
|
1322
1322
|
}
|
|
1323
|
-
]
|
|
1323
|
+
]
|