pcb-mcp
README.md
# pcb-mcp
Grok-native KiCad MCP. Design, inspect, fix, and export KiCad 9/10 boards from a Grok session without clicking the GUI.
This is **not** a pcbnew API wrapper and **not** a clone of mixelpixx. Sixteen tools, in-process `pcbnew`, `kicad-cli` as the source of truth for DRC/ERC/export, every mutation ends in a PNG + DRC/ERC summary.
Register as **`pcb`**. Leave any existing `[mcp_servers.kicad]` (mixelpixx) alone.
## Mandatory loop (keep it fast)
PNGs always land at:
`<project>/.pcb-mcp/snapshots/current/pcb.png` and `sch.png` (overwritten each snapshot).
```
pcb_open
pcb_snapshot / pcb_state # look
pcb_place symbol=Device:R footprint=Resistor_SMD:R_0805_2012Metric
pcb_connect R1.2 R2.1 net=NET1
pcb_place from_schematic=true # optional: push sch netlist onto the PCB
pcb_route net=NET1 dry_run=false
pcb_drc # full kicad-cli DRC (the slow-but-true check)
pcb_export_fab out_dir=fab
pcb_save
```
Place/connect/edit snapshot the board in ~0.3s and return a **lite** DRC (unconnected count from pcbnew). After routing, call `pcb_drc` for shorts/clearance. Prefer **ref.pad** (`R1.2`). Width/clearance come from the open netclass.
See [SPEC.md](SPEC.md) for the tool contract.
## Install
You need **KiCad 9 or 10** (with `pcbnew` and `kicad-cli`) and the **Grok CLI**. Do not clone this into a KiCad project directory; keep it as its own repo.
KiCad's `python.exe` is isolated and **ignores `PYTHONPATH`**. Always launch this server with that interpreter via `run.py`. Never point Grok at a venv python.
### 1. Clone
```powershell
git clone https://github.com/LukeVincent25/pcb-mcp.git
cd pcb-mcp
```
### 2. Install Python packages into `.deps`
Use KiCad's python, not `python` from PATH:
**Windows** (this machine: `E:\Kicad`):
```powershell
E:\Kicad\bin\python.exe scripts\install_deps.py
```
**Windows (typical Program Files install):**
```powershell
& "C:\Program Files\KiCad\10.0\bin\python.exe" scripts\install_deps.py
```
**Linux:**
```bash
/usr/bin/python3 scripts/install_deps.py
# if that is not KiCad's interpreter:
"$HOME/kicad/bin/python" scripts/install_deps.py
```
That runs `pip install "mcp>=1.12,<2" "pytest>=8" --target .deps`. `.deps` stays out of git.
Confirm `pcbnew` imports on that same interpreter:
```powershell
E:\Kicad\bin\python.exe -c "import pcbnew; print(pcbnew.GetBuildVersion())"
```
### 3. Register with Grok as server `pcb`
```powershell
E:\Kicad\bin\python.exe scripts\register_grok.py --kicad-root E:\Kicad
```
This writes `[mcp_servers.pcb]` in `%USERPROFILE%\.grok\config.toml` and **does not** change `[mcp_servers.kicad]`.
Equivalent manual config:
```toml
[mcp_servers.pcb]
command = "E:\\Kicad\\bin\\python.exe"
args = ["E:\\pcb-mcp\\run.py"]
enabled = true
startup_timeout_sec = 60
tool_timeout_sec = 600
[mcp_servers.pcb.env]
PCB_MCP_KICAD_ROOT = "E:\\Kicad"
KICAD_ROOT = "E:\\Kicad"
```
Adjust the two paths to your clone and KiCad install.
### 4. Verify
```powershell
grok mcp doctor pcb
```
You want: handshake OK, **16 tools**, healthy. Then: `pcb_open` → `pcb_snapshot` → design → `pcb_drc` → `pcb_export_fab`.
### Tests (optional)
```powershell
E:\Kicad\bin\python.exe scripts\run_tests.py
```
Fixtures live under `tests/boards/` (generated with pcbnew + `kicad-cli`, not hand-minified S-expressions).
## What works (v1)
All 16 tools:
| Tool | Does |
|------|------|
| `pcb_open` / `close` / `save` | Project session. Save refuses a clobber unless `force=true`. |
| `pcb_state` / `pcb_snapshot` / `pcb_query` / `pcb_diff` | Compact JSON, PNG paths, search, DRC delta. |
| `pcb_drc` / `pcb_erc` | `kicad-cli` JSON. |
| `pcb_spec_apply` | Outline, copper layers, Default netclass rules, mounting holes. |
| `pcb_place` | Footprint and/or symbol by `lib:name`. |
| `pcb_connect` | `R1.2` ↔ `R2.1` (PCB nets; schematic labels if symbols exist). |
| `pcb_route` / `pcb_unroute` | 2-layer netclass-aware router. `dry_run=true` first. Restores the board if DRC still has unconnected/shorts. |
| `pcb_edit` | Value, footprint, ref, side, netclass. |
| `pcb_export_fab` | Gerbers, drill, POS, BOM, schematic PDF via `kicad-cli`. |
Mutators take `dry_run` (default true) and on commit return snapshot + DRC. Track width and clearance come from the open board's netclass, not hardcoded vendor numbers.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues