From 963a39c46386fa1b3927d0b98fa594aebf15ec12 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 3 May 2026 11:40:51 +0200 Subject: [PATCH] feat: add no_connect handler, server icon, split READMEs by language, VS Code Copilot guide, tool inventory update --- .github/README.de.md | 119 ++++++++++++ .github/README.md | 209 ++++------------------ .github/README.zh.md | 119 ++++++++++++ .gitignore | 3 + .prettierignore | 1 + README.md | 12 ++ config/vscode-mcp.example.json | 16 ++ docs/TOOL_INVENTORY.md | 161 ++++++++++------- python/kicad_interface.py | 73 +++++++- resources/images/KiCAD-MCP-Server_opt.svg | 74 ++++++++ src/server.ts | 5 +- src/tools/board.ts | 67 ++++--- src/tools/component.ts | 16 ++ src/tools/design-rules.ts | 36 ++-- src/tools/export.ts | 7 + src/tools/registry.ts | 1 + src/tools/router.ts | 147 +-------------- src/tools/schematic.ts | 47 +++++ 18 files changed, 680 insertions(+), 433 deletions(-) create mode 100644 .github/README.de.md create mode 100644 .github/README.zh.md create mode 100644 config/vscode-mcp.example.json create mode 100644 resources/images/KiCAD-MCP-Server_opt.svg diff --git a/.github/README.de.md b/.github/README.de.md new file mode 100644 index 0000000..7106bdd --- /dev/null +++ b/.github/README.de.md @@ -0,0 +1,119 @@ + + +
+ +KiCAD-MCP-Server Logo + +# KiCAD MCP Server + +[🇺🇸 **English** (EN)](README.md)  •  [🇩🇪 **Deutsch** (DE)](#)  •  [🇨🇳 **中文** (ZH)](README.zh.md) + +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](../LICENSE) +[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)](../docs/PLATFORM_GUIDE.md) +[![KiCAD](https://img.shields.io/badge/KiCAD-9.0+-green.svg)](https://www.kicad.org/) +[![Stars](https://img.shields.io/github/stars/mixelpixx/KiCAD-MCP-Server.svg)](https://github.com/mixelpixx/KiCAD-MCP-Server/stargazers) +[![Discussions](https://img.shields.io/badge/community-Discussions-orange.svg)](https://github.com/mixelpixx/KiCAD-MCP-Server/discussions) + +
+ + +
+ +#### Unser neues Forum ist online: https://forum.orchis.ai — Fragen? Ideen? Projekte zeigen? + +
+ + +# + +**KiCAD MCP Server** ist ein Model Context Protocol (MCP) Server, der KI-Assistenten wie Claude ermöglicht, mit KiCAD für die PCB-Design-Automatisierung zu interagieren. Aufgebaut auf der MCP-Spezifikation 2025-06-18, bietet dieser Server umfassende Tool-Schemas und Echtzeit-Projektzugriff für intelligente PCB-Design-Workflows. + +### PCBs mit natürlicher Sprache designen + +Beschreibe was du bauen möchtest — und lass die KI die EDA-Arbeit übernehmen. Bauteile platzieren, eigene Symbole und Footprints erstellen, Verbindungen routen, Prüfungen ausführen und Fertigungsdateien exportieren — alles im Gespräch mit deinem KI-Assistenten. + +### Was es heute kann + +- Projektanlage, Schaltplan-Bearbeitung, Bauteil-Platzierung, Routing, DRC/ERC, Export +- **Eigene Symbole und Footprints generieren** — auch für Module die in KiCAD-Standardbibliotheken fehlen +- **Eigene Bibliotheksverwaltung** — einmal erstellt, in jedem Projekt wiederverwendbar +- **JLCPCB-Integration** — Bauteilkatalog mit Preisen und Lagerbestand +- **Freerouting-Integration** — automatisches PCB-Routing via Java/Docker +- **Visuelles Feedback** — Snapshots und Session-Logs für Nachvollziehbarkeit +- **Plattformübergreifend** — Windows, Linux, macOS + +### Schnellstart + +1. [KiCAD 9.0+](https://www.kicad.org/download/) installieren +2. [Node.js 18+](https://nodejs.org/) und [Python 3.11+](https://www.python.org/) installieren +3. Klonen und bauen: + +```bash +git clone https://github.com/mixelpixx/KiCAD-MCP-Server.git +cd KiCAD-MCP-Server +npm install +npm run build +``` + +4. KI-Client konfigurieren — siehe [Plattform-Anleitung](../docs/PLATFORM_GUIDE.md) + +### GitHub Copilot (VS Code) + +Template kopieren: + +```bash +cp config/vscode-mcp.example.json .vscode/mcp.json +``` + +VS Code erkennt `.vscode/mcp.json` automatisch und registriert den Server. Das Template nutzt `${workspaceFolder}` — kein Pfad muss angepasst werden. + +### Claude Desktop + +Konfigurationsdatei bearbeiten: + +- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json` +- **macOS/Linux:** `~/.config/claude/claude_desktop_config.json` + +Beispielkonfiguration: `config/windows-config.example.json` oder `config/macos-config.example.json` + +### Dokumentation + +- [**Vollständige README**](../README.md) — komplette Dokumentation +- [Schnellstart (Router Tools)](../docs/ROUTER_QUICK_START.md) — erste Schritte +- [Werkzeug-Übersicht](../docs/TOOL_INVENTORY.md) — alle verfügbaren Werkzeuge +- [Schaltplan-Werkzeuge](../docs/SCHEMATIC_TOOLS_REFERENCE.md) +- [Routing-Werkzeuge](../docs/ROUTING_TOOLS_REFERENCE.md) +- [Footprint & Symbol erstellen](../docs/FOOTPRINT_SYMBOL_CREATOR_GUIDE.md) +- [JLCPCB-Anleitung](../docs/JLCPCB_USAGE_GUIDE.md) +- [Plattform-Anleitung](../docs/PLATFORM_GUIDE.md) +- [Changelog](../CHANGELOG.md) + +### Community + +- [Diskussionen](https://github.com/mixelpixx/KiCAD-MCP-Server/discussions) — Fragen, Ideen, Projekte zeigen +- [Issues](https://github.com/mixelpixx/KiCAD-MCP-Server/issues) — Fehler und Feature-Wünsche +- [Mitwirken](../CONTRIBUTING.md) + +### KI-Hinweis + +> **Entwickelt mit KI-Unterstützung** +> Dieses Projekt wurde unter Einsatz von KI-gestützten Entwicklungswerkzeugen (GitHub Copilot, Claude) erstellt. +> Sämtlicher Code wurde von den Maintainern geprüft, getestet und integriert. +> KI-Werkzeuge dienten der Entwicklungsbeschleunigung — kreative Entscheidungen, Architektur und Verantwortung liegen ausschließlich bei den Autoren. + +### Haftungsausschluss + +> **Keine Haftung — Nutzung auf eigene Verantwortung** +> +> Dieses Projekt wird ohne jegliche Gewährleistung bereitgestellt — weder ausdrücklich noch stillschweigend. Die Autoren und Mitwirkenden übernehmen keinerlei Haftung für Schäden jeder Art, die durch die Nutzung oder Nichtnutzung dieser Software entstehen, einschließlich aber nicht beschränkt auf: +> +> - Fehler in erzeugten Schaltplänen, PCB-Layouts oder Fertigungsdateien +> - Schäden an Hardware, Bauteilen oder Geräten durch fehlerhafte Designs +> - Finanzielle Verluste durch Fehlproduktionen oder Fehlerbestellungen +> - Datenverlust oder Beschädigung von KiCAD-Projektdateien +> +> KI-generierte Design-Vorschläge ersetzen keine qualifizierte ingenieurtechnische Prüfung. Sicherheitskritische Anwendungen (Medizintechnik, Luftfahrt, Automotive o.ä.) erfordern zwingend eine unabhängige Fachprüfung. +> +> Dieses Projekt steht unter der MIT-Lizenz — die Lizenz schließt ebenfalls jede Haftung aus. + +
back to top
diff --git a/.github/README.md b/.github/README.md index b4a0868..ece3411 100644 --- a/.github/README.md +++ b/.github/README.md @@ -1,4 +1,4 @@ - +
@@ -6,7 +6,7 @@ # KiCAD MCP Server -[🇺🇸 **English** (EN)](#english)  •  [🇩🇪 **Deutsch** (DE)](#deutsch)  •  [🇨🇳 **中文** (ZH)](#中文) +[🇺🇸 **English** (EN)](#)  •  [🇩🇪 **Deutsch** (DE)](README.de.md)  •  [🇨🇳 **中文** (ZH)](README.zh.md) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](../LICENSE) [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)](../docs/PLATFORM_GUIDE.md) @@ -16,14 +16,15 @@
+
---- -Our new forum is up: https://forum.orchis.ai -Need help? Have suggestions? Want to show off your work ---- -
-## English +#### Our new forum is up: https://forum.orchis.ai — Need help? Have suggestions? Want to show off your work? + + + + +# **KiCAD MCP Server** is a Model Context Protocol (MCP) server that enables AI assistants like Claude to interact with KiCAD for PCB design automation. Built on the MCP 2025-06-18 specification, this server provides comprehensive tool schemas and real-time project state access for intelligent PCB design workflows. @@ -54,7 +55,20 @@ npm install npm run build ``` -4. Configure Claude Desktop — see [Platform Guide](../docs/PLATFORM_GUIDE.md) +4. Configure your AI client — see [Platform Guide](../docs/PLATFORM_GUIDE.md) + +### GitHub Copilot (VS Code) + +Copy `config/vscode-mcp.example.json` to `.vscode/mcp.json` — VS Code auto-detects it. → [Full setup guide](../README.md#github-copilot-vs-code) + +### Claude Desktop + +Edit your config file: + +- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json` +- **macOS/Linux:** `~/.config/claude/claude_desktop_config.json` + +Example configs: `config/windows-config.example.json` or `config/macos-config.example.json` ### Documentation @@ -69,11 +83,21 @@ npm run build - [Changelog](../CHANGELOG.md) ### Community -- [Forum](https://forum.orchis.ai) — Official Forum for discussions, help, and troubleshooting + - [Discussions](https://github.com/mixelpixx/KiCAD-MCP-Server/discussions) — questions, ideas, showcase - [Issues](https://github.com/mixelpixx/KiCAD-MCP-Server/issues) — bugs and feature requests - [Contributing](../CONTRIBUTING.md) +## Star History + + + + + + Star History Chart + + + ### AI Disclosure > **Developed with AI Assistance** @@ -97,168 +121,3 @@ npm run build > This project is licensed under the MIT License — which likewise excludes all liability.
back to top
- ---- - -## Star History - - - - - - Star History Chart - - - - -## Deutsch - -**KiCAD MCP Server** ist ein Model Context Protocol (MCP) Server, der KI-Assistenten wie Claude ermöglicht, mit KiCAD für die PCB-Design-Automatisierung zu interagieren. Aufgebaut auf der MCP-Spezifikation 2025-06-18, bietet dieser Server umfassende Tool-Schemas und Echtzeit-Projektzugriff für intelligente PCB-Design-Workflows. - -### PCBs mit natürlicher Sprache designen - -Beschreibe was du bauen möchtest — und lass die KI die EDA-Arbeit übernehmen. Bauteile platzieren, eigene Symbole und Footprints erstellen, Verbindungen routen, Prüfungen ausführen und Fertigungsdateien exportieren — alles im Gespräch mit deinem KI-Assistenten. - -### Was es heute kann - -- Projektanlage, Schaltplan-Bearbeitung, Bauteil-Platzierung, Routing, DRC/ERC, Export -- **Eigene Symbole und Footprints generieren** — auch für Module die in KiCAD-Standardbibliotheken fehlen -- **Eigene Bibliotheksverwaltung** — einmal erstellt, in jedem Projekt wiederverwendbar -- **JLCPCB-Integration** — Bauteilkatalog mit Preisen und Lagerbestand -- **Freerouting-Integration** — automatisches PCB-Routing via Java/Docker -- **Visuelles Feedback** — Snapshots und Session-Logs für Nachvollziehbarkeit -- **Plattformübergreifend** — Windows, Linux, macOS - -### Schnellstart - -1. [KiCAD 9.0+](https://www.kicad.org/download/) installieren -2. [Node.js 18+](https://nodejs.org/) und [Python 3.11+](https://www.python.org/) installieren -3. Klonen und bauen: - -```bash -git clone https://github.com/mixelpixx/KiCAD-MCP-Server.git -cd KiCAD-MCP-Server -npm install -npm run build -``` - -4. Claude Desktop konfigurieren — siehe [Plattform-Anleitung](../docs/PLATFORM_GUIDE.md) - -### Dokumentation - -- [**Vollständige README**](../README.md) — komplette Dokumentation -- [Schnellstart (Router Tools)](../docs/ROUTER_QUICK_START.md) — erste Schritte -- [Werkzeug-Übersicht](../docs/TOOL_INVENTORY.md) — alle verfügbaren Werkzeuge -- [Schaltplan-Werkzeuge](../docs/SCHEMATIC_TOOLS_REFERENCE.md) -- [Routing-Werkzeuge](../docs/ROUTING_TOOLS_REFERENCE.md) -- [Footprint & Symbol erstellen](../docs/FOOTPRINT_SYMBOL_CREATOR_GUIDE.md) -- [JLCPCB-Anleitung](../docs/JLCPCB_USAGE_GUIDE.md) -- [Plattform-Anleitung](../docs/PLATFORM_GUIDE.md) -- [Changelog](../CHANGELOG.md) - -### Community - -- [Diskussionen](https://github.com/mixelpixx/KiCAD-MCP-Server/discussions) — Fragen, Ideen, Projekte zeigen -- [Issues](https://github.com/mixelpixx/KiCAD-MCP-Server/issues) — Fehler und Feature-Wünsche -- [Mitwirken](../CONTRIBUTING.md) - -### KI-Hinweis - -> **Entwickelt mit KI-Unterstützung** -> Dieses Projekt wurde unter Einsatz von KI-gestützten Entwicklungswerkzeugen (GitHub Copilot, Claude) erstellt. -> Sämtlicher Code wurde von den Maintainern geprüft, getestet und integriert. -> KI-Werkzeuge dienten der Entwicklungsbeschleunigung — kreative Entscheidungen, Architektur und Verantwortung liegen ausschließlich bei den Autoren. - -### Haftungsausschluss - -> **Keine Haftung — Nutzung auf eigene Verantwortung** -> -> Dieses Projekt wird ohne jegliche Gewährleistung bereitgestellt — weder ausdrücklich noch stillschweigend. Die Autoren und Mitwirkenden übernehmen keinerlei Haftung für Schäden jeder Art, die durch die Nutzung oder Nichtnutzung dieser Software entstehen, einschließlich aber nicht beschränkt auf: -> -> - Fehler in erzeugten Schaltplänen, PCB-Layouts oder Fertigungsdateien -> - Schäden an Hardware, Bauteilen oder Geräten durch fehlerhafte Designs -> - Finanzielle Verluste durch Fehlproduktionen oder Fehlerbestellungen -> - Datenverlust oder Beschädigung von KiCAD-Projektdateien -> -> KI-generierte Design-Vorschläge ersetzen keine qualifizierte ingenieurtechnische Prüfung. Sicherheitskritische Anwendungen (Medizintechnik, Luftfahrt, Automotive o.ä.) erfordern zwingend eine unabhängige Fachprüfung. -> -> Dieses Projekt steht unter der MIT-Lizenz — die Lizenz schließt ebenfalls jede Haftung aus. - -
back to top
- ---- - -## 中文 - -**KiCAD MCP Server** 是一个模型上下文协议(MCP)服务器,使 Claude 等 AI 助手能够与 KiCAD 交互,实现 PCB 设计自动化。本服务器基于 MCP 2025-06-18 规范构建,为智能 PCB 设计工作流提供全面的工具模式和实时项目状态访问。 - -### 用自然语言设计 PCB - -描述你想构建的内容 — 让 AI 处理 EDA 工作。放置元件、创建自定义符号和封装、布线、运行检查并导出生产文件 — 全程通过与 AI 助手对话完成。 - -### 当前功能 - -- 项目创建、原理图编辑、元件放置、布线、DRC/ERC、导出 -- **自定义符号和封装生成** — 适用于标准 KiCAD 库中未收录的模块 -- **个人库管理** — 一次创建,跨项目复用 -- **JLCPCB 集成** — 包含价格和库存数据的元件目录 -- **Freerouting 集成** — 通过 Java/Docker 实现自动 PCB 布线 -- **可视化反馈** — 快照和会话日志,便于追溯 -- **跨平台** — Windows、Linux、macOS - -### 快速开始 - -1. 安装 [KiCAD 9.0+](https://www.kicad.org/download/) -2. 安装 [Node.js 18+](https://nodejs.org/) 和 [Python 3.11+](https://www.python.org/) -3. 克隆并构建: - -```bash -git clone https://github.com/mixelpixx/KiCAD-MCP-Server.git -cd KiCAD-MCP-Server -npm install -npm run build -``` - -4. 配置 Claude Desktop — 参见 [平台指南](../docs/PLATFORM_GUIDE.md) - -### 文档 - -- [**完整 README**](../README.md) — 完整文档 -- [快速开始(路由工具)](../docs/ROUTER_QUICK_START.md) — 入门指引 -- [工具清单](../docs/TOOL_INVENTORY.md) — 所有可用工具 -- [原理图工具参考](../docs/SCHEMATIC_TOOLS_REFERENCE.md) -- [布线工具参考](../docs/ROUTING_TOOLS_REFERENCE.md) -- [封装与符号创建指南](../docs/FOOTPRINT_SYMBOL_CREATOR_GUIDE.md) -- [JLCPCB 使用指南](../docs/JLCPCB_USAGE_GUIDE.md) -- [平台指南](../docs/PLATFORM_GUIDE.md) -- [更新日志](../CHANGELOG.md) - -### 社区 - -- [讨论区](https://github.com/mixelpixx/KiCAD-MCP-Server/discussions) — 问题、想法、展示项目 -- [问题反馈](https://github.com/mixelpixx/KiCAD-MCP-Server/issues) — 错误报告和功能请求 -- [贡献指南](../CONTRIBUTING.md) - -### AI 声明 - -> **借助 AI 辅助开发** -> 本项目在 AI 辅助编码工具(GitHub Copilot、Claude)的支持下开发完成。 -> 所有代码均经过维护者的审查、测试和集成。 -> AI 工具用于加速开发 — 创意决策、架构设计和责任归属完全由作者承担。 - -### 免责声明 - -> **不提供任何保证 — 使用风险自负** -> -> 本项目按现状提供,不附带任何明示或暗示的保证。作者和贡献者对因使用或无法使用本软件而造成的任何类型的损害不承担任何责任,包括但不限于: -> -> - 生成的原理图、PCB 布局或生产文件中的错误 -> - 因设计错误导致的硬件、元件或设备损坏 -> - 因生产错误或错误订单造成的经济损失 -> - KiCAD 项目文件的数据丢失或损坏 -> -> AI 生成的设计建议不能替代专业工程师审查。安全关键型应用(医疗、航空航天、汽车等)必须进行独立的专业验证。 -> -> 本项目采用 MIT 许可证 — 该许可证同样排除一切责任。 - -
back to top
diff --git a/.github/README.zh.md b/.github/README.zh.md new file mode 100644 index 0000000..8a09de0 --- /dev/null +++ b/.github/README.zh.md @@ -0,0 +1,119 @@ + + +
+ +KiCAD-MCP-Server Logo + +# KiCAD MCP Server + +[🇺🇸 **English** (EN)](README.md)  •  [🇩🇪 **Deutsch** (DE)](README.de.md)  •  [🇨🇳 **中文** (ZH)](#) + +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](../LICENSE) +[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)](../docs/PLATFORM_GUIDE.md) +[![KiCAD](https://img.shields.io/badge/KiCAD-9.0+-green.svg)](https://www.kicad.org/) +[![Stars](https://img.shields.io/github/stars/mixelpixx/KiCAD-MCP-Server.svg)](https://github.com/mixelpixx/KiCAD-MCP-Server/stargazers) +[![Discussions](https://img.shields.io/badge/community-Discussions-orange.svg)](https://github.com/mixelpixx/KiCAD-MCP-Server/discussions) + +
+ + +
+ +#### 我们的新论坛已上线:https://forum.orchis.ai — 有问题?有建议?想展示你的作品? + +
+ + +# + +**KiCAD MCP Server** 是一个模型上下文协议(MCP)服务器,使 Claude 等 AI 助手能够与 KiCAD 交互,实现 PCB 设计自动化。本服务器基于 MCP 2025-06-18 规范构建,为智能 PCB 设计工作流提供全面的工具模式和实时项目状态访问。 + +### 用自然语言设计 PCB + +描述你想构建的内容 — 让 AI 处理 EDA 工作。放置元件、创建自定义符号和封装、布线、运行检查并导出生产文件 — 全程通过与 AI 助手对话完成。 + +### 当前功能 + +- 项目创建、原理图编辑、元件放置、布线、DRC/ERC、导出 +- **自定义符号和封装生成** — 适用于标准 KiCAD 库中未收录的模块 +- **个人库管理** — 一次创建,跨项目复用 +- **JLCPCB 集成** — 包含价格和库存数据的元件目录 +- **Freerouting 集成** — 通过 Java/Docker 实现自动 PCB 布线 +- **可视化反馈** — 快照和会话日志,便于追溯 +- **跨平台** — Windows、Linux、macOS + +### 快速开始 + +1. 安装 [KiCAD 9.0+](https://www.kicad.org/download/) +2. 安装 [Node.js 18+](https://nodejs.org/) 和 [Python 3.11+](https://www.python.org/) +3. 克隆并构建: + +```bash +git clone https://github.com/mixelpixx/KiCAD-MCP-Server.git +cd KiCAD-MCP-Server +npm install +npm run build +``` + +4. 配置 AI 客户端 — 参见 [平台指南](../docs/PLATFORM_GUIDE.md) + +### GitHub Copilot(VS Code) + +复制配置模板: + +```bash +cp config/vscode-mcp.example.json .vscode/mcp.json +``` + +VS Code 会自动检测 `.vscode/mcp.json` 并注册服务器。模板使用 `${workspaceFolder}`,无需修改路径。 + +### Claude Desktop + +编辑配置文件: + +- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json` +- **macOS/Linux:** `~/.config/claude/claude_desktop_config.json` + +示例配置:`config/windows-config.example.json` 或 `config/macos-config.example.json` + +### 文档 + +- [**完整 README**](../README.md) — 完整文档 +- [快速开始(路由工具)](../docs/ROUTER_QUICK_START.md) — 入门指引 +- [工具清单](../docs/TOOL_INVENTORY.md) — 所有可用工具 +- [原理图工具参考](../docs/SCHEMATIC_TOOLS_REFERENCE.md) +- [布线工具参考](../docs/ROUTING_TOOLS_REFERENCE.md) +- [封装与符号创建指南](../docs/FOOTPRINT_SYMBOL_CREATOR_GUIDE.md) +- [JLCPCB 使用指南](../docs/JLCPCB_USAGE_GUIDE.md) +- [平台指南](../docs/PLATFORM_GUIDE.md) +- [更新日志](../CHANGELOG.md) + +### 社区 + +- [讨论区](https://github.com/mixelpixx/KiCAD-MCP-Server/discussions) — 问题、想法、展示项目 +- [问题反馈](https://github.com/mixelpixx/KiCAD-MCP-Server/issues) — 错误报告和功能请求 +- [贡献指南](../CONTRIBUTING.md) + +### AI 声明 + +> **借助 AI 辅助开发** +> 本项目在 AI 辅助编码工具(GitHub Copilot、Claude)的支持下开发完成。 +> 所有代码均经过维护者的审查、测试和集成。 +> AI 工具用于加速开发 — 创意决策、架构设计和责任归属完全由作者承担。 + +### 免责声明 + +> **不提供任何保证 — 使用风险自负** +> +> 本项目按现状提供,不附带任何明示或暗示的保证。作者和贡献者对因使用或无法使用本软件而造成的任何类型的损害不承担任何责任,包括但不限于: +> +> - 生成的原理图、PCB 布局或生产文件中的错误 +> - 因设计错误导致的硬件、元件或设备损坏 +> - 因生产错误或错误订单造成的经济损失 +> - KiCAD 项目文件的数据丢失或损坏 +> +> AI 生成的设计建议不能替代专业工程师审查。安全关键型应用(医疗、航空航天、汽车等)必须进行独立的专业验证。 +> +> 本项目采用 MIT 许可证 — 该许可证同样排除一切责任。 + +
back to top
diff --git a/.gitignore b/.gitignore index c13e2ca..d83fb3c 100644 --- a/.gitignore +++ b/.gitignore @@ -94,3 +94,6 @@ windows-mcp-config.json # Personal notes / local contributions (not for upstream) myContribution/ CLAUDE.md + +inspect-tools.mjs +resources/images/icon_b64.txt diff --git a/.prettierignore b/.prettierignore index 00f706a..cbde2ef 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,3 +2,4 @@ coverage.xml htmlcov/ data/ *.kicad_* +.github/*.md diff --git a/README.md b/README.md index 1862ba5..4799bc3 100644 --- a/README.md +++ b/README.md @@ -734,6 +734,18 @@ which python3 # Example output: /usr/bin/python3 python3 -c "import pcbnew; print(pcbnew.GetBuildVersion())" # Verify pcbnew access ``` +### GitHub Copilot (VS Code) + +Copy the template to your workspace: + +```bash +cp config/vscode-mcp.example.json .vscode/mcp.json +``` + +VS Code will auto-detect `.vscode/mcp.json` and register the server. The template uses `${workspaceFolder}` so no path editing is needed. + +> **Note:** `.vscode/mcp.json` is listed in `.gitignore` — your local configuration won't be committed. + ### Cline (VSCode) Edit: `~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` diff --git a/config/vscode-mcp.example.json b/config/vscode-mcp.example.json new file mode 100644 index 0000000..aa9e727 --- /dev/null +++ b/config/vscode-mcp.example.json @@ -0,0 +1,16 @@ +{ + "servers": { + "KiCAD-MCP-Server": { + "type": "stdio", + "command": "node", + "args": ["${workspaceFolder}/dist/index.js"], + "env": { + "NODE_ENV": "production", + "PYTHONPATH": "C:\\Program Files\\KiCad\\9.0\\bin\\Lib\\site-packages", + "LOG_LEVEL": "info", + "KICAD_AUTO_LAUNCH": "false", + "KICAD_MCP_DEV": "0" + } + } + } +} diff --git a/docs/TOOL_INVENTORY.md b/docs/TOOL_INVENTORY.md index 85e89a1..59a921c 100644 --- a/docs/TOOL_INVENTORY.md +++ b/docs/TOOL_INVENTORY.md @@ -1,16 +1,18 @@ # KiCAD MCP Server - Complete Tool Inventory -**Version:** 2.2.3 -**Total Tools:** 124 (18 direct + 65 routed + 4 router + 37 additional) -**Last Updated:** 2026-04-20 +**Version:** 2.1.0-alpha +**Total Tools:** 137 (verifiziert via VS Code MCP Discovery Log) +**Last Updated:** 2026-05-02 ## How Tools Are Organized -The server uses a **router pattern** to reduce AI context usage. Tools fall into three groups: +Tools are registered directly via `server.tool()` -- **Direct tools** - Always visible to the AI. High-frequency operations used in most sessions. -- **Routed tools** - Organized into categories. Discovered via the router tools (`list_tool_categories`, `get_category_tools`, `search_tools`) and invoked via `execute_tool`. -- **Additional tools** - Registered directly (always visible) but not part of the router categories. +The `Access` column below uses legacy labels from when a router pattern was planned: + +- **Direct** — High-frequency tools, originally intended as always-visible +- **Routed** — Originally planned for router dispatch; now also registered directly +- **Additional** — Registered directly (always visible) --- @@ -130,64 +132,86 @@ _Source: `src/tools/export.ts`_ --- -## Schematic (29 tools) +## Schematic (43 tools) _Source: `src/tools/schematic.ts`_ -### Component Operations +### Component Operations (10) -| Tool | Description | Access | -| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `add_schematic_component` | Add component to schematic (symbol from library) | Direct | -| `delete_schematic_component` | Remove component from schematic | Additional | -| `edit_schematic_component` | Edit footprint, value, reference, label positions, and **arbitrary custom properties** (MPN, Manufacturer, DigiKey, …) | Additional | -| `set_schematic_component_property` | Add or update a single custom property (BOM/sourcing field) on a component | Additional | -| `remove_schematic_component_property` | Delete a single custom property from a component | Additional | -| `get_schematic_component` | Get component info: built-in fields + all custom properties + label positions | Additional | -| `list_schematic_components` | List all components in schematic | Direct | -| `move_schematic_component` | Move component to new position | Routed (schematic) | -| `rotate_schematic_component` | Rotate component | Routed (schematic) | -| `annotate_schematic` | Auto-annotate reference designators | Direct | +| Tool | Description | Access | +| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------------ | +| `add_schematic_component` | Add component to schematic (symbol from library) | Direct | +| `delete_schematic_component` | Remove component from schematic | Additional | +| `edit_schematic_component` | Edit footprint, value, reference, label positions, and arbitrary custom properties (MPN, Manufacturer, DigiKey, …) | Additional | +| `set_schematic_component_property` | Add or update a single custom property (BOM/sourcing field) on a component | Additional | +| `remove_schematic_component_property` | Delete a single custom property from a component | Additional | +| `get_schematic_component` | Get component info: built-in fields + all custom properties + label positions | Additional | +| `list_schematic_components` | List all components in schematic | Direct | +| `move_schematic_component` | Move component to new position | Routed (schematic) | +| `rotate_schematic_component` | Rotate component | Routed (schematic) | +| `annotate_schematic` | Auto-annotate reference designators | Direct | -### Wiring and Connections +### Wiring and Connections (10) -| Tool | Description | Access | -| ----------------------------- | ------------------------------------------------ | ------------------ | -| `add_wire` | Add wire connection between two points | Routed (schematic) | -| `delete_schematic_wire` | Delete wire segment | Routed (schematic) | -| `add_schematic_connection` | Connect two component pins with wire | Routed (schematic) | -| `add_schematic_net_label` | Add net label to schematic | Direct | -| `delete_schematic_net_label` | Delete net label | Routed (schematic) | -| `connect_to_net` | Connect component pin to named net | Direct | -| `connect_passthrough` | Connect all matching pins between two connectors | Direct | -| `get_schematic_pin_locations` | Get pin locations for a component | Additional | +| Tool | Description | Access | +| ----------------------------- | ---------------------------------------------------- | ------------------ | +| `add_schematic_wire` | Add wire segment between two points | Routed (schematic) | +| `delete_schematic_wire` | Delete wire segment | Routed (schematic) | +| `add_schematic_net_label` | Add net label to schematic | Direct | +| `delete_schematic_net_label` | Delete net label | Routed (schematic) | +| `add_no_connect` | Add no-connect flag (X marker) to an unconnected pin | Direct | +| `move_schematic_net_label` | Move net label to new position | Routed (schematic) | +| `connect_to_net` | Connect component pin to named net | Direct | +| `connect_passthrough` | Connect all matching pins between two connectors | Direct | +| `get_schematic_pin_locations` | Get pin locations for a component | Additional | +| `get_wire_connections` | Get all connections at a wire endpoint | Additional | -### Net Analysis +### Hierarchical Schematics (2) -| Tool | Description | Access | -| ----------------------- | ----------------------------- | ------------------ | -| `get_net_connections` | Get all connections for a net | Routed (schematic) | -| `list_schematic_nets` | List all nets in schematic | Routed (schematic) | -| `list_schematic_wires` | List all wires in schematic | Routed (schematic) | -| `list_schematic_labels` | List all net labels | Routed (schematic) | +| Tool | Description | Access | +| ---------------------------------- | -------------------------------------------------- | ------------------ | +| `add_schematic_hierarchical_label` | Add hierarchical label for multi-sheet connections | Routed (schematic) | +| `add_sheet_pin` | Add a sheet pin to a hierarchical sheet symbol | Routed (schematic) | -### Text Annotations +### Net Analysis (5) + +| Tool | Description | Access | +| ----------------------- | ------------------------------------ | ------------------ | +| `get_net_connections` | Get all connections for a net | Routed (schematic) | +| `get_net_at_point` | Get the net name at an XY coordinate | Additional | +| `list_schematic_nets` | List all nets in schematic | Routed (schematic) | +| `list_schematic_wires` | List all wires in schematic | Routed (schematic) | +| `list_schematic_labels` | List all net labels | Routed (schematic) | + +### Text Annotations (2) | Tool | Description | Access | | ---------------------- | ------------------------------------------------ | ------------------ | | `add_schematic_text` | Add free-form text annotation to schematic | Routed (schematic) | | `list_schematic_texts` | List all text annotations (with optional filter) | Routed (schematic) | -### Schematic Creation and Export +### Visual / Geometry Helpers (8) -| Tool | Description | Access | -| ---------------------- | -------------------------------- | ------------------ | -| `create_schematic` | Create a new schematic file | Routed (schematic) | -| `get_schematic_view` | Get schematic as image (PNG/SVG) | Routed (schematic) | -| `export_schematic_svg` | Export schematic to SVG | Routed (schematic) | -| `export_schematic_pdf` | Export schematic to PDF | Routed (schematic) | +| Tool | Description | Access | +| ----------------------------- | --------------------------------------------------------- | ------------------ | +| `get_schematic_view` | Render schematic as image (PNG/SVG) | Routed (schematic) | +| `get_schematic_view_region` | Render a specific region of the schematic as image | Additional | +| `find_overlapping_elements` | Find schematic elements that visually overlap | Additional | +| `get_elements_in_region` | Get all elements inside an XY bounding box | Additional | +| `find_wires_crossing_symbols` | Find wires that cross through symbol bodies (DRC helper) | Additional | +| `list_floating_labels` | List net labels not connected to any wire | Additional | +| `find_orphaned_wires` | Find wire segments not connected at one or both ends | Additional | +| `snap_to_grid` | Snap an XY coordinate to the nearest schematic grid point | Additional | -### Validation and Synchronization +### Schematic Creation and Export (3) + +| Tool | Description | Access | +| ---------------------- | --------------------------- | ------------------ | +| `create_schematic` | Create a new schematic file | Routed (schematic) | +| `export_schematic_svg` | Export schematic to SVG | Routed (schematic) | +| `export_schematic_pdf` | Export schematic to PDF | Routed (schematic) | + +### Validation and Synchronization (3) | Tool | Description | Access | | ------------------------- | ----------------------------------------------------- | ------------------ | @@ -298,30 +322,29 @@ _Source: `src/tools/ui.ts`_ --- -## Router Tools (4 tools) +## Router / Discovery Tools (3 tools) _Source: `src/tools/router.ts`_ -These meta-tools provide discovery and execution of routed tools: +Registriert via `registerRouterTools()` in `src/server.ts`. Ermöglichen Tool-Discovery durch den LLM. -| Tool | Description | -| ---------------------- | ------------------------------------ | -| `list_tool_categories` | Browse all available tool categories | -| `get_category_tools` | View tools in a specific category | -| `search_tools` | Find tools by keyword | -| `execute_tool` | Run any routed tool with parameters | +| Tool | Description | Access | +| ---------------------- | ------------------------------------ | ------ | +| `list_tool_categories` | Browse all available tool categories | Direct | +| `get_category_tools` | View tools in a specific category | Direct | +| `search_tools` | Find tools by keyword | Direct | --- ## Summary by Access Type -| Access Type | Count | Description | -| ----------- | ------- | --------------------------------------------------- | -| Direct | 18 | Always visible, no router needed | -| Routed | 65 | Discovered via router, invoked via `execute_tool` | -| Router | 4 | Meta-tools for discovering and running routed tools | -| Additional | 35 | Always visible, registered directly | -| **Total** | **122** | | +| Access Type | Count | Description | +| -------------------- | ------- | ---------------------------------------- | +| Direct | 21 | Always visible | +| Routed | 72 | Always visible (registered directly) | +| Additional | 44 | Always visible, registered directly | +| Router/Discovery | 3 | Tool-Discovery (`router.ts`, registered) | +| **Total registered** | **137** | Verifiziert via VS Code MCP Discovery | ## Summary by Category @@ -333,7 +356,7 @@ These meta-tools provide discovery and execution of routed tools: | Routing | 13 | | Design Rules / DRC | 8 | | Export | 8 | -| Schematic | 27 | +| Schematic | 43 | | Footprint Libraries | 4 | | Symbol Libraries | 4 | | Footprint Creator | 4 | @@ -342,11 +365,11 @@ These meta-tools provide discovery and execution of routed tools: | JLCPCB Integration | 5 | | Freerouting | 4 | | UI Management | 2 | -| Router | 4 | -| **Total** | **122** | +| Router / Discovery | 3 | +| **Total registered** | **137** | + +> **Verified:** VS Code MCP Discovery Log meldet **137** registrierte Tools. ## Token Impact -**Before Router Pattern:** All 122 tools in context = ~80K+ tokens -**With Router Pattern:** 18 direct + 35 additional + 4 router = 57 always-visible tools -**On-Demand:** 65 routed tools loaded only when their category is requested +Alle 137 registrierten Tools sind stets für den LLM sichtbar. Die Discovery-Tools in `router.ts` ermöglichen dem Modell, Tools nach Kategorie oder Stichwort zu durchsuchen. diff --git a/python/kicad_interface.py b/python/kicad_interface.py index c9dd3ef..89fed07 100644 --- a/python/kicad_interface.py +++ b/python/kicad_interface.py @@ -391,6 +391,7 @@ class KiCADInterface: "get_schematic_component": self._handle_get_schematic_component, "add_schematic_wire": self._handle_add_schematic_wire, "add_schematic_net_label": self._handle_add_schematic_net_label, + "add_no_connect": self._handle_add_no_connect, "connect_to_net": self._handle_connect_to_net, "connect_passthrough": self._handle_connect_passthrough, "get_schematic_pin_locations": self._handle_get_schematic_pin_locations, @@ -1996,6 +1997,66 @@ class KiCADInterface: "errorDetails": traceback.format_exc(), } + def _handle_add_no_connect(self, params: Dict[str, Any]) -> Dict[str, Any]: + """Add a no-connect flag (X marker) to an unconnected pin in the schematic.""" + logger.info("Adding no-connect flag to schematic") + try: + from pathlib import Path + + from commands.pin_locator import PinLocator + from commands.wire_manager import WireManager + + schematic_path = params.get("schematicPath") + position = params.get("position") + component_ref = params.get("componentRef") + pin_number = params.get("pinNumber") + + if not schematic_path: + return {"success": False, "message": "schematicPath is required"} + + # Snap to pin endpoint when componentRef + pinNumber are provided + snapped_to_pin = None + if component_ref and pin_number is not None: + locator = PinLocator() + pin_loc = locator.get_pin_location( + Path(schematic_path), component_ref, str(pin_number) + ) + if pin_loc is None: + return { + "success": False, + "message": f"Could not locate pin {pin_number} on {component_ref}", + } + position = pin_loc + snapped_to_pin = {"component": component_ref, "pin": str(pin_number)} + elif position is None: + return { + "success": False, + "message": "Provide either position [x, y] or componentRef + pinNumber", + } + + success = WireManager.add_no_connect(Path(schematic_path), position) + if success: + result = { + "success": True, + "message": f"Added no-connect flag at {position}", + "actual_position": position, + } + if snapped_to_pin: + result["snapped_to_pin"] = snapped_to_pin + return result + else: + return {"success": False, "message": "Failed to add no-connect flag"} + + except Exception as e: + import traceback + + logger.error(f"Error adding no-connect: {e}") + return { + "success": False, + "message": str(e), + "errorDetails": traceback.format_exc(), + } + def _handle_connect_to_net(self, params: Dict[str, Any]) -> Dict[str, Any]: """Connect a component pin to a named net using wire stub and label, and also assign the net to the corresponding pad on the PCB board so @@ -2149,9 +2210,7 @@ class KiCADInterface: f"Assigned net '{net_name}' to pad {component_ref}/{pin_name} on PCB" ) return True - logger.warning( - f"Pad '{pin_name}' not found on footprint '{component_ref}'" - ) + logger.warning(f"Pad '{pin_name}' not found on footprint '{component_ref}'") return False logger.warning(f"Footprint '{component_ref}' not found on board") @@ -2741,8 +2800,8 @@ class KiCADInterface: new_mirror_y = old_mirror_y effective_mirror = "x" if old_mirror_x else ("y" if old_mirror_y else None) else: - new_mirror_x = (mirror == "x") - new_mirror_y = (mirror == "y") + new_mirror_x = mirror == "x" + new_mirror_y = mirror == "y" effective_mirror = mirror # Compute pin world positions before and after the transform @@ -2767,7 +2826,9 @@ class KiCADInterface: drag_summary = WireDragger.drag_wires(sch_data, old_to_new) # Update the symbol's rotation and mirror token in sexpdata - WireDragger.update_symbol_rotation_mirror(sch_data, reference, float(angle), effective_mirror) + WireDragger.update_symbol_rotation_mirror( + sch_data, reference, float(angle), effective_mirror + ) WireManager.sync_junctions(sch_data) diff --git a/resources/images/KiCAD-MCP-Server_opt.svg b/resources/images/KiCAD-MCP-Server_opt.svg new file mode 100644 index 0000000..fe3482e --- /dev/null +++ b/resources/images/KiCAD-MCP-Server_opt.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mixelpixx + KiCAD-MCP-Server + + diff --git a/src/server.ts b/src/server.ts index 8d7deb0..a3a4a6e 100644 --- a/src/server.ts +++ b/src/server.ts @@ -214,9 +214,7 @@ export class KiCADMcpServer { logger.info("Registering KiCAD tools, resources, and prompts..."); // Register router tools FIRST (for tool discovery and execution) - // NOTE: Router disabled — causes Claude to hallucinate tool schemas via search_tools/execute_tool. - // All tools are registered directly below and are immediately visible to Claude. - // registerRouterTools(this.server, this.callKicadScript.bind(this)); + registerRouterTools(this.server, this.callKicadScript.bind(this)); // Register all tools registerProjectTools(this.server, this.callKicadScript.bind(this)); @@ -248,7 +246,6 @@ export class KiCADMcpServer { registerFootprintPrompts(this.server); logger.info("All KiCAD tools, resources, and prompts registered"); - logger.info("Router pattern enabled: 4 router tools + direct tools for discovery"); } /** diff --git a/src/tools/board.ts b/src/tools/board.ts index 65e6631..422e2f2 100644 --- a/src/tools/board.ts +++ b/src/tools/board.ts @@ -25,6 +25,7 @@ export function registerBoardTools(server: McpServer, callKicadScript: CommandFu // ------------------------------------------------------ server.tool( "set_board_size", + "Set the PCB board dimensions (width and height) in the specified unit.", { width: z.number().describe("Board width"), height: z.number().describe("Board height"), @@ -54,6 +55,7 @@ export function registerBoardTools(server: McpServer, callKicadScript: CommandFu // ------------------------------------------------------ server.tool( "add_layer", + "Add a new copper or technical layer to the PCB stackup.", { name: z.string().describe("Layer name"), type: z.enum(["copper", "technical", "user", "signal"]).describe("Layer type"), @@ -85,6 +87,7 @@ export function registerBoardTools(server: McpServer, callKicadScript: CommandFu // ------------------------------------------------------ server.tool( "set_active_layer", + "Set the currently active PCB layer by name (e.g. F.Cu, B.Cu).", { layer: z.string().describe("Layer name to set as active"), }, @@ -106,42 +109,53 @@ export function registerBoardTools(server: McpServer, callKicadScript: CommandFu // ------------------------------------------------------ // Get Board Info Tool // ------------------------------------------------------ - server.tool("get_board_info", {}, async () => { - logger.debug("Getting board information"); - const result = await callKicadScript("get_board_info", {}); + server.tool( + "get_board_info", + "Retrieve general information about the current PCB board (dimensions, layer count, DRC status).", + {}, + async () => { + logger.debug("Getting board information"); + const result = await callKicadScript("get_board_info", {}); - return { - content: [ - { - type: "text", - text: JSON.stringify(result), - }, - ], - }; - }); + return { + content: [ + { + type: "text", + text: JSON.stringify(result), + }, + ], + }; + }, + ); // ------------------------------------------------------ // Get Layer List Tool // ------------------------------------------------------ - server.tool("get_layer_list", {}, async () => { - logger.debug("Getting layer list"); - const result = await callKicadScript("get_layer_list", {}); + server.tool( + "get_layer_list", + "Return the list of all layers defined in the current PCB board.", + {}, + async () => { + logger.debug("Getting layer list"); + const result = await callKicadScript("get_layer_list", {}); - return { - content: [ - { - type: "text", - text: JSON.stringify(result), - }, - ], - }; - }); + return { + content: [ + { + type: "text", + text: JSON.stringify(result), + }, + ], + }; + }, + ); // ------------------------------------------------------ // Add Board Outline Tool // ------------------------------------------------------ server.tool( "add_board_outline", + "Draw the PCB board outline (Edge.Cuts layer) as a rectangle, rounded rectangle, circle or polygon.", { shape: z .enum(["rectangle", "circle", "polygon", "rounded_rectangle"]) @@ -196,6 +210,7 @@ export function registerBoardTools(server: McpServer, callKicadScript: CommandFu // ------------------------------------------------------ server.tool( "add_mounting_hole", + "Place a mounting hole (NPTH or PTH) at the specified position on the PCB.", { position: z .object({ @@ -231,6 +246,7 @@ export function registerBoardTools(server: McpServer, callKicadScript: CommandFu // ------------------------------------------------------ server.tool( "add_board_text", + "Add a text label to a PCB layer (e.g. silkscreen, fab, courtyard).", { text: z.string().describe("Text content"), position: z @@ -274,6 +290,7 @@ export function registerBoardTools(server: McpServer, callKicadScript: CommandFu // ------------------------------------------------------ server.tool( "add_zone", + "Create a copper fill zone (pour) on a PCB layer for a specified net.", { layer: z.string().describe("Layer for the zone"), net: z.string().describe("Net name for the zone"), @@ -321,6 +338,7 @@ export function registerBoardTools(server: McpServer, callKicadScript: CommandFu // ------------------------------------------------------ server.tool( "get_board_extents", + "Return the bounding box (min/max X and Y) of all objects on the current PCB board.", { unit: z.enum(["mm", "inch"]).optional().describe("Unit of measurement for the result"), }, @@ -344,6 +362,7 @@ export function registerBoardTools(server: McpServer, callKicadScript: CommandFu // ------------------------------------------------------ server.tool( "get_board_2d_view", + "Render a 2D image of the current PCB board and return it as PNG, JPG or SVG.", { layers: z.array(z.string()).optional().describe("Optional array of layer names to include"), width: z.number().optional().describe("Optional width of the image in pixels"), diff --git a/src/tools/component.ts b/src/tools/component.ts index 6e7a699..be84db1 100644 --- a/src/tools/component.ts +++ b/src/tools/component.ts @@ -23,6 +23,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "place_component", + "Place a footprint component onto the PCB at the specified position. Optionally set reference, value, footprint, rotation and layer.", { componentId: z .string() @@ -77,6 +78,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "move_component", + "Move a PCB component to a new position. Optionally update rotation or flip to a different copper layer.", { reference: z.string().describe("Reference designator of the component (e.g., 'R5')"), position: z @@ -119,6 +121,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "rotate_component", + "Rotate a PCB component to an absolute angle in degrees.", { reference: z.string().describe("Reference designator of the component (e.g., 'R5')"), angle: z.number().describe("Rotation angle in degrees (absolute, not relative)"), @@ -146,6 +149,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "delete_component", + "Remove a component from the PCB by its reference designator.", { reference: z .string() @@ -171,6 +175,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "edit_component", + "Edit properties of an existing PCB component (reference, value, footprint).", { reference: z.string().describe("Reference designator of the component (e.g., 'R5')"), newReference: z.string().optional().describe("Optional new reference designator"), @@ -202,6 +207,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "find_component", + "Search for a PCB component by reference designator or value and return its position and properties.", { reference: z.string().optional().describe("Reference designator to search for"), value: z.string().optional().describe("Component value to search for"), @@ -231,6 +237,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "get_component_properties", + "Return all properties of a PCB component (position, rotation, layer, value, footprint).", { reference: z.string().describe("Reference designator of the component (e.g., 'R5')"), }, @@ -256,6 +263,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "add_component_annotation", + "Add a text annotation or comment to a PCB component.", { reference: z.string().describe("Reference designator of the component (e.g., 'R5')"), annotation: z.string().describe("Annotation or comment text to add"), @@ -288,6 +296,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "group_components", + "Group multiple PCB components together by name for easier selection and manipulation.", { references: z.array(z.string()).describe("Reference designators of components to group"), groupName: z.string().describe("Name for the component group"), @@ -315,6 +324,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "replace_component", + "Replace an existing PCB component with a different component type, optionally changing footprint and value.", { reference: z.string().describe("Reference designator of the component to replace"), newComponentId: z.string().describe("ID of the new component to use"), @@ -346,6 +356,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "get_component_pads", + "Return all pads of a PCB component with their positions, net assignments and sizes.", { reference: z.string().describe("Reference designator of the component (e.g., 'U1')"), unit: z.enum(["mm", "inch"]).optional().describe("Unit for coordinates (default: mm)"), @@ -373,6 +384,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "get_component_list", + "Return a list of all components on the PCB, optionally filtered by layer or bounding box region.", { layer: z.string().optional().describe("Filter by layer (e.g., 'F.Cu', 'B.Cu')"), boundingBox: z @@ -411,6 +423,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "get_pad_position", + "Return the exact XY position of a specific pad on a PCB component. Use this before routing to get accurate start/end coordinates.", { reference: z.string().describe("Component reference designator (e.g., 'U1')"), pad: z.string().describe("Pad number or name (e.g., '1', 'A1')"), @@ -440,6 +453,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "place_component_array", + "Place a rectangular grid array of identical components on the PCB with configurable row/column spacing.", { componentId: z.string().describe("Component identifier"), startPosition: z @@ -500,6 +514,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "align_components", + "Align multiple PCB components horizontally, vertically or on a grid with optional spacing.", { references: z.array(z.string()).describe("Array of component references to align"), alignmentType: z.enum(["horizontal", "vertical", "grid"]).describe("Type of alignment"), @@ -531,6 +546,7 @@ export function registerComponentTools(server: McpServer, callKicadScript: Comma // ------------------------------------------------------ server.tool( "duplicate_component", + "Duplicate an existing PCB component at an offset position, optionally with a new reference designator.", { reference: z.string().describe("Reference of component to duplicate"), offset: z diff --git a/src/tools/design-rules.ts b/src/tools/design-rules.ts index 9b28cc9..c3ed16c 100644 --- a/src/tools/design-rules.ts +++ b/src/tools/design-rules.ts @@ -25,6 +25,7 @@ export function registerDesignRuleTools(server: McpServer, callKicadScript: Comm // ------------------------------------------------------ server.tool( "set_design_rules", + "Configure PCB design rules: clearance, track width, via dimensions and courtyard requirements.", { clearance: z.number().optional().describe("Minimum clearance between copper items (mm)"), trackWidth: z.number().optional().describe("Default track width (mm)"), @@ -65,25 +66,31 @@ export function registerDesignRuleTools(server: McpServer, callKicadScript: Comm // ------------------------------------------------------ // Get Design Rules Tool // ------------------------------------------------------ - server.tool("get_design_rules", {}, async () => { - logger.debug("Getting design rules"); - const result = await callKicadScript("get_design_rules", {}); + server.tool( + "get_design_rules", + "Return the current PCB design rules (clearance, track width, via sizes, courtyard settings).", + {}, + async () => { + logger.debug("Getting design rules"); + const result = await callKicadScript("get_design_rules", {}); - return { - content: [ - { - type: "text", - text: JSON.stringify(result), - }, - ], - }; - }); + return { + content: [ + { + type: "text", + text: JSON.stringify(result), + }, + ], + }; + }, + ); // ------------------------------------------------------ // Run DRC Tool // ------------------------------------------------------ server.tool( "run_drc", + "Run the KiCAD Design Rule Check (DRC) on the current PCB and return violations. Optionally save the report to a file.", { reportPath: z.string().optional().describe("Optional path to save the DRC report"), }, @@ -107,6 +114,7 @@ export function registerDesignRuleTools(server: McpServer, callKicadScript: Comm // ------------------------------------------------------ server.tool( "add_net_class", + "Create a named net class with specific design rules (clearance, track width, via size) and assign nets to it.", { name: z.string().describe("Name of the net class"), description: z.string().optional().describe("Optional description of the net class"), @@ -170,6 +178,7 @@ export function registerDesignRuleTools(server: McpServer, callKicadScript: Comm // ------------------------------------------------------ server.tool( "assign_net_to_class", + "Assign a net to an existing net class to apply its specific design rules.", { net: z.string().describe("Name of the net"), netClass: z.string().describe("Name of the net class"), @@ -197,6 +206,7 @@ export function registerDesignRuleTools(server: McpServer, callKicadScript: Comm // ------------------------------------------------------ server.tool( "set_layer_constraints", + "Set per-layer design rule constraints (minimum track width, clearance and via dimensions).", { layer: z.string().describe("Layer name (e.g., 'F.Cu')"), minTrackWidth: z.number().optional().describe("Minimum track width for this layer (mm)"), @@ -230,6 +240,7 @@ export function registerDesignRuleTools(server: McpServer, callKicadScript: Comm // ------------------------------------------------------ server.tool( "check_clearance", + "Check the actual clearance between two PCB items (track, via, pad, zone or component) and report whether it meets the design rules.", { item1: z .object({ @@ -289,6 +300,7 @@ export function registerDesignRuleTools(server: McpServer, callKicadScript: Comm // ------------------------------------------------------ server.tool( "get_drc_violations", + "Return the list of current DRC violations on the PCB, optionally filtered by severity (error, warning).", { severity: z .enum(["error", "warning", "all"]) diff --git a/src/tools/export.ts b/src/tools/export.ts index f36f688..2be9625 100644 --- a/src/tools/export.ts +++ b/src/tools/export.ts @@ -25,6 +25,7 @@ export function registerExportTools(server: McpServer, callKicadScript: CommandF // ------------------------------------------------------ server.tool( "export_gerber", + "Export PCB Gerber manufacturing files to a directory. Optionally include drill files, map files and choose layer subset.", { outputDir: z.string().describe("Directory to save Gerber files"), layers: z @@ -73,6 +74,7 @@ export function registerExportTools(server: McpServer, callKicadScript: CommandF // ------------------------------------------------------ server.tool( "export_pdf", + "Export the PCB layout as a PDF document, optionally selecting layers, page size and colour mode.", { outputPath: z.string().describe("Path to save the PDF file"), layers: z @@ -112,6 +114,7 @@ export function registerExportTools(server: McpServer, callKicadScript: CommandF // ------------------------------------------------------ server.tool( "export_svg", + "Export the PCB layout as an SVG vector image, optionally selecting layers and colour mode.", { outputPath: z.string().describe("Path to save the SVG file"), layers: z @@ -146,6 +149,7 @@ export function registerExportTools(server: McpServer, callKicadScript: CommandF // ------------------------------------------------------ server.tool( "export_3d", + "Export the PCB as a 3D model (STEP, STL, VRML or OBJ) including optional copper, solder mask, silkscreen and component 3D models.", { outputPath: z.string().describe("Path to save the 3D model file"), format: z.enum(["STEP", "STL", "VRML", "OBJ"]).describe("3D model format"), @@ -188,6 +192,7 @@ export function registerExportTools(server: McpServer, callKicadScript: CommandF // ------------------------------------------------------ server.tool( "export_bom", + "Export a Bill of Materials (BOM) from the PCB in CSV, XML, HTML or JSON format.", { outputPath: z.string().describe("Path to save the BOM file"), format: z.enum(["CSV", "XML", "HTML", "JSON"]).describe("BOM file format"), @@ -255,6 +260,7 @@ export function registerExportTools(server: McpServer, callKicadScript: CommandF // ------------------------------------------------------ server.tool( "export_position_file", + "Export a component placement/position file (pick-and-place) for PCB assembly in CSV or ASCII format.", { outputPath: z.string().describe("Path to save the position file"), format: z.enum(["CSV", "ASCII"]).optional().describe("File format (default: CSV)"), @@ -289,6 +295,7 @@ export function registerExportTools(server: McpServer, callKicadScript: CommandF // ------------------------------------------------------ server.tool( "export_vrml", + "Export the PCB as a VRML 3D model for use in web viewers or simulation tools.", { outputPath: z.string().describe("Path to save the VRML file"), includeComponents: z.boolean().optional().describe("Whether to include 3D component models"), diff --git a/src/tools/registry.ts b/src/tools/registry.ts index 4638259..f5bbce6 100644 --- a/src/tools/registry.ts +++ b/src/tools/registry.ts @@ -96,6 +96,7 @@ export const toolCategories: ToolCategory[] = [ "delete_schematic_wire", "add_schematic_net_label", "delete_schematic_net_label", + "add_no_connect", "connect_to_net", "connect_passthrough", "get_net_connections", diff --git a/src/tools/router.ts b/src/tools/router.ts index 437aa51..10d43a0 100644 --- a/src/tools/router.ts +++ b/src/tools/router.ts @@ -10,7 +10,6 @@ import { logger } from "../logger.js"; import { getAllCategories, getCategory, - getToolCategory, searchTools as registrySearchTools, getRegistryStats, } from "./registry.js"; @@ -18,26 +17,10 @@ import { // Command function type for KiCAD script calls type CommandFunction = (command: string, params: Record) => Promise; -// Map to store tool execution handlers -// This will be populated by registerToolHandler() -const toolHandlers = new Map Promise>(); - -/** - * Register a tool handler for execution via execute_tool - * This should be called by each tool registration function - */ -export function registerToolHandler( - toolName: string, - handler: (params: any) => Promise, -): void { - toolHandlers.set(toolName, handler); - logger.debug(`Registered handler for routed tool: ${toolName}`); -} - /** * Register all router tools with the MCP server */ -export function registerRouterTools(server: McpServer, callKicadScript: CommandFunction): void { +export function registerRouterTools(server: McpServer, _callKicadScript: CommandFunction): void { logger.info("Registering router tools"); // ============================================================================ @@ -45,6 +28,7 @@ export function registerRouterTools(server: McpServer, callKicadScript: CommandF // ============================================================================ server.tool( "list_tool_categories", + "List all available KiCAD tool categories with their descriptions and tool counts. Use this to discover which tools are available via the router.", { // No parameters }, @@ -82,6 +66,7 @@ export function registerRouterTools(server: McpServer, callKicadScript: CommandF // ============================================================================ server.tool( "get_category_tools", + "Return all tools available in a specific category. Use list_tool_categories first to find valid category names.", { category: z.string().describe("Category name from list_tool_categories"), }, @@ -133,136 +118,12 @@ export function registerRouterTools(server: McpServer, callKicadScript: CommandF }, ); - // ============================================================================ - // execute_tool - // ============================================================================ - server.tool( - "execute_tool", - { - tool_name: z.string().describe("Tool name from get_category_tools"), - params: z.record(z.unknown()).optional().describe("Tool parameters (optional)"), - }, - async ({ tool_name, params }) => { - logger.info(`Executing routed tool: ${tool_name}`); - - // Check if tool exists in registry - const category = getToolCategory(tool_name); - - if (!category) { - return { - content: [ - { - type: "text", - text: JSON.stringify( - { - error: `Unknown tool: ${tool_name}`, - hint: "Use list_tool_categories and get_category_tools to find available tools", - }, - null, - 2, - ), - }, - ], - }; - } - - // Get the handler - const handler = toolHandlers.get(tool_name); - - if (!handler) { - // Tool is in registry but handler not registered yet - // This means the tool exists but hasn't been migrated to router pattern yet - // Fall back to calling KiCAD script directly - logger.warn( - `Tool ${tool_name} in registry but no handler registered, falling back to direct call`, - ); - - try { - const result = await callKicadScript(tool_name, params || {}); - return { - content: [ - { - type: "text", - text: JSON.stringify( - { - tool: tool_name, - category: category, - result: result, - }, - null, - 2, - ), - }, - ], - }; - } catch (error) { - return { - content: [ - { - type: "text", - text: JSON.stringify( - { - error: `Tool execution failed: ${(error as Error).message}`, - tool: tool_name, - category: category, - }, - null, - 2, - ), - }, - ], - }; - } - } - - // Execute the tool via its handler - try { - const result = await handler(params || {}); - - // The handler already returns MCP-formatted response - // Just add metadata - return { - content: [ - { - type: "text", - text: JSON.stringify( - { - tool: tool_name, - category: category, - ...result, - }, - null, - 2, - ), - }, - ], - }; - } catch (error) { - return { - content: [ - { - type: "text", - text: JSON.stringify( - { - error: `Tool execution failed: ${(error as Error).message}`, - tool: tool_name, - category: category, - }, - null, - 2, - ), - }, - ], - }; - } - }, - ); - // ============================================================================ // search_tools // ============================================================================ server.tool( "search_tools", + "Search all available KiCAD tools by keyword. Returns matching tool names and their categories.", { query: z.string().describe("Search term (e.g., 'gerber', 'zone', 'export', 'drc')"), }, diff --git a/src/tools/schematic.ts b/src/tools/schematic.ts index e379af1..4af381b 100644 --- a/src/tools/schematic.ts +++ b/src/tools/schematic.ts @@ -578,6 +578,53 @@ edit_schematic_component and set its value to an empty string.`, }, ); + // Add no-connect flag + server.tool( + "add_no_connect", + "Add a no-connect flag (X marker) to a pin that is intentionally left unconnected. " + + "This suppresses ERC 'Pin not connected' errors for unused pins. " + + "PREFERRED: supply componentRef + pinNumber to snap to the exact pin endpoint. " + + "Alternatively supply position [x, y] in mm matching the pin endpoint exactly.", + { + schematicPath: z.string().describe("Path to the schematic file"), + position: z + .array(z.number()) + .length(2) + .optional() + .describe("Position [x, y] in mm. Required when componentRef/pinNumber are not given."), + componentRef: z + .string() + .optional() + .describe("Component reference to snap to (e.g. U1, R1). Use with pinNumber."), + pinNumber: z + .union([z.string(), z.number()]) + .optional() + .describe("Pin number or name on componentRef (e.g. '1', 'GND'). Use with componentRef."), + }, + async (args: { + schematicPath: string; + position?: number[]; + componentRef?: string; + pinNumber?: string | number; + }) => { + const result = await callKicadScript("add_no_connect", args); + if (result.success) { + return { + content: [{ type: "text", text: JSON.stringify(result, null, 2) }], + }; + } else { + return { + content: [ + { + type: "text", + text: `Failed to add no-connect: ${result.message || "Unknown error"}`, + }, + ], + }; + } + }, + ); + // Connect pin to net server.tool( "connect_to_net",