Skip to main content
Glama
lmaag182

KiCad MCP Server (IPC API)

by lmaag182
README.md
# 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

B3.2/5.0

Scored across 77 tools

Disambiguation4/5

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.

Naming Consistency5/5

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.

Tool Count3/5

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.

Completeness5/5

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.

Maintenance

ActivityInactive
ResponsivenessNo issues