KiCad MCP Server (IPC API)
# KiCad MCP Server (IPC API)
MCP server that controls a **running KiCad 9+** instance via the official [IPC API](https://dev-docs.kicad.org/en/apis-and-binding/ipc-api/index.html) and [`kicad-python`](https://gitlab.com/kicad/code/kicad-python) (`kipy`).
Board edits appear immediately in the KiCad UI — no reload required. The server wraps the full Board + Project IPC surface available in `kicad-python` 0.7.1 (KiCad 10).
## Prerequisites
1. **KiCad 9.0+** running with a PCB open
2. **IPC API enabled**: Preferences → Plugins → Enable IPC API Server
3. Python 3.10+
## Install
```bash
cd kicad_mcp_server_ipc
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
```
## Run
```bash
kicad-mcp-ipc
# or
python -m kicad_mcp_ipc
```
## Cursor / Grok MCP configuration
```json
{
"mcpServers": {
"kicad-ipc": {
"command": "/path/to/kicad_mcp_server_ipc/.venv/bin/kicad-mcp-ipc"
}
}
}
```
Optional environment variables:
| Variable | Description |
|---|---|
| `KICAD_API_SOCKET` | Path to KiCad IPC socket (auto-detected if unset) |
| `KICAD_API_TOKEN` | Auth token from KiCad when launched as plugin |
| `KICAD_IPC_TIMEOUT_MS` | Request timeout in ms (default: 5000) |
## Architecture
```
server.py → FastMCP entry point
services/api.py → Unified KiCadAPI facade (board + project + session)
services/export.py → Export jobs via IPC RunJob, kicad-cli fallback
tools/definitions.py → Tool definitions mapped to API methods
tools/registry.py → Categories, search, JSON schemas
tools/register.py → Dynamic MCP tool registration
layers.py / serialize.py → Layer aliases and JSON serialization
```
Design principles:
- **Service layer** — MCP tools call `KiCadAPI`, not `kipy` directly
- **Registry** — tool metadata (category, parameters, schema) is separate from handlers
- **Transactions** — edits use `begin_commit` / `push_commit` for undo support
- **Meta tools** — discover and invoke tools without loading all schemas upfront
## Tools (77 total)
Use `list_tool_categories`, `search_tools`, or `get_tool_schema` to explore the full set at runtime.
### Meta / discovery
| Tool | Description |
|---|---|
| `list_tool_categories` | Browse all categories and tool names |
| `search_tools` | Search by name, description, or category |
| `get_tool_schema` | Get parameter schema for a specific tool |
| `execute_kicad_tool` | Run any tool by name with a JSON arguments object |
### Session (5)
`ping_kicad`, `get_kicad_status`, `list_open_documents`, `get_kicad_version`, `run_kicad_action`
### Board query (21)
Read-only inspection: `get_board_info`, `get_board_size`, `get_board_as_string`, `get_selection_as_string`, `list_components`, `get_component`, `list_tracks`, `list_vias`, `list_pads`, `list_nets`, `list_zones`, `list_groups`, `list_dimensions`, `list_board_text`, `list_board_shapes`, `list_barcodes`, `get_items_by_id`, `get_items_by_net`, `get_connected_items`, `get_stackup`, `get_title_block`
### Board edit (16)
`save_board`, `revert_board`, `place_component`, `move_component`, `rotate_component`, `delete_component`, `route_trace`, `add_via`, `add_copper_pour`, `refill_zones`, `add_board_text`, `add_board_outline`, `add_mounting_hole`, `set_board_size`, `delete_items_by_id`, `set_title_block`
### Layers (8)
`get_layer_list`, `get_visible_layers`, `get_active_layer`, `set_active_layer`, `set_visible_layers`, `get_copper_layer_count`, `set_enabled_layers`, `get_layer_name`
### Selection (4)
`get_selection`, `add_to_selection`, `remove_from_selection`, `clear_selection`
### Geometry (2)
`get_item_bounding_box`, `hit_test`
### Origins (2)
`get_board_origin`, `set_board_origin`
### Appearance (1)
`get_editor_appearance`
### Project (4)
`get_net_classes`, `get_text_variables`, `set_text_variables`, `expand_text_variables`
### Export (10)
Manufacturing and documentation output. Each export tries the IPC `RunJob` API first, then falls back to `kicad-cli` if needed.
| Tool | Output |
|---|---|
| `export_gerbers` | Gerber copper/silk/mask layers |
| `export_drill` | Excellon drill files |
| `export_pdf` | PDF plot |
| `export_svg` | SVG plot |
| `export_dxf` | DXF |
| `export_3d` | STEP, GLB, STL, VRML, etc. |
| `export_position` | Pick-and-place centroid files |
| `export_ipc2581` | IPC-2581 package |
| `export_odb` | ODB++ package |
| `export_stats` | Board statistics report |
## Response format
All tools return JSON strings:
```json
{
"success": true,
"components": [...],
"count": 42
}
```
On failure:
```json
{
"success": false,
"message": "No PCB board is open in KiCad. Open a .kicad_pcb file first.",
"operation": "get_board_info"
}
```
## Limitations (kicad-python 0.7.1)
The following are **not** exposed because they are unavailable or unstable in the installed IPC bindings:
- Schematic editing (Schematic class exists; IPC commands not wired in 0.7.1)
- `get_design_rules` / `import_netlist` (KiCad 11+)
- `set_editor_appearance_settings` (read-only for safety)
- `run_kicad_action` (unstable KiCad internal API)
## Project layout
```
src/kicad_mcp_ipc/
├── server.py # MCP entry point
├── connection.py # KiCad IPC connection singleton
├── services/
│ ├── api.py # KiCadAPI facade
│ └── export.py # Export via IPC jobs + kicad-cli
├── tools/
│ ├── definitions.py # All tool definitions
│ ├── registry.py # Category/search/schema registry
│ └── register.py # Dynamic FastMCP registration
├── layers.py # Layer name ↔ enum helpers
├── serialize.py # kipy object → JSON helpers
├── board.py # Backward-compat alias for KiCadAPI
├── errors.py
└── utils.py
```
## License
Uses KiCad IPC via `kicad-python`, which is licensed under the GPL. This MCP server is a separate client application that communicates with KiCad over IPC.TDQS
Scored across 77 tools
Most tools target distinct objects or actions, but there is potential confusion between 'execute_kicad_tool' and 'run_kicad_action', as well as among the many getter/list tools like 'get_board_info' vs 'get_board_size'. Overall, the descriptions clarify differences, keeping ambiguity low.
The naming follows a consistent verb_noun pattern (e.g., add_board_outline, export_gerbers, list_nets). Minor exceptions like 'ping_kicad' and 'hit_test' are still intuitive and do not break the overall pattern.
With 77 tools, this is a very large set for a single server. While the comprehensive PCB design domain justifies many operations, the count feels heavy and could overwhelm agents. Some tools are highly specific (e.g., refill_zones, set_board_origin), making the set borderline appropriate.
The tool set covers the full PCB design lifecycle: adding elements, editing, querying, exporting, and project management. It includes both high-level operations and detailed settings, leaving no obvious dead ends for common PCB editing tasks.