@hybridlabor-api/bdb-hardware-pcb 0.1.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.
- package/README.md +116 -0
- package/config/mcp/antigravity.json +22 -0
- package/config/mcp/claude.json +22 -0
- package/config/mcp/codex.toml +25 -0
- package/docs/adr/ADR-001-KICAD-OPENSCAD-MCP-STRATEGY.md +334 -0
- package/docs/review_documentation.md +121 -0
- package/installer.js +358 -0
- package/mcp_servers/kicad-mcp-server/.env.example +22 -0
- package/mcp_servers/kicad-mcp-server/.github/workflows/ci.yml +36 -0
- package/mcp_servers/kicad-mcp-server/CLAUDE.md +487 -0
- package/mcp_servers/kicad-mcp-server/README.md +316 -0
- package/mcp_servers/kicad-mcp-server/docs/DEVICE_TREE.md +416 -0
- package/mcp_servers/kicad-mcp-server/docs/INSTALLATION.md +332 -0
- package/mcp_servers/kicad-mcp-server/docs/PIN_ANALYSIS.md +332 -0
- package/mcp_servers/kicad-mcp-server/docs/README.md +240 -0
- package/mcp_servers/kicad-mcp-server/docs/TESTING.md +613 -0
- package/mcp_servers/kicad-mcp-server/docs/VALIDATION.md +268 -0
- package/mcp_servers/kicad-mcp-server/pyproject.toml +96 -0
- package/mcp_servers/kicad-mcp-server/requirements-dev.txt +16 -0
- package/mcp_servers/kicad-mcp-server/requirements-test.txt +24 -0
- package/mcp_servers/kicad-mcp-server/requirements.txt +13 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/__init__.py +3 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/__main__.py +17 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/config.py +46 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/models/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/models/types.py +87 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/netlist_parser.py +234 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/pcb_parser.py +375 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/pcb_parser_kicad.py +327 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/schematic_parser.py +902 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/server.py +71 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/arduino/connectivity_test.cpp.j2 +189 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/atmega.dts.j2 +77 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/esp32.dts.j2 +77 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/nrf52.dts.j2 +77 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/stm32f4.dts.j2 +89 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/esp_idf/test_suite.c.j2 +340 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/pytest/test_connectivity.py.j2 +147 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/st_hal/hal_test.c.j2 +313 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_gpio_test.py.j2 +99 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_i2c_test.py.j2 +117 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_pinmux_test.py.j2 +43 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_spi_test.py.j2 +94 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_gpio_test.c.j2 +113 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_i2c_test.c.j2 +101 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_spi_test.c.j2 +94 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/unittest/test_schematic.py.j2 +172 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/__init__.py +36 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/device_tree.py +1187 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/hierarchical_analysis.py +211 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/netlist.py +320 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/parts_registry.py +142 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pcb.py +955 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pcb_layout.py +308 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pin_analysis.py +765 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/project.py +196 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic.py +319 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic_editor.py +674 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic_search.py +158 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/validation.py +866 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/visualization.py +225 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/file_handlers.py +65 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/kicad_cli.py +103 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/kicad_version.py +103 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/parts_registry.py +197 -0
- package/mcp_servers/kicad-mcp-server/tests/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/tests/examples/ESP32S3_TEST.md +219 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/README.md +65 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/example_pcb.kicad_pcb +177 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/example_schematic.kicad_sch +145 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/hier/child.kicad_sch +24 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/hier/root.kicad_sch +38 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_hierarchical_labels.py +195 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_kicad_cli.py +116 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_netlist_cache_path.py +29 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_schematic.py +189 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_schematic_hierarchy.py +69 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_visualization.py +136 -0
- package/mcp_servers/kicad-mcp-server/uv.lock +2873 -0
- package/mcp_servers/openscad-mcp-server/.dockerignore +9 -0
- package/mcp_servers/openscad-mcp-server/.github/workflows/test.yml +40 -0
- package/mcp_servers/openscad-mcp-server/Dockerfile +29 -0
- package/mcp_servers/openscad-mcp-server/LICENSE +21 -0
- package/mcp_servers/openscad-mcp-server/README.md +154 -0
- package/mcp_servers/openscad-mcp-server/docs/audit.md +56 -0
- package/mcp_servers/openscad-mcp-server/docs/docker.md +66 -0
- package/mcp_servers/openscad-mcp-server/docs/issue-followup.md +19 -0
- package/mcp_servers/openscad-mcp-server/docs/jetson.md +17 -0
- package/mcp_servers/openscad-mcp-server/glama.json +4 -0
- package/mcp_servers/openscad-mcp-server/legacy/README.md +15 -0
- package/mcp_servers/openscad-mcp-server/legacy/README.original.md +294 -0
- package/mcp_servers/openscad-mcp-server/legacy/implementation_plan.md +100 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/download_sam2_checkpoint.py +115 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/src/ai/sam_segmentation.py +209 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/src/models/threestudio_generator.py +231 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/src/workflow/image_to_model_pipeline.py +260 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/test_sam2_segmentation.py +96 -0
- package/mcp_servers/openscad-mcp-server/legacy/requirements.txt +57 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/README.md +39 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/decisions/ai-driven-code-generation.md +122 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/decisions/export-formats.md +76 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/ai/ai_service.py.md +51 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/main.py.md +63 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/models/code_generator.py.md +63 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/nlp/parameter_extractor.py.md +63 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/ai/natural-language-processing.md +78 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/nlp/parameter-extraction.md +173 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/export-formats.md +91 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/openscad-basics.md +66 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/primitive-testing.md +79 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/ai/ai_service.py +257 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/ai/gemini_api.py +161 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/ai/venice_api.py +203 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/config.py +121 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/main.py +1456 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/main.py.new +404 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/main_remote.py +401 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/code_generator.py +321 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/cuda_mvs.py +209 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/scad_templates/basic_shapes.scad +144 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/nlp/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/nlp/parameter_extractor.py +388 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/openscad_wrapper/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/openscad_wrapper/wrapper.py +418 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/printer_discovery/__init__.py +1 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/printer_discovery/printer_discovery.py +471 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/connection_manager.py +537 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/cuda_mvs_client.py +435 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/cuda_mvs_server.py +787 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/error_handling.py +415 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/testing/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/testing/primitive_tester.py +203 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/testing/test_primitives.py +98 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/__init__.py +1 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/cad_exporter.py +241 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/format_validator.py +206 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_exporter.py +140 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_repair.py +91 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_validator.py +123 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/headless_renderer.py +52 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/renderer.py +177 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/web_interface.py +639 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/workflow/image_approval.py +148 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/workflow/multi_view_to_model_pipeline.py +338 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_complete_workflow.py +374 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_cuda_mvs.py +191 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_gemini_api.py +168 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_image_approval.py +192 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_image_approval_workflow.py +251 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_image_to_model_pipeline.py +145 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_model_selection.py +41 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_multi_view_pipeline.py +290 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_primitives.sh +13 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_rabbit_direct.py +71 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_remote_cuda_mvs.py +283 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_venice_example.py +69 -0
- package/mcp_servers/openscad-mcp-server/pyproject.toml +33 -0
- package/mcp_servers/openscad-mcp-server/requirements.txt +2 -0
- package/mcp_servers/openscad-mcp-server/scad/simple_cube.scad +2 -0
- package/mcp_servers/openscad-mcp-server/scripts/test_docker.py +220 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/__init__.py +3 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/__main__.py +3 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/engine.py +94 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/geometry.py +242 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/server.py +245 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/service.py +190 -0
- package/mcp_servers/openscad-mcp-server/tests/conftest.py +17 -0
- package/mcp_servers/openscad-mcp-server/tests/test_engine.py +37 -0
- package/mcp_servers/openscad-mcp-server/tests/test_geometry.py +106 -0
- package/mcp_servers/openscad-mcp-server/tests/test_integration.py +172 -0
- package/mcp_servers/openscad-mcp-server/tests/test_transports.py +314 -0
- package/mcp_servers/openscad-mcp-server/uv.lock +1123 -0
- package/package.json +44 -0
- package/scripts/install_mcps.sh +86 -0
- package/scripts/openscad_wrapper.sh +62 -0
- package/scripts/run_kicad_mcp.sh +25 -0
- package/scripts/run_openscad_mcp.sh +41 -0
- package/scripts/test_mcp_connection.py +626 -0
- package/scripts/test_mcp_connection.sh +168 -0
- package/skills/code-first-hardware-design/SKILL.md +260 -0
- package/skills/pcb-constraint-definition/SKILL.md +236 -0
- package/skills/pcb-layout-routing-automation/SKILL.md +153 -0
- package/skills/pcb-validation-dfm-signoff/SKILL.md +194 -0
- package/skills/schematic-datasheet-analysis/SKILL.md +202 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
# KiCad MCP Server - Development Documentation
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
A Model Context Protocol (MCP) server for KiCad 9.0 EDA software that provides:
|
|
6
|
+
- Schematic analysis and component listing
|
|
7
|
+
- PCB analysis using pcbnew API
|
|
8
|
+
- Netlist-based connection tracing
|
|
9
|
+
- Project creation and editing
|
|
10
|
+
- Schematic and PCB layout modification
|
|
11
|
+
|
|
12
|
+
## Core Design Principles
|
|
13
|
+
|
|
14
|
+
### 1. Use KiCad Python API
|
|
15
|
+
Use KiCad's Python API (pcbnew) for PCB operations instead of manually generating S-expression files.
|
|
16
|
+
|
|
17
|
+
**Why:**
|
|
18
|
+
- Ensures 100% file format compatibility
|
|
19
|
+
- Avoids manual format errors
|
|
20
|
+
- Automatically handles KiCad version differences
|
|
21
|
+
|
|
22
|
+
**Implementation:**
|
|
23
|
+
```python
|
|
24
|
+
# Import KiCad API (requires KiCad environment)
|
|
25
|
+
import pcbnew
|
|
26
|
+
|
|
27
|
+
# Load PCB
|
|
28
|
+
board = pcbnew.LoadBoard("/path/to/project.kicad_pcb")
|
|
29
|
+
|
|
30
|
+
# Get footprints
|
|
31
|
+
for footprint in board.GetFootprints():
|
|
32
|
+
ref = footprint.GetReference()
|
|
33
|
+
pos = footprint.GetPosition()
|
|
34
|
+
# Process footprint...
|
|
35
|
+
|
|
36
|
+
# Save
|
|
37
|
+
pcbnew.SaveBoard("/path/to/project.kicad_pcb", board)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Based on KiCad 9.0
|
|
41
|
+
- Project file format: `.kicad_pro` (JSON, version=3)
|
|
42
|
+
- Schematic format: `.kicad_sch` (version 20240130)
|
|
43
|
+
- PCB format: `.kicad_pcb` (version 20240130)
|
|
44
|
+
|
|
45
|
+
### 3. Netlist-Based Analysis
|
|
46
|
+
Use KiCad XML netlist for accurate connection tracking:
|
|
47
|
+
- Export using: `kicad-cli sch export netlist --format kicadxml`
|
|
48
|
+
- Parse XML to get pin-level connections
|
|
49
|
+
- Bidirectional queries (component <-> network)
|
|
50
|
+
|
|
51
|
+
## Architecture
|
|
52
|
+
|
|
53
|
+
### MCP Server Structure
|
|
54
|
+
```
|
|
55
|
+
FastMCP Framework
|
|
56
|
+
↓
|
|
57
|
+
Tool Registration (@mcp.tool())
|
|
58
|
+
↓
|
|
59
|
+
KiCad Python API / File Parsing
|
|
60
|
+
↓
|
|
61
|
+
Result Return (Markdown format)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Core Modules (6 Tools)
|
|
65
|
+
|
|
66
|
+
#### 1. Schematic Analysis (`tools/schematic.py`)
|
|
67
|
+
Parse and analyze `.kicad_sch` files:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
@mcp.tool()
|
|
71
|
+
async def list_schematic_components(
|
|
72
|
+
file_path: str,
|
|
73
|
+
filter_type: str = ""
|
|
74
|
+
) -> str:
|
|
75
|
+
"""List all components with optional filtering"""
|
|
76
|
+
|
|
77
|
+
@mcp.tool()
|
|
78
|
+
async def list_schematic_nets(
|
|
79
|
+
file_path: str,
|
|
80
|
+
filter_power: bool = False
|
|
81
|
+
) -> str:
|
|
82
|
+
"""List all nets"""
|
|
83
|
+
|
|
84
|
+
@mcp.tool()
|
|
85
|
+
async def get_schematic_info(file_path: str) -> str:
|
|
86
|
+
"""Get schematic metadata and statistics"""
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Parser Implementation:**
|
|
90
|
+
- Custom S-expression parser
|
|
91
|
+
- Regex-based pattern matching
|
|
92
|
+
- No Python API available for schematics
|
|
93
|
+
|
|
94
|
+
#### 2. PCB Analysis (`tools/pcb.py`)
|
|
95
|
+
Analyze PCB files using pcbnew API:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
@mcp.tool()
|
|
99
|
+
async def list_pcb_footprints(
|
|
100
|
+
file_path: str,
|
|
101
|
+
filter_layer: str = None
|
|
102
|
+
) -> str:
|
|
103
|
+
"""List all footprints"""
|
|
104
|
+
|
|
105
|
+
@mcp.tool()
|
|
106
|
+
async def get_pcb_statistics(file_path: str) -> str:
|
|
107
|
+
"""Get PCB statistics"""
|
|
108
|
+
|
|
109
|
+
@mcp.tool()
|
|
110
|
+
async def find_tracks_by_net(
|
|
111
|
+
file_path: str,
|
|
112
|
+
net_name: str
|
|
113
|
+
) -> str:
|
|
114
|
+
"""Find tracks by net name"""
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Parser Implementation:**
|
|
118
|
+
```python
|
|
119
|
+
import pcbnew
|
|
120
|
+
|
|
121
|
+
class PCBParserKiCad:
|
|
122
|
+
def __init__(self, file_path: str):
|
|
123
|
+
self.board = pcbnew.LoadBoard(file_path)
|
|
124
|
+
|
|
125
|
+
def get_footprints(self):
|
|
126
|
+
"""Use pcbnew API"""
|
|
127
|
+
for fp in self.board.GetFootprints():
|
|
128
|
+
yield {
|
|
129
|
+
"reference": fp.GetReference(),
|
|
130
|
+
"value": fp.GetValue(),
|
|
131
|
+
"position": fp.GetPosition()
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### 3. Netlist Analysis (`tools/netlist.py`)
|
|
136
|
+
Parse KiCad XML netlist files:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
@mcp.tool()
|
|
140
|
+
async def trace_netlist_connection(
|
|
141
|
+
netlist_path: str,
|
|
142
|
+
reference: str,
|
|
143
|
+
pin_number: str = ""
|
|
144
|
+
) -> str:
|
|
145
|
+
"""Trace component connections (100% accurate)"""
|
|
146
|
+
|
|
147
|
+
@mcp.tool()
|
|
148
|
+
async def get_netlist_nets(
|
|
149
|
+
netlist_path: str,
|
|
150
|
+
filter_pattern: str = ""
|
|
151
|
+
) -> str:
|
|
152
|
+
"""List all nets with filtering"""
|
|
153
|
+
|
|
154
|
+
@mcp.tool()
|
|
155
|
+
async def get_netlist_components(
|
|
156
|
+
netlist_path: str,
|
|
157
|
+
filter_ref: str = ""
|
|
158
|
+
) -> str:
|
|
159
|
+
"""List components with net connections"""
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Parser Implementation:**
|
|
163
|
+
```python
|
|
164
|
+
import xml.etree.ElementTree as ET
|
|
165
|
+
|
|
166
|
+
class NetlistParser:
|
|
167
|
+
def _parse_file(self):
|
|
168
|
+
tree = ET.parse(self.file_path)
|
|
169
|
+
root = tree.getroot()
|
|
170
|
+
|
|
171
|
+
# Parse components
|
|
172
|
+
for comp in root.findall(".//comp"):
|
|
173
|
+
ref = comp.get("ref")
|
|
174
|
+
# Process component...
|
|
175
|
+
|
|
176
|
+
# Parse nets
|
|
177
|
+
for net in root.findall(".//net"):
|
|
178
|
+
name = net.get("name")
|
|
179
|
+
# Process nodes...
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**KiCad 9.0 Netlist Format:**
|
|
183
|
+
- Uses `<comp>` tags (not `<component>`)
|
|
184
|
+
- Pin information in `<nets>` section only
|
|
185
|
+
- Requires bidirectional parsing
|
|
186
|
+
|
|
187
|
+
#### 4. Schematic Editing (`tools/schematic_editor.py`)
|
|
188
|
+
Create and modify schematics:
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
@mcp.tool()
|
|
192
|
+
async def create_kicad_project(
|
|
193
|
+
path: str,
|
|
194
|
+
name: str,
|
|
195
|
+
title: str = "",
|
|
196
|
+
company: str = ""
|
|
197
|
+
) -> str:
|
|
198
|
+
"""Create project from KiCad template"""
|
|
199
|
+
|
|
200
|
+
@mcp.tool()
|
|
201
|
+
async def add_component_from_library(
|
|
202
|
+
file_path: str,
|
|
203
|
+
library_name: str,
|
|
204
|
+
symbol_name: str,
|
|
205
|
+
reference: str,
|
|
206
|
+
value: str,
|
|
207
|
+
footprint: str = "",
|
|
208
|
+
x: float = 100,
|
|
209
|
+
y: float = 100,
|
|
210
|
+
unit: int = 1
|
|
211
|
+
) -> str:
|
|
212
|
+
"""Add component to schematic"""
|
|
213
|
+
|
|
214
|
+
@mcp.tool()
|
|
215
|
+
async def add_wire(
|
|
216
|
+
file_path: str,
|
|
217
|
+
points: list[tuple[float, float]]
|
|
218
|
+
) -> str:
|
|
219
|
+
"""Add wire connection"""
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Project Creation Method:**
|
|
223
|
+
```python
|
|
224
|
+
def _find_kicad_template() -> Path:
|
|
225
|
+
"""Find KiCad template path"""
|
|
226
|
+
templates = [
|
|
227
|
+
"/Applications/KiCad/KiCad.app/Contents/SharedSupport/template",
|
|
228
|
+
"/usr/share/kicad/template",
|
|
229
|
+
"C:/Program Files/KiCad/9.0/share/kicad/template",
|
|
230
|
+
]
|
|
231
|
+
for template_path in templates:
|
|
232
|
+
path = Path(template_path)
|
|
233
|
+
if path.exists():
|
|
234
|
+
return path
|
|
235
|
+
raise FileNotFoundError("KiCad template not found")
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
#### 5. PCB Layout (`tools/pcb_layout.py`)
|
|
239
|
+
PCB layout initialization and editing:
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
@mcp.tool()
|
|
243
|
+
async def setup_pcb_layout(
|
|
244
|
+
schematic_path: str,
|
|
245
|
+
width: float = 100,
|
|
246
|
+
height: float = 100,
|
|
247
|
+
unit: str = "mm"
|
|
248
|
+
) -> str:
|
|
249
|
+
"""Initialize PCB with dimensions"""
|
|
250
|
+
|
|
251
|
+
@mcp.tool()
|
|
252
|
+
async def export_gerber(
|
|
253
|
+
pcb_path: str,
|
|
254
|
+
output_dir: str = ""
|
|
255
|
+
) -> str:
|
|
256
|
+
"""Export Gerber files"""
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### 6. Project Management (`tools/project.py`)
|
|
260
|
+
KiCad project management:
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
@mcp.tool()
|
|
264
|
+
async def create_kicad_project(
|
|
265
|
+
path: str,
|
|
266
|
+
name: str,
|
|
267
|
+
title: str = "",
|
|
268
|
+
company: str = ""
|
|
269
|
+
) -> str:
|
|
270
|
+
"""Create new project"""
|
|
271
|
+
|
|
272
|
+
@mcp.tool()
|
|
273
|
+
async def copy_kicad_project(
|
|
274
|
+
source_path: str,
|
|
275
|
+
target_path: str
|
|
276
|
+
) -> str:
|
|
277
|
+
"""Copy existing project"""
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## File Format Handling
|
|
281
|
+
|
|
282
|
+
### KiCad 9.0 File Formats
|
|
283
|
+
|
|
284
|
+
#### .kicad_pro (JSON format)
|
|
285
|
+
```json
|
|
286
|
+
{
|
|
287
|
+
"meta": {
|
|
288
|
+
"filename": "project.kicad_pro",
|
|
289
|
+
"version": 3
|
|
290
|
+
},
|
|
291
|
+
"board": {
|
|
292
|
+
"design_settings": {...}
|
|
293
|
+
},
|
|
294
|
+
"sheets": [[uuid, "Root"]],
|
|
295
|
+
"libraries": {...}
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### .kicad_sch (S-expression)
|
|
300
|
+
```lisp
|
|
301
|
+
(kicad_sch
|
|
302
|
+
(version 20240130)
|
|
303
|
+
(generator "eeschema")
|
|
304
|
+
(generator_version "9.0")
|
|
305
|
+
(uuid "...")
|
|
306
|
+
(paper "A4")
|
|
307
|
+
(title_block ...)
|
|
308
|
+
(lib_symbols ...)
|
|
309
|
+
(symbol ...)
|
|
310
|
+
(wire ...)
|
|
311
|
+
)
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### S-expression Parsing
|
|
315
|
+
Since KiCad has no Python API for schematics, use custom parser:
|
|
316
|
+
|
|
317
|
+
```python
|
|
318
|
+
import re
|
|
319
|
+
|
|
320
|
+
def parse_symbol(content: str, reference: str):
|
|
321
|
+
"""Parse symbol from schematic"""
|
|
322
|
+
# Match symbol with reference
|
|
323
|
+
pattern = rf'\(symbol.*?{reference}[\s\S]*?\(properties[\s\S]*?\)'
|
|
324
|
+
match = re.search(pattern, content)
|
|
325
|
+
if match:
|
|
326
|
+
# Extract properties
|
|
327
|
+
# Extract pins
|
|
328
|
+
return symbol_data
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Key Patterns:**
|
|
332
|
+
- Use `[\s\S]*?` for multi-line matching (not `[^)]*?`)
|
|
333
|
+
- Escape special regex characters
|
|
334
|
+
- Handle nested S-expressions carefully
|
|
335
|
+
|
|
336
|
+
## Development Standards
|
|
337
|
+
|
|
338
|
+
### Adding New Tools
|
|
339
|
+
```python
|
|
340
|
+
# 1. Create in appropriate tools/*.py
|
|
341
|
+
from ..server import mcp
|
|
342
|
+
|
|
343
|
+
@mcp.tool()
|
|
344
|
+
async def new_tool(param: type, ...) -> str:
|
|
345
|
+
"""Tool description (for AI understanding)"""
|
|
346
|
+
try:
|
|
347
|
+
# Implementation
|
|
348
|
+
return formatted_result
|
|
349
|
+
except Exception as e:
|
|
350
|
+
return f"Error: {e}"
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Error Handling Pattern
|
|
354
|
+
```python
|
|
355
|
+
try:
|
|
356
|
+
# KiCad operations
|
|
357
|
+
result = perform_operation()
|
|
358
|
+
except FileNotFoundError:
|
|
359
|
+
return "Error: File not found"
|
|
360
|
+
except Exception as e:
|
|
361
|
+
import traceback
|
|
362
|
+
return f"Error: {e}\n\n{traceback.format_exc()}"
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Return Format
|
|
366
|
+
Use Markdown for output:
|
|
367
|
+
```python
|
|
368
|
+
return f"""# Operation Successful
|
|
369
|
+
|
|
370
|
+
**File**: {file_path}
|
|
371
|
+
**Component**: {component}
|
|
372
|
+
|
|
373
|
+
## Details
|
|
374
|
+
| Item | Value |
|
|
375
|
+
|------|-------|
|
|
376
|
+
| Reference | {reference} |
|
|
377
|
+
| Value | {value} |
|
|
378
|
+
"""
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## Common Issues
|
|
382
|
+
|
|
383
|
+
### Q: KiCad crashes on opening file?
|
|
384
|
+
**A**: File format error. Use template copy method, don't manually generate S-expressions.
|
|
385
|
+
|
|
386
|
+
### Q: pcbnew import fails?
|
|
387
|
+
**A**: Ensure KiCad is installed and in PATH. pcbnew requires KiCad environment.
|
|
388
|
+
|
|
389
|
+
### Q: Netlist parsing returns empty results?
|
|
390
|
+
**A**: Check KiCad version. KiCad 9.0 uses `<comp>` tags, not `<component>`.
|
|
391
|
+
|
|
392
|
+
### Q: How to handle KiCad version differences?
|
|
393
|
+
**A**: Check version string in file header. KiCad 9.0 uses version 20240130.
|
|
394
|
+
|
|
395
|
+
## Testing Strategy
|
|
396
|
+
|
|
397
|
+
### Unit Tests
|
|
398
|
+
```python
|
|
399
|
+
def test_schematic_parser():
|
|
400
|
+
"""Test schematic parsing"""
|
|
401
|
+
parser = SchematicParser("test.kicad_sch")
|
|
402
|
+
components = parser.get_components()
|
|
403
|
+
assert len(components) > 0
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Integration Tests
|
|
407
|
+
```bash
|
|
408
|
+
# Test in real KiCad environment
|
|
409
|
+
1. Create project
|
|
410
|
+
2. Open in KiCad 9.0
|
|
411
|
+
3. Verify no warnings
|
|
412
|
+
4. Run ERC/DRC
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Performance Considerations
|
|
416
|
+
|
|
417
|
+
### Large File Processing
|
|
418
|
+
```python
|
|
419
|
+
# Use streaming for large files
|
|
420
|
+
def process_large_schematic(file_path):
|
|
421
|
+
with open(file_path) as f:
|
|
422
|
+
for line in f:
|
|
423
|
+
process_line(line)
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Caching
|
|
427
|
+
```python
|
|
428
|
+
from functools import lru_cache
|
|
429
|
+
|
|
430
|
+
@lru_cache(maxsize=128)
|
|
431
|
+
def get_footprint_info(name):
|
|
432
|
+
# Cache footprint info
|
|
433
|
+
return query_footprint(name)
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
## Resources
|
|
437
|
+
|
|
438
|
+
### KiCad Official
|
|
439
|
+
- [KiCad 9.0 Documentation](https://docs.kicad.org/)
|
|
440
|
+
- [File Format Specification](https://dev-docs.kicad.org/en/file-formats/)
|
|
441
|
+
- [Python Scripting](https://docs.kicad.org/doxygen-python/)
|
|
442
|
+
|
|
443
|
+
### MCP Protocol
|
|
444
|
+
- [MCP Specification](https://modelcontextprotocol.io/)
|
|
445
|
+
- [FastMCP Documentation](https://github.com/jlowin/fastmcp)
|
|
446
|
+
|
|
447
|
+
## Project Structure
|
|
448
|
+
|
|
449
|
+
```
|
|
450
|
+
kicad-mcp-server/
|
|
451
|
+
├── src/kicad_mcp_server/
|
|
452
|
+
│ ├── tools/ # MCP tool implementations
|
|
453
|
+
│ │ ├── project.py # Project management
|
|
454
|
+
│ │ ├── schematic.py # Schematic analysis
|
|
455
|
+
│ │ ├── schematic_editor.py # Schematic editing
|
|
456
|
+
│ │ ├── pcb.py # PCB analysis
|
|
457
|
+
│ │ ├── pcb_layout.py # PCB layout
|
|
458
|
+
│ │ └── netlist.py # Netlist analysis
|
|
459
|
+
│ ├── parsers/ # File parsers
|
|
460
|
+
│ │ ├── schematic_parser.py
|
|
461
|
+
│ │ ├── pcb_parser_kicad.py
|
|
462
|
+
│ │ └── netlist_parser.py
|
|
463
|
+
│ ├── config.py # Configuration
|
|
464
|
+
│ └── server.py # MCP server setup
|
|
465
|
+
├── tests/ # Test files
|
|
466
|
+
├── README.md # User documentation
|
|
467
|
+
└── CLAUDE.md # This file
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
## Scope
|
|
471
|
+
|
|
472
|
+
### Included
|
|
473
|
+
- Schematic analysis (components, nets, symbols)
|
|
474
|
+
- PCB analysis (footprints, tracks, statistics)
|
|
475
|
+
- Netlist-based connection tracing
|
|
476
|
+
- Project creation and editing
|
|
477
|
+
- Schematic and PCB layout modification
|
|
478
|
+
|
|
479
|
+
### Not Included
|
|
480
|
+
- Test code generation
|
|
481
|
+
- Natural language processing
|
|
482
|
+
- Component library management
|
|
483
|
+
- Auto-routing
|
|
484
|
+
- LCSC integration
|
|
485
|
+
- 3D model generation
|
|
486
|
+
|
|
487
|
+
The server focuses on core analysis and editing capabilities, leaving specialized features to dedicated tools.
|