【免费下载链接】CAD-MCP
CAD MCP Server
CAD-MCP 是一个让 AI 通过自然语言驱动 AutoCAD / 浩辰CAD / 中望CAD 进行绘图的 MCP 服务器。当 AI 接管 CAD 操作后,最让人担心的不再是"画不画得出",而是"图纸会不会丢"和"服务会不会崩"。这篇文章带你拆解 CAD-MCP 的可靠性设计:从防数据丢失、COM 调用自动重试,到线程隔离、独立撤销与滚动日志,看它如何为 CAD 自动化筑起五道防线。
一、AI 驱动的 CAD 自动化,隐藏风险在哪?
先看看 CAD-MCP 的工作形态:AI 客户端在右侧下达指令,服务器通过 COM 接口驱动左侧的 CAD 完成绘图、查询与编辑,全程无需人工操作界面。
这种架构看起来简单,实际跑起来却处处是坑:
- CAD 会"忙碌":正在执行命令、弹窗或重生成时,COM 调用会被直接拒绝(
RPC_E_CALL_REJECTED) - 文件会冲突:保存目标被其他已打开的图纸占用时,保存会持续报错且重试无效
- COM 套间模型严格:跨线程访问接口指针会导致调用失败甚至进程崩溃
- 操作不可逆:一次误操作覆盖保存,用户文件里的内容不可恢复
下面按"防线"逐层拆解 cad_controller.py 与 server.py 中的关键设计。
二、防数据丢失:绝不覆盖用户图纸
⚠️ 这是整个项目优先级最高的设计目标:宁可操作失败,也绝不碰坏用户文件。
CAD-MCP 在三个最容易丢数据的位置做了"安全失败"处理:
2.1 保存时不自动启动 CAD
save_drawing工具在 CAD 未运行时直接返回失败,而不是先启动 CAD 再保存——因为start_cad()会新建一张空白 Drawing1.dwg,随后的 SaveAs 会把用户路径上已有的图纸直接覆盖成空白图,且原内容不可恢复。相关说明见 server.py。
2.2 拿不到活动文档时,绝不关闭用户图纸
早期版本的兜底逻辑会用Close(False)强制关闭用户已打开的图纸来获取文档,这会直接丢弃未保存的修改。现在改为新建一个文档作为安全做法,注释中明确将其定性为"数据丢失级缺陷":cad_controller.py。
2.3 保存前检查目标文件占用
_check_target_not_occupied会在保存前扫描当前 CAD 中所有已打开的文档,若目标路径已被其他图纸占用(AutoCAD 会锁定该文件),立即快速失败并给出可操作的提示,而不是让 SaveAs 陷入"持续报错且重试无效"的循环:cad_controller.py。
细节上同样体现可靠性意识:保存和打开图纸时都会把相对路径转为绝对路径(CAD 进程的工作目录与服务器不同,相对路径会存到别处),并自动创建缺失的目录:cad_controller.py。
三、自动重试:CAD"忙碌"时不轻易报错
3.1 只重试瞬态错误
_call_with_com_retry是核心重试器:对"CAD 忙碌被拒"(RPC_E_CALL_REJECTED)和"瞬态保存冲突"(-2145320861)这类稍等即恢复的错误,最多重试 20 次、每次间隔 0.5 秒;其他异常则直接抛出,不做无意义重试:cad_controller.py。
一个容易被忽略的边界:动态派发模式下,"成员查找"本身也是一次 COM 调用,pywin32 会把它吞成AttributeError。_call_attr将"查找 + 调用"合并为一个重试单元,避免这类错误绕过重试保护:cad_controller.py。
3.2 重试粒度:调用级,而非方法级
为什么不能"整个绘图方法失败就重试一遍"?因为方法前半段可能已成功、后半段被 CAD 拒绝——整体重试会重复绘制实体。所以重试粒度精确到单个 COM 调用,这在注释中有明确说明:cad_controller.py。
3.3 检测"死引用"并自动重连
如果 CAD 进程已被用户手动关闭,持有的接口指针全部失效(RPC_E_DISCONNECTED等)。此时重试毫无意义,控制器会重置连接状态,让下一次操作自动重新启动 CAD,而不是持续报错:cad_controller.py。
四、线程隔离:专用 COM 线程防崩溃
Windows COM 的套间(Apartment)模型要求:接口指针应在创建它的线程上使用,跨线程直接访问会导致失败甚至崩溃。CAD-MCP 的COMExecutor把所有 COM 调用串行化到单一 STA 线程上执行,一举两得:
- 线程安全——多个工具并发调用也不会出现跨套间访问
- 不阻塞事件循环——COM 阻塞调用(如等待 CAD 启动约 20 秒)发生在专用线程上,服务器仍能响应其他请求
嵌套调用时还会直接执行以避免死锁。实现见 cad_controller.py。
与此配套的是_ensure_running:每个工具执行前确保 CAD 已运行,未运行时先给客户端发送进度提示("首次启动可能需要约20秒")再自动启动,避免客户端在漫长的启动过程中误判超时:server.py。
五、一步可撤销:绘图操作独立成撤销组
AutoCAD 会把命令行空闲期间的批量 COM 修改合并为同一个撤销组——不加处理时,一次UNDO可能把 AI 刚画的一整批图形全部撤销。
_undo_group用StartUndoMark/EndUndoMark把每次工具操作打包为独立撤销组,保证UNDO 1正好撤销一步,且嵌套使用安全:cad_controller.py。服务层同时暴露了undo/redo工具,AI 自己也能在出错时回退:server.py。
六、快速失败:参数校验与清晰的错误语义
把错误拦在到达 CAD 之前,是可靠性的重要一环:
| 参数 | 校验规则 | 目的 |
|---|---|---|
PosFloat | 必须为正数 | CAD 对半径/字高的 0 或负值会直接报错 |
HatchPoints | 至少 3 个点 | 填充边界无法闭合 |
ArrayCount | 2 ~ 10000 | 防止误操作生成海量实体卡死图纸 |
这些约束定义在 server.py。输入校验错误以工具错误形式返回,让 AI 模型能够自我纠正后重试,而非把坏参数透传给 CAD。
另外,所有删除、新建、打开、关闭、保存类工具都标注了destructiveHint,查询类工具标注readOnlyHint,客户端可据此实施确认策略,让 AI 的"破坏性操作"始终可见、可控。
配置层同样有兜底:config.py 中配置文件缺失或损坏时自动回退到内置默认配置,保证服务不因一个坏掉的 config.json 而无法启动。
七、滚动日志:长期运行可追溯
服务会 7×24 挂着的场景下,日志无限增长同样是一种故障。_build_log_handlers的设计很克制:
- 滚动日志:单文件 5MB、保留 2 个备份,防止日志无限膨胀
- 路径回退:日志优先写源码目录;pip 安装到 site-packages 等无写权限的位置时,回退到用户目录,避免因
PermissionError导致服务器启动失败 - 不污染协议:stdio 传输下日志走 stderr,不会混入 MCP 协议数据
工具失败时返回的提示(如"详情见 cad_mcp.log")也指向这份日志,排障链路是闭环的:server.py。
总结:五道防线
CAD-MCP 的可靠性不是单点功能,而是一套分层的防御体系:
- 🛡️防数据丢失——保存不自动启动 CAD、不关闭用户图纸、占用预检
- 🔁自动重试——只对瞬态错误做调用级重试,杜绝重复绘制
- 🧵线程隔离——专用 COM 线程保证线程安全且不阻塞事件循环
- ↩️一步可撤销——独立撤销组 + undo/redo 工具兜底
- 📋可观测——参数前置校验、快速失败语义、滚动日志
对想自建 CAD 自动化服务的人来说,这份设计清单本身就是一份很好的检查表:先假设 CAD 会忙、文件会被占、进程会退出,再谈功能。
【免费下载链接】CAD-MCP
CAD MCP Server
相关推荐
Windows COM自动化详解:CAD-MCP如何用pywin32驱动AutoCAD、浩辰与中望CAD
Windows COM自动化详解:CAD MCP如何用pywin32驱动AutoCAD、浩辰与中望CAD CAD MCP 是一个基于 pywin32 实现 Wi
CANN直调工作流设计约束
设计约束 为保证实现一致性、在方案出现分歧时提供统一指导,约定以下设计约束。 1. 结构约束 1.1 SOLID 原则 | 条款 | 说明 | 示例 | | |
AI 技能AI 插件AI 评测人工智能CANNAscendcad-skill 测试体系完整指南:AI 生成的 CAD 脚本如何做到稳定可靠
cad skill 测试体系完整指南:AI 生成的 CAD 脚本如何做到稳定可靠 cad skill 是一个基于 CadQuery 的 Claude Code
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考