style: apply Prettier formatting to TS/JS/JSON/MD files
Add Prettier as a dev dependency with .prettierrc.json config and .prettierignore. Hook added via mirrors-prettier in pre-commit config. All TypeScript, JSON, Markdown, and YAML files auto-formatted. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -118,10 +118,12 @@ KiCAD-MCP-Server/
|
||||
### Tool Registration
|
||||
|
||||
Each tool file exports a `register*Tools(server, callKicadScript)` function that:
|
||||
|
||||
- Defines tool name, description, and Zod schema for parameters
|
||||
- Registers a handler that calls `callKicadScript(command, args)`
|
||||
|
||||
Example from `src/tools/project.ts`:
|
||||
|
||||
```typescript
|
||||
server.tool(
|
||||
"create_project",
|
||||
@@ -130,13 +132,14 @@ server.tool(
|
||||
async (args) => {
|
||||
const result = await callKicadScript("create_project", args);
|
||||
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
||||
}
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
### Tool Router (`src/tools/router.ts` and `src/tools/registry.ts`)
|
||||
|
||||
The router pattern reduces AI context usage:
|
||||
|
||||
- `registry.ts` defines tool categories and which tools are "direct" (always visible) vs "routed" (discoverable)
|
||||
- `router.ts` provides 4 meta-tools: `list_tool_categories`, `get_category_tools`, `search_tools`, `execute_tool`
|
||||
- Routed tools are not registered as individual MCP tools -- they are invoked through `execute_tool`
|
||||
@@ -144,6 +147,7 @@ The router pattern reduces AI context usage:
|
||||
### Python Subprocess Communication
|
||||
|
||||
`callKicadScript(command, args)` in `server.ts`:
|
||||
|
||||
1. Spawns `python3 python/kicad_interface.py` (if not already running)
|
||||
2. Sends a JSON message: `{"command": "...", "params": {...}}`
|
||||
3. Reads the JSON response
|
||||
@@ -164,6 +168,7 @@ The router pattern reduces AI context usage:
|
||||
### Command Routing
|
||||
|
||||
Commands are routed by name to handler methods. The mapping is defined in `kicad_interface.py`. Each handler:
|
||||
|
||||
1. Receives a params dict
|
||||
2. Calls the appropriate command class method
|
||||
3. Returns a result dict with `success`, `message`, and any additional data
|
||||
@@ -173,12 +178,14 @@ Commands are routed by name to handler methods. The mapping is defined in `kicad
|
||||
Two backends for interacting with KiCAD:
|
||||
|
||||
**SWIG Backend** (default):
|
||||
|
||||
- Direct Python bindings to KiCAD's C++ API via SWIG
|
||||
- Operates on files -- loads .kicad_pcb, modifies in memory, saves back
|
||||
- Works without KiCAD running
|
||||
- Requires manual UI reload to see changes
|
||||
|
||||
**IPC Backend** (experimental):
|
||||
|
||||
- Communicates with running KiCAD via IPC API socket
|
||||
- Changes appear in the UI immediately
|
||||
- Requires KiCAD 9.0+ running with IPC enabled
|
||||
@@ -189,6 +196,7 @@ Two backends for interacting with KiCAD:
|
||||
### Schematic System
|
||||
|
||||
Schematic manipulation uses a different stack than PCB operations:
|
||||
|
||||
- **kicad-skip** library for reading/modifying schematic files
|
||||
- **S-expression parsing** for direct file manipulation (wires, symbols)
|
||||
- **DynamicSymbolLoader** for injecting any KiCad symbol into a schematic
|
||||
@@ -214,7 +222,7 @@ server.tool(
|
||||
async (args) => {
|
||||
const result = await callKicadScript("my_new_tool", args);
|
||||
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
||||
}
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
@@ -271,11 +279,13 @@ npm run test:py # Run Python tests
|
||||
### Python Tests
|
||||
|
||||
Located in `python/tests/`. Run with:
|
||||
|
||||
```bash
|
||||
pytest python/tests/ -v
|
||||
```
|
||||
|
||||
Key test files:
|
||||
|
||||
- `test_schematic_tools.py` -- schematic tool tests
|
||||
- `test_freerouting.py` -- autorouter tests
|
||||
- `test_delete_schematic_component.py` -- component deletion tests
|
||||
@@ -302,13 +312,13 @@ Key test files:
|
||||
|
||||
## Source Files Reference
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/server.ts` | MCP server, subprocess management |
|
||||
| `src/tools/registry.ts` | Tool categories and organization |
|
||||
| `src/tools/router.ts` | Router meta-tools |
|
||||
| `python/kicad_interface.py` | Python entry point, command routing |
|
||||
| `python/kicad_api/factory.py` | Backend selection |
|
||||
| `python/commands/dynamic_symbol_loader.py` | Symbol injection system |
|
||||
| `python/commands/wire_manager.py` | Wire creation engine |
|
||||
| `python/commands/pin_locator.py` | Pin position discovery |
|
||||
| File | Purpose |
|
||||
| ------------------------------------------ | ----------------------------------- |
|
||||
| `src/server.ts` | MCP server, subprocess management |
|
||||
| `src/tools/registry.ts` | Tool categories and organization |
|
||||
| `src/tools/router.ts` | Router meta-tools |
|
||||
| `python/kicad_interface.py` | Python entry point, command routing |
|
||||
| `python/kicad_api/factory.py` | Backend selection |
|
||||
| `python/commands/dynamic_symbol_loader.py` | Symbol injection system |
|
||||
| `python/commands/wire_manager.py` | Wire creation engine |
|
||||
| `python/commands/pin_locator.py` | Pin position discovery |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,7 @@ Scans a KiCAD schematic and fills in missing Datasheet URLs for components that
|
||||
**How it works:**
|
||||
|
||||
For every placed symbol that has:
|
||||
|
||||
- An LCSC property set (e.g., `(property "LCSC" "C123456")`)
|
||||
- An empty or missing Datasheet field
|
||||
|
||||
@@ -24,23 +25,26 @@ The URL is then visible in KiCAD's footprint browser, symbol properties dialog,
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Default | Description |
|
||||
|-----------|------|----------|---------|-------------|
|
||||
| `schematic_path` | string | Yes | -- | Path to the .kicad_sch file to enrich |
|
||||
| `dry_run` | boolean | No | false | Preview changes without writing to disk |
|
||||
| Parameter | Type | Required | Default | Description |
|
||||
| ---------------- | ------- | -------- | ------- | --------------------------------------- |
|
||||
| `schematic_path` | string | Yes | -- | Path to the .kicad_sch file to enrich |
|
||||
| `dry_run` | boolean | No | false | Preview changes without writing to disk |
|
||||
|
||||
**Returns:**
|
||||
|
||||
- Number of components updated
|
||||
- Number already set (skipped)
|
||||
- Number without LCSC number
|
||||
- Details of each updated component (reference, LCSC number, URL)
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
Enrich datasheets for all components in ~/Projects/MyBoard/MyBoard.kicad_sch
|
||||
```
|
||||
|
||||
Use `dry_run=true` to preview what would change:
|
||||
|
||||
```
|
||||
Preview datasheet enrichment for ~/Projects/MyBoard/MyBoard.kicad_sch with dry run enabled.
|
||||
```
|
||||
@@ -53,15 +57,17 @@ Get the LCSC datasheet URL for a single component by LCSC number.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `lcsc` | string | Yes | LCSC part number, with or without "C" prefix (e.g., "C179739" or "179739") |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------ | -------- | -------------------------------------------------------------------------- |
|
||||
| `lcsc` | string | Yes | LCSC part number, with or without "C" prefix (e.g., "C179739" or "179739") |
|
||||
|
||||
**Returns:**
|
||||
|
||||
- Datasheet PDF URL
|
||||
- Product page URL
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
Get the datasheet URL for LCSC part C179739.
|
||||
```
|
||||
|
||||
@@ -12,63 +12,63 @@ Footprints define the physical copper pads, silkscreen markings, and courtyard b
|
||||
|
||||
Create a new KiCAD footprint (.kicad_mod) inside a .pretty library directory. Supports SMD and THT pads, courtyard, silkscreen, and fab-layer rectangles.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `libraryPath` | string | Yes | Path to the .pretty library directory (created if missing). E.g. C:/MyProject/MyLib.pretty |
|
||||
| `name` | string | Yes | Footprint name, e.g. 'R_0603_Custom' |
|
||||
| `description` | string | No | Human-readable description |
|
||||
| `tags` | string | No | Space-separated tag string, e.g. 'resistor SMD 0603' |
|
||||
| `pads` | array | No | List of pad objects (see Pad Schema below). Can be empty for outlines-only footprints |
|
||||
| `courtyard` | object | No | Courtyard rectangle on F.CrtYd (recommended: 0.25 mm clearance around pads) |
|
||||
| `silkscreen` | object | No | Silkscreen rectangle on F.SilkS |
|
||||
| `fabLayer` | object | No | Fab-layer rectangle on F.Fab (shows component body) |
|
||||
| `refPosition` | object | No | Position of the REF** text, e.g. {x: 0, y: -1.27} (default: 0, -1.27) |
|
||||
| `valuePosition` | object | No | Position of the Value text, e.g. {x: 0, y: 1.27} (default: 0, 1.27) |
|
||||
| `overwrite` | boolean | No | Replace existing footprint file (default: false) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------------- | ------- | -------- | ------------------------------------------------------------------------------------------ |
|
||||
| `libraryPath` | string | Yes | Path to the .pretty library directory (created if missing). E.g. C:/MyProject/MyLib.pretty |
|
||||
| `name` | string | Yes | Footprint name, e.g. 'R_0603_Custom' |
|
||||
| `description` | string | No | Human-readable description |
|
||||
| `tags` | string | No | Space-separated tag string, e.g. 'resistor SMD 0603' |
|
||||
| `pads` | array | No | List of pad objects (see Pad Schema below). Can be empty for outlines-only footprints |
|
||||
| `courtyard` | object | No | Courtyard rectangle on F.CrtYd (recommended: 0.25 mm clearance around pads) |
|
||||
| `silkscreen` | object | No | Silkscreen rectangle on F.SilkS |
|
||||
| `fabLayer` | object | No | Fab-layer rectangle on F.Fab (shows component body) |
|
||||
| `refPosition` | object | No | Position of the REF\*\* text, e.g. {x: 0, y: -1.27} (default: 0, -1.27) |
|
||||
| `valuePosition` | object | No | Position of the Value text, e.g. {x: 0, y: 1.27} (default: 0, 1.27) |
|
||||
| `overwrite` | boolean | No | Replace existing footprint file (default: false) |
|
||||
|
||||
#### Pad Schema
|
||||
|
||||
Each pad object in the `pads` array supports:
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `number` | string | Yes | Pad number / name, e.g. '1', '2', 'A1' |
|
||||
| `type` | enum | Yes | Pad type: `smd`, `thru_hole`, or `np_thru_hole` |
|
||||
| `shape` | enum | No | Pad shape: `rect`, `circle`, `oval`, or `roundrect` (default: rect for SMD, circle for THT) |
|
||||
| `at` | object | Yes | Pad centre position: {x: number, y: number, angle?: number} in mm |
|
||||
| `size` | object | Yes | Pad size: {w: number, h: number} in mm |
|
||||
| `drill` | number or object | No | Round drill diameter (mm) or oval drill {w: number, h: number} (required for thru_hole pads) |
|
||||
| `layers` | array | No | Override default layer list, e.g. ['F.Cu','F.Paste','F.Mask'] |
|
||||
| `roundrect_ratio` | number | No | Corner radius ratio for roundrect shape (0.0-0.5, default 0.25) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ----------------- | ---------------- | -------- | -------------------------------------------------------------------------------------------- |
|
||||
| `number` | string | Yes | Pad number / name, e.g. '1', '2', 'A1' |
|
||||
| `type` | enum | Yes | Pad type: `smd`, `thru_hole`, or `np_thru_hole` |
|
||||
| `shape` | enum | No | Pad shape: `rect`, `circle`, `oval`, or `roundrect` (default: rect for SMD, circle for THT) |
|
||||
| `at` | object | Yes | Pad centre position: {x: number, y: number, angle?: number} in mm |
|
||||
| `size` | object | Yes | Pad size: {w: number, h: number} in mm |
|
||||
| `drill` | number or object | No | Round drill diameter (mm) or oval drill {w: number, h: number} (required for thru_hole pads) |
|
||||
| `layers` | array | No | Override default layer list, e.g. ['F.Cu','F.Paste','F.Mask'] |
|
||||
| `roundrect_ratio` | number | No | Corner radius ratio for roundrect shape (0.0-0.5, default 0.25) |
|
||||
|
||||
#### Rectangle Schema (courtyard, silkscreen, fabLayer)
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `x1` | number | Yes | Left X in mm |
|
||||
| `y1` | number | Yes | Top Y in mm |
|
||||
| `x2` | number | Yes | Right X in mm |
|
||||
| `y2` | number | Yes | Bottom Y in mm |
|
||||
| `width` | number | No | Line width in mm |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------ | -------- | ---------------- |
|
||||
| `x1` | number | Yes | Left X in mm |
|
||||
| `y1` | number | Yes | Top Y in mm |
|
||||
| `x2` | number | Yes | Right X in mm |
|
||||
| `y2` | number | Yes | Bottom Y in mm |
|
||||
| `width` | number | No | Line width in mm |
|
||||
|
||||
#### Pad Types
|
||||
|
||||
- **SMD (smd)**: Surface-mount pads for components that sit on top of the PCB. Default layers: F.Cu, F.Paste, F.Mask
|
||||
- **THT (thru_hole)**: Through-hole pads for components with leads that pass through the PCB. Requires `drill` parameter. Default layers: *.Cu, F.Mask, B.Mask
|
||||
- **NPTH (np_thru_hole)**: Non-plated through-holes for mechanical mounting. Requires `drill` parameter. Default layers: *.Mask
|
||||
- **THT (thru_hole)**: Through-hole pads for components with leads that pass through the PCB. Requires `drill` parameter. Default layers: \*.Cu, F.Mask, B.Mask
|
||||
- **NPTH (np_thru_hole)**: Non-plated through-holes for mechanical mounting. Requires `drill` parameter. Default layers: \*.Mask
|
||||
|
||||
### edit_footprint_pad
|
||||
|
||||
Edit an existing pad inside a .kicad_mod footprint file. Updates size, position, drill, or shape without recreating the whole footprint.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `footprintPath` | string | Yes | Full path to the .kicad_mod file, e.g. C:/MyLib.pretty/R_Custom.kicad_mod |
|
||||
| `padNumber` | string or number | Yes | Pad number to edit, e.g. '1' or 2 |
|
||||
| `size` | object | No | New pad size: {w: number, h: number} in mm |
|
||||
| `at` | object | No | New pad position: {x: number, y: number, angle?: number} in mm |
|
||||
| `drill` | number or object | No | New drill size: number (round) or {w: number, h: number} (oval) for THT pads |
|
||||
| `shape` | enum | No | New pad shape: `rect`, `circle`, `oval`, or `roundrect` |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------------- | ---------------- | -------- | ---------------------------------------------------------------------------- |
|
||||
| `footprintPath` | string | Yes | Full path to the .kicad_mod file, e.g. C:/MyLib.pretty/R_Custom.kicad_mod |
|
||||
| `padNumber` | string or number | Yes | Pad number to edit, e.g. '1' or 2 |
|
||||
| `size` | object | No | New pad size: {w: number, h: number} in mm |
|
||||
| `at` | object | No | New pad position: {x: number, y: number, angle?: number} in mm |
|
||||
| `drill` | number or object | No | New drill size: number (round) or {w: number, h: number} (oval) for THT pads |
|
||||
| `shape` | enum | No | New pad shape: `rect`, `circle`, `oval`, or `roundrect` |
|
||||
|
||||
**When to use:** Use this tool when you need to adjust an existing footprint's pad dimensions or positions without recreating the entire footprint. Useful for fine-tuning after initial creation or adapting existing footprints.
|
||||
|
||||
@@ -76,13 +76,13 @@ Edit an existing pad inside a .kicad_mod footprint file. Updates size, position,
|
||||
|
||||
Register a .pretty footprint library in KiCAD's fp-lib-table so KiCAD can find the footprints. Run this after create_footprint when KiCAD shows 'library not found in footprint library table'.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `libraryPath` | string | Yes | Full path to the .pretty directory to register |
|
||||
| `libraryName` | string | No | Nickname for the library in KiCAD (default: directory name without .pretty) |
|
||||
| `description` | string | No | Optional description |
|
||||
| `scope` | enum | No | `project` = writes fp-lib-table next to the .kicad_pro file (default); `global` = writes to the user's global KiCAD config |
|
||||
| `projectPath` | string | No | Path to the .kicad_pro file or its directory (required for scope=project when the library is not in the project folder) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `libraryPath` | string | Yes | Full path to the .pretty directory to register |
|
||||
| `libraryName` | string | No | Nickname for the library in KiCAD (default: directory name without .pretty) |
|
||||
| `description` | string | No | Optional description |
|
||||
| `scope` | enum | No | `project` = writes fp-lib-table next to the .kicad_pro file (default); `global` = writes to the user's global KiCAD config |
|
||||
| `projectPath` | string | No | Path to the .kicad_pro file or its directory (required for scope=project when the library is not in the project folder) |
|
||||
|
||||
**How fp-lib-table works:** KiCAD maintains a table mapping library nicknames to filesystem paths. Project-scope tables (fp-lib-table in the project directory) take precedence over global tables. This allows project-specific libraries without polluting the global configuration.
|
||||
|
||||
@@ -90,9 +90,9 @@ Register a .pretty footprint library in KiCAD's fp-lib-table so KiCAD can find t
|
||||
|
||||
List available .pretty footprint libraries and their contents (first 20 footprints per library). Searches KiCAD standard install paths by default.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `searchPaths` | array | No | Override default search paths. Each entry should be a directory that contains .pretty subdirs |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ----- | -------- | --------------------------------------------------------------------------------------------- |
|
||||
| `searchPaths` | array | No | Override default search paths. Each entry should be a directory that contains .pretty subdirs |
|
||||
|
||||
### Example: Creating a Custom SOT-23 Footprint
|
||||
|
||||
@@ -172,6 +172,7 @@ Create a new schematic symbol in a .kicad_sym library file (created if missing).
|
||||
Pin positions are where the wire connects; the symbol body is drawn between them.
|
||||
|
||||
**Coordinate tips:**
|
||||
|
||||
- Body rectangle typically spans ±2.54 to ±5.08 mm
|
||||
- Pins on left side: at.x = body_left - length, angle=0 (wire goes right)
|
||||
- Pins on right side: at.x = body_right + length, angle=180 (wire goes left)
|
||||
@@ -179,36 +180,37 @@ Pin positions are where the wire connects; the symbol body is drawn between them
|
||||
- Pins on bottom: at.y = body_bottom - length, angle=90 (wire goes up)
|
||||
- Standard pin length: 2.54 mm, standard grid: 2.54 mm
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `libraryPath` | string | Yes | Path to the .kicad_sym file (created if missing) |
|
||||
| `name` | string | Yes | Symbol name, e.g. 'TMC2209', 'MyOpAmp' |
|
||||
| `referencePrefix` | string | No | Schematic reference prefix: 'U' (IC), 'R' (resistor), 'J' (connector), etc. Default: 'U' |
|
||||
| `description` | string | No | Human-readable description |
|
||||
| `keywords` | string | No | Space-separated search keywords |
|
||||
| `datasheet` | string | No | Datasheet URL or '~' |
|
||||
| `footprint` | string | No | Default footprint, e.g. 'Package_SO:SOIC-8_3.9x4.9mm_P1.27mm' |
|
||||
| `inBom` | boolean | No | Include in BOM (default true) |
|
||||
| `onBoard` | boolean | No | Include in netlist for PCB (default true) |
|
||||
| `pins` | array | No | List of pin objects (see Pin Schema below). Can be empty for graphical-only symbols |
|
||||
| `rectangles` | array | No | Body rectangle(s). Typically one rectangle defining the IC body |
|
||||
| `polylines` | array | No | Polyline graphics for custom body shapes (op-amp triangles, etc.) |
|
||||
| `overwrite` | boolean | No | Replace existing symbol with same name (default false) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ----------------- | ------- | -------- | ---------------------------------------------------------------------------------------- |
|
||||
| `libraryPath` | string | Yes | Path to the .kicad_sym file (created if missing) |
|
||||
| `name` | string | Yes | Symbol name, e.g. 'TMC2209', 'MyOpAmp' |
|
||||
| `referencePrefix` | string | No | Schematic reference prefix: 'U' (IC), 'R' (resistor), 'J' (connector), etc. Default: 'U' |
|
||||
| `description` | string | No | Human-readable description |
|
||||
| `keywords` | string | No | Space-separated search keywords |
|
||||
| `datasheet` | string | No | Datasheet URL or '~' |
|
||||
| `footprint` | string | No | Default footprint, e.g. 'Package_SO:SOIC-8_3.9x4.9mm_P1.27mm' |
|
||||
| `inBom` | boolean | No | Include in BOM (default true) |
|
||||
| `onBoard` | boolean | No | Include in netlist for PCB (default true) |
|
||||
| `pins` | array | No | List of pin objects (see Pin Schema below). Can be empty for graphical-only symbols |
|
||||
| `rectangles` | array | No | Body rectangle(s). Typically one rectangle defining the IC body |
|
||||
| `polylines` | array | No | Polyline graphics for custom body shapes (op-amp triangles, etc.) |
|
||||
| `overwrite` | boolean | No | Replace existing symbol with same name (default false) |
|
||||
|
||||
#### Pin Schema
|
||||
|
||||
Each pin object in the `pins` array supports:
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `name` | string | Yes | Pin name, e.g. 'VCC', 'GND', 'IN+', '~' for unnamed |
|
||||
| `number` | string or number | Yes | Pin number, e.g. '1', '2', 'A1' |
|
||||
| `type` | enum | Yes | Electrical pin type (see Pin Types below) |
|
||||
| `at` | object | Yes | Pin endpoint position: {x: number, y: number, angle: number} where angle is the direction the pin wire extends FROM the symbol body |
|
||||
| `length` | number | No | Pin length in mm (default 2.54) |
|
||||
| `shape` | enum | No | Pin graphic shape (default: line) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `name` | string | Yes | Pin name, e.g. 'VCC', 'GND', 'IN+', '~' for unnamed |
|
||||
| `number` | string or number | Yes | Pin number, e.g. '1', '2', 'A1' |
|
||||
| `type` | enum | Yes | Electrical pin type (see Pin Types below) |
|
||||
| `at` | object | Yes | Pin endpoint position: {x: number, y: number, angle: number} where angle is the direction the pin wire extends FROM the symbol body |
|
||||
| `length` | number | No | Pin length in mm (default 2.54) |
|
||||
| `shape` | enum | No | Pin graphic shape (default: line) |
|
||||
|
||||
**Pin angle conventions:**
|
||||
|
||||
- 0 = right (wire extends to the right from the symbol body)
|
||||
- 90 = up (wire extends upward)
|
||||
- 180 = left (wire extends to the left)
|
||||
@@ -216,82 +218,82 @@ Each pin object in the `pins` array supports:
|
||||
|
||||
#### Pin Types (Electrical)
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `input` | Input pin |
|
||||
| `output` | Output pin |
|
||||
| `bidirectional` | Bidirectional I/O |
|
||||
| `tri_state` | Tri-state output |
|
||||
| `passive` | Passive component (resistors, capacitors) |
|
||||
| `free` | Free pin (no electrical rule checking) |
|
||||
| `unspecified` | Unspecified type |
|
||||
| `power_in` | Power input (VCC, VDD) |
|
||||
| `power_out` | Power output (regulators) |
|
||||
| `open_collector` | Open collector output |
|
||||
| `open_emitter` | Open emitter output |
|
||||
| `no_connect` | Not connected |
|
||||
| Type | Description |
|
||||
| ---------------- | ----------------------------------------- |
|
||||
| `input` | Input pin |
|
||||
| `output` | Output pin |
|
||||
| `bidirectional` | Bidirectional I/O |
|
||||
| `tri_state` | Tri-state output |
|
||||
| `passive` | Passive component (resistors, capacitors) |
|
||||
| `free` | Free pin (no electrical rule checking) |
|
||||
| `unspecified` | Unspecified type |
|
||||
| `power_in` | Power input (VCC, VDD) |
|
||||
| `power_out` | Power output (regulators) |
|
||||
| `open_collector` | Open collector output |
|
||||
| `open_emitter` | Open emitter output |
|
||||
| `no_connect` | Not connected |
|
||||
|
||||
#### Pin Shapes (Graphical)
|
||||
|
||||
| Shape | Description |
|
||||
|-------|-------------|
|
||||
| `line` | Standard pin (default) |
|
||||
| `inverted` | Pin with inversion bubble |
|
||||
| `clock` | Clock input (triangle) |
|
||||
| `inverted_clock` | Inverted clock with bubble |
|
||||
| `input_low` | Active-low input |
|
||||
| `clock_low` | Active-low clock |
|
||||
| `output_low` | Active-low output |
|
||||
| `falling_edge_clock` | Falling edge triggered |
|
||||
| `non_logic` | Non-logic pin |
|
||||
| Shape | Description |
|
||||
| -------------------- | -------------------------- |
|
||||
| `line` | Standard pin (default) |
|
||||
| `inverted` | Pin with inversion bubble |
|
||||
| `clock` | Clock input (triangle) |
|
||||
| `inverted_clock` | Inverted clock with bubble |
|
||||
| `input_low` | Active-low input |
|
||||
| `clock_low` | Active-low clock |
|
||||
| `output_low` | Active-low output |
|
||||
| `falling_edge_clock` | Falling edge triggered |
|
||||
| `non_logic` | Non-logic pin |
|
||||
|
||||
#### Rectangle Schema
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `x1` | number | Yes | Left X in mm |
|
||||
| `y1` | number | Yes | Top Y in mm |
|
||||
| `x2` | number | Yes | Right X in mm |
|
||||
| `y2` | number | Yes | Bottom Y in mm |
|
||||
| `width` | number | No | Stroke width in mm (default 0.254) |
|
||||
| `fill` | enum | No | Fill type: `none`, `outline`, or `background` (default: background) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------ | -------- | ------------------------------------------------------------------- |
|
||||
| `x1` | number | Yes | Left X in mm |
|
||||
| `y1` | number | Yes | Top Y in mm |
|
||||
| `x2` | number | Yes | Right X in mm |
|
||||
| `y2` | number | Yes | Bottom Y in mm |
|
||||
| `width` | number | No | Stroke width in mm (default 0.254) |
|
||||
| `fill` | enum | No | Fill type: `none`, `outline`, or `background` (default: background) |
|
||||
|
||||
#### Polyline Schema
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `points` | array | Yes | List of XY points: [{x: number, y: number}, ...] in mm |
|
||||
| `width` | number | No | Stroke width in mm (default 0.254) |
|
||||
| `fill` | enum | No | Fill type: `none`, `outline`, or `background` |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------ | -------- | ------------------------------------------------------ |
|
||||
| `points` | array | Yes | List of XY points: [{x: number, y: number}, ...] in mm |
|
||||
| `width` | number | No | Stroke width in mm (default 0.254) |
|
||||
| `fill` | enum | No | Fill type: `none`, `outline`, or `background` |
|
||||
|
||||
### delete_symbol
|
||||
|
||||
Remove a symbol from a .kicad_sym library file.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `libraryPath` | string | Yes | Path to the .kicad_sym file |
|
||||
| `name` | string | Yes | Symbol name to delete |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | --------------------------- |
|
||||
| `libraryPath` | string | Yes | Path to the .kicad_sym file |
|
||||
| `name` | string | Yes | Symbol name to delete |
|
||||
|
||||
### list_symbols_in_library
|
||||
|
||||
List all symbol names in a .kicad_sym library file.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `libraryPath` | string | Yes | Path to the .kicad_sym file |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | --------------------------- |
|
||||
| `libraryPath` | string | Yes | Path to the .kicad_sym file |
|
||||
|
||||
### register_symbol_library
|
||||
|
||||
Register a .kicad_sym library in KiCAD's sym-lib-table so symbols can be used in schematics. Run this after create_symbol when KiCAD shows 'library not found'.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `libraryPath` | string | Yes | Full path to the .kicad_sym file |
|
||||
| `libraryName` | string | No | Nickname (default: file name without extension) |
|
||||
| `description` | string | No | Optional description |
|
||||
| `scope` | enum | No | `project` = writes sym-lib-table next to .kicad_pro (default); `global` = user config |
|
||||
| `projectPath` | string | No | Path to .kicad_pro or its directory (for scope=project) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ------------------------------------------------------------------------------------- |
|
||||
| `libraryPath` | string | Yes | Full path to the .kicad_sym file |
|
||||
| `libraryName` | string | No | Nickname (default: file name without extension) |
|
||||
| `description` | string | No | Optional description |
|
||||
| `scope` | enum | No | `project` = writes sym-lib-table next to .kicad_pro (default); `global` = user config |
|
||||
| `projectPath` | string | No | Path to .kicad_pro or its directory (for scope=project) |
|
||||
|
||||
### Example: Creating a Simple IC Symbol
|
||||
|
||||
@@ -351,6 +353,7 @@ This example creates a 4-pin IC symbol (VCC, GND, IN, OUT):
|
||||
```
|
||||
|
||||
**Pin positioning explained:**
|
||||
|
||||
- VIN pin at (-7.62, 2.54, angle=0): Wire extends to the right, so the symbol body should be to the right. Body left edge is at -5.08, and pin length is 2.54, so -7.62 = -5.08 - 2.54
|
||||
- GND pin at (0, -7.62, angle=90): Wire extends upward, body bottom is at -5.08, so -7.62 = -5.08 - 2.54
|
||||
- VOUT pin at (7.62, 2.54, angle=180): Wire extends to the left, body right is at 5.08, so 7.62 = 5.08 + 2.54
|
||||
@@ -397,6 +400,7 @@ Footprints use a "Y-down" coordinate system (like screen coordinates), while sym
|
||||
### Validation
|
||||
|
||||
After creating custom parts:
|
||||
|
||||
- Open KiCAD schematic editor and verify the symbol appears in the "Add Symbol" dialog
|
||||
- Check pin numbers, names, and electrical types in symbol properties
|
||||
- Open KiCAD PCB editor and verify the footprint appears in the footprint browser
|
||||
|
||||
@@ -32,6 +32,7 @@ curl -L -o ~/.kicad-mcp/freerouting.jar \
|
||||
```
|
||||
|
||||
The default location is `~/.kicad-mcp/freerouting.jar`. You can override this with:
|
||||
|
||||
- The `freeroutingJar` parameter on any tool call
|
||||
- The `FREEROUTING_JAR` environment variable
|
||||
|
||||
@@ -85,6 +86,7 @@ Verify that prerequisites are installed before running the autorouter.
|
||||
**Returns:** Java availability, version, Docker status, JAR location
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
Check if Freerouting is ready on my system.
|
||||
```
|
||||
@@ -102,6 +104,7 @@ Run the full autorouting workflow (export DSN, route, import SES).
|
||||
| `timeout` | number | No | 300 | Timeout in seconds |
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
Autoroute the current board using Freerouting with a 5-minute timeout.
|
||||
```
|
||||
@@ -153,6 +156,7 @@ For advanced users or external autorouters:
|
||||
```
|
||||
|
||||
This is useful when you want to:
|
||||
|
||||
- Use the Freerouting GUI for interactive routing
|
||||
- Use a different autorouter that supports DSN/SES
|
||||
- Route the board on a different machine
|
||||
@@ -190,12 +194,14 @@ Install either Java 21+ or Docker/Podman. See the Prerequisites section above.
|
||||
### "Java found but version < 21"
|
||||
|
||||
Freerouting 2.x requires Java 21+. Either:
|
||||
|
||||
- Upgrade your Java installation
|
||||
- Install Docker as a fallback
|
||||
|
||||
### Timeout Errors
|
||||
|
||||
For complex boards, increase the timeout:
|
||||
|
||||
```
|
||||
Autoroute with timeout 600 and max passes 30.
|
||||
```
|
||||
@@ -203,6 +209,7 @@ Autoroute with timeout 600 and max passes 30.
|
||||
### Routing Quality
|
||||
|
||||
If the autorouter does not route all connections:
|
||||
|
||||
- Increase `maxPasses` (default: 20)
|
||||
- Check that your design rules allow the autorouter enough clearance
|
||||
- Run DRC after autorouting to identify any violations
|
||||
@@ -211,6 +218,7 @@ If the autorouter does not route all connections:
|
||||
### Docker Permission Errors
|
||||
|
||||
If Docker reports permission errors:
|
||||
|
||||
```bash
|
||||
# Add your user to the docker group
|
||||
sudo usermod -aG docker $USER
|
||||
|
||||
@@ -8,79 +8,79 @@ KiCAD MCP Server -- AI-assisted PCB design via Model Context Protocol
|
||||
|
||||
## Getting Started
|
||||
|
||||
| Document | Description |
|
||||
|----------|-------------|
|
||||
| [README](../README.md) | Project overview, installation, configuration, quick start |
|
||||
| [Client Configuration](CLIENT_CONFIGURATION.md) | MCP client setup (Claude Desktop, Cline, Claude Code) |
|
||||
| [Platform Guide](PLATFORM_GUIDE.md) | Linux vs Windows vs macOS differences |
|
||||
| [PCB Design Workflow](PCB_DESIGN_WORKFLOW.md) | End-to-end design guide from project creation to manufacturing |
|
||||
| Document | Description |
|
||||
| ----------------------------------------------- | -------------------------------------------------------------- |
|
||||
| [README](../README.md) | Project overview, installation, configuration, quick start |
|
||||
| [Client Configuration](CLIENT_CONFIGURATION.md) | MCP client setup (Claude Desktop, Cline, Claude Code) |
|
||||
| [Platform Guide](PLATFORM_GUIDE.md) | Linux vs Windows vs macOS differences |
|
||||
| [PCB Design Workflow](PCB_DESIGN_WORKFLOW.md) | End-to-end design guide from project creation to manufacturing |
|
||||
|
||||
---
|
||||
|
||||
## Tool References
|
||||
|
||||
| Document | Description |
|
||||
|----------|-------------|
|
||||
| [Tool Inventory](TOOL_INVENTORY.md) | Complete list of all 122 tools with access types |
|
||||
| [Schematic Tools Reference](SCHEMATIC_TOOLS_REFERENCE.md) | 27 schematic tools -- components, wiring, analysis, export |
|
||||
| [Routing Tools Reference](ROUTING_TOOLS_REFERENCE.md) | 13 routing tools -- traces, vias, differential pairs, zones |
|
||||
| [Footprint and Symbol Creator Guide](FOOTPRINT_SYMBOL_CREATOR_GUIDE.md) | 8 tools for creating custom footprints and symbols |
|
||||
| [Freerouting Guide](FREEROUTING_GUIDE.md) | 4 autorouter tools -- setup, usage, Docker support |
|
||||
| [SVG Import Guide](SVG_IMPORT_GUIDE.md) | Import SVG logos onto PCB layers |
|
||||
| [Datasheet Tools Guide](DATASHEET_TOOLS_GUIDE.md) | Datasheet enrichment via LCSC |
|
||||
| Document | Description |
|
||||
| ----------------------------------------------------------------------- | ----------------------------------------------------------- |
|
||||
| [Tool Inventory](TOOL_INVENTORY.md) | Complete list of all 122 tools with access types |
|
||||
| [Schematic Tools Reference](SCHEMATIC_TOOLS_REFERENCE.md) | 27 schematic tools -- components, wiring, analysis, export |
|
||||
| [Routing Tools Reference](ROUTING_TOOLS_REFERENCE.md) | 13 routing tools -- traces, vias, differential pairs, zones |
|
||||
| [Footprint and Symbol Creator Guide](FOOTPRINT_SYMBOL_CREATOR_GUIDE.md) | 8 tools for creating custom footprints and symbols |
|
||||
| [Freerouting Guide](FREEROUTING_GUIDE.md) | 4 autorouter tools -- setup, usage, Docker support |
|
||||
| [SVG Import Guide](SVG_IMPORT_GUIDE.md) | Import SVG logos onto PCB layers |
|
||||
| [Datasheet Tools Guide](DATASHEET_TOOLS_GUIDE.md) | Datasheet enrichment via LCSC |
|
||||
|
||||
---
|
||||
|
||||
## Integration Guides
|
||||
|
||||
| Document | Description |
|
||||
|----------|-------------|
|
||||
| [JLCPCB Integration](JLCPCB_INTEGRATION.md) | JLCPCB parts catalog, pricing, component selection |
|
||||
| [JLCPCB Usage Guide](JLCPCB_USAGE_GUIDE.md) | Detailed JLCPCB setup and usage |
|
||||
| [Library Integration](LIBRARY_INTEGRATION.md) | Footprint and symbol library setup |
|
||||
| [IPC Backend Status](IPC_BACKEND_STATUS.md) | Real-time KiCAD UI synchronization (experimental) |
|
||||
| Document | Description |
|
||||
| --------------------------------------------- | -------------------------------------------------- |
|
||||
| [JLCPCB Integration](JLCPCB_INTEGRATION.md) | JLCPCB parts catalog, pricing, component selection |
|
||||
| [JLCPCB Usage Guide](JLCPCB_USAGE_GUIDE.md) | Detailed JLCPCB setup and usage |
|
||||
| [Library Integration](LIBRARY_INTEGRATION.md) | Footprint and symbol library setup |
|
||||
| [IPC Backend Status](IPC_BACKEND_STATUS.md) | Real-time KiCAD UI synchronization (experimental) |
|
||||
|
||||
---
|
||||
|
||||
## Workflows
|
||||
|
||||
| Document | Description |
|
||||
|----------|-------------|
|
||||
| [Realtime Workflow](REALTIME_WORKFLOW.md) | Working with IPC backend for live updates |
|
||||
| [Visual Feedback](VISUAL_FEEDBACK.md) | UI visual feedback guide |
|
||||
| [UI Auto Launch](UI_AUTO_LAUNCH.md) | Automatic KiCAD UI launch feature |
|
||||
| [Router Guide](mcp-router-guide.md) | Tool router pattern usage |
|
||||
| [Router Architecture](ROUTER_ARCHITECTURE.md) | Router pattern design |
|
||||
| [Router Quick Start](ROUTER_QUICK_START.md) | Quick start for the router pattern |
|
||||
| Document | Description |
|
||||
| --------------------------------------------- | ----------------------------------------- |
|
||||
| [Realtime Workflow](REALTIME_WORKFLOW.md) | Working with IPC backend for live updates |
|
||||
| [Visual Feedback](VISUAL_FEEDBACK.md) | UI visual feedback guide |
|
||||
| [UI Auto Launch](UI_AUTO_LAUNCH.md) | Automatic KiCAD UI launch feature |
|
||||
| [Router Guide](mcp-router-guide.md) | Tool router pattern usage |
|
||||
| [Router Architecture](ROUTER_ARCHITECTURE.md) | Router pattern design |
|
||||
| [Router Quick Start](ROUTER_QUICK_START.md) | Quick start for the router pattern |
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Document | Description |
|
||||
|----------|-------------|
|
||||
| [Known Issues](KNOWN_ISSUES.md) | Current issues and workarounds |
|
||||
| [Windows Troubleshooting](WINDOWS_TROUBLESHOOTING.md) | Windows-specific problems |
|
||||
| [Linux Compatibility Audit](LINUX_COMPATIBILITY_AUDIT.md) | Linux platform details |
|
||||
| Document | Description |
|
||||
| --------------------------------------------------------- | ------------------------------ |
|
||||
| [Known Issues](KNOWN_ISSUES.md) | Current issues and workarounds |
|
||||
| [Windows Troubleshooting](WINDOWS_TROUBLESHOOTING.md) | Windows-specific problems |
|
||||
| [Linux Compatibility Audit](LINUX_COMPATIBILITY_AUDIT.md) | Linux platform details |
|
||||
|
||||
---
|
||||
|
||||
## Project Information
|
||||
|
||||
| Document | Description |
|
||||
|----------|-------------|
|
||||
| Document | Description |
|
||||
| ----------------------------------- | ----------------------------------------- |
|
||||
| [Status Summary](STATUS_SUMMARY.md) | Current project status and feature matrix |
|
||||
| [Roadmap](ROADMAP.md) | Development roadmap and planned features |
|
||||
| [Changelog](../CHANGELOG.md) | Detailed release notes for all versions |
|
||||
| [Roadmap](ROADMAP.md) | Development roadmap and planned features |
|
||||
| [Changelog](../CHANGELOG.md) | Detailed release notes for all versions |
|
||||
|
||||
---
|
||||
|
||||
## For Contributors
|
||||
|
||||
| Document | Description |
|
||||
|----------|-------------|
|
||||
| [Contributing](../CONTRIBUTING.md) | How to contribute to the project |
|
||||
| [Architecture](ARCHITECTURE.md) | System architecture and adding new tools |
|
||||
| Document | Description |
|
||||
| ---------------------------------- | ---------------------------------------- |
|
||||
| [Contributing](../CONTRIBUTING.md) | How to contribute to the project |
|
||||
| [Architecture](ARCHITECTURE.md) | System architecture and adding new tools |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,212 +1,223 @@
|
||||
# KiCAD IPC Backend Implementation Status
|
||||
|
||||
**Status:** Under Active Development and Testing
|
||||
**Date:** 2026-03-21
|
||||
**KiCAD Version:** 9.0+
|
||||
**kicad-python Version:** 0.5.0+
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The IPC backend provides real-time UI synchronization with KiCAD 9.0+ via the official IPC API. When KiCAD is running with IPC enabled, commands can update the KiCAD UI immediately without requiring manual reload.
|
||||
|
||||
This feature is experimental and under active testing. The server uses a hybrid approach: IPC when available, automatic fallback to SWIG when IPC is not connected.
|
||||
|
||||
## Key Differences
|
||||
|
||||
| Feature | SWIG | IPC |
|
||||
|---------|------|-----|
|
||||
| UI Updates | Manual reload required | Immediate (when working) |
|
||||
| Undo/Redo | Not supported | Transaction support |
|
||||
| API Stability | Deprecated in KiCAD 9 | Official, versioned |
|
||||
| Connection | File-based | Live socket connection |
|
||||
| KiCAD Required | No (file operations) | Yes (must be running) |
|
||||
|
||||
## Implemented IPC Commands
|
||||
|
||||
The following MCP commands have IPC handlers:
|
||||
|
||||
| Command | IPC Handler | Status |
|
||||
|---------|-------------|--------|
|
||||
| `route_trace` | `_ipc_route_trace` | Implemented |
|
||||
| `add_via` | `_ipc_add_via` | Implemented |
|
||||
| `add_net` | `_ipc_add_net` | Implemented |
|
||||
| `delete_trace` | `_ipc_delete_trace` | Falls back to SWIG |
|
||||
| `get_nets_list` | `_ipc_get_nets_list` | Implemented |
|
||||
| `add_copper_pour` | `_ipc_add_copper_pour` | Implemented |
|
||||
| `refill_zones` | `_ipc_refill_zones` | Implemented |
|
||||
| `add_text` | `_ipc_add_text` | Implemented |
|
||||
| `add_board_text` | `_ipc_add_text` | Implemented |
|
||||
| `set_board_size` | `_ipc_set_board_size` | Implemented |
|
||||
| `get_board_info` | `_ipc_get_board_info` | Implemented |
|
||||
| `add_board_outline` | `_ipc_add_board_outline` | Implemented |
|
||||
| `add_mounting_hole` | `_ipc_add_mounting_hole` | Implemented |
|
||||
| `get_layer_list` | `_ipc_get_layer_list` | Implemented |
|
||||
| `place_component` | `_ipc_place_component` | Implemented (hybrid) |
|
||||
| `move_component` | `_ipc_move_component` | Implemented |
|
||||
| `rotate_component` | `_ipc_rotate_component` | Implemented |
|
||||
| `delete_component` | `_ipc_delete_component` | Implemented |
|
||||
| `get_component_list` | `_ipc_get_component_list` | Implemented |
|
||||
| `get_component_properties` | `_ipc_get_component_properties` | Implemented |
|
||||
| `save_project` | `_ipc_save_project` | Implemented |
|
||||
|
||||
### Implemented Backend Features
|
||||
|
||||
**Core Connection:**
|
||||
- Connect to running KiCAD instance
|
||||
- Auto-detect socket path (`/tmp/kicad/api.sock`)
|
||||
- Version checking and validation
|
||||
- Auto-fallback to SWIG when IPC unavailable
|
||||
- Change notification callbacks
|
||||
|
||||
**Board Operations:**
|
||||
- Get board reference
|
||||
- Get/Set board size
|
||||
- List enabled layers
|
||||
- Save board
|
||||
- Add board outline segments
|
||||
- Add mounting holes
|
||||
|
||||
**Component Operations:**
|
||||
- List all components
|
||||
- Place component (hybrid: SWIG for library loading, IPC for placement)
|
||||
- Move component
|
||||
- Rotate component
|
||||
- Delete component
|
||||
- Get component properties
|
||||
|
||||
**Routing Operations:**
|
||||
- Add track
|
||||
- Add via
|
||||
- Get all tracks
|
||||
- Get all vias
|
||||
- Get all nets
|
||||
|
||||
**Zone Operations:**
|
||||
- Add copper pour zones
|
||||
- Get zones list
|
||||
- Refill zones
|
||||
|
||||
**UI Integration:**
|
||||
- Add text to board
|
||||
- Get current selection
|
||||
- Clear selection
|
||||
|
||||
**Transaction Support:**
|
||||
- Begin transaction
|
||||
- Commit transaction (with description for undo)
|
||||
- Rollback transaction
|
||||
|
||||
## Usage
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. **KiCAD 9.0+** must be running
|
||||
2. **IPC API must be enabled**: `Preferences > Plugins > Enable IPC API Server`
|
||||
3. A board must be open in the PCB editor
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
pip install kicad-python
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
Run the test script to verify IPC functionality:
|
||||
|
||||
```bash
|
||||
# Make sure KiCAD is running with IPC enabled and a board open
|
||||
./venv/bin/python python/test_ipc_backend.py
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
+-------------------------------------------------------------+
|
||||
| MCP Server (TypeScript/Node.js) |
|
||||
+---------------------------+---------------------------------+
|
||||
| JSON commands
|
||||
+---------------------------v---------------------------------+
|
||||
| Python Interface Layer |
|
||||
| +--------------------------------------------------------+ |
|
||||
| | kicad_interface.py | |
|
||||
| | - Routes commands to IPC or SWIG handlers | |
|
||||
| | - IPC_CAPABLE_COMMANDS dict defines routing | |
|
||||
| +--------------------------------------------------------+ |
|
||||
| +--------------------------------------------------------+ |
|
||||
| | kicad_api/ipc_backend.py | |
|
||||
| | - IPCBackend (connection management) | |
|
||||
| | - IPCBoardAPI (board operations) | |
|
||||
| +--------------------------------------------------------+ |
|
||||
+---------------------------+---------------------------------+
|
||||
| kicad-python (kipy) library
|
||||
+---------------------------v---------------------------------+
|
||||
| Protocol Buffers over UNIX Sockets |
|
||||
+---------------------------+---------------------------------+
|
||||
|
|
||||
+---------------------------v---------------------------------+
|
||||
| KiCAD 9.0+ (IPC Server) |
|
||||
+-------------------------------------------------------------+
|
||||
```
|
||||
|
||||
## Known Limitations
|
||||
|
||||
1. **KiCAD must be running**: Unlike SWIG, IPC requires KiCAD to be open
|
||||
2. **Project creation**: Not supported via IPC, uses file system
|
||||
3. **Footprint library access**: Uses hybrid approach (SWIG loads from library, IPC places)
|
||||
4. **Delete trace**: Falls back to SWIG (IPC API doesn't support direct deletion)
|
||||
5. **Some operations may not work as expected**: This is experimental code
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Connection failed"
|
||||
- Ensure KiCAD is running
|
||||
- Enable IPC API: `Preferences > Plugins > Enable IPC API Server`
|
||||
- Check if a board is open
|
||||
|
||||
### "kicad-python not found"
|
||||
```bash
|
||||
pip install kicad-python
|
||||
```
|
||||
|
||||
### "Version mismatch"
|
||||
- Update kicad-python: `pip install --upgrade kicad-python`
|
||||
- Ensure KiCAD 9.0+ is installed
|
||||
|
||||
### "No board open"
|
||||
- Open a board in KiCAD's PCB editor before connecting
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
python/kicad_api/
|
||||
├── __init__.py # Package exports
|
||||
├── base.py # Abstract base classes
|
||||
├── factory.py # Backend auto-detection
|
||||
├── ipc_backend.py # IPC implementation
|
||||
└── swig_backend.py # Legacy SWIG wrapper
|
||||
|
||||
python/
|
||||
└── test_ipc_backend.py # IPC test script
|
||||
```
|
||||
|
||||
## Future Work
|
||||
|
||||
1. More comprehensive testing of all IPC commands
|
||||
2. Footprint library integration via IPC (when kipy supports it)
|
||||
3. Schematic IPC support (when available in kicad-python)
|
||||
4. Event subscriptions to react to changes made in KiCAD UI
|
||||
5. Multi-board support
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [ROADMAP.md](./ROADMAP.md) - Project roadmap
|
||||
- [IPC_API_MIGRATION_PLAN.md](./IPC_API_MIGRATION_PLAN.md) - Migration details
|
||||
- [REALTIME_WORKFLOW.md](./REALTIME_WORKFLOW.md) - Collaboration workflows
|
||||
- [kicad-python docs](https://docs.kicad.org/kicad-python-main/) - Official API docs
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2026-03-21
|
||||
# KiCAD IPC Backend Implementation Status
|
||||
|
||||
**Status:** Under Active Development and Testing
|
||||
**Date:** 2026-03-21
|
||||
**KiCAD Version:** 9.0+
|
||||
**kicad-python Version:** 0.5.0+
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The IPC backend provides real-time UI synchronization with KiCAD 9.0+ via the official IPC API. When KiCAD is running with IPC enabled, commands can update the KiCAD UI immediately without requiring manual reload.
|
||||
|
||||
This feature is experimental and under active testing. The server uses a hybrid approach: IPC when available, automatic fallback to SWIG when IPC is not connected.
|
||||
|
||||
## Key Differences
|
||||
|
||||
| Feature | SWIG | IPC |
|
||||
| -------------- | ---------------------- | ------------------------ |
|
||||
| UI Updates | Manual reload required | Immediate (when working) |
|
||||
| Undo/Redo | Not supported | Transaction support |
|
||||
| API Stability | Deprecated in KiCAD 9 | Official, versioned |
|
||||
| Connection | File-based | Live socket connection |
|
||||
| KiCAD Required | No (file operations) | Yes (must be running) |
|
||||
|
||||
## Implemented IPC Commands
|
||||
|
||||
The following MCP commands have IPC handlers:
|
||||
|
||||
| Command | IPC Handler | Status |
|
||||
| -------------------------- | ------------------------------- | -------------------- |
|
||||
| `route_trace` | `_ipc_route_trace` | Implemented |
|
||||
| `add_via` | `_ipc_add_via` | Implemented |
|
||||
| `add_net` | `_ipc_add_net` | Implemented |
|
||||
| `delete_trace` | `_ipc_delete_trace` | Falls back to SWIG |
|
||||
| `get_nets_list` | `_ipc_get_nets_list` | Implemented |
|
||||
| `add_copper_pour` | `_ipc_add_copper_pour` | Implemented |
|
||||
| `refill_zones` | `_ipc_refill_zones` | Implemented |
|
||||
| `add_text` | `_ipc_add_text` | Implemented |
|
||||
| `add_board_text` | `_ipc_add_text` | Implemented |
|
||||
| `set_board_size` | `_ipc_set_board_size` | Implemented |
|
||||
| `get_board_info` | `_ipc_get_board_info` | Implemented |
|
||||
| `add_board_outline` | `_ipc_add_board_outline` | Implemented |
|
||||
| `add_mounting_hole` | `_ipc_add_mounting_hole` | Implemented |
|
||||
| `get_layer_list` | `_ipc_get_layer_list` | Implemented |
|
||||
| `place_component` | `_ipc_place_component` | Implemented (hybrid) |
|
||||
| `move_component` | `_ipc_move_component` | Implemented |
|
||||
| `rotate_component` | `_ipc_rotate_component` | Implemented |
|
||||
| `delete_component` | `_ipc_delete_component` | Implemented |
|
||||
| `get_component_list` | `_ipc_get_component_list` | Implemented |
|
||||
| `get_component_properties` | `_ipc_get_component_properties` | Implemented |
|
||||
| `save_project` | `_ipc_save_project` | Implemented |
|
||||
|
||||
### Implemented Backend Features
|
||||
|
||||
**Core Connection:**
|
||||
|
||||
- Connect to running KiCAD instance
|
||||
- Auto-detect socket path (`/tmp/kicad/api.sock`)
|
||||
- Version checking and validation
|
||||
- Auto-fallback to SWIG when IPC unavailable
|
||||
- Change notification callbacks
|
||||
|
||||
**Board Operations:**
|
||||
|
||||
- Get board reference
|
||||
- Get/Set board size
|
||||
- List enabled layers
|
||||
- Save board
|
||||
- Add board outline segments
|
||||
- Add mounting holes
|
||||
|
||||
**Component Operations:**
|
||||
|
||||
- List all components
|
||||
- Place component (hybrid: SWIG for library loading, IPC for placement)
|
||||
- Move component
|
||||
- Rotate component
|
||||
- Delete component
|
||||
- Get component properties
|
||||
|
||||
**Routing Operations:**
|
||||
|
||||
- Add track
|
||||
- Add via
|
||||
- Get all tracks
|
||||
- Get all vias
|
||||
- Get all nets
|
||||
|
||||
**Zone Operations:**
|
||||
|
||||
- Add copper pour zones
|
||||
- Get zones list
|
||||
- Refill zones
|
||||
|
||||
**UI Integration:**
|
||||
|
||||
- Add text to board
|
||||
- Get current selection
|
||||
- Clear selection
|
||||
|
||||
**Transaction Support:**
|
||||
|
||||
- Begin transaction
|
||||
- Commit transaction (with description for undo)
|
||||
- Rollback transaction
|
||||
|
||||
## Usage
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. **KiCAD 9.0+** must be running
|
||||
2. **IPC API must be enabled**: `Preferences > Plugins > Enable IPC API Server`
|
||||
3. A board must be open in the PCB editor
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
pip install kicad-python
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
Run the test script to verify IPC functionality:
|
||||
|
||||
```bash
|
||||
# Make sure KiCAD is running with IPC enabled and a board open
|
||||
./venv/bin/python python/test_ipc_backend.py
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
+-------------------------------------------------------------+
|
||||
| MCP Server (TypeScript/Node.js) |
|
||||
+---------------------------+---------------------------------+
|
||||
| JSON commands
|
||||
+---------------------------v---------------------------------+
|
||||
| Python Interface Layer |
|
||||
| +--------------------------------------------------------+ |
|
||||
| | kicad_interface.py | |
|
||||
| | - Routes commands to IPC or SWIG handlers | |
|
||||
| | - IPC_CAPABLE_COMMANDS dict defines routing | |
|
||||
| +--------------------------------------------------------+ |
|
||||
| +--------------------------------------------------------+ |
|
||||
| | kicad_api/ipc_backend.py | |
|
||||
| | - IPCBackend (connection management) | |
|
||||
| | - IPCBoardAPI (board operations) | |
|
||||
| +--------------------------------------------------------+ |
|
||||
+---------------------------+---------------------------------+
|
||||
| kicad-python (kipy) library
|
||||
+---------------------------v---------------------------------+
|
||||
| Protocol Buffers over UNIX Sockets |
|
||||
+---------------------------+---------------------------------+
|
||||
|
|
||||
+---------------------------v---------------------------------+
|
||||
| KiCAD 9.0+ (IPC Server) |
|
||||
+-------------------------------------------------------------+
|
||||
```
|
||||
|
||||
## Known Limitations
|
||||
|
||||
1. **KiCAD must be running**: Unlike SWIG, IPC requires KiCAD to be open
|
||||
2. **Project creation**: Not supported via IPC, uses file system
|
||||
3. **Footprint library access**: Uses hybrid approach (SWIG loads from library, IPC places)
|
||||
4. **Delete trace**: Falls back to SWIG (IPC API doesn't support direct deletion)
|
||||
5. **Some operations may not work as expected**: This is experimental code
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Connection failed"
|
||||
|
||||
- Ensure KiCAD is running
|
||||
- Enable IPC API: `Preferences > Plugins > Enable IPC API Server`
|
||||
- Check if a board is open
|
||||
|
||||
### "kicad-python not found"
|
||||
|
||||
```bash
|
||||
pip install kicad-python
|
||||
```
|
||||
|
||||
### "Version mismatch"
|
||||
|
||||
- Update kicad-python: `pip install --upgrade kicad-python`
|
||||
- Ensure KiCAD 9.0+ is installed
|
||||
|
||||
### "No board open"
|
||||
|
||||
- Open a board in KiCAD's PCB editor before connecting
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
python/kicad_api/
|
||||
├── __init__.py # Package exports
|
||||
├── base.py # Abstract base classes
|
||||
├── factory.py # Backend auto-detection
|
||||
├── ipc_backend.py # IPC implementation
|
||||
└── swig_backend.py # Legacy SWIG wrapper
|
||||
|
||||
python/
|
||||
└── test_ipc_backend.py # IPC test script
|
||||
```
|
||||
|
||||
## Future Work
|
||||
|
||||
1. More comprehensive testing of all IPC commands
|
||||
2. Footprint library integration via IPC (when kipy supports it)
|
||||
3. Schematic IPC support (when available in kicad-python)
|
||||
4. Event subscriptions to react to changes made in KiCAD UI
|
||||
5. Multi-board support
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [ROADMAP.md](./ROADMAP.md) - Project roadmap
|
||||
- [IPC_API_MIGRATION_PLAN.md](./IPC_API_MIGRATION_PLAN.md) - Migration details
|
||||
- [REALTIME_WORKFLOW.md](./REALTIME_WORKFLOW.md) - Collaboration workflows
|
||||
- [kicad-python docs](https://docs.kicad.org/kicad-python-main/) - Official API docs
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2026-03-21
|
||||
|
||||
@@ -1,344 +1,374 @@
|
||||
# JLCPCB Parts Integration - Complete Guide
|
||||
|
||||
## Overview
|
||||
|
||||
The KiCAD MCP Server integrates with JLCPCB's parts library to provide intelligent component selection, cost optimization, and automated part sourcing for PCB assembly.
|
||||
|
||||
**Current Implementation**: Uses the **JLCSearch public API** (by tscircuit) for free, unauthenticated access to JLCPCB's ~100k parts catalog.
|
||||
|
||||
## Features
|
||||
|
||||
✅ **Parametric Search** - Find components by specifications (resistance, capacitance, package, etc.)
|
||||
✅ **Price Comparison** - Compare Basic vs Extended library pricing
|
||||
✅ **Alternative Suggestions** - Find cheaper or higher-stock alternatives
|
||||
✅ **Footprint Mapping** - Automatic JLCPCB package to KiCad footprint mapping
|
||||
✅ **Stock Availability** - Real-time stock levels from JLCPCB
|
||||
✅ **No Authentication Required** - Public API, no API keys needed
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Search for Components
|
||||
|
||||
```python
|
||||
from commands.jlcsearch import JLCSearchClient
|
||||
|
||||
client = JLCSearchClient()
|
||||
|
||||
# Search for resistors
|
||||
resistors = client.search_resistors(
|
||||
resistance=10000, # 10kΩ
|
||||
package="0603",
|
||||
limit=20
|
||||
)
|
||||
|
||||
# Search for capacitors
|
||||
capacitors = client.search_capacitors(
|
||||
capacitance=1e-7, # 100nF
|
||||
package="0603",
|
||||
limit=20
|
||||
)
|
||||
|
||||
# General component search
|
||||
components = client.search_components(
|
||||
"components",
|
||||
package="0603",
|
||||
limit=100
|
||||
)
|
||||
```
|
||||
|
||||
### 2. Get Part Details
|
||||
|
||||
```python
|
||||
# Get specific part by LCSC number
|
||||
part = client.get_part_by_lcsc(25804) # C25804
|
||||
print(f"Part: {part['mfr']}")
|
||||
print(f"Stock: {part['stock']}")
|
||||
print(f"Price: ${part['price1']}")
|
||||
print(f"Basic Library: {part['is_basic']}")
|
||||
```
|
||||
|
||||
### 3. Database Integration
|
||||
|
||||
```python
|
||||
from commands.jlcpcb_parts import JLCPCBPartsManager
|
||||
|
||||
# Initialize database
|
||||
db = JLCPCBPartsManager() # Uses data/jlcpcb_parts.db
|
||||
|
||||
# Download and import parts (one-time setup)
|
||||
client = JLCSearchClient()
|
||||
parts = client.download_all_components()
|
||||
db.import_jlcsearch_parts(parts)
|
||||
|
||||
# Search imported database
|
||||
results = db.search_parts(
|
||||
query="resistor",
|
||||
package="0603",
|
||||
library_type="Basic",
|
||||
in_stock=True,
|
||||
limit=20
|
||||
)
|
||||
```
|
||||
|
||||
### 4. Footprint Mapping
|
||||
|
||||
```python
|
||||
# Map JLCPCB package to KiCad footprints
|
||||
footprints = db.map_package_to_footprint("0603")
|
||||
# Returns:
|
||||
# [
|
||||
# "Resistor_SMD:R_0603_1608Metric",
|
||||
# "Capacitor_SMD:C_0603_1608Metric",
|
||||
# "LED_SMD:LED_0603_1608Metric"
|
||||
# ]
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### JLCSearchClient
|
||||
|
||||
#### `search_resistors(resistance, package, limit)`
|
||||
Search for resistors by value and package.
|
||||
|
||||
**Parameters:**
|
||||
- `resistance` (int, optional): Resistance in ohms
|
||||
- `package` (str, optional): Package size ("0402", "0603", "0805", etc.)
|
||||
- `limit` (int): Maximum results (default: 100)
|
||||
|
||||
**Returns:** List of resistor dicts with fields:
|
||||
- `lcsc`: LCSC number (integer)
|
||||
- `mfr`: Manufacturer part number
|
||||
- `package`: Package size
|
||||
- `is_basic`: True if Basic library part (no assembly fee)
|
||||
- `resistance`: Resistance in ohms
|
||||
- `tolerance_fraction`: Tolerance (0.01 = 1%)
|
||||
- `power_watts`: Power rating in mW
|
||||
- `stock`: Available stock
|
||||
- `price1`: Unit price in USD
|
||||
|
||||
#### `search_capacitors(capacitance, package, limit)`
|
||||
Search for capacitors by value and package.
|
||||
|
||||
**Parameters:**
|
||||
- `capacitance` (float, optional): Capacitance in farads (e.g., 1e-7 for 100nF)
|
||||
- `package` (str, optional): Package size
|
||||
- `limit` (int): Maximum results
|
||||
|
||||
**Returns:** List of capacitor dicts
|
||||
|
||||
#### `search_components(category, limit, offset, **filters)`
|
||||
General component search.
|
||||
|
||||
**Parameters:**
|
||||
- `category` (str): "resistors", "capacitors", "components", etc.
|
||||
- `limit` (int): Maximum results
|
||||
- `offset` (int): Pagination offset
|
||||
- `**filters`: Additional filters (package="0603", lcsc=25804, etc.)
|
||||
|
||||
**Returns:** List of component dicts
|
||||
|
||||
#### `download_all_components(callback, batch_size)`
|
||||
Download entire JLCPCB parts catalog.
|
||||
|
||||
**Parameters:**
|
||||
- `callback` (callable, optional): Progress callback(parts_count, status_msg)
|
||||
- `batch_size` (int): Parts per batch (default: 1000)
|
||||
|
||||
**Returns:** List of all parts (~100k components)
|
||||
|
||||
**Note:** This may take 5-10 minutes to complete.
|
||||
|
||||
### JLCPCBPartsManager
|
||||
|
||||
#### `import_jlcsearch_parts(parts, progress_callback)`
|
||||
Import parts from JLCSearch into local SQLite database.
|
||||
|
||||
**Parameters:**
|
||||
- `parts` (list): List of part dicts from JLCSearchClient
|
||||
- `progress_callback` (callable, optional): Progress updates
|
||||
|
||||
#### `search_parts(query, category, package, library_type, manufacturer, in_stock, limit)`
|
||||
Search local database with filters.
|
||||
|
||||
**Parameters:**
|
||||
- `query` (str, optional): Free-text search
|
||||
- `category` (str, optional): Category filter
|
||||
- `package` (str, optional): Package filter
|
||||
- `library_type` (str, optional): "Basic", "Extended", or "Preferred"
|
||||
- `manufacturer` (str, optional): Manufacturer filter
|
||||
- `in_stock` (bool): Only in-stock parts (default: True)
|
||||
- `limit` (int): Maximum results
|
||||
|
||||
**Returns:** List of matching parts
|
||||
|
||||
#### `get_part_info(lcsc_number)`
|
||||
Get detailed part information.
|
||||
|
||||
**Parameters:**
|
||||
- `lcsc_number` (str): LCSC part number (e.g., "C25804")
|
||||
|
||||
**Returns:** Part dict or None
|
||||
|
||||
#### `get_database_stats()`
|
||||
Get database statistics.
|
||||
|
||||
**Returns:** Dict with:
|
||||
- `total_parts`: Total parts count
|
||||
- `basic_parts`: Basic library count
|
||||
- `extended_parts`: Extended library count
|
||||
- `in_stock`: Parts with stock > 0
|
||||
- `db_path`: Database file path
|
||||
|
||||
#### `map_package_to_footprint(package)`
|
||||
Map JLCPCB package to KiCad footprints.
|
||||
|
||||
**Parameters:**
|
||||
- `package` (str): JLCPCB package name
|
||||
|
||||
**Returns:** List of KiCad footprint library references
|
||||
|
||||
## Data Format
|
||||
|
||||
### JLCSearch Part Object
|
||||
|
||||
```json
|
||||
{
|
||||
"lcsc": 25804,
|
||||
"mfr": "0603WAF1002T5E",
|
||||
"package": "0603",
|
||||
"is_basic": true,
|
||||
"is_preferred": false,
|
||||
"resistance": 10000,
|
||||
"tolerance_fraction": 0.01,
|
||||
"power_watts": 100,
|
||||
"stock": 37165617,
|
||||
"price1": 0.000842857
|
||||
}
|
||||
```
|
||||
|
||||
### Database Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE components (
|
||||
lcsc TEXT PRIMARY KEY, -- "C25804"
|
||||
category TEXT, -- "Resistors"
|
||||
subcategory TEXT, -- "Chip Resistor"
|
||||
mfr_part TEXT, -- "0603WAF1002T5E"
|
||||
package TEXT, -- "0603"
|
||||
solder_joints INTEGER,
|
||||
manufacturer TEXT,
|
||||
library_type TEXT, -- "Basic" or "Extended"
|
||||
description TEXT, -- "10kΩ ±1% 100mW"
|
||||
datasheet TEXT,
|
||||
stock INTEGER,
|
||||
price_json TEXT, -- JSON array of price breaks
|
||||
last_updated INTEGER -- Unix timestamp
|
||||
);
|
||||
```
|
||||
|
||||
## Package to Footprint Mappings
|
||||
|
||||
| JLCPCB Package | KiCad Footprints |
|
||||
|----------------|------------------|
|
||||
| 0402 | Resistor_SMD:R_0402_1005Metric<br>Capacitor_SMD:C_0402_1005Metric<br>LED_SMD:LED_0402_1005Metric |
|
||||
| 0603 | Resistor_SMD:R_0603_1608Metric<br>Capacitor_SMD:C_0603_1608Metric<br>LED_SMD:LED_0603_1608Metric |
|
||||
| 0805 | Resistor_SMD:R_0805_2012Metric<br>Capacitor_SMD:C_0805_2012Metric |
|
||||
| 1206 | Resistor_SMD:R_1206_3216Metric<br>Capacitor_SMD:C_1206_3216Metric |
|
||||
| SOT-23 | Package_TO_SOT_SMD:SOT-23<br>Package_TO_SOT_SMD:SOT-23-3 |
|
||||
| SOT-23-5 | Package_TO_SOT_SMD:SOT-23-5 |
|
||||
| SOT-23-6 | Package_TO_SOT_SMD:SOT-23-6 |
|
||||
| SOT-223 | Package_TO_SOT_SMD:SOT-223 |
|
||||
| SOIC-8 | Package_SO:SOIC-8_3.9x4.9mm_P1.27mm |
|
||||
| QFN-20 | Package_DFN_QFN:QFN-20-1EP_4x4mm_P0.5mm_EP2.5x2.5mm |
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Always Use Basic Library Parts First
|
||||
Basic library parts have **no assembly fee** ($0/part), while Extended parts cost **$3/part**.
|
||||
|
||||
```python
|
||||
# Filter for Basic parts only
|
||||
basic_parts = [p for p in results if p['is_basic']]
|
||||
```
|
||||
|
||||
### 2. Check Stock Availability
|
||||
Ensure sufficient stock before committing to a design.
|
||||
|
||||
```python
|
||||
# Only use parts with >1000 stock
|
||||
high_stock = [p for p in results if p['stock'] > 1000]
|
||||
```
|
||||
|
||||
### 3. Compare Prices
|
||||
Even within Basic library, prices vary significantly.
|
||||
|
||||
```python
|
||||
# Find cheapest option
|
||||
cheapest = min(results, key=lambda x: x.get('price1', 999))
|
||||
```
|
||||
|
||||
### 4. Use Standardized Packages
|
||||
Stick to common packages (0402, 0603, 0805) for better availability and pricing.
|
||||
|
||||
### 5. Cache Database Locally
|
||||
Download the full parts database once and search locally for faster results.
|
||||
|
||||
```python
|
||||
# Initial download (one-time, ~5-10 minutes)
|
||||
if not os.path.exists("data/jlcpcb_parts.db"):
|
||||
parts = client.download_all_components()
|
||||
db.import_jlcsearch_parts(parts)
|
||||
|
||||
# Subsequent searches use local database (instant)
|
||||
results = db.search_parts(...)
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### API Rate Limiting
|
||||
JLCSearch is a community service. If you hit rate limits:
|
||||
- Add delays between requests (`time.sleep(0.1)`)
|
||||
- Use the local database instead of repeated API calls
|
||||
- Download the full database once and work offline
|
||||
|
||||
### Missing Data
|
||||
JLCSearch may not have all fields that official JLCPCB API provides:
|
||||
- No datasheets (use manufacturer website)
|
||||
- Limited category information
|
||||
- No solder joint count
|
||||
|
||||
### Stock Discrepancies
|
||||
Stock levels are updated periodically but may lag real-time JLCPCB data by a few hours.
|
||||
|
||||
## Official JLCPCB API (Alternative)
|
||||
|
||||
The project also includes an implementation of the official JLCPCB API with HMAC-SHA256 authentication. However, this requires:
|
||||
1. API approval from JLCPCB (not all applications are approved)
|
||||
2. APP_ID, ACCESS_KEY, and SECRET_KEY credentials
|
||||
3. Previous order history with JLCPCB
|
||||
|
||||
To use the official API instead of JLCSearch:
|
||||
|
||||
```python
|
||||
from commands.jlcpcb import JLCPCBClient
|
||||
|
||||
# Set credentials in .env file:
|
||||
# JLCPCB_APP_ID=<your_app_id>
|
||||
# JLCPCB_API_KEY=<your_access_key>
|
||||
# JLCPCB_API_SECRET=<your_secret_key>
|
||||
|
||||
client = JLCPCBClient(app_id, access_key, secret_key)
|
||||
data = client.fetch_parts_page()
|
||||
```
|
||||
|
||||
**Note:** Most users should use JLCSearch public API instead, as it's freely available and requires no authentication.
|
||||
|
||||
## Credits
|
||||
|
||||
- **JLCSearch API**: https://jlcsearch.tscircuit.com/ (by [@tscircuit](https://github.com/tscircuit/jlcsearch))
|
||||
- **JLCParts Database**: https://github.com/yaqwsx/jlcparts (by [@yaqwsx](https://github.com/yaqwsx))
|
||||
- **JLCPCB**: https://jlcpcb.com/ (official parts library provider)
|
||||
|
||||
## License
|
||||
|
||||
This integration uses publicly available JLCPCB parts data via the JLCSearch community service. Users must comply with JLCPCB's terms of service when using this data for production PCB orders.
|
||||
# JLCPCB Parts Integration - Complete Guide
|
||||
|
||||
## Overview
|
||||
|
||||
The KiCAD MCP Server integrates with JLCPCB's parts library to provide intelligent component selection, cost optimization, and automated part sourcing for PCB assembly.
|
||||
|
||||
**Current Implementation**: Uses the **JLCSearch public API** (by tscircuit) for free, unauthenticated access to JLCPCB's ~100k parts catalog.
|
||||
|
||||
## Features
|
||||
|
||||
✅ **Parametric Search** - Find components by specifications (resistance, capacitance, package, etc.)
|
||||
✅ **Price Comparison** - Compare Basic vs Extended library pricing
|
||||
✅ **Alternative Suggestions** - Find cheaper or higher-stock alternatives
|
||||
✅ **Footprint Mapping** - Automatic JLCPCB package to KiCad footprint mapping
|
||||
✅ **Stock Availability** - Real-time stock levels from JLCPCB
|
||||
✅ **No Authentication Required** - Public API, no API keys needed
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Search for Components
|
||||
|
||||
```python
|
||||
from commands.jlcsearch import JLCSearchClient
|
||||
|
||||
client = JLCSearchClient()
|
||||
|
||||
# Search for resistors
|
||||
resistors = client.search_resistors(
|
||||
resistance=10000, # 10kΩ
|
||||
package="0603",
|
||||
limit=20
|
||||
)
|
||||
|
||||
# Search for capacitors
|
||||
capacitors = client.search_capacitors(
|
||||
capacitance=1e-7, # 100nF
|
||||
package="0603",
|
||||
limit=20
|
||||
)
|
||||
|
||||
# General component search
|
||||
components = client.search_components(
|
||||
"components",
|
||||
package="0603",
|
||||
limit=100
|
||||
)
|
||||
```
|
||||
|
||||
### 2. Get Part Details
|
||||
|
||||
```python
|
||||
# Get specific part by LCSC number
|
||||
part = client.get_part_by_lcsc(25804) # C25804
|
||||
print(f"Part: {part['mfr']}")
|
||||
print(f"Stock: {part['stock']}")
|
||||
print(f"Price: ${part['price1']}")
|
||||
print(f"Basic Library: {part['is_basic']}")
|
||||
```
|
||||
|
||||
### 3. Database Integration
|
||||
|
||||
```python
|
||||
from commands.jlcpcb_parts import JLCPCBPartsManager
|
||||
|
||||
# Initialize database
|
||||
db = JLCPCBPartsManager() # Uses data/jlcpcb_parts.db
|
||||
|
||||
# Download and import parts (one-time setup)
|
||||
client = JLCSearchClient()
|
||||
parts = client.download_all_components()
|
||||
db.import_jlcsearch_parts(parts)
|
||||
|
||||
# Search imported database
|
||||
results = db.search_parts(
|
||||
query="resistor",
|
||||
package="0603",
|
||||
library_type="Basic",
|
||||
in_stock=True,
|
||||
limit=20
|
||||
)
|
||||
```
|
||||
|
||||
### 4. Footprint Mapping
|
||||
|
||||
```python
|
||||
# Map JLCPCB package to KiCad footprints
|
||||
footprints = db.map_package_to_footprint("0603")
|
||||
# Returns:
|
||||
# [
|
||||
# "Resistor_SMD:R_0603_1608Metric",
|
||||
# "Capacitor_SMD:C_0603_1608Metric",
|
||||
# "LED_SMD:LED_0603_1608Metric"
|
||||
# ]
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### JLCSearchClient
|
||||
|
||||
#### `search_resistors(resistance, package, limit)`
|
||||
|
||||
Search for resistors by value and package.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `resistance` (int, optional): Resistance in ohms
|
||||
- `package` (str, optional): Package size ("0402", "0603", "0805", etc.)
|
||||
- `limit` (int): Maximum results (default: 100)
|
||||
|
||||
**Returns:** List of resistor dicts with fields:
|
||||
|
||||
- `lcsc`: LCSC number (integer)
|
||||
- `mfr`: Manufacturer part number
|
||||
- `package`: Package size
|
||||
- `is_basic`: True if Basic library part (no assembly fee)
|
||||
- `resistance`: Resistance in ohms
|
||||
- `tolerance_fraction`: Tolerance (0.01 = 1%)
|
||||
- `power_watts`: Power rating in mW
|
||||
- `stock`: Available stock
|
||||
- `price1`: Unit price in USD
|
||||
|
||||
#### `search_capacitors(capacitance, package, limit)`
|
||||
|
||||
Search for capacitors by value and package.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `capacitance` (float, optional): Capacitance in farads (e.g., 1e-7 for 100nF)
|
||||
- `package` (str, optional): Package size
|
||||
- `limit` (int): Maximum results
|
||||
|
||||
**Returns:** List of capacitor dicts
|
||||
|
||||
#### `search_components(category, limit, offset, **filters)`
|
||||
|
||||
General component search.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `category` (str): "resistors", "capacitors", "components", etc.
|
||||
- `limit` (int): Maximum results
|
||||
- `offset` (int): Pagination offset
|
||||
- `**filters`: Additional filters (package="0603", lcsc=25804, etc.)
|
||||
|
||||
**Returns:** List of component dicts
|
||||
|
||||
#### `download_all_components(callback, batch_size)`
|
||||
|
||||
Download entire JLCPCB parts catalog.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `callback` (callable, optional): Progress callback(parts_count, status_msg)
|
||||
- `batch_size` (int): Parts per batch (default: 1000)
|
||||
|
||||
**Returns:** List of all parts (~100k components)
|
||||
|
||||
**Note:** This may take 5-10 minutes to complete.
|
||||
|
||||
### JLCPCBPartsManager
|
||||
|
||||
#### `import_jlcsearch_parts(parts, progress_callback)`
|
||||
|
||||
Import parts from JLCSearch into local SQLite database.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `parts` (list): List of part dicts from JLCSearchClient
|
||||
- `progress_callback` (callable, optional): Progress updates
|
||||
|
||||
#### `search_parts(query, category, package, library_type, manufacturer, in_stock, limit)`
|
||||
|
||||
Search local database with filters.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `query` (str, optional): Free-text search
|
||||
- `category` (str, optional): Category filter
|
||||
- `package` (str, optional): Package filter
|
||||
- `library_type` (str, optional): "Basic", "Extended", or "Preferred"
|
||||
- `manufacturer` (str, optional): Manufacturer filter
|
||||
- `in_stock` (bool): Only in-stock parts (default: True)
|
||||
- `limit` (int): Maximum results
|
||||
|
||||
**Returns:** List of matching parts
|
||||
|
||||
#### `get_part_info(lcsc_number)`
|
||||
|
||||
Get detailed part information.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `lcsc_number` (str): LCSC part number (e.g., "C25804")
|
||||
|
||||
**Returns:** Part dict or None
|
||||
|
||||
#### `get_database_stats()`
|
||||
|
||||
Get database statistics.
|
||||
|
||||
**Returns:** Dict with:
|
||||
|
||||
- `total_parts`: Total parts count
|
||||
- `basic_parts`: Basic library count
|
||||
- `extended_parts`: Extended library count
|
||||
- `in_stock`: Parts with stock > 0
|
||||
- `db_path`: Database file path
|
||||
|
||||
#### `map_package_to_footprint(package)`
|
||||
|
||||
Map JLCPCB package to KiCad footprints.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `package` (str): JLCPCB package name
|
||||
|
||||
**Returns:** List of KiCad footprint library references
|
||||
|
||||
## Data Format
|
||||
|
||||
### JLCSearch Part Object
|
||||
|
||||
```json
|
||||
{
|
||||
"lcsc": 25804,
|
||||
"mfr": "0603WAF1002T5E",
|
||||
"package": "0603",
|
||||
"is_basic": true,
|
||||
"is_preferred": false,
|
||||
"resistance": 10000,
|
||||
"tolerance_fraction": 0.01,
|
||||
"power_watts": 100,
|
||||
"stock": 37165617,
|
||||
"price1": 0.000842857
|
||||
}
|
||||
```
|
||||
|
||||
### Database Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE components (
|
||||
lcsc TEXT PRIMARY KEY, -- "C25804"
|
||||
category TEXT, -- "Resistors"
|
||||
subcategory TEXT, -- "Chip Resistor"
|
||||
mfr_part TEXT, -- "0603WAF1002T5E"
|
||||
package TEXT, -- "0603"
|
||||
solder_joints INTEGER,
|
||||
manufacturer TEXT,
|
||||
library_type TEXT, -- "Basic" or "Extended"
|
||||
description TEXT, -- "10kΩ ±1% 100mW"
|
||||
datasheet TEXT,
|
||||
stock INTEGER,
|
||||
price_json TEXT, -- JSON array of price breaks
|
||||
last_updated INTEGER -- Unix timestamp
|
||||
);
|
||||
```
|
||||
|
||||
## Package to Footprint Mappings
|
||||
|
||||
| JLCPCB Package | KiCad Footprints |
|
||||
| -------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| 0402 | Resistor_SMD:R_0402_1005Metric<br>Capacitor_SMD:C_0402_1005Metric<br>LED_SMD:LED_0402_1005Metric |
|
||||
| 0603 | Resistor_SMD:R_0603_1608Metric<br>Capacitor_SMD:C_0603_1608Metric<br>LED_SMD:LED_0603_1608Metric |
|
||||
| 0805 | Resistor_SMD:R_0805_2012Metric<br>Capacitor_SMD:C_0805_2012Metric |
|
||||
| 1206 | Resistor_SMD:R_1206_3216Metric<br>Capacitor_SMD:C_1206_3216Metric |
|
||||
| SOT-23 | Package_TO_SOT_SMD:SOT-23<br>Package_TO_SOT_SMD:SOT-23-3 |
|
||||
| SOT-23-5 | Package_TO_SOT_SMD:SOT-23-5 |
|
||||
| SOT-23-6 | Package_TO_SOT_SMD:SOT-23-6 |
|
||||
| SOT-223 | Package_TO_SOT_SMD:SOT-223 |
|
||||
| SOIC-8 | Package_SO:SOIC-8_3.9x4.9mm_P1.27mm |
|
||||
| QFN-20 | Package_DFN_QFN:QFN-20-1EP_4x4mm_P0.5mm_EP2.5x2.5mm |
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Always Use Basic Library Parts First
|
||||
|
||||
Basic library parts have **no assembly fee** ($0/part), while Extended parts cost **$3/part**.
|
||||
|
||||
```python
|
||||
# Filter for Basic parts only
|
||||
basic_parts = [p for p in results if p['is_basic']]
|
||||
```
|
||||
|
||||
### 2. Check Stock Availability
|
||||
|
||||
Ensure sufficient stock before committing to a design.
|
||||
|
||||
```python
|
||||
# Only use parts with >1000 stock
|
||||
high_stock = [p for p in results if p['stock'] > 1000]
|
||||
```
|
||||
|
||||
### 3. Compare Prices
|
||||
|
||||
Even within Basic library, prices vary significantly.
|
||||
|
||||
```python
|
||||
# Find cheapest option
|
||||
cheapest = min(results, key=lambda x: x.get('price1', 999))
|
||||
```
|
||||
|
||||
### 4. Use Standardized Packages
|
||||
|
||||
Stick to common packages (0402, 0603, 0805) for better availability and pricing.
|
||||
|
||||
### 5. Cache Database Locally
|
||||
|
||||
Download the full parts database once and search locally for faster results.
|
||||
|
||||
```python
|
||||
# Initial download (one-time, ~5-10 minutes)
|
||||
if not os.path.exists("data/jlcpcb_parts.db"):
|
||||
parts = client.download_all_components()
|
||||
db.import_jlcsearch_parts(parts)
|
||||
|
||||
# Subsequent searches use local database (instant)
|
||||
results = db.search_parts(...)
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### API Rate Limiting
|
||||
|
||||
JLCSearch is a community service. If you hit rate limits:
|
||||
|
||||
- Add delays between requests (`time.sleep(0.1)`)
|
||||
- Use the local database instead of repeated API calls
|
||||
- Download the full database once and work offline
|
||||
|
||||
### Missing Data
|
||||
|
||||
JLCSearch may not have all fields that official JLCPCB API provides:
|
||||
|
||||
- No datasheets (use manufacturer website)
|
||||
- Limited category information
|
||||
- No solder joint count
|
||||
|
||||
### Stock Discrepancies
|
||||
|
||||
Stock levels are updated periodically but may lag real-time JLCPCB data by a few hours.
|
||||
|
||||
## Official JLCPCB API (Alternative)
|
||||
|
||||
The project also includes an implementation of the official JLCPCB API with HMAC-SHA256 authentication. However, this requires:
|
||||
|
||||
1. API approval from JLCPCB (not all applications are approved)
|
||||
2. APP_ID, ACCESS_KEY, and SECRET_KEY credentials
|
||||
3. Previous order history with JLCPCB
|
||||
|
||||
To use the official API instead of JLCSearch:
|
||||
|
||||
```python
|
||||
from commands.jlcpcb import JLCPCBClient
|
||||
|
||||
# Set credentials in .env file:
|
||||
# JLCPCB_APP_ID=<your_app_id>
|
||||
# JLCPCB_API_KEY=<your_access_key>
|
||||
# JLCPCB_API_SECRET=<your_secret_key>
|
||||
|
||||
client = JLCPCBClient(app_id, access_key, secret_key)
|
||||
data = client.fetch_parts_page()
|
||||
```
|
||||
|
||||
**Note:** Most users should use JLCSearch public API instead, as it's freely available and requires no authentication.
|
||||
|
||||
## Credits
|
||||
|
||||
- **JLCSearch API**: https://jlcsearch.tscircuit.com/ (by [@tscircuit](https://github.com/tscircuit/jlcsearch))
|
||||
- **JLCParts Database**: https://github.com/yaqwsx/jlcparts (by [@yaqwsx](https://github.com/yaqwsx))
|
||||
- **JLCPCB**: https://jlcpcb.com/ (official parts library provider)
|
||||
|
||||
## License
|
||||
|
||||
This integration uses publicly available JLCPCB parts data via the JLCSearch community service. Users must comply with JLCPCB's terms of service when using this data for production PCB orders.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,7 @@ This document tracks known issues and provides workarounds where available.
|
||||
**Status:** KNOWN - Non-critical
|
||||
|
||||
**Symptoms:**
|
||||
|
||||
```
|
||||
AttributeError: 'BOARD' object has no attribute 'LT_USER'
|
||||
```
|
||||
@@ -31,10 +32,12 @@ AttributeError: 'BOARD' object has no attribute 'LT_USER'
|
||||
**Status:** KNOWN - Workaround available
|
||||
|
||||
**Symptoms:**
|
||||
|
||||
- Copper pours created but not filled automatically when using SWIG backend
|
||||
- Calling `ZONE_FILLER` via SWIG causes segfault
|
||||
|
||||
**Workaround Options:**
|
||||
|
||||
1. Use IPC backend (zones fill correctly via IPC)
|
||||
2. Open the board in KiCAD UI -- zones fill automatically when opened
|
||||
3. Use `refill_zones` tool (may still segfault in some configurations)
|
||||
@@ -48,6 +51,7 @@ AttributeError: 'BOARD' object has no attribute 'LT_USER'
|
||||
**Status:** BY DESIGN
|
||||
|
||||
**Symptoms:**
|
||||
|
||||
- MCP makes changes via SWIG backend
|
||||
- KiCAD does not show changes until file is reloaded
|
||||
|
||||
@@ -64,6 +68,7 @@ AttributeError: 'BOARD' object has no attribute 'LT_USER'
|
||||
**Status:** EXPERIMENTAL
|
||||
|
||||
**Known Limitations:**
|
||||
|
||||
- KiCAD must be running with IPC enabled (Preferences > Plugins > Enable IPC API Server)
|
||||
- Some commands fall back to SWIG (e.g., delete_trace)
|
||||
- Footprint loading uses hybrid approach (SWIG for library, IPC for placement)
|
||||
@@ -85,32 +90,40 @@ AttributeError: 'BOARD' object has no attribute 'LT_USER'
|
||||
## Recently Fixed (v2.2.0 - v2.2.3)
|
||||
|
||||
### B.Cu Footprint Routing (Fixed v2.2.3)
|
||||
|
||||
- `route_pad_to_pad` now correctly detects B.Cu footprints and inserts vias
|
||||
- KiCAD 9 SWIG `pad.GetLayerName()` always returned F.Cu for flipped footprints -- fixed using `footprint.GetLayer()`
|
||||
|
||||
### B.Cu Placement Hang (Fixed v2.2.3)
|
||||
|
||||
- Placing footprints on B.Cu no longer causes ~30s freeze
|
||||
- Fix: call `board.Add()` before `Flip()`
|
||||
|
||||
### Board Outline Rounded Corners (Fixed v2.2.3)
|
||||
|
||||
- `add_board_outline` now correctly applies cornerRadius for rounded_rectangle shape
|
||||
|
||||
### Project-Local Library Resolution (Fixed v2.2.2)
|
||||
|
||||
- `add_schematic_component` and `place_component` now search project-local sym-lib-table and fp-lib-table
|
||||
- Previously only global KiCAD library paths were searched
|
||||
|
||||
### Template File Corruption (Fixed v2.2.2)
|
||||
|
||||
- Removed invalid `;;` comment lines from template schematics
|
||||
- Restored KiCAD 9 format version (20250114) in templates
|
||||
|
||||
### copy_routing_pattern Empty Results (Fixed v2.2.2)
|
||||
|
||||
- Added geometric fallback when pads have no net assignments
|
||||
|
||||
### Schematic Component Corruption (Fixed v2.2.1)
|
||||
|
||||
- `add_schematic_component` no longer corrupts .kicad_sch files
|
||||
- Rewritten to use text manipulation instead of sexpdata formatting
|
||||
|
||||
### SWIG/UUID Comparison Bugs (Fixed v2.2.0)
|
||||
|
||||
- Fixed SwigPyObject UUID comparison
|
||||
- Fixed SWIG iterator invalidation after board.Remove()
|
||||
- Added board.SetModified() to prevent dangling pointer crashes
|
||||
@@ -136,6 +149,7 @@ If you encounter an issue not listed here:
|
||||
## General Workarounds
|
||||
|
||||
### Server Will Not Start
|
||||
|
||||
```bash
|
||||
# Check Python can import pcbnew
|
||||
python3 -c "import pcbnew; print(pcbnew.GetBuildVersion())"
|
||||
@@ -145,12 +159,14 @@ python3 python/utils/platform_helper.py
|
||||
```
|
||||
|
||||
### Commands Fail After Server Restart
|
||||
|
||||
```
|
||||
# Board reference is lost on restart
|
||||
# Always run open_project after server restart
|
||||
```
|
||||
|
||||
### KiCAD UI Does Not Show Changes (SWIG Mode)
|
||||
|
||||
```
|
||||
# File > Revert (or click reload prompt)
|
||||
# Or: Close and reopen file in KiCAD
|
||||
@@ -158,6 +174,7 @@ python3 python/utils/platform_helper.py
|
||||
```
|
||||
|
||||
### IPC Not Connecting
|
||||
|
||||
```
|
||||
# Ensure KiCAD is running
|
||||
# Enable IPC: Preferences > Plugins > Enable IPC API Server
|
||||
@@ -168,6 +185,7 @@ python3 python/utils/platform_helper.py
|
||||
---
|
||||
|
||||
**Need Help?**
|
||||
|
||||
- Check [IPC_BACKEND_STATUS.md](IPC_BACKEND_STATUS.md) for IPC details
|
||||
- Check logs: `~/.kicad-mcp/logs/kicad_interface.log`
|
||||
- Open an issue on GitHub
|
||||
|
||||
@@ -1,364 +1,390 @@
|
||||
# KiCAD Library Integration
|
||||
|
||||
**Status:** ✅ COMPLETE
|
||||
**Date:** 2026-03-21
|
||||
**Version:** 2.2.3+
|
||||
|
||||
## Overview
|
||||
|
||||
The KiCAD MCP Server includes full library integration for both footprints and symbols, enabling:
|
||||
- ✅ Automatic discovery of all installed KiCAD footprint libraries
|
||||
- ✅ Automatic discovery of KiCAD symbol libraries (including project-local)
|
||||
- ✅ Search and browse footprints/symbols across all libraries
|
||||
- ✅ Component placement using library footprints
|
||||
- ✅ Symbol creation and editing with project-local library support (v2.2.2+)
|
||||
- ✅ Support for both `Library:Footprint` and `Footprint` formats
|
||||
|
||||
## How It Works
|
||||
|
||||
### Library Discovery
|
||||
|
||||
The library system automatically discovers both footprint and symbol libraries:
|
||||
|
||||
**Footprint Libraries** - `LibraryManager` class:
|
||||
|
||||
1. **Parsing fp-lib-table files:**
|
||||
- Global: `~/.config/kicad/9.0/fp-lib-table`
|
||||
- Project-specific: `project-dir/fp-lib-table`
|
||||
|
||||
**Symbol Libraries** - `DynamicSymbolLoader` class (v2.2.2+):
|
||||
|
||||
1. **Parsing sym-lib-table files:**
|
||||
- Global: `~/.config/kicad/9.0/sym-lib-table`
|
||||
- Project-local: `project-dir/sym-lib-table` (added v2.2.2)
|
||||
|
||||
2. **Resolving environment variables:**
|
||||
- `${KICAD9_FOOTPRINT_DIR}` → `/usr/share/kicad/footprints`
|
||||
- `${K IPRJMOD}` → project directory
|
||||
- Supports custom paths
|
||||
|
||||
3. **Indexing footprints:**
|
||||
- Scans `.kicad_mod` files in each library
|
||||
- Caches results for performance
|
||||
- Provides fast search capabilities
|
||||
|
||||
### Supported Formats
|
||||
|
||||
**Library:Footprint format (recommended):**
|
||||
```json
|
||||
{
|
||||
"componentId": "Resistor_SMD:R_0603_1608Metric"
|
||||
}
|
||||
```
|
||||
|
||||
**Footprint-only format (searches all libraries):**
|
||||
```json
|
||||
{
|
||||
"componentId": "R_0603_1608Metric"
|
||||
}
|
||||
```
|
||||
|
||||
## New MCP Tools
|
||||
|
||||
### 1. `list_libraries`
|
||||
|
||||
List all available footprint libraries.
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"libraries": ["Resistor_SMD", "Capacitor_SMD", "LED_SMD", ...],
|
||||
"count": 153
|
||||
}
|
||||
```
|
||||
|
||||
### 2. `search_footprints`
|
||||
|
||||
Search for footprints matching a pattern.
|
||||
|
||||
**Parameters:**
|
||||
```json
|
||||
{
|
||||
"pattern": "*0603*", // Supports wildcards
|
||||
"limit": 20 // Optional, default: 20
|
||||
}
|
||||
```
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"footprints": [
|
||||
{
|
||||
"library": "Resistor_SMD",
|
||||
"footprint": "R_0603_1608Metric",
|
||||
"full_name": "Resistor_SMD:R_0603_1608Metric"
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3. `list_library_footprints`
|
||||
|
||||
List all footprints in a specific library.
|
||||
|
||||
**Parameters:**
|
||||
```json
|
||||
{
|
||||
"library": "Resistor_SMD"
|
||||
}
|
||||
```
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"library": "Resistor_SMD",
|
||||
"footprints": ["R_0402_1005Metric", "R_0603_1608Metric", ...],
|
||||
"count": 120
|
||||
}
|
||||
```
|
||||
|
||||
### 4. `get_footprint_info`
|
||||
|
||||
Get detailed information about a specific footprint.
|
||||
|
||||
**Parameters:**
|
||||
```json
|
||||
{
|
||||
"footprint": "Resistor_SMD:R_0603_1608Metric"
|
||||
}
|
||||
```
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"footprint_info": {
|
||||
"library": "Resistor_SMD",
|
||||
"footprint": "R_0603_1608Metric",
|
||||
"full_name": "Resistor_SMD:R_0603_1608Metric",
|
||||
"library_path": "/usr/share/kicad/footprints/Resistor_SMD.pretty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Updated Component Placement
|
||||
|
||||
The `place_component` tool now uses the library system:
|
||||
|
||||
```json
|
||||
{
|
||||
"componentId": "Resistor_SMD:R_0603_1608Metric", // Library:Footprint format
|
||||
"position": {"x": 50, "y": 40, "unit": "mm"},
|
||||
"reference": "R1",
|
||||
"value": "10k",
|
||||
"rotation": 0,
|
||||
"layer": "F.Cu"
|
||||
}
|
||||
```
|
||||
|
||||
**Features:**
|
||||
- ✅ Automatic footprint discovery across all libraries
|
||||
- ✅ Helpful error messages with suggestions
|
||||
- ✅ Supports KiCAD 9.0 API (EDA_ANGLE, GetFPIDAsString)
|
||||
|
||||
## Example Usage (Claude Code)
|
||||
|
||||
**Search for a resistor footprint:**
|
||||
```
|
||||
User: "Find me a 0603 resistor footprint"
|
||||
|
||||
Claude: [uses search_footprints tool with pattern "*R_0603*"]
|
||||
Found: Resistor_SMD:R_0603_1608Metric
|
||||
```
|
||||
|
||||
**Place a component:**
|
||||
```
|
||||
User: "Place a 10k 0603 resistor at 50,40mm"
|
||||
|
||||
Claude: [uses place_component with "Resistor_SMD:R_0603_1608Metric"]
|
||||
✅ Placed R1: 10k at (50, 40) mm
|
||||
```
|
||||
|
||||
**List available capacitors:**
|
||||
```
|
||||
User: "What capacitor footprints are available?"
|
||||
|
||||
Claude: [uses list_library_footprints with "Capacitor_SMD"]
|
||||
Found 103 capacitor footprints including:
|
||||
- C_0402_1005Metric
|
||||
- C_0603_1608Metric
|
||||
- C_0805_2012Metric
|
||||
...
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Custom Library Paths
|
||||
|
||||
The system automatically detects KiCAD installations, but you can add custom libraries:
|
||||
|
||||
1. **Via KiCAD Preferences:**
|
||||
- Open KiCAD → Preferences → Manage Footprint Libraries
|
||||
- Add your custom library paths
|
||||
- The MCP server will automatically discover them
|
||||
|
||||
2. **Via Project fp-lib-table:**
|
||||
- Create `fp-lib-table` in your project directory
|
||||
- Follow the KiCAD S-expression format
|
||||
|
||||
### Supported Platforms
|
||||
|
||||
- ✅ **Linux:** `/usr/share/kicad/footprints`, `~/.config/kicad/9.0/`
|
||||
- ✅ **Windows:** `C:/Program Files/KiCAD/*/share/kicad/footprints`
|
||||
- ✅ **macOS:** `/Applications/KiCad/KiCad.app/Contents/SharedSupport/footprints`
|
||||
|
||||
## KiCAD 9.0 API Compatibility
|
||||
|
||||
The library integration includes full KiCAD 9.0 API support:
|
||||
|
||||
### Fixed API Changes:
|
||||
1. ✅ `SetOrientation()` → now uses `EDA_ANGLE(degrees, DEGREES_T)`
|
||||
2. ✅ `GetOrientation()` → returns `EDA_ANGLE`, call `.AsDegrees()`
|
||||
3. ✅ `GetFootprintName()` → now `GetFPIDAsString()`
|
||||
|
||||
### Example Fixes:
|
||||
**Old (KiCAD 8.0):**
|
||||
```python
|
||||
module.SetOrientation(90 * 10) # Decidegrees
|
||||
rotation = module.GetOrientation() / 10
|
||||
```
|
||||
|
||||
**New (KiCAD 9.0):**
|
||||
```python
|
||||
angle = pcbnew.EDA_ANGLE(90, pcbnew.DEGREES_T)
|
||||
module.SetOrientation(angle)
|
||||
rotation = module.GetOrientation().AsDegrees()
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### LibraryManager Class
|
||||
|
||||
**Location:** `python/commands/library.py`
|
||||
|
||||
**Key Methods:**
|
||||
- `_load_libraries()` - Parse fp-lib-table files
|
||||
- `_parse_fp_lib_table()` - S-expression parser
|
||||
- `_resolve_uri()` - Handle environment variables
|
||||
- `find_footprint()` - Locate footprint in libraries
|
||||
- `search_footprints()` - Pattern-based search
|
||||
- `list_footprints()` - List library contents
|
||||
|
||||
**Performance:**
|
||||
- Libraries loaded once at startup
|
||||
- Footprint lists cached on first access
|
||||
- Fast search using Python regex
|
||||
- Minimal memory footprint
|
||||
|
||||
### Integration Points
|
||||
|
||||
1. **KiCADInterface (`kicad_interface.py`):**
|
||||
- Creates `FootprintLibraryManager` on init
|
||||
- Passes to `ComponentCommands`
|
||||
- Routes library commands
|
||||
|
||||
2. **ComponentCommands (`component.py`):**
|
||||
- Uses `LibraryManager.find_footprint()`
|
||||
- Provides suggestions on errors
|
||||
- Supports both lookup formats
|
||||
|
||||
3. **MCP Tools (`src/tools/index.ts`):**
|
||||
- Exposes 4 new library tools
|
||||
- Fully typed TypeScript interfaces
|
||||
- Documented parameters
|
||||
|
||||
## Testing
|
||||
|
||||
**Test Coverage:**
|
||||
- ✅ Library path discovery (Linux/Windows/macOS)
|
||||
- ✅ fp-lib-table parsing
|
||||
- ✅ Environment variable resolution
|
||||
- ✅ Footprint search and lookup
|
||||
- ✅ Component placement integration
|
||||
- ✅ Error handling and suggestions
|
||||
|
||||
**Verified With:**
|
||||
- KiCAD 9.0.5 on Ubuntu 24.04
|
||||
- 153 standard libraries (8,000+ footprints)
|
||||
- pcbnew Python API
|
||||
|
||||
## Known Limitations
|
||||
|
||||
1. **Library Updates:** Changes to fp-lib-table require server restart
|
||||
2. **Custom Libraries:** Must be added via KiCAD preferences first
|
||||
3. **Network Libraries:** GitHub-based libraries not yet supported
|
||||
4. **Search Performance:** Linear search across all libraries (fast for <200 libs)
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- [ ] Watch fp-lib-table for changes (auto-reload)
|
||||
- [ ] Support for GitHub library URLs
|
||||
- [ ] Fuzzy search for typo tolerance
|
||||
- [ ] Library metadata (descriptions, categories)
|
||||
- [ ] Footprint previews (SVG/PNG generation)
|
||||
- [ ] Most-used footprints caching
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "No footprint libraries found"
|
||||
|
||||
**Cause:** fp-lib-table not found or empty
|
||||
|
||||
**Solution:**
|
||||
1. Verify KiCAD is installed
|
||||
2. Open KiCAD and ensure libraries are configured
|
||||
3. Check `~/.config/kicad/9.0/fp-lib-table` exists
|
||||
|
||||
### "Footprint not found"
|
||||
|
||||
**Cause:** Footprint doesn't exist or library not loaded
|
||||
|
||||
**Solution:**
|
||||
1. Use `search_footprints` to find similar footprints
|
||||
2. Check library name is correct
|
||||
3. Verify library is in fp-lib-table
|
||||
|
||||
### "Failed to load footprint"
|
||||
|
||||
**Cause:** Corrupt .kicad_mod file or permissions issue
|
||||
|
||||
**Solution:**
|
||||
1. Check file permissions on library directories
|
||||
2. Reinstall KiCAD libraries if corrupt
|
||||
3. Check logs for detailed error
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [ROADMAP.md](./ROADMAP.md) - Week 2 planning
|
||||
- [STATUS_SUMMARY.md](./STATUS_SUMMARY.md) - Current implementation status
|
||||
- [API.md](./API.md) - Full MCP API reference
|
||||
- [KiCAD Documentation](https://docs.kicad.org/9.0/en/pcbnew/pcbnew.html) - Official KiCAD docs
|
||||
|
||||
## Changelog
|
||||
|
||||
**2026-03-21 - v2.2.3+**
|
||||
- ✅ Project-local symbol library support (v2.2.2)
|
||||
- ✅ Project-local footprint library support (v2.2.2)
|
||||
- ✅ Implemented LibraryManager class
|
||||
- ✅ Added 4 new MCP library tools
|
||||
- ✅ Updated component placement to use libraries
|
||||
- ✅ Fixed all KiCAD 9.0 API compatibility issues
|
||||
- ✅ Tested end-to-end with real components
|
||||
- ✅ Created comprehensive documentation
|
||||
|
||||
---
|
||||
|
||||
**Status: PRODUCTION READY** 🎉
|
||||
|
||||
The library integration is complete and fully functional. Component placement now works seamlessly with KiCAD's footprint libraries, enabling AI-driven PCB design with real, validated components.
|
||||
# KiCAD Library Integration
|
||||
|
||||
**Status:** ✅ COMPLETE
|
||||
**Date:** 2026-03-21
|
||||
**Version:** 2.2.3+
|
||||
|
||||
## Overview
|
||||
|
||||
The KiCAD MCP Server includes full library integration for both footprints and symbols, enabling:
|
||||
|
||||
- ✅ Automatic discovery of all installed KiCAD footprint libraries
|
||||
- ✅ Automatic discovery of KiCAD symbol libraries (including project-local)
|
||||
- ✅ Search and browse footprints/symbols across all libraries
|
||||
- ✅ Component placement using library footprints
|
||||
- ✅ Symbol creation and editing with project-local library support (v2.2.2+)
|
||||
- ✅ Support for both `Library:Footprint` and `Footprint` formats
|
||||
|
||||
## How It Works
|
||||
|
||||
### Library Discovery
|
||||
|
||||
The library system automatically discovers both footprint and symbol libraries:
|
||||
|
||||
**Footprint Libraries** - `LibraryManager` class:
|
||||
|
||||
1. **Parsing fp-lib-table files:**
|
||||
- Global: `~/.config/kicad/9.0/fp-lib-table`
|
||||
- Project-specific: `project-dir/fp-lib-table`
|
||||
|
||||
**Symbol Libraries** - `DynamicSymbolLoader` class (v2.2.2+):
|
||||
|
||||
1. **Parsing sym-lib-table files:**
|
||||
- Global: `~/.config/kicad/9.0/sym-lib-table`
|
||||
- Project-local: `project-dir/sym-lib-table` (added v2.2.2)
|
||||
|
||||
2. **Resolving environment variables:**
|
||||
- `${KICAD9_FOOTPRINT_DIR}` → `/usr/share/kicad/footprints`
|
||||
- `${K IPRJMOD}` → project directory
|
||||
- Supports custom paths
|
||||
|
||||
3. **Indexing footprints:**
|
||||
- Scans `.kicad_mod` files in each library
|
||||
- Caches results for performance
|
||||
- Provides fast search capabilities
|
||||
|
||||
### Supported Formats
|
||||
|
||||
**Library:Footprint format (recommended):**
|
||||
|
||||
```json
|
||||
{
|
||||
"componentId": "Resistor_SMD:R_0603_1608Metric"
|
||||
}
|
||||
```
|
||||
|
||||
**Footprint-only format (searches all libraries):**
|
||||
|
||||
```json
|
||||
{
|
||||
"componentId": "R_0603_1608Metric"
|
||||
}
|
||||
```
|
||||
|
||||
## New MCP Tools
|
||||
|
||||
### 1. `list_libraries`
|
||||
|
||||
List all available footprint libraries.
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Returns:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"libraries": ["Resistor_SMD", "Capacitor_SMD", "LED_SMD", ...],
|
||||
"count": 153
|
||||
}
|
||||
```
|
||||
|
||||
### 2. `search_footprints`
|
||||
|
||||
Search for footprints matching a pattern.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
```json
|
||||
{
|
||||
"pattern": "*0603*", // Supports wildcards
|
||||
"limit": 20 // Optional, default: 20
|
||||
}
|
||||
```
|
||||
|
||||
**Returns:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"footprints": [
|
||||
{
|
||||
"library": "Resistor_SMD",
|
||||
"footprint": "R_0603_1608Metric",
|
||||
"full_name": "Resistor_SMD:R_0603_1608Metric"
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3. `list_library_footprints`
|
||||
|
||||
List all footprints in a specific library.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
```json
|
||||
{
|
||||
"library": "Resistor_SMD"
|
||||
}
|
||||
```
|
||||
|
||||
**Returns:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"library": "Resistor_SMD",
|
||||
"footprints": ["R_0402_1005Metric", "R_0603_1608Metric", ...],
|
||||
"count": 120
|
||||
}
|
||||
```
|
||||
|
||||
### 4. `get_footprint_info`
|
||||
|
||||
Get detailed information about a specific footprint.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
```json
|
||||
{
|
||||
"footprint": "Resistor_SMD:R_0603_1608Metric"
|
||||
}
|
||||
```
|
||||
|
||||
**Returns:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"footprint_info": {
|
||||
"library": "Resistor_SMD",
|
||||
"footprint": "R_0603_1608Metric",
|
||||
"full_name": "Resistor_SMD:R_0603_1608Metric",
|
||||
"library_path": "/usr/share/kicad/footprints/Resistor_SMD.pretty"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Updated Component Placement
|
||||
|
||||
The `place_component` tool now uses the library system:
|
||||
|
||||
```json
|
||||
{
|
||||
"componentId": "Resistor_SMD:R_0603_1608Metric", // Library:Footprint format
|
||||
"position": { "x": 50, "y": 40, "unit": "mm" },
|
||||
"reference": "R1",
|
||||
"value": "10k",
|
||||
"rotation": 0,
|
||||
"layer": "F.Cu"
|
||||
}
|
||||
```
|
||||
|
||||
**Features:**
|
||||
|
||||
- ✅ Automatic footprint discovery across all libraries
|
||||
- ✅ Helpful error messages with suggestions
|
||||
- ✅ Supports KiCAD 9.0 API (EDA_ANGLE, GetFPIDAsString)
|
||||
|
||||
## Example Usage (Claude Code)
|
||||
|
||||
**Search for a resistor footprint:**
|
||||
|
||||
```
|
||||
User: "Find me a 0603 resistor footprint"
|
||||
|
||||
Claude: [uses search_footprints tool with pattern "*R_0603*"]
|
||||
Found: Resistor_SMD:R_0603_1608Metric
|
||||
```
|
||||
|
||||
**Place a component:**
|
||||
|
||||
```
|
||||
User: "Place a 10k 0603 resistor at 50,40mm"
|
||||
|
||||
Claude: [uses place_component with "Resistor_SMD:R_0603_1608Metric"]
|
||||
✅ Placed R1: 10k at (50, 40) mm
|
||||
```
|
||||
|
||||
**List available capacitors:**
|
||||
|
||||
```
|
||||
User: "What capacitor footprints are available?"
|
||||
|
||||
Claude: [uses list_library_footprints with "Capacitor_SMD"]
|
||||
Found 103 capacitor footprints including:
|
||||
- C_0402_1005Metric
|
||||
- C_0603_1608Metric
|
||||
- C_0805_2012Metric
|
||||
...
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Custom Library Paths
|
||||
|
||||
The system automatically detects KiCAD installations, but you can add custom libraries:
|
||||
|
||||
1. **Via KiCAD Preferences:**
|
||||
- Open KiCAD → Preferences → Manage Footprint Libraries
|
||||
- Add your custom library paths
|
||||
- The MCP server will automatically discover them
|
||||
|
||||
2. **Via Project fp-lib-table:**
|
||||
- Create `fp-lib-table` in your project directory
|
||||
- Follow the KiCAD S-expression format
|
||||
|
||||
### Supported Platforms
|
||||
|
||||
- ✅ **Linux:** `/usr/share/kicad/footprints`, `~/.config/kicad/9.0/`
|
||||
- ✅ **Windows:** `C:/Program Files/KiCAD/*/share/kicad/footprints`
|
||||
- ✅ **macOS:** `/Applications/KiCad/KiCad.app/Contents/SharedSupport/footprints`
|
||||
|
||||
## KiCAD 9.0 API Compatibility
|
||||
|
||||
The library integration includes full KiCAD 9.0 API support:
|
||||
|
||||
### Fixed API Changes:
|
||||
|
||||
1. ✅ `SetOrientation()` → now uses `EDA_ANGLE(degrees, DEGREES_T)`
|
||||
2. ✅ `GetOrientation()` → returns `EDA_ANGLE`, call `.AsDegrees()`
|
||||
3. ✅ `GetFootprintName()` → now `GetFPIDAsString()`
|
||||
|
||||
### Example Fixes:
|
||||
|
||||
**Old (KiCAD 8.0):**
|
||||
|
||||
```python
|
||||
module.SetOrientation(90 * 10) # Decidegrees
|
||||
rotation = module.GetOrientation() / 10
|
||||
```
|
||||
|
||||
**New (KiCAD 9.0):**
|
||||
|
||||
```python
|
||||
angle = pcbnew.EDA_ANGLE(90, pcbnew.DEGREES_T)
|
||||
module.SetOrientation(angle)
|
||||
rotation = module.GetOrientation().AsDegrees()
|
||||
```
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### LibraryManager Class
|
||||
|
||||
**Location:** `python/commands/library.py`
|
||||
|
||||
**Key Methods:**
|
||||
|
||||
- `_load_libraries()` - Parse fp-lib-table files
|
||||
- `_parse_fp_lib_table()` - S-expression parser
|
||||
- `_resolve_uri()` - Handle environment variables
|
||||
- `find_footprint()` - Locate footprint in libraries
|
||||
- `search_footprints()` - Pattern-based search
|
||||
- `list_footprints()` - List library contents
|
||||
|
||||
**Performance:**
|
||||
|
||||
- Libraries loaded once at startup
|
||||
- Footprint lists cached on first access
|
||||
- Fast search using Python regex
|
||||
- Minimal memory footprint
|
||||
|
||||
### Integration Points
|
||||
|
||||
1. **KiCADInterface (`kicad_interface.py`):**
|
||||
- Creates `FootprintLibraryManager` on init
|
||||
- Passes to `ComponentCommands`
|
||||
- Routes library commands
|
||||
|
||||
2. **ComponentCommands (`component.py`):**
|
||||
- Uses `LibraryManager.find_footprint()`
|
||||
- Provides suggestions on errors
|
||||
- Supports both lookup formats
|
||||
|
||||
3. **MCP Tools (`src/tools/index.ts`):**
|
||||
- Exposes 4 new library tools
|
||||
- Fully typed TypeScript interfaces
|
||||
- Documented parameters
|
||||
|
||||
## Testing
|
||||
|
||||
**Test Coverage:**
|
||||
|
||||
- ✅ Library path discovery (Linux/Windows/macOS)
|
||||
- ✅ fp-lib-table parsing
|
||||
- ✅ Environment variable resolution
|
||||
- ✅ Footprint search and lookup
|
||||
- ✅ Component placement integration
|
||||
- ✅ Error handling and suggestions
|
||||
|
||||
**Verified With:**
|
||||
|
||||
- KiCAD 9.0.5 on Ubuntu 24.04
|
||||
- 153 standard libraries (8,000+ footprints)
|
||||
- pcbnew Python API
|
||||
|
||||
## Known Limitations
|
||||
|
||||
1. **Library Updates:** Changes to fp-lib-table require server restart
|
||||
2. **Custom Libraries:** Must be added via KiCAD preferences first
|
||||
3. **Network Libraries:** GitHub-based libraries not yet supported
|
||||
4. **Search Performance:** Linear search across all libraries (fast for <200 libs)
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- [ ] Watch fp-lib-table for changes (auto-reload)
|
||||
- [ ] Support for GitHub library URLs
|
||||
- [ ] Fuzzy search for typo tolerance
|
||||
- [ ] Library metadata (descriptions, categories)
|
||||
- [ ] Footprint previews (SVG/PNG generation)
|
||||
- [ ] Most-used footprints caching
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "No footprint libraries found"
|
||||
|
||||
**Cause:** fp-lib-table not found or empty
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Verify KiCAD is installed
|
||||
2. Open KiCAD and ensure libraries are configured
|
||||
3. Check `~/.config/kicad/9.0/fp-lib-table` exists
|
||||
|
||||
### "Footprint not found"
|
||||
|
||||
**Cause:** Footprint doesn't exist or library not loaded
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Use `search_footprints` to find similar footprints
|
||||
2. Check library name is correct
|
||||
3. Verify library is in fp-lib-table
|
||||
|
||||
### "Failed to load footprint"
|
||||
|
||||
**Cause:** Corrupt .kicad_mod file or permissions issue
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Check file permissions on library directories
|
||||
2. Reinstall KiCAD libraries if corrupt
|
||||
3. Check logs for detailed error
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [ROADMAP.md](./ROADMAP.md) - Week 2 planning
|
||||
- [STATUS_SUMMARY.md](./STATUS_SUMMARY.md) - Current implementation status
|
||||
- [API.md](./API.md) - Full MCP API reference
|
||||
- [KiCAD Documentation](https://docs.kicad.org/9.0/en/pcbnew/pcbnew.html) - Official KiCAD docs
|
||||
|
||||
## Changelog
|
||||
|
||||
**2026-03-21 - v2.2.3+**
|
||||
|
||||
- ✅ Project-local symbol library support (v2.2.2)
|
||||
- ✅ Project-local footprint library support (v2.2.2)
|
||||
- ✅ Implemented LibraryManager class
|
||||
- ✅ Added 4 new MCP library tools
|
||||
- ✅ Updated component placement to use libraries
|
||||
- ✅ Fixed all KiCAD 9.0 API compatibility issues
|
||||
- ✅ Tested end-to-end with real components
|
||||
- ✅ Created comprehensive documentation
|
||||
|
||||
---
|
||||
|
||||
**Status: PRODUCTION READY** 🎉
|
||||
|
||||
The library integration is complete and fully functional. Component placement now works seamlessly with KiCAD's footprint libraries, enabling AI-driven PCB design with real, validated components.
|
||||
|
||||
@@ -1,313 +1,336 @@
|
||||
# Linux Compatibility Audit Report
|
||||
**Date:** 2025-10-25
|
||||
**Target Platform:** Ubuntu 24.04 LTS (primary), Fedora, Arch (secondary)
|
||||
**Current Status:** Windows-optimized, partial Linux support
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
The KiCAD MCP Server was originally developed for Windows and has several compatibility issues preventing smooth operation on Linux. This audit identifies all platform-specific issues and provides remediation priorities.
|
||||
|
||||
**Overall Status:** 🟡 **PARTIAL COMPATIBILITY**
|
||||
- ✅ TypeScript server: Good cross-platform support
|
||||
- 🟡 Python interface: Mixed (some hardcoded paths)
|
||||
- ❌ Configuration: Windows-specific examples
|
||||
- ❌ Documentation: Windows-only instructions
|
||||
|
||||
---
|
||||
|
||||
## Critical Issues (P0 - Must Fix)
|
||||
|
||||
### 1. Hardcoded Windows Paths in Config Examples
|
||||
**File:** `config/claude-desktop-config.json`
|
||||
```json
|
||||
"cwd": "c:/repo/KiCAD-MCP",
|
||||
"PYTHONPATH": "C:/Program Files/KiCad/9.0/lib/python3/dist-packages"
|
||||
```
|
||||
|
||||
**Impact:** Config file won't work on Linux without manual editing
|
||||
**Fix:** Create platform-specific config templates
|
||||
**Priority:** P0
|
||||
|
||||
---
|
||||
|
||||
### 2. Library Search Paths (Mixed Approach)
|
||||
**File:** `python/commands/library_schematic.py:16`
|
||||
```python
|
||||
search_paths = [
|
||||
"C:/Program Files/KiCad/*/share/kicad/symbols/*.kicad_sym", # Windows
|
||||
"/usr/share/kicad/symbols/*.kicad_sym", # Linux
|
||||
"/Applications/KiCad/KiCad.app/Contents/SharedSupport/symbols/*.kicad_sym", # macOS
|
||||
]
|
||||
```
|
||||
|
||||
**Impact:** Works but inefficient (checks all platforms)
|
||||
**Fix:** Auto-detect platform and use appropriate paths
|
||||
**Priority:** P0
|
||||
|
||||
---
|
||||
|
||||
### 3. Python Path Detection
|
||||
**File:** `python/kicad_interface.py:38-45`
|
||||
```python
|
||||
kicad_paths = [
|
||||
os.path.join(os.path.dirname(sys.executable), 'Lib', 'site-packages'),
|
||||
os.path.dirname(sys.executable)
|
||||
]
|
||||
```
|
||||
|
||||
**Impact:** Paths use Windows convention ('Lib' is 'lib' on Linux)
|
||||
**Fix:** Platform-specific path detection
|
||||
**Priority:** P0
|
||||
|
||||
---
|
||||
|
||||
## High Priority Issues (P1)
|
||||
|
||||
### 4. Documentation is Windows-Only
|
||||
**Files:** `README.md`, installation instructions
|
||||
|
||||
**Issues:**
|
||||
- Installation paths reference `C:\Program Files`
|
||||
- VSCode settings path is Windows format
|
||||
- No Linux-specific troubleshooting
|
||||
|
||||
**Fix:** Add Linux installation section
|
||||
**Priority:** P1
|
||||
|
||||
---
|
||||
|
||||
### 5. Missing Python Dependencies Documentation
|
||||
**File:** None (no requirements.txt)
|
||||
|
||||
**Impact:** Users don't know what Python packages to install
|
||||
**Fix:** Create `requirements.txt` and `requirements-dev.txt`
|
||||
**Priority:** P1
|
||||
|
||||
---
|
||||
|
||||
### 6. Path Handling Uses os.path Instead of pathlib
|
||||
**Files:** All Python files (11 files)
|
||||
|
||||
**Impact:** Code is less readable and more error-prone
|
||||
**Fix:** Migrate to `pathlib.Path` throughout
|
||||
**Priority:** P1
|
||||
|
||||
---
|
||||
|
||||
## Medium Priority Issues (P2)
|
||||
|
||||
### 7. No Linux-Specific Testing
|
||||
**Impact:** Can't verify Linux compatibility
|
||||
**Fix:** Add GitHub Actions with Ubuntu runner
|
||||
**Priority:** P2
|
||||
|
||||
---
|
||||
|
||||
### 8. Log File Paths May Differ
|
||||
**File:** `src/logger.ts:13`
|
||||
```typescript
|
||||
const DEFAULT_LOG_DIR = join(os.homedir(), '.kicad-mcp', 'logs');
|
||||
```
|
||||
|
||||
**Impact:** `.kicad-mcp` is okay for Linux, but best practice is `~/.config/kicad-mcp`
|
||||
**Fix:** Use XDG Base Directory spec on Linux
|
||||
**Priority:** P2
|
||||
|
||||
---
|
||||
|
||||
### 9. No Bash/Shell Scripts for Linux
|
||||
**Impact:** Manual setup is harder on Linux
|
||||
**Fix:** Create `install.sh` and `run.sh` scripts
|
||||
**Priority:** P2
|
||||
|
||||
---
|
||||
|
||||
## Low Priority Issues (P3)
|
||||
|
||||
### 10. TypeScript Build Uses Windows Conventions
|
||||
**File:** `package.json`
|
||||
|
||||
**Impact:** Works but could be more Linux-friendly
|
||||
**Fix:** Add platform-specific build scripts
|
||||
**Priority:** P3
|
||||
|
||||
---
|
||||
|
||||
## Positive Findings ✅
|
||||
|
||||
### What's Already Good:
|
||||
|
||||
1. **TypeScript Path Handling** - Uses `path.join()` and `os.homedir()` correctly
|
||||
2. **Node.js Dependencies** - All cross-platform
|
||||
3. **JSON Communication** - Platform-agnostic
|
||||
4. **Python Base** - Python 3 works identically on all platforms
|
||||
|
||||
---
|
||||
|
||||
## Recommended Fixes - Priority Order
|
||||
|
||||
### **Week 1 - Critical Fixes (P0)**
|
||||
|
||||
1. **Create Platform-Specific Config Templates**
|
||||
```bash
|
||||
config/
|
||||
├── linux-config.example.json
|
||||
├── windows-config.example.json
|
||||
└── macos-config.example.json
|
||||
```
|
||||
|
||||
2. **Fix Python Path Detection**
|
||||
```python
|
||||
# Detect platform and set appropriate paths
|
||||
import platform
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
if platform.system() == "Windows":
|
||||
kicad_paths = [Path(sys.executable).parent / "Lib" / "site-packages"]
|
||||
else: # Linux/Mac
|
||||
kicad_paths = [Path(sys.executable).parent / "lib" / "python3.X" / "site-packages"]
|
||||
```
|
||||
|
||||
3. **Update Library Search Path Logic**
|
||||
```python
|
||||
def get_kicad_library_paths():
|
||||
"""Auto-detect KiCAD library paths based on platform"""
|
||||
system = platform.system()
|
||||
if system == "Windows":
|
||||
return ["C:/Program Files/KiCad/*/share/kicad/symbols/*.kicad_sym"]
|
||||
elif system == "Linux":
|
||||
return ["/usr/share/kicad/symbols/*.kicad_sym"]
|
||||
elif system == "Darwin": # macOS
|
||||
return ["/Applications/KiCad/KiCad.app/Contents/SharedSupport/symbols/*.kicad_sym"]
|
||||
```
|
||||
|
||||
### **Week 1 - High Priority (P1)**
|
||||
|
||||
4. **Create requirements.txt**
|
||||
```txt
|
||||
# requirements.txt
|
||||
kicad-skip>=0.1.0
|
||||
Pillow>=9.0.0
|
||||
cairosvg>=2.7.0
|
||||
colorlog>=6.7.0
|
||||
```
|
||||
|
||||
5. **Add Linux Installation Documentation**
|
||||
- Ubuntu/Debian instructions
|
||||
- Fedora/RHEL instructions
|
||||
- Arch Linux instructions
|
||||
|
||||
6. **Migrate to pathlib**
|
||||
- Convert all `os.path` calls to `Path`
|
||||
- More Pythonic and readable
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### Ubuntu 24.04 LTS Testing
|
||||
- [ ] Install KiCAD 9.0 from official PPA
|
||||
- [ ] Install Node.js 18+ from NodeSource
|
||||
- [ ] Clone repository
|
||||
- [ ] Run `npm install`
|
||||
- [ ] Run `npm run build`
|
||||
- [ ] Configure MCP settings (Cline)
|
||||
- [ ] Test: Create project
|
||||
- [ ] Test: Place components
|
||||
- [ ] Test: Export Gerbers
|
||||
|
||||
### Fedora Testing
|
||||
- [ ] Install KiCAD from Fedora repos
|
||||
- [ ] Test same workflow
|
||||
|
||||
### Arch Testing
|
||||
- [ ] Install KiCAD from AUR
|
||||
- [ ] Test same workflow
|
||||
|
||||
---
|
||||
|
||||
## Platform Detection Helper
|
||||
|
||||
Create `python/utils/platform_helper.py`:
|
||||
|
||||
```python
|
||||
"""Platform detection and path utilities"""
|
||||
import platform
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
class PlatformHelper:
|
||||
@staticmethod
|
||||
def is_windows() -> bool:
|
||||
return platform.system() == "Windows"
|
||||
|
||||
@staticmethod
|
||||
def is_linux() -> bool:
|
||||
return platform.system() == "Linux"
|
||||
|
||||
@staticmethod
|
||||
def is_macos() -> bool:
|
||||
return platform.system() == "Darwin"
|
||||
|
||||
@staticmethod
|
||||
def get_kicad_python_path() -> Path:
|
||||
"""Get KiCAD Python dist-packages path"""
|
||||
if PlatformHelper.is_windows():
|
||||
return Path("C:/Program Files/KiCad/9.0/lib/python3/dist-packages")
|
||||
elif PlatformHelper.is_linux():
|
||||
# Common Linux paths
|
||||
candidates = [
|
||||
Path("/usr/lib/kicad/lib/python3/dist-packages"),
|
||||
Path("/usr/share/kicad/scripting/plugins"),
|
||||
]
|
||||
for path in candidates:
|
||||
if path.exists():
|
||||
return path
|
||||
elif PlatformHelper.is_macos():
|
||||
return Path("/Applications/KiCad/KiCad.app/Contents/Frameworks/Python.framework/Versions/3.X/lib/python3.X/site-packages")
|
||||
|
||||
raise RuntimeError(f"Could not find KiCAD Python path for {platform.system()}")
|
||||
|
||||
@staticmethod
|
||||
def get_config_dir() -> Path:
|
||||
"""Get appropriate config directory"""
|
||||
if PlatformHelper.is_windows():
|
||||
return Path.home() / ".kicad-mcp"
|
||||
elif PlatformHelper.is_linux():
|
||||
# Use XDG Base Directory specification
|
||||
xdg_config = os.environ.get("XDG_CONFIG_HOME")
|
||||
if xdg_config:
|
||||
return Path(xdg_config) / "kicad-mcp"
|
||||
return Path.home() / ".config" / "kicad-mcp"
|
||||
elif PlatformHelper.is_macos():
|
||||
return Path.home() / "Library" / "Application Support" / "kicad-mcp"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
✅ Server starts on Ubuntu 24.04 LTS without errors
|
||||
✅ Can create and manipulate KiCAD projects
|
||||
✅ CI/CD pipeline tests on Linux
|
||||
✅ Documentation includes Linux setup
|
||||
✅ All tests pass on Linux
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Implement P0 fixes (this week)
|
||||
2. Set up GitHub Actions CI/CD
|
||||
3. Test on Ubuntu 24.04 LTS
|
||||
4. Document Linux-specific issues
|
||||
5. Create installation scripts
|
||||
|
||||
---
|
||||
|
||||
**Audited by:** Claude Code
|
||||
**Review Status:** ✅ Complete
|
||||
# Linux Compatibility Audit Report
|
||||
|
||||
**Date:** 2025-10-25
|
||||
**Target Platform:** Ubuntu 24.04 LTS (primary), Fedora, Arch (secondary)
|
||||
**Current Status:** Windows-optimized, partial Linux support
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
The KiCAD MCP Server was originally developed for Windows and has several compatibility issues preventing smooth operation on Linux. This audit identifies all platform-specific issues and provides remediation priorities.
|
||||
|
||||
**Overall Status:** 🟡 **PARTIAL COMPATIBILITY**
|
||||
|
||||
- ✅ TypeScript server: Good cross-platform support
|
||||
- 🟡 Python interface: Mixed (some hardcoded paths)
|
||||
- ❌ Configuration: Windows-specific examples
|
||||
- ❌ Documentation: Windows-only instructions
|
||||
|
||||
---
|
||||
|
||||
## Critical Issues (P0 - Must Fix)
|
||||
|
||||
### 1. Hardcoded Windows Paths in Config Examples
|
||||
|
||||
**File:** `config/claude-desktop-config.json`
|
||||
|
||||
```json
|
||||
"cwd": "c:/repo/KiCAD-MCP",
|
||||
"PYTHONPATH": "C:/Program Files/KiCad/9.0/lib/python3/dist-packages"
|
||||
```
|
||||
|
||||
**Impact:** Config file won't work on Linux without manual editing
|
||||
**Fix:** Create platform-specific config templates
|
||||
**Priority:** P0
|
||||
|
||||
---
|
||||
|
||||
### 2. Library Search Paths (Mixed Approach)
|
||||
|
||||
**File:** `python/commands/library_schematic.py:16`
|
||||
|
||||
```python
|
||||
search_paths = [
|
||||
"C:/Program Files/KiCad/*/share/kicad/symbols/*.kicad_sym", # Windows
|
||||
"/usr/share/kicad/symbols/*.kicad_sym", # Linux
|
||||
"/Applications/KiCad/KiCad.app/Contents/SharedSupport/symbols/*.kicad_sym", # macOS
|
||||
]
|
||||
```
|
||||
|
||||
**Impact:** Works but inefficient (checks all platforms)
|
||||
**Fix:** Auto-detect platform and use appropriate paths
|
||||
**Priority:** P0
|
||||
|
||||
---
|
||||
|
||||
### 3. Python Path Detection
|
||||
|
||||
**File:** `python/kicad_interface.py:38-45`
|
||||
|
||||
```python
|
||||
kicad_paths = [
|
||||
os.path.join(os.path.dirname(sys.executable), 'Lib', 'site-packages'),
|
||||
os.path.dirname(sys.executable)
|
||||
]
|
||||
```
|
||||
|
||||
**Impact:** Paths use Windows convention ('Lib' is 'lib' on Linux)
|
||||
**Fix:** Platform-specific path detection
|
||||
**Priority:** P0
|
||||
|
||||
---
|
||||
|
||||
## High Priority Issues (P1)
|
||||
|
||||
### 4. Documentation is Windows-Only
|
||||
|
||||
**Files:** `README.md`, installation instructions
|
||||
|
||||
**Issues:**
|
||||
|
||||
- Installation paths reference `C:\Program Files`
|
||||
- VSCode settings path is Windows format
|
||||
- No Linux-specific troubleshooting
|
||||
|
||||
**Fix:** Add Linux installation section
|
||||
**Priority:** P1
|
||||
|
||||
---
|
||||
|
||||
### 5. Missing Python Dependencies Documentation
|
||||
|
||||
**File:** None (no requirements.txt)
|
||||
|
||||
**Impact:** Users don't know what Python packages to install
|
||||
**Fix:** Create `requirements.txt` and `requirements-dev.txt`
|
||||
**Priority:** P1
|
||||
|
||||
---
|
||||
|
||||
### 6. Path Handling Uses os.path Instead of pathlib
|
||||
|
||||
**Files:** All Python files (11 files)
|
||||
|
||||
**Impact:** Code is less readable and more error-prone
|
||||
**Fix:** Migrate to `pathlib.Path` throughout
|
||||
**Priority:** P1
|
||||
|
||||
---
|
||||
|
||||
## Medium Priority Issues (P2)
|
||||
|
||||
### 7. No Linux-Specific Testing
|
||||
|
||||
**Impact:** Can't verify Linux compatibility
|
||||
**Fix:** Add GitHub Actions with Ubuntu runner
|
||||
**Priority:** P2
|
||||
|
||||
---
|
||||
|
||||
### 8. Log File Paths May Differ
|
||||
|
||||
**File:** `src/logger.ts:13`
|
||||
|
||||
```typescript
|
||||
const DEFAULT_LOG_DIR = join(os.homedir(), ".kicad-mcp", "logs");
|
||||
```
|
||||
|
||||
**Impact:** `.kicad-mcp` is okay for Linux, but best practice is `~/.config/kicad-mcp`
|
||||
**Fix:** Use XDG Base Directory spec on Linux
|
||||
**Priority:** P2
|
||||
|
||||
---
|
||||
|
||||
### 9. No Bash/Shell Scripts for Linux
|
||||
|
||||
**Impact:** Manual setup is harder on Linux
|
||||
**Fix:** Create `install.sh` and `run.sh` scripts
|
||||
**Priority:** P2
|
||||
|
||||
---
|
||||
|
||||
## Low Priority Issues (P3)
|
||||
|
||||
### 10. TypeScript Build Uses Windows Conventions
|
||||
|
||||
**File:** `package.json`
|
||||
|
||||
**Impact:** Works but could be more Linux-friendly
|
||||
**Fix:** Add platform-specific build scripts
|
||||
**Priority:** P3
|
||||
|
||||
---
|
||||
|
||||
## Positive Findings ✅
|
||||
|
||||
### What's Already Good:
|
||||
|
||||
1. **TypeScript Path Handling** - Uses `path.join()` and `os.homedir()` correctly
|
||||
2. **Node.js Dependencies** - All cross-platform
|
||||
3. **JSON Communication** - Platform-agnostic
|
||||
4. **Python Base** - Python 3 works identically on all platforms
|
||||
|
||||
---
|
||||
|
||||
## Recommended Fixes - Priority Order
|
||||
|
||||
### **Week 1 - Critical Fixes (P0)**
|
||||
|
||||
1. **Create Platform-Specific Config Templates**
|
||||
|
||||
```bash
|
||||
config/
|
||||
├── linux-config.example.json
|
||||
├── windows-config.example.json
|
||||
└── macos-config.example.json
|
||||
```
|
||||
|
||||
2. **Fix Python Path Detection**
|
||||
|
||||
```python
|
||||
# Detect platform and set appropriate paths
|
||||
import platform
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
if platform.system() == "Windows":
|
||||
kicad_paths = [Path(sys.executable).parent / "Lib" / "site-packages"]
|
||||
else: # Linux/Mac
|
||||
kicad_paths = [Path(sys.executable).parent / "lib" / "python3.X" / "site-packages"]
|
||||
```
|
||||
|
||||
3. **Update Library Search Path Logic**
|
||||
```python
|
||||
def get_kicad_library_paths():
|
||||
"""Auto-detect KiCAD library paths based on platform"""
|
||||
system = platform.system()
|
||||
if system == "Windows":
|
||||
return ["C:/Program Files/KiCad/*/share/kicad/symbols/*.kicad_sym"]
|
||||
elif system == "Linux":
|
||||
return ["/usr/share/kicad/symbols/*.kicad_sym"]
|
||||
elif system == "Darwin": # macOS
|
||||
return ["/Applications/KiCad/KiCad.app/Contents/SharedSupport/symbols/*.kicad_sym"]
|
||||
```
|
||||
|
||||
### **Week 1 - High Priority (P1)**
|
||||
|
||||
4. **Create requirements.txt**
|
||||
|
||||
```txt
|
||||
# requirements.txt
|
||||
kicad-skip>=0.1.0
|
||||
Pillow>=9.0.0
|
||||
cairosvg>=2.7.0
|
||||
colorlog>=6.7.0
|
||||
```
|
||||
|
||||
5. **Add Linux Installation Documentation**
|
||||
- Ubuntu/Debian instructions
|
||||
- Fedora/RHEL instructions
|
||||
- Arch Linux instructions
|
||||
|
||||
6. **Migrate to pathlib**
|
||||
- Convert all `os.path` calls to `Path`
|
||||
- More Pythonic and readable
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### Ubuntu 24.04 LTS Testing
|
||||
|
||||
- [ ] Install KiCAD 9.0 from official PPA
|
||||
- [ ] Install Node.js 18+ from NodeSource
|
||||
- [ ] Clone repository
|
||||
- [ ] Run `npm install`
|
||||
- [ ] Run `npm run build`
|
||||
- [ ] Configure MCP settings (Cline)
|
||||
- [ ] Test: Create project
|
||||
- [ ] Test: Place components
|
||||
- [ ] Test: Export Gerbers
|
||||
|
||||
### Fedora Testing
|
||||
|
||||
- [ ] Install KiCAD from Fedora repos
|
||||
- [ ] Test same workflow
|
||||
|
||||
### Arch Testing
|
||||
|
||||
- [ ] Install KiCAD from AUR
|
||||
- [ ] Test same workflow
|
||||
|
||||
---
|
||||
|
||||
## Platform Detection Helper
|
||||
|
||||
Create `python/utils/platform_helper.py`:
|
||||
|
||||
```python
|
||||
"""Platform detection and path utilities"""
|
||||
import platform
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
class PlatformHelper:
|
||||
@staticmethod
|
||||
def is_windows() -> bool:
|
||||
return platform.system() == "Windows"
|
||||
|
||||
@staticmethod
|
||||
def is_linux() -> bool:
|
||||
return platform.system() == "Linux"
|
||||
|
||||
@staticmethod
|
||||
def is_macos() -> bool:
|
||||
return platform.system() == "Darwin"
|
||||
|
||||
@staticmethod
|
||||
def get_kicad_python_path() -> Path:
|
||||
"""Get KiCAD Python dist-packages path"""
|
||||
if PlatformHelper.is_windows():
|
||||
return Path("C:/Program Files/KiCad/9.0/lib/python3/dist-packages")
|
||||
elif PlatformHelper.is_linux():
|
||||
# Common Linux paths
|
||||
candidates = [
|
||||
Path("/usr/lib/kicad/lib/python3/dist-packages"),
|
||||
Path("/usr/share/kicad/scripting/plugins"),
|
||||
]
|
||||
for path in candidates:
|
||||
if path.exists():
|
||||
return path
|
||||
elif PlatformHelper.is_macos():
|
||||
return Path("/Applications/KiCad/KiCad.app/Contents/Frameworks/Python.framework/Versions/3.X/lib/python3.X/site-packages")
|
||||
|
||||
raise RuntimeError(f"Could not find KiCAD Python path for {platform.system()}")
|
||||
|
||||
@staticmethod
|
||||
def get_config_dir() -> Path:
|
||||
"""Get appropriate config directory"""
|
||||
if PlatformHelper.is_windows():
|
||||
return Path.home() / ".kicad-mcp"
|
||||
elif PlatformHelper.is_linux():
|
||||
# Use XDG Base Directory specification
|
||||
xdg_config = os.environ.get("XDG_CONFIG_HOME")
|
||||
if xdg_config:
|
||||
return Path(xdg_config) / "kicad-mcp"
|
||||
return Path.home() / ".config" / "kicad-mcp"
|
||||
elif PlatformHelper.is_macos():
|
||||
return Path.home() / "Library" / "Application Support" / "kicad-mcp"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
✅ Server starts on Ubuntu 24.04 LTS without errors
|
||||
✅ Can create and manipulate KiCAD projects
|
||||
✅ CI/CD pipeline tests on Linux
|
||||
✅ Documentation includes Linux setup
|
||||
✅ All tests pass on Linux
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Implement P0 fixes (this week)
|
||||
2. Set up GitHub Actions CI/CD
|
||||
3. Test on Ubuntu 24.04 LTS
|
||||
4. Document Linux-specific issues
|
||||
5. Create installation scripts
|
||||
|
||||
---
|
||||
|
||||
**Audited by:** Claude Code
|
||||
**Review Status:** ✅ Complete
|
||||
|
||||
@@ -25,6 +25,7 @@ Create a new KiCAD project named "LEDBoard" in ~/Projects/
|
||||
```
|
||||
|
||||
This uses `create_project` to generate:
|
||||
|
||||
- `.kicad_pro` -- project file
|
||||
- `.kicad_pcb` -- PCB layout file
|
||||
- `.kicad_sch` -- schematic file (with template symbols pre-loaded)
|
||||
@@ -119,6 +120,7 @@ Align all resistors horizontally.
|
||||
### Route Traces
|
||||
|
||||
**Preferred approach -- pad-to-pad routing:**
|
||||
|
||||
```
|
||||
Route R1 pad 2 to LED1 pad 1 with 0.3mm trace width.
|
||||
```
|
||||
@@ -126,6 +128,7 @@ Route R1 pad 2 to LED1 pad 1 with 0.3mm trace width.
|
||||
**Tool:** `route_pad_to_pad` -- auto-detects pad positions, nets, and inserts vias when pads are on different layers
|
||||
|
||||
**Manual approach:**
|
||||
|
||||
```
|
||||
Route a trace from x=15, y=25 to x=25, y=25 on the front copper layer.
|
||||
```
|
||||
@@ -135,11 +138,13 @@ Route a trace from x=15, y=25 to x=25, y=25 on the front copper layer.
|
||||
### Advanced Routing
|
||||
|
||||
**Differential pairs:**
|
||||
|
||||
```
|
||||
Route a differential pair for USB_P and USB_N with 0.2mm width and 0.15mm gap.
|
||||
```
|
||||
|
||||
**Copper zones:**
|
||||
|
||||
```
|
||||
Add a GND copper pour on the bottom layer covering the entire board.
|
||||
```
|
||||
@@ -149,6 +154,7 @@ Add a GND copper pour on the bottom layer covering the entire board.
|
||||
### Autorouting
|
||||
|
||||
For boards with many connections:
|
||||
|
||||
```
|
||||
Check if Freerouting is available.
|
||||
Autoroute the board using Freerouting.
|
||||
@@ -246,6 +252,7 @@ Suggest alternatives to part C25804.
|
||||
```
|
||||
|
||||
After selecting parts, enrich datasheets:
|
||||
|
||||
```
|
||||
Enrich datasheets for all components in the schematic.
|
||||
```
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,416 +1,441 @@
|
||||
# Real-Time Collaboration Workflow
|
||||
|
||||
**Status:** ✅ TESTED AND WORKING
|
||||
**Date:** 2025-11-01
|
||||
**Version:** 2.1.0-alpha
|
||||
|
||||
## Overview
|
||||
|
||||
The KiCAD MCP Server enables **real-time paired circuit board design** between Claude Code (via MCP) and a human designer using the KiCAD UI. Both workflows have been tested and confirmed working:
|
||||
|
||||
- ✅ **MCP→UI**: AI places components, human sees them in KiCAD
|
||||
- ✅ **UI→MCP**: Human edits board, AI reads changes back
|
||||
|
||||
## How It Works
|
||||
|
||||
### Architecture
|
||||
|
||||
The MCP server uses KiCAD's Python API (`pcbnew` module) to read and write `.kicad_pcb` files. The KiCAD UI and MCP both operate on the same file, enabling collaboration through the file system.
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌──────────────────┐
|
||||
│ Claude Code │ │ Human Designer │
|
||||
│ (via MCP) │ │ (KiCAD UI) │
|
||||
└────────┬────────┘ └────────┬─────────┘
|
||||
│ │
|
||||
│ pcbnew Python API │ KiCAD UI
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ project.kicad_pcb (file system) │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### MCP→UI Workflow (AI to Human)
|
||||
|
||||
**Use case:** Claude places components via MCP, human sees them in KiCAD UI
|
||||
|
||||
1. **Claude places components** via MCP tools:
|
||||
```python
|
||||
# MCP internally uses:
|
||||
board = pcbnew.LoadBoard('project.kicad_pcb')
|
||||
module = pcbnew.FootprintLoad(library_path, 'R_0603_1608Metric')
|
||||
module.SetPosition(pcbnew.VECTOR2I(x_nm, y_nm))
|
||||
board.Add(module)
|
||||
pcbnew.SaveBoard('project.kicad_pcb', board)
|
||||
```
|
||||
|
||||
2. **Human opens/reloads in KiCAD UI:**
|
||||
- **Option A (first time):** Open the project in KiCAD
|
||||
- **Option B (already open):** File → Revert or close and reopen the PCB editor
|
||||
- Components appear instantly ✅
|
||||
|
||||
**Example:**
|
||||
```
|
||||
User: "Place a 10k resistor at position 30, 30mm"
|
||||
Claude: [uses place_component MCP tool]
|
||||
✅ Placed R1: 10k at (30.0, 30.0) mm
|
||||
User: [opens KiCAD UI]
|
||||
[sees R1 at the specified position]
|
||||
```
|
||||
|
||||
### UI→MCP Workflow (Human to AI)
|
||||
|
||||
**Use case:** Human edits board in KiCAD UI, Claude reads changes via MCP
|
||||
|
||||
1. **Human makes changes in KiCAD UI:**
|
||||
- Move components
|
||||
- Add new components
|
||||
- Route traces
|
||||
- Edit properties
|
||||
|
||||
2. **Human saves the file:**
|
||||
- Ctrl+S or File → Save
|
||||
- KiCAD writes changes to `.kicad_pcb` file
|
||||
|
||||
3. **Claude reads changes** via MCP tools:
|
||||
```python
|
||||
# MCP internally uses:
|
||||
board = pcbnew.LoadBoard('project.kicad_pcb')
|
||||
footprints = board.GetFootprints()
|
||||
# Reads all current component positions, values, etc.
|
||||
```
|
||||
|
||||
4. **Claude can see the updates:**
|
||||
- New component positions
|
||||
- Added/removed components
|
||||
- Updated values and references
|
||||
- New traces and nets
|
||||
|
||||
**Example:**
|
||||
```
|
||||
User: "I moved R1 to a new position, can you see it?"
|
||||
Claude: [uses get_board_info MCP tool]
|
||||
Yes! I can see R1 is now at (59.175, 49.0) mm
|
||||
(previously it was at 30.0, 30.0 mm)
|
||||
```
|
||||
|
||||
## Tested Workflows
|
||||
|
||||
### Test 1: MCP→UI (Verified ✅)
|
||||
|
||||
**Setup:**
|
||||
- Created new board via MCP (100x80mm)
|
||||
- Placed R1 (10k resistor) at (30, 30) mm
|
||||
- Placed D1 (RED LED) at (50, 30) mm
|
||||
|
||||
**Result:**
|
||||
- Opened KiCAD PCB editor
|
||||
- Both components visible at correct positions ✅
|
||||
- All properties (reference, value, rotation) correct ✅
|
||||
|
||||
### Test 2: UI→MCP (Verified ✅)
|
||||
|
||||
**Setup:**
|
||||
- User moved R1 from (30, 30) mm to (59.175, 49.0) mm in UI
|
||||
- User saved file (Ctrl+S)
|
||||
|
||||
**Result:**
|
||||
- MCP read board via `get_board_info`
|
||||
- New position detected correctly ✅
|
||||
- D1 position unchanged (as expected) ✅
|
||||
|
||||
## Current Capabilities
|
||||
|
||||
### What Works
|
||||
|
||||
1. **Bidirectional sync** (via file save/reload)
|
||||
2. **Component placement** (MCP→UI)
|
||||
3. **Component reading** (UI→MCP)
|
||||
4. **Position/rotation updates** (both directions)
|
||||
5. **Value/reference changes** (both directions)
|
||||
6. **Trace routing** (both directions)
|
||||
7. **Net information** (both directions)
|
||||
8. **Board properties** (size, layers, design rules)
|
||||
|
||||
### MCP Tools for Collaboration
|
||||
|
||||
**Reading board state:**
|
||||
- `get_board_info` - Get all components and their positions
|
||||
- `get_project_info` - Get project metadata
|
||||
- `list_components` - List all components (if implemented)
|
||||
|
||||
**Modifying board:**
|
||||
- `place_component` - Add new components
|
||||
- `add_trace` - Add copper traces
|
||||
- `add_via` - Add vias
|
||||
- `add_copper_pour` - Add copper zones
|
||||
- `add_mounting_hole` - Add mounting holes
|
||||
- `add_board_text` - Add text to board
|
||||
|
||||
## Limitations
|
||||
|
||||
### Current Limitations
|
||||
|
||||
1. **Manual Save Required**
|
||||
- UI changes require manual save (Ctrl+S)
|
||||
- No automatic file watching (yet)
|
||||
- Workaround: Always save before asking Claude
|
||||
|
||||
2. **Manual Reload Required**
|
||||
- MCP changes require reload in UI
|
||||
- Options: File → Revert, or close/reopen
|
||||
- Future: Could implement auto-reload trigger
|
||||
|
||||
3. **No Live Sync**
|
||||
- Changes not visible until save/reload
|
||||
- Not truly "real-time" (more like "near-time")
|
||||
- File-based sync has ~1-5 second latency
|
||||
|
||||
4. **No Conflict Detection**
|
||||
- If both edit simultaneously, last save wins
|
||||
- No merge conflict resolution
|
||||
- Best practice: Take turns editing
|
||||
|
||||
5. **No Change Notifications**
|
||||
- MCP doesn't know when UI saves
|
||||
- UI doesn't know when MCP saves
|
||||
- Future: Could add file system watchers
|
||||
|
||||
### Known Issues
|
||||
|
||||
1. **Zone Filling:** Copper pours created by MCP won't be filled (requires UI to fill)
|
||||
2. **Undo History:** UI undo history lost after MCP changes
|
||||
3. **DRC Errors:** MCP doesn't run design rule checks automatically
|
||||
|
||||
## Best Practices
|
||||
|
||||
### For AI-Human Collaboration
|
||||
|
||||
1. **Establish Turn-Taking:**
|
||||
```
|
||||
User: "I'm going to add some components, one sec"
|
||||
[User edits in UI]
|
||||
User: "Done, saved the file"
|
||||
Claude: [reads changes] "I see you added C1 and C2..."
|
||||
```
|
||||
|
||||
2. **Always Save/Reload:**
|
||||
- Human: Save after every change (Ctrl+S)
|
||||
- Human: Reload after Claude makes changes
|
||||
- Claude: Always read fresh before making decisions
|
||||
|
||||
3. **Communicate Changes:**
|
||||
```
|
||||
Claude: "I'm placing R1-R4 now..."
|
||||
[MCP places components]
|
||||
Claude: "Done! Reload the board to see them"
|
||||
User: [File → Revert]
|
||||
```
|
||||
|
||||
4. **Use Descriptive References:**
|
||||
- Good: R1, R2, C1, C2 (sequential)
|
||||
- Bad: R_temp, R_test (unclear)
|
||||
|
||||
### Workflow Patterns
|
||||
|
||||
**Pattern 1: AI Does Layout, Human Reviews**
|
||||
```
|
||||
1. Claude places all components via MCP
|
||||
2. Claude routes critical traces via MCP
|
||||
3. Human opens in KiCAD UI
|
||||
4. Human fine-tunes positions
|
||||
5. Human completes routing
|
||||
6. Saves → Claude reads final result
|
||||
```
|
||||
|
||||
**Pattern 2: Human Sketches, AI Refines**
|
||||
```
|
||||
1. Human places major components in UI
|
||||
2. Saves → Claude reads layout
|
||||
3. Claude suggests improvements
|
||||
4. Claude places remaining components via MCP
|
||||
5. Human reloads and reviews
|
||||
6. Iterate until satisfied
|
||||
```
|
||||
|
||||
**Pattern 3: Pair Programming Style**
|
||||
```
|
||||
User: "Place a 10k pull-up resistor on pin 3"
|
||||
Claude: [places R1 at calculated position]
|
||||
"Done! Check position (45, 20) mm"
|
||||
User: [reloads] "Looks good, now add the LED"
|
||||
Claude: [places D1]
|
||||
[Continue back-and-forth]
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### Planned Improvements
|
||||
|
||||
1. **File System Watchers** (Week 4+)
|
||||
- Auto-detect when UI saves file
|
||||
- Auto-reload UI when MCP saves (via IPC)
|
||||
- Near-instant sync (<100ms)
|
||||
|
||||
2. **IPC Backend** (Week 3)
|
||||
- Direct communication with KiCAD process
|
||||
- Live sync without file save/reload
|
||||
- True real-time collaboration
|
||||
|
||||
3. **Change Notifications**
|
||||
- MCP sends notification when it modifies board
|
||||
- UI shows toast: "Claude added 4 components"
|
||||
- Automatic reload option
|
||||
|
||||
4. **Conflict Detection**
|
||||
- Detect when both edited same component
|
||||
- Show diff/merge UI
|
||||
- Allow choosing which changes to keep
|
||||
|
||||
5. **Collaborative Cursor**
|
||||
- Show Claude's "cursor" in UI
|
||||
- Highlight component being placed
|
||||
- Visual feedback for AI actions
|
||||
|
||||
### Long-Term Vision
|
||||
|
||||
**Fully Real-Time Collaboration:**
|
||||
- Both AI and human see changes instantly
|
||||
- No manual save/reload required
|
||||
- Conflict detection and resolution
|
||||
- Visual indicators for who's editing what
|
||||
- Chat/comment system for design discussion
|
||||
|
||||
**Example Future Workflow:**
|
||||
```
|
||||
[Claude and human both have board open]
|
||||
Claude: [starts placing R1]
|
||||
[R1 appears in UI with "Claude is placing..." indicator]
|
||||
User: [sees R1 appear in real-time]
|
||||
[moves D1 to better position]
|
||||
[Claude sees D1 move instantly]
|
||||
Claude: "Good position for D1! I'll route them now"
|
||||
[traces appear as Claude creates them]
|
||||
```
|
||||
|
||||
## Technical Details
|
||||
|
||||
### File Format
|
||||
|
||||
KiCAD uses S-expression format (`.kicad_pcb`):
|
||||
```lisp
|
||||
(kicad_pcb (version 20240108) (generator "pcbnew")
|
||||
(footprint "Resistor_SMD:R_0603_1608Metric"
|
||||
(layer "F.Cu")
|
||||
(at 30.0 30.0 0)
|
||||
(property "Reference" "R1")
|
||||
(property "Value" "10k")
|
||||
...
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Sync Mechanism
|
||||
|
||||
**Current (File-based):**
|
||||
1. MCP: `pcbnew.SaveBoard(path, board)` → writes file
|
||||
2. UI: File → Revert → reads file
|
||||
3. Latency: ~1-5 seconds (manual)
|
||||
|
||||
**Future (IPC-based):**
|
||||
1. MCP: `kicad.AddFootprint(...)` → sends IPC command
|
||||
2. KiCAD: Receives command → updates internal state
|
||||
3. UI: Automatically refreshes display
|
||||
4. Latency: ~50-100ms (automatic)
|
||||
|
||||
### Python API Used
|
||||
|
||||
```python
|
||||
import pcbnew
|
||||
|
||||
# Load board
|
||||
board = pcbnew.LoadBoard('project.kicad_pcb')
|
||||
|
||||
# Read components
|
||||
for fp in board.GetFootprints():
|
||||
ref = fp.Reference().GetText()
|
||||
pos = fp.GetPosition()
|
||||
x_mm = pos.x / 1_000_000.0
|
||||
y_mm = pos.y / 1_000_000.0
|
||||
|
||||
# Modify board
|
||||
module = pcbnew.FootprintLoad(lib_path, 'R_0603')
|
||||
module.SetPosition(pcbnew.VECTOR2I(x_nm, y_nm))
|
||||
board.Add(module)
|
||||
|
||||
# Save changes
|
||||
pcbnew.SaveBoard('project.kicad_pcb', board)
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "I don't see MCP changes in KiCAD UI"
|
||||
|
||||
**Cause:** UI hasn't reloaded the file
|
||||
|
||||
**Solution:**
|
||||
1. File → Revert (or Ctrl+R if configured)
|
||||
2. Or close PCB editor and reopen
|
||||
3. Or restart KiCAD
|
||||
|
||||
### "MCP doesn't see my UI changes"
|
||||
|
||||
**Cause:** File not saved
|
||||
|
||||
**Solution:**
|
||||
1. Save file: Ctrl+S or File → Save
|
||||
2. Verify save: Check file modification time
|
||||
3. Ask Claude to read board again
|
||||
|
||||
### "Changes disappeared after reload"
|
||||
|
||||
**Cause:** File overwritten by other party
|
||||
|
||||
**Solution:**
|
||||
1. Always save before asking MCP to make changes
|
||||
2. Don't edit while MCP is working
|
||||
3. Take turns to avoid conflicts
|
||||
|
||||
### "Components appear in wrong positions"
|
||||
|
||||
**Cause:** Unit conversion error or coordinate system mismatch
|
||||
|
||||
**Solution:**
|
||||
1. Check KiCAD units (View → Switch Units)
|
||||
2. MCP uses millimeters internally
|
||||
3. Report issue if positions consistently wrong
|
||||
|
||||
## Conclusion
|
||||
|
||||
**The real-time collaboration workflow is WORKING and TESTED! ✅**
|
||||
|
||||
The KiCAD MCP Server successfully enables paired circuit board design between AI (Claude) and human designers. While it requires manual save/reload steps, both MCP→UI and UI→MCP workflows function correctly.
|
||||
|
||||
**Current State:** "Near-real-time" collaboration (1-5 second latency)
|
||||
|
||||
**Future State:** True real-time with IPC backend (<100ms latency)
|
||||
|
||||
**Mission Accomplished:** Real-time paired circuit board design is operational and ready for use! 🎉
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [LIBRARY_INTEGRATION.md](./LIBRARY_INTEGRATION.md) - Component library system
|
||||
- [STATUS_SUMMARY.md](./STATUS_SUMMARY.md) - Current implementation status
|
||||
- [ROADMAP.md](./ROADMAP.md) - Future development plans
|
||||
- [API.md](./API.md) - Full MCP API reference
|
||||
|
||||
## Changelog
|
||||
|
||||
**2025-11-01 - v2.1.0-alpha**
|
||||
- ✅ Tested MCP→UI workflow (placing components via MCP, viewing in UI)
|
||||
- ✅ Tested UI→MCP workflow (editing in UI, reading via MCP)
|
||||
- ✅ Documented best practices and limitations
|
||||
- ✅ Confirmed real-time collaboration mission is met
|
||||
# Real-Time Collaboration Workflow
|
||||
|
||||
**Status:** ✅ TESTED AND WORKING
|
||||
**Date:** 2025-11-01
|
||||
**Version:** 2.1.0-alpha
|
||||
|
||||
## Overview
|
||||
|
||||
The KiCAD MCP Server enables **real-time paired circuit board design** between Claude Code (via MCP) and a human designer using the KiCAD UI. Both workflows have been tested and confirmed working:
|
||||
|
||||
- ✅ **MCP→UI**: AI places components, human sees them in KiCAD
|
||||
- ✅ **UI→MCP**: Human edits board, AI reads changes back
|
||||
|
||||
## How It Works
|
||||
|
||||
### Architecture
|
||||
|
||||
The MCP server uses KiCAD's Python API (`pcbnew` module) to read and write `.kicad_pcb` files. The KiCAD UI and MCP both operate on the same file, enabling collaboration through the file system.
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌──────────────────┐
|
||||
│ Claude Code │ │ Human Designer │
|
||||
│ (via MCP) │ │ (KiCAD UI) │
|
||||
└────────┬────────┘ └────────┬─────────┘
|
||||
│ │
|
||||
│ pcbnew Python API │ KiCAD UI
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ project.kicad_pcb (file system) │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### MCP→UI Workflow (AI to Human)
|
||||
|
||||
**Use case:** Claude places components via MCP, human sees them in KiCAD UI
|
||||
|
||||
1. **Claude places components** via MCP tools:
|
||||
|
||||
```python
|
||||
# MCP internally uses:
|
||||
board = pcbnew.LoadBoard('project.kicad_pcb')
|
||||
module = pcbnew.FootprintLoad(library_path, 'R_0603_1608Metric')
|
||||
module.SetPosition(pcbnew.VECTOR2I(x_nm, y_nm))
|
||||
board.Add(module)
|
||||
pcbnew.SaveBoard('project.kicad_pcb', board)
|
||||
```
|
||||
|
||||
2. **Human opens/reloads in KiCAD UI:**
|
||||
- **Option A (first time):** Open the project in KiCAD
|
||||
- **Option B (already open):** File → Revert or close and reopen the PCB editor
|
||||
- Components appear instantly ✅
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
User: "Place a 10k resistor at position 30, 30mm"
|
||||
Claude: [uses place_component MCP tool]
|
||||
✅ Placed R1: 10k at (30.0, 30.0) mm
|
||||
User: [opens KiCAD UI]
|
||||
[sees R1 at the specified position]
|
||||
```
|
||||
|
||||
### UI→MCP Workflow (Human to AI)
|
||||
|
||||
**Use case:** Human edits board in KiCAD UI, Claude reads changes via MCP
|
||||
|
||||
1. **Human makes changes in KiCAD UI:**
|
||||
- Move components
|
||||
- Add new components
|
||||
- Route traces
|
||||
- Edit properties
|
||||
|
||||
2. **Human saves the file:**
|
||||
- Ctrl+S or File → Save
|
||||
- KiCAD writes changes to `.kicad_pcb` file
|
||||
|
||||
3. **Claude reads changes** via MCP tools:
|
||||
|
||||
```python
|
||||
# MCP internally uses:
|
||||
board = pcbnew.LoadBoard('project.kicad_pcb')
|
||||
footprints = board.GetFootprints()
|
||||
# Reads all current component positions, values, etc.
|
||||
```
|
||||
|
||||
4. **Claude can see the updates:**
|
||||
- New component positions
|
||||
- Added/removed components
|
||||
- Updated values and references
|
||||
- New traces and nets
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
User: "I moved R1 to a new position, can you see it?"
|
||||
Claude: [uses get_board_info MCP tool]
|
||||
Yes! I can see R1 is now at (59.175, 49.0) mm
|
||||
(previously it was at 30.0, 30.0 mm)
|
||||
```
|
||||
|
||||
## Tested Workflows
|
||||
|
||||
### Test 1: MCP→UI (Verified ✅)
|
||||
|
||||
**Setup:**
|
||||
|
||||
- Created new board via MCP (100x80mm)
|
||||
- Placed R1 (10k resistor) at (30, 30) mm
|
||||
- Placed D1 (RED LED) at (50, 30) mm
|
||||
|
||||
**Result:**
|
||||
|
||||
- Opened KiCAD PCB editor
|
||||
- Both components visible at correct positions ✅
|
||||
- All properties (reference, value, rotation) correct ✅
|
||||
|
||||
### Test 2: UI→MCP (Verified ✅)
|
||||
|
||||
**Setup:**
|
||||
|
||||
- User moved R1 from (30, 30) mm to (59.175, 49.0) mm in UI
|
||||
- User saved file (Ctrl+S)
|
||||
|
||||
**Result:**
|
||||
|
||||
- MCP read board via `get_board_info`
|
||||
- New position detected correctly ✅
|
||||
- D1 position unchanged (as expected) ✅
|
||||
|
||||
## Current Capabilities
|
||||
|
||||
### What Works
|
||||
|
||||
1. **Bidirectional sync** (via file save/reload)
|
||||
2. **Component placement** (MCP→UI)
|
||||
3. **Component reading** (UI→MCP)
|
||||
4. **Position/rotation updates** (both directions)
|
||||
5. **Value/reference changes** (both directions)
|
||||
6. **Trace routing** (both directions)
|
||||
7. **Net information** (both directions)
|
||||
8. **Board properties** (size, layers, design rules)
|
||||
|
||||
### MCP Tools for Collaboration
|
||||
|
||||
**Reading board state:**
|
||||
|
||||
- `get_board_info` - Get all components and their positions
|
||||
- `get_project_info` - Get project metadata
|
||||
- `list_components` - List all components (if implemented)
|
||||
|
||||
**Modifying board:**
|
||||
|
||||
- `place_component` - Add new components
|
||||
- `add_trace` - Add copper traces
|
||||
- `add_via` - Add vias
|
||||
- `add_copper_pour` - Add copper zones
|
||||
- `add_mounting_hole` - Add mounting holes
|
||||
- `add_board_text` - Add text to board
|
||||
|
||||
## Limitations
|
||||
|
||||
### Current Limitations
|
||||
|
||||
1. **Manual Save Required**
|
||||
- UI changes require manual save (Ctrl+S)
|
||||
- No automatic file watching (yet)
|
||||
- Workaround: Always save before asking Claude
|
||||
|
||||
2. **Manual Reload Required**
|
||||
- MCP changes require reload in UI
|
||||
- Options: File → Revert, or close/reopen
|
||||
- Future: Could implement auto-reload trigger
|
||||
|
||||
3. **No Live Sync**
|
||||
- Changes not visible until save/reload
|
||||
- Not truly "real-time" (more like "near-time")
|
||||
- File-based sync has ~1-5 second latency
|
||||
|
||||
4. **No Conflict Detection**
|
||||
- If both edit simultaneously, last save wins
|
||||
- No merge conflict resolution
|
||||
- Best practice: Take turns editing
|
||||
|
||||
5. **No Change Notifications**
|
||||
- MCP doesn't know when UI saves
|
||||
- UI doesn't know when MCP saves
|
||||
- Future: Could add file system watchers
|
||||
|
||||
### Known Issues
|
||||
|
||||
1. **Zone Filling:** Copper pours created by MCP won't be filled (requires UI to fill)
|
||||
2. **Undo History:** UI undo history lost after MCP changes
|
||||
3. **DRC Errors:** MCP doesn't run design rule checks automatically
|
||||
|
||||
## Best Practices
|
||||
|
||||
### For AI-Human Collaboration
|
||||
|
||||
1. **Establish Turn-Taking:**
|
||||
|
||||
```
|
||||
User: "I'm going to add some components, one sec"
|
||||
[User edits in UI]
|
||||
User: "Done, saved the file"
|
||||
Claude: [reads changes] "I see you added C1 and C2..."
|
||||
```
|
||||
|
||||
2. **Always Save/Reload:**
|
||||
- Human: Save after every change (Ctrl+S)
|
||||
- Human: Reload after Claude makes changes
|
||||
- Claude: Always read fresh before making decisions
|
||||
|
||||
3. **Communicate Changes:**
|
||||
|
||||
```
|
||||
Claude: "I'm placing R1-R4 now..."
|
||||
[MCP places components]
|
||||
Claude: "Done! Reload the board to see them"
|
||||
User: [File → Revert]
|
||||
```
|
||||
|
||||
4. **Use Descriptive References:**
|
||||
- Good: R1, R2, C1, C2 (sequential)
|
||||
- Bad: R_temp, R_test (unclear)
|
||||
|
||||
### Workflow Patterns
|
||||
|
||||
**Pattern 1: AI Does Layout, Human Reviews**
|
||||
|
||||
```
|
||||
1. Claude places all components via MCP
|
||||
2. Claude routes critical traces via MCP
|
||||
3. Human opens in KiCAD UI
|
||||
4. Human fine-tunes positions
|
||||
5. Human completes routing
|
||||
6. Saves → Claude reads final result
|
||||
```
|
||||
|
||||
**Pattern 2: Human Sketches, AI Refines**
|
||||
|
||||
```
|
||||
1. Human places major components in UI
|
||||
2. Saves → Claude reads layout
|
||||
3. Claude suggests improvements
|
||||
4. Claude places remaining components via MCP
|
||||
5. Human reloads and reviews
|
||||
6. Iterate until satisfied
|
||||
```
|
||||
|
||||
**Pattern 3: Pair Programming Style**
|
||||
|
||||
```
|
||||
User: "Place a 10k pull-up resistor on pin 3"
|
||||
Claude: [places R1 at calculated position]
|
||||
"Done! Check position (45, 20) mm"
|
||||
User: [reloads] "Looks good, now add the LED"
|
||||
Claude: [places D1]
|
||||
[Continue back-and-forth]
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### Planned Improvements
|
||||
|
||||
1. **File System Watchers** (Week 4+)
|
||||
- Auto-detect when UI saves file
|
||||
- Auto-reload UI when MCP saves (via IPC)
|
||||
- Near-instant sync (<100ms)
|
||||
|
||||
2. **IPC Backend** (Week 3)
|
||||
- Direct communication with KiCAD process
|
||||
- Live sync without file save/reload
|
||||
- True real-time collaboration
|
||||
|
||||
3. **Change Notifications**
|
||||
- MCP sends notification when it modifies board
|
||||
- UI shows toast: "Claude added 4 components"
|
||||
- Automatic reload option
|
||||
|
||||
4. **Conflict Detection**
|
||||
- Detect when both edited same component
|
||||
- Show diff/merge UI
|
||||
- Allow choosing which changes to keep
|
||||
|
||||
5. **Collaborative Cursor**
|
||||
- Show Claude's "cursor" in UI
|
||||
- Highlight component being placed
|
||||
- Visual feedback for AI actions
|
||||
|
||||
### Long-Term Vision
|
||||
|
||||
**Fully Real-Time Collaboration:**
|
||||
|
||||
- Both AI and human see changes instantly
|
||||
- No manual save/reload required
|
||||
- Conflict detection and resolution
|
||||
- Visual indicators for who's editing what
|
||||
- Chat/comment system for design discussion
|
||||
|
||||
**Example Future Workflow:**
|
||||
|
||||
```
|
||||
[Claude and human both have board open]
|
||||
Claude: [starts placing R1]
|
||||
[R1 appears in UI with "Claude is placing..." indicator]
|
||||
User: [sees R1 appear in real-time]
|
||||
[moves D1 to better position]
|
||||
[Claude sees D1 move instantly]
|
||||
Claude: "Good position for D1! I'll route them now"
|
||||
[traces appear as Claude creates them]
|
||||
```
|
||||
|
||||
## Technical Details
|
||||
|
||||
### File Format
|
||||
|
||||
KiCAD uses S-expression format (`.kicad_pcb`):
|
||||
|
||||
```lisp
|
||||
(kicad_pcb (version 20240108) (generator "pcbnew")
|
||||
(footprint "Resistor_SMD:R_0603_1608Metric"
|
||||
(layer "F.Cu")
|
||||
(at 30.0 30.0 0)
|
||||
(property "Reference" "R1")
|
||||
(property "Value" "10k")
|
||||
...
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Sync Mechanism
|
||||
|
||||
**Current (File-based):**
|
||||
|
||||
1. MCP: `pcbnew.SaveBoard(path, board)` → writes file
|
||||
2. UI: File → Revert → reads file
|
||||
3. Latency: ~1-5 seconds (manual)
|
||||
|
||||
**Future (IPC-based):**
|
||||
|
||||
1. MCP: `kicad.AddFootprint(...)` → sends IPC command
|
||||
2. KiCAD: Receives command → updates internal state
|
||||
3. UI: Automatically refreshes display
|
||||
4. Latency: ~50-100ms (automatic)
|
||||
|
||||
### Python API Used
|
||||
|
||||
```python
|
||||
import pcbnew
|
||||
|
||||
# Load board
|
||||
board = pcbnew.LoadBoard('project.kicad_pcb')
|
||||
|
||||
# Read components
|
||||
for fp in board.GetFootprints():
|
||||
ref = fp.Reference().GetText()
|
||||
pos = fp.GetPosition()
|
||||
x_mm = pos.x / 1_000_000.0
|
||||
y_mm = pos.y / 1_000_000.0
|
||||
|
||||
# Modify board
|
||||
module = pcbnew.FootprintLoad(lib_path, 'R_0603')
|
||||
module.SetPosition(pcbnew.VECTOR2I(x_nm, y_nm))
|
||||
board.Add(module)
|
||||
|
||||
# Save changes
|
||||
pcbnew.SaveBoard('project.kicad_pcb', board)
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "I don't see MCP changes in KiCAD UI"
|
||||
|
||||
**Cause:** UI hasn't reloaded the file
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. File → Revert (or Ctrl+R if configured)
|
||||
2. Or close PCB editor and reopen
|
||||
3. Or restart KiCAD
|
||||
|
||||
### "MCP doesn't see my UI changes"
|
||||
|
||||
**Cause:** File not saved
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Save file: Ctrl+S or File → Save
|
||||
2. Verify save: Check file modification time
|
||||
3. Ask Claude to read board again
|
||||
|
||||
### "Changes disappeared after reload"
|
||||
|
||||
**Cause:** File overwritten by other party
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Always save before asking MCP to make changes
|
||||
2. Don't edit while MCP is working
|
||||
3. Take turns to avoid conflicts
|
||||
|
||||
### "Components appear in wrong positions"
|
||||
|
||||
**Cause:** Unit conversion error or coordinate system mismatch
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Check KiCAD units (View → Switch Units)
|
||||
2. MCP uses millimeters internally
|
||||
3. Report issue if positions consistently wrong
|
||||
|
||||
## Conclusion
|
||||
|
||||
**The real-time collaboration workflow is WORKING and TESTED! ✅**
|
||||
|
||||
The KiCAD MCP Server successfully enables paired circuit board design between AI (Claude) and human designers. While it requires manual save/reload steps, both MCP→UI and UI→MCP workflows function correctly.
|
||||
|
||||
**Current State:** "Near-real-time" collaboration (1-5 second latency)
|
||||
|
||||
**Future State:** True real-time with IPC backend (<100ms latency)
|
||||
|
||||
**Mission Accomplished:** Real-time paired circuit board design is operational and ready for use! 🎉
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [LIBRARY_INTEGRATION.md](./LIBRARY_INTEGRATION.md) - Component library system
|
||||
- [STATUS_SUMMARY.md](./STATUS_SUMMARY.md) - Current implementation status
|
||||
- [ROADMAP.md](./ROADMAP.md) - Future development plans
|
||||
- [API.md](./API.md) - Full MCP API reference
|
||||
|
||||
## Changelog
|
||||
|
||||
**2025-11-01 - v2.1.0-alpha**
|
||||
|
||||
- ✅ Tested MCP→UI workflow (placing components via MCP, viewing in UI)
|
||||
- ✅ Tested UI→MCP workflow (editing in UI, reading via MCP)
|
||||
- ✅ Documented best practices and limitations
|
||||
- ✅ Confirmed real-time collaboration mission is met
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
## Completed Milestones
|
||||
|
||||
### v1.0.0 - Core Foundation (October 2025)
|
||||
|
||||
- [x] MCP protocol implementation (JSON-RPC 2.0, MCP 2025-06-18)
|
||||
- [x] Project management (create, open, save)
|
||||
- [x] Board operations (size, outline, layers, mounting holes, text)
|
||||
@@ -21,12 +22,14 @@
|
||||
- [x] UI auto-launch and detection
|
||||
|
||||
### v2.0.0-alpha - Router and IPC (November-December 2025)
|
||||
|
||||
- [x] Tool router pattern -- 70% AI context reduction
|
||||
- [x] IPC backend for real-time KiCAD UI synchronization (21 commands)
|
||||
- [x] Hybrid SWIG/IPC backend with automatic fallback
|
||||
- [x] Comprehensive Windows support with automated setup
|
||||
|
||||
### v2.1.0-alpha - Schematics and JLCPCB (January 2026)
|
||||
|
||||
- [x] Complete schematic workflow fix (Issue #26)
|
||||
- [x] Dynamic symbol loading -- access to all ~10,000 KiCad symbols
|
||||
- [x] Intelligent wiring system with pin discovery and smart routing
|
||||
@@ -36,6 +39,7 @@
|
||||
- [x] Local symbol library search (contributor: @l3wi)
|
||||
|
||||
### v2.2.0 through v2.2.3 - Routing, Creators, Autorouting (February-March 2026)
|
||||
|
||||
- [x] 13 new routing/component tools (delete/query/modify traces, arrays, alignment)
|
||||
- [x] route_pad_to_pad with auto-via insertion for cross-layer connections
|
||||
- [x] copy_routing_pattern for trace replication
|
||||
@@ -57,12 +61,14 @@
|
||||
## Current Focus: v2.3+
|
||||
|
||||
### Documentation Overhaul (In Progress)
|
||||
|
||||
- [ ] Per-feature documentation for all 122 tools
|
||||
- [ ] Architecture guide for contributors
|
||||
- [ ] End-to-end PCB design workflow guide
|
||||
- [ ] Documentation index
|
||||
|
||||
### Quality and Stability
|
||||
|
||||
- [ ] Expand test coverage across all tool categories
|
||||
- [ ] Performance profiling for large boards
|
||||
- [ ] Update package.json version to match CHANGELOG
|
||||
@@ -72,24 +78,28 @@
|
||||
## Planned Features
|
||||
|
||||
### Supplier Integration
|
||||
|
||||
- [ ] Digikey API integration
|
||||
- [ ] Mouser API integration
|
||||
- [ ] Smart BOM management with real-time pricing
|
||||
- [ ] Cost optimization across suppliers
|
||||
|
||||
### Design Patterns and Templates
|
||||
|
||||
- [ ] Circuit patterns library (voltage regulators, USB, microcontrollers)
|
||||
- [ ] Board templates (Arduino shields, RPi HATs, Feather wings)
|
||||
- [ ] Auto-suggest trace widths by current
|
||||
- [ ] Impedance-controlled trace support
|
||||
|
||||
### Advanced Capabilities
|
||||
|
||||
- [ ] Panelization support
|
||||
- [ ] Multi-board project management
|
||||
- [ ] High-speed design helpers (length matching, via stitching)
|
||||
- [ ] SPICE simulation integration
|
||||
|
||||
### Community and Education
|
||||
|
||||
- [ ] Example project gallery with tutorials
|
||||
- [ ] Video walkthrough series
|
||||
- [ ] Interactive beginner tutorials
|
||||
@@ -111,4 +121,4 @@ Check [CONTRIBUTING.md](../CONTRIBUTING.md) for details.
|
||||
|
||||
---
|
||||
|
||||
*Maintained by: KiCAD MCP Team and community contributors*
|
||||
_Maintained by: KiCAD MCP Team and community contributors_
|
||||
|
||||
@@ -1,353 +1,383 @@
|
||||
# Router Architecture Design
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the router pattern implementation for the KiCAD MCP Server. The router reduces context window consumption by organizing 122+ tools into 8 discoverable categories, keeping only the most frequently used tools directly visible.
|
||||
|
||||
## Architecture Layers
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ MCP Client (Claude) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ KiCAD MCP Server │
|
||||
│ ┌─────────────────────────────────────────────────────────┐│
|
||||
│ │ DIRECT TOOLS (Always Visible - 12) ││
|
||||
│ │ • create_project • open_project • save_project ││
|
||||
│ │ • get_project_info • place_component • move_component ││
|
||||
│ │ • add_net • route_trace • get_board_info ││
|
||||
│ │ • set_board_size • add_board_outline • check_kicad_ui││
|
||||
│ └─────────────────────────────────────────────────────────┘│
|
||||
│ ┌─────────────────────────────────────────────────────────┐│
|
||||
│ │ ROUTER TOOLS (Discovery - 4) ││
|
||||
│ │ • list_tool_categories • get_category_tools ││
|
||||
│ │ • execute_tool • search_tools ││
|
||||
│ └─────────────────────────────────────────────────────────┘│
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐│
|
||||
│ │ ROUTED TOOLS (Hidden - 110+) ││
|
||||
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││
|
||||
│ │ │ board │ │component │ │ export │ │ drc │ ││
|
||||
│ │ │ tools │ │ tools │ │ tools │ │ tools │ ││
|
||||
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ ││
|
||||
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││
|
||||
│ │ │schematic │ │ library │ │ routing │ │footprint │ ││
|
||||
│ │ │ tools │ │ tools │ │ tools │ │ tools │ ││
|
||||
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ ││
|
||||
│ └─────────────────────────────────────────────────────────┘│
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Tool Categories
|
||||
|
||||
### Direct Tools (12 tools - always visible)
|
||||
|
||||
These cover the primary workflow (80%+ of use cases):
|
||||
|
||||
1. **Project Lifecycle** (4):
|
||||
- `create_project` - Create new KiCAD project
|
||||
- `open_project` - Open existing project
|
||||
- `save_project` - Save current project
|
||||
- `get_project_info` - Get project information
|
||||
|
||||
2. **Core PCB Operations** (6):
|
||||
- `place_component` - Place component on board
|
||||
- `move_component` - Move component to new position
|
||||
- `add_net` - Create a new net
|
||||
- `route_trace` - Route trace between points
|
||||
- `get_board_info` - Get board information
|
||||
- `set_board_size` - Set board dimensions
|
||||
|
||||
3. **Board Setup** (1):
|
||||
- `add_board_outline` - Add board outline
|
||||
|
||||
4. **UI Management** (1):
|
||||
- `check_kicad_ui` - Check if KiCAD UI is running
|
||||
|
||||
### Routed Categories (8+ categories, 110+ tools)
|
||||
|
||||
#### 1. `board` - Board Configuration & Layout (9 tools)
|
||||
Setup and configuration operations.
|
||||
|
||||
**Tools:**
|
||||
- `add_layer` - Add PCB layer
|
||||
- `set_active_layer` - Set active layer
|
||||
- `get_layer_list` - List all layers
|
||||
- `add_mounting_hole` - Add mounting hole
|
||||
- `add_board_text` - Add text to board
|
||||
- `add_zone` - Add copper zone/pour
|
||||
- `get_board_extents` - Get board boundaries
|
||||
- `get_board_2d_view` - Get 2D visualization
|
||||
- `launch_kicad_ui` - Launch KiCAD UI
|
||||
|
||||
#### 2. `component` - Advanced Component Operations (8 tools)
|
||||
Beyond basic placement.
|
||||
|
||||
**Tools:**
|
||||
- `rotate_component` - Rotate component
|
||||
- `delete_component` - Delete component
|
||||
- `edit_component` - Edit component properties
|
||||
- `find_component` - Find component by reference/value
|
||||
- `get_component_properties` - Get component properties
|
||||
- `add_component_annotation` - Add component annotation
|
||||
- `group_components` - Group components together
|
||||
- `replace_component` - Replace component with another
|
||||
|
||||
#### 3. `export` - File Export & Manufacturing (8 tools)
|
||||
Generate output files for fabrication and documentation.
|
||||
|
||||
**Tools:**
|
||||
- `export_gerber` - Export Gerber files
|
||||
- `export_pdf` - Export PDF
|
||||
- `export_svg` - Export SVG
|
||||
- `export_3d` - Export 3D model (STEP/STL/VRML/OBJ)
|
||||
- `export_bom` - Export bill of materials
|
||||
- `export_netlist` - Export netlist
|
||||
- `export_position_file` - Export component positions
|
||||
- `export_vrml` - Export VRML 3D model
|
||||
|
||||
#### 4. `drc` - Design Rules & Validation (9 tools)
|
||||
Design rule checking and electrical validation.
|
||||
|
||||
**Tools:**
|
||||
- `set_design_rules` - Configure design rules
|
||||
- `get_design_rules` - Get current rules
|
||||
- `run_drc` - Run design rule check
|
||||
- `add_net_class` - Add net class
|
||||
- `assign_net_to_class` - Assign net to class
|
||||
- `set_layer_constraints` - Set layer constraints
|
||||
- `check_clearance` - Check clearance between items
|
||||
- `get_drc_violations` - Get DRC violations
|
||||
|
||||
#### 5. `schematic` - Schematic Operations (9 tools)
|
||||
Schematic editor operations.
|
||||
|
||||
**Tools:**
|
||||
- `create_schematic` - Create new schematic
|
||||
- `add_schematic_component` - Add component to schematic
|
||||
- `add_wire` - Add wire connection
|
||||
- `add_schematic_connection` - Connect component pins
|
||||
- `add_schematic_net_label` - Add net label
|
||||
- `connect_to_net` - Connect pin to net
|
||||
- `get_net_connections` - Get net connections
|
||||
- `generate_netlist` - Generate netlist
|
||||
|
||||
#### 6. `library` - Footprint Library Access (4 tools)
|
||||
Search and browse footprint libraries.
|
||||
|
||||
**Tools:**
|
||||
- `list_libraries` - List available libraries
|
||||
- `search_footprints` - Search footprints
|
||||
- `list_library_footprints` - List library footprints
|
||||
- `get_footprint_info` - Get footprint details
|
||||
|
||||
#### 7. `routing` - Advanced Routing (3 tools)
|
||||
Advanced routing operations beyond basic trace routing.
|
||||
|
||||
**Tools:**
|
||||
- `add_via` - Add via
|
||||
- `add_copper_pour` - Add copper pour
|
||||
|
||||
**Note:** `add_net` and `route_trace` are direct tools as they're core operations.
|
||||
|
||||
## Router Tools
|
||||
|
||||
### 1. `list_tool_categories`
|
||||
**Description:** List all available tool categories with descriptions and tool counts.
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"total_categories": 7,
|
||||
"total_tools": 47,
|
||||
"categories": [
|
||||
{
|
||||
"name": "board",
|
||||
"description": "Board configuration: layers, mounting holes, zones, visualization",
|
||||
"tool_count": 9
|
||||
},
|
||||
// ... more categories
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2. `get_category_tools`
|
||||
**Description:** Get detailed information about all tools in a specific category.
|
||||
|
||||
**Parameters:**
|
||||
- `category` (string) - Category name from `list_tool_categories`
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"category": "export",
|
||||
"description": "File export for fabrication and documentation: Gerber, PDF, BOM, 3D models",
|
||||
"tools": [
|
||||
{
|
||||
"name": "export_gerber",
|
||||
"description": "Export Gerber files for PCB fabrication",
|
||||
"parameters": { /* zod schema */ }
|
||||
},
|
||||
// ... more tools
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3. `execute_tool`
|
||||
**Description:** Execute a tool from any category.
|
||||
|
||||
**Parameters:**
|
||||
- `tool_name` (string) - Tool name from `get_category_tools`
|
||||
- `params` (object, optional) - Tool parameters
|
||||
|
||||
**Returns:** Tool execution result
|
||||
|
||||
### 4. `search_tools`
|
||||
**Description:** Search for tools by keyword across all categories.
|
||||
|
||||
**Parameters:**
|
||||
- `query` (string) - Search term (e.g., "gerber", "zone", "export")
|
||||
|
||||
**Returns:**
|
||||
```json
|
||||
{
|
||||
"query": "export",
|
||||
"count": 8,
|
||||
"matches": [
|
||||
{
|
||||
"category": "export",
|
||||
"tool": "export_gerber",
|
||||
"description": "Export Gerber files for PCB fabrication"
|
||||
},
|
||||
// ... more matches
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation Files
|
||||
|
||||
### New Files to Create
|
||||
|
||||
1. **`src/tools/registry.ts`**
|
||||
- Tool category definitions
|
||||
- Tool metadata storage
|
||||
- Lookup maps (by name, by category)
|
||||
- Search functionality
|
||||
|
||||
2. **`src/tools/router.ts`**
|
||||
- Router tool implementations
|
||||
- `list_tool_categories` handler
|
||||
- `get_category_tools` handler
|
||||
- `execute_tool` handler
|
||||
- `search_tools` handler
|
||||
|
||||
3. **`src/tools/direct.ts`**
|
||||
- Export direct tool definitions
|
||||
- Keep existing tool implementations but organized
|
||||
|
||||
### Modified Files
|
||||
|
||||
1. **`src/server.ts`** or **`src/kicad-server.ts`**
|
||||
- Register only direct tools + router tools
|
||||
- Remove registration of routed tools
|
||||
- Tools still callable via `execute_tool`
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### Phase 1: Create Infrastructure
|
||||
1. Create `registry.ts` with all tool definitions
|
||||
2. Create `router.ts` with router tools
|
||||
3. Create `direct.ts` with direct tool list
|
||||
|
||||
### Phase 2: Update Server
|
||||
1. Modify server registration to use direct + router only
|
||||
2. Keep all existing tool handlers intact
|
||||
3. Route through `execute_tool`
|
||||
|
||||
### Phase 3: Testing
|
||||
1. Test direct tools work as before
|
||||
2. Test router tools (list/get/execute/search)
|
||||
3. Test routed tools via `execute_tool`
|
||||
|
||||
### Phase 4: Optimization (Optional)
|
||||
1. Add caching for tool lookups
|
||||
2. Add tool usage analytics
|
||||
3. Implement intelligent tool suggestions
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Context Efficiency**: 70% reduction in tokens (~28K saved)
|
||||
2. **Better Organization**: Tools grouped by function
|
||||
3. **Discoverability**: Easy to find the right tool
|
||||
4. **Scalability**: Can add unlimited tools without bloating context
|
||||
5. **Backwards Compatible**: Existing Python commands still work
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Example 1: User Wants to Export Gerbers
|
||||
|
||||
```
|
||||
User: "Export gerbers for this board"
|
||||
|
||||
Claude's workflow:
|
||||
1. Sees "export" keyword
|
||||
2. Calls search_tools({ query: "gerber" })
|
||||
→ Returns: { category: "export", tool: "export_gerber", ... }
|
||||
3. Calls execute_tool({
|
||||
tool_name: "export_gerber",
|
||||
params: { outputDir: "./gerbers" }
|
||||
})
|
||||
→ Returns: { success: true, files: [...] }
|
||||
|
||||
Claude: "I've exported the Gerber files to ./gerbers/"
|
||||
```
|
||||
|
||||
### Example 2: User Wants to Place Component
|
||||
|
||||
```
|
||||
User: "Add a 0805 resistor at position 10,20"
|
||||
|
||||
Claude's workflow:
|
||||
1. Sees place_component in direct tools
|
||||
2. Calls place_component({
|
||||
componentId: "R_0805",
|
||||
position: { x: 10, y: 20, unit: "mm" }
|
||||
})
|
||||
→ Returns: { success: true, reference: "R1" }
|
||||
|
||||
Claude: "Added R1 (0805 resistor) at position (10, 20) mm"
|
||||
```
|
||||
|
||||
### Example 3: User Wants Unknown Operation
|
||||
|
||||
```
|
||||
User: "Check the board for design rule violations"
|
||||
|
||||
Claude's workflow:
|
||||
1. Uncertain which tool to use
|
||||
2. Calls search_tools({ query: "design rule violations" })
|
||||
→ Returns: { category: "drc", tool: "run_drc", ...}
|
||||
3. Calls get_category_tools({ category: "drc" })
|
||||
→ Returns full DRC category tools with parameters
|
||||
4. Calls execute_tool({
|
||||
tool_name: "run_drc",
|
||||
params: {}
|
||||
})
|
||||
→ Returns: DRC results
|
||||
|
||||
Claude: "I ran the design rule check. Found 3 violations: ..."
|
||||
```
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- ✅ Token usage: ~12K (vs 40K before)
|
||||
- ✅ Tool discovery time: <2 calls (search → execute)
|
||||
- ✅ User experience: Unchanged (seamless)
|
||||
- ✅ Maintainability: Improved (organized categories)
|
||||
- ✅ Scalability: Can add 100+ more tools easily
|
||||
# Router Architecture Design
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the router pattern implementation for the KiCAD MCP Server. The router reduces context window consumption by organizing 122+ tools into 8 discoverable categories, keeping only the most frequently used tools directly visible.
|
||||
|
||||
## Architecture Layers
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ MCP Client (Claude) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ KiCAD MCP Server │
|
||||
│ ┌─────────────────────────────────────────────────────────┐│
|
||||
│ │ DIRECT TOOLS (Always Visible - 12) ││
|
||||
│ │ • create_project • open_project • save_project ││
|
||||
│ │ • get_project_info • place_component • move_component ││
|
||||
│ │ • add_net • route_trace • get_board_info ││
|
||||
│ │ • set_board_size • add_board_outline • check_kicad_ui││
|
||||
│ └─────────────────────────────────────────────────────────┘│
|
||||
│ ┌─────────────────────────────────────────────────────────┐│
|
||||
│ │ ROUTER TOOLS (Discovery - 4) ││
|
||||
│ │ • list_tool_categories • get_category_tools ││
|
||||
│ │ • execute_tool • search_tools ││
|
||||
│ └─────────────────────────────────────────────────────────┘│
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐│
|
||||
│ │ ROUTED TOOLS (Hidden - 110+) ││
|
||||
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││
|
||||
│ │ │ board │ │component │ │ export │ │ drc │ ││
|
||||
│ │ │ tools │ │ tools │ │ tools │ │ tools │ ││
|
||||
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ ││
|
||||
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││
|
||||
│ │ │schematic │ │ library │ │ routing │ │footprint │ ││
|
||||
│ │ │ tools │ │ tools │ │ tools │ │ tools │ ││
|
||||
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ ││
|
||||
│ └─────────────────────────────────────────────────────────┘│
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Tool Categories
|
||||
|
||||
### Direct Tools (12 tools - always visible)
|
||||
|
||||
These cover the primary workflow (80%+ of use cases):
|
||||
|
||||
1. **Project Lifecycle** (4):
|
||||
- `create_project` - Create new KiCAD project
|
||||
- `open_project` - Open existing project
|
||||
- `save_project` - Save current project
|
||||
- `get_project_info` - Get project information
|
||||
|
||||
2. **Core PCB Operations** (6):
|
||||
- `place_component` - Place component on board
|
||||
- `move_component` - Move component to new position
|
||||
- `add_net` - Create a new net
|
||||
- `route_trace` - Route trace between points
|
||||
- `get_board_info` - Get board information
|
||||
- `set_board_size` - Set board dimensions
|
||||
|
||||
3. **Board Setup** (1):
|
||||
- `add_board_outline` - Add board outline
|
||||
|
||||
4. **UI Management** (1):
|
||||
- `check_kicad_ui` - Check if KiCAD UI is running
|
||||
|
||||
### Routed Categories (8+ categories, 110+ tools)
|
||||
|
||||
#### 1. `board` - Board Configuration & Layout (9 tools)
|
||||
|
||||
Setup and configuration operations.
|
||||
|
||||
**Tools:**
|
||||
|
||||
- `add_layer` - Add PCB layer
|
||||
- `set_active_layer` - Set active layer
|
||||
- `get_layer_list` - List all layers
|
||||
- `add_mounting_hole` - Add mounting hole
|
||||
- `add_board_text` - Add text to board
|
||||
- `add_zone` - Add copper zone/pour
|
||||
- `get_board_extents` - Get board boundaries
|
||||
- `get_board_2d_view` - Get 2D visualization
|
||||
- `launch_kicad_ui` - Launch KiCAD UI
|
||||
|
||||
#### 2. `component` - Advanced Component Operations (8 tools)
|
||||
|
||||
Beyond basic placement.
|
||||
|
||||
**Tools:**
|
||||
|
||||
- `rotate_component` - Rotate component
|
||||
- `delete_component` - Delete component
|
||||
- `edit_component` - Edit component properties
|
||||
- `find_component` - Find component by reference/value
|
||||
- `get_component_properties` - Get component properties
|
||||
- `add_component_annotation` - Add component annotation
|
||||
- `group_components` - Group components together
|
||||
- `replace_component` - Replace component with another
|
||||
|
||||
#### 3. `export` - File Export & Manufacturing (8 tools)
|
||||
|
||||
Generate output files for fabrication and documentation.
|
||||
|
||||
**Tools:**
|
||||
|
||||
- `export_gerber` - Export Gerber files
|
||||
- `export_pdf` - Export PDF
|
||||
- `export_svg` - Export SVG
|
||||
- `export_3d` - Export 3D model (STEP/STL/VRML/OBJ)
|
||||
- `export_bom` - Export bill of materials
|
||||
- `export_netlist` - Export netlist
|
||||
- `export_position_file` - Export component positions
|
||||
- `export_vrml` - Export VRML 3D model
|
||||
|
||||
#### 4. `drc` - Design Rules & Validation (9 tools)
|
||||
|
||||
Design rule checking and electrical validation.
|
||||
|
||||
**Tools:**
|
||||
|
||||
- `set_design_rules` - Configure design rules
|
||||
- `get_design_rules` - Get current rules
|
||||
- `run_drc` - Run design rule check
|
||||
- `add_net_class` - Add net class
|
||||
- `assign_net_to_class` - Assign net to class
|
||||
- `set_layer_constraints` - Set layer constraints
|
||||
- `check_clearance` - Check clearance between items
|
||||
- `get_drc_violations` - Get DRC violations
|
||||
|
||||
#### 5. `schematic` - Schematic Operations (9 tools)
|
||||
|
||||
Schematic editor operations.
|
||||
|
||||
**Tools:**
|
||||
|
||||
- `create_schematic` - Create new schematic
|
||||
- `add_schematic_component` - Add component to schematic
|
||||
- `add_wire` - Add wire connection
|
||||
- `add_schematic_connection` - Connect component pins
|
||||
- `add_schematic_net_label` - Add net label
|
||||
- `connect_to_net` - Connect pin to net
|
||||
- `get_net_connections` - Get net connections
|
||||
- `generate_netlist` - Generate netlist
|
||||
|
||||
#### 6. `library` - Footprint Library Access (4 tools)
|
||||
|
||||
Search and browse footprint libraries.
|
||||
|
||||
**Tools:**
|
||||
|
||||
- `list_libraries` - List available libraries
|
||||
- `search_footprints` - Search footprints
|
||||
- `list_library_footprints` - List library footprints
|
||||
- `get_footprint_info` - Get footprint details
|
||||
|
||||
#### 7. `routing` - Advanced Routing (3 tools)
|
||||
|
||||
Advanced routing operations beyond basic trace routing.
|
||||
|
||||
**Tools:**
|
||||
|
||||
- `add_via` - Add via
|
||||
- `add_copper_pour` - Add copper pour
|
||||
|
||||
**Note:** `add_net` and `route_trace` are direct tools as they're core operations.
|
||||
|
||||
## Router Tools
|
||||
|
||||
### 1. `list_tool_categories`
|
||||
|
||||
**Description:** List all available tool categories with descriptions and tool counts.
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Returns:**
|
||||
|
||||
```json
|
||||
{
|
||||
"total_categories": 7,
|
||||
"total_tools": 47,
|
||||
"categories": [
|
||||
{
|
||||
"name": "board",
|
||||
"description": "Board configuration: layers, mounting holes, zones, visualization",
|
||||
"tool_count": 9
|
||||
}
|
||||
// ... more categories
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2. `get_category_tools`
|
||||
|
||||
**Description:** Get detailed information about all tools in a specific category.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `category` (string) - Category name from `list_tool_categories`
|
||||
|
||||
**Returns:**
|
||||
|
||||
```json
|
||||
{
|
||||
"category": "export",
|
||||
"description": "File export for fabrication and documentation: Gerber, PDF, BOM, 3D models",
|
||||
"tools": [
|
||||
{
|
||||
"name": "export_gerber",
|
||||
"description": "Export Gerber files for PCB fabrication",
|
||||
"parameters": {
|
||||
/* zod schema */
|
||||
}
|
||||
}
|
||||
// ... more tools
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3. `execute_tool`
|
||||
|
||||
**Description:** Execute a tool from any category.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `tool_name` (string) - Tool name from `get_category_tools`
|
||||
- `params` (object, optional) - Tool parameters
|
||||
|
||||
**Returns:** Tool execution result
|
||||
|
||||
### 4. `search_tools`
|
||||
|
||||
**Description:** Search for tools by keyword across all categories.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `query` (string) - Search term (e.g., "gerber", "zone", "export")
|
||||
|
||||
**Returns:**
|
||||
|
||||
```json
|
||||
{
|
||||
"query": "export",
|
||||
"count": 8,
|
||||
"matches": [
|
||||
{
|
||||
"category": "export",
|
||||
"tool": "export_gerber",
|
||||
"description": "Export Gerber files for PCB fabrication"
|
||||
}
|
||||
// ... more matches
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation Files
|
||||
|
||||
### New Files to Create
|
||||
|
||||
1. **`src/tools/registry.ts`**
|
||||
- Tool category definitions
|
||||
- Tool metadata storage
|
||||
- Lookup maps (by name, by category)
|
||||
- Search functionality
|
||||
|
||||
2. **`src/tools/router.ts`**
|
||||
- Router tool implementations
|
||||
- `list_tool_categories` handler
|
||||
- `get_category_tools` handler
|
||||
- `execute_tool` handler
|
||||
- `search_tools` handler
|
||||
|
||||
3. **`src/tools/direct.ts`**
|
||||
- Export direct tool definitions
|
||||
- Keep existing tool implementations but organized
|
||||
|
||||
### Modified Files
|
||||
|
||||
1. **`src/server.ts`** or **`src/kicad-server.ts`**
|
||||
- Register only direct tools + router tools
|
||||
- Remove registration of routed tools
|
||||
- Tools still callable via `execute_tool`
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### Phase 1: Create Infrastructure
|
||||
|
||||
1. Create `registry.ts` with all tool definitions
|
||||
2. Create `router.ts` with router tools
|
||||
3. Create `direct.ts` with direct tool list
|
||||
|
||||
### Phase 2: Update Server
|
||||
|
||||
1. Modify server registration to use direct + router only
|
||||
2. Keep all existing tool handlers intact
|
||||
3. Route through `execute_tool`
|
||||
|
||||
### Phase 3: Testing
|
||||
|
||||
1. Test direct tools work as before
|
||||
2. Test router tools (list/get/execute/search)
|
||||
3. Test routed tools via `execute_tool`
|
||||
|
||||
### Phase 4: Optimization (Optional)
|
||||
|
||||
1. Add caching for tool lookups
|
||||
2. Add tool usage analytics
|
||||
3. Implement intelligent tool suggestions
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Context Efficiency**: 70% reduction in tokens (~28K saved)
|
||||
2. **Better Organization**: Tools grouped by function
|
||||
3. **Discoverability**: Easy to find the right tool
|
||||
4. **Scalability**: Can add unlimited tools without bloating context
|
||||
5. **Backwards Compatible**: Existing Python commands still work
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Example 1: User Wants to Export Gerbers
|
||||
|
||||
```
|
||||
User: "Export gerbers for this board"
|
||||
|
||||
Claude's workflow:
|
||||
1. Sees "export" keyword
|
||||
2. Calls search_tools({ query: "gerber" })
|
||||
→ Returns: { category: "export", tool: "export_gerber", ... }
|
||||
3. Calls execute_tool({
|
||||
tool_name: "export_gerber",
|
||||
params: { outputDir: "./gerbers" }
|
||||
})
|
||||
→ Returns: { success: true, files: [...] }
|
||||
|
||||
Claude: "I've exported the Gerber files to ./gerbers/"
|
||||
```
|
||||
|
||||
### Example 2: User Wants to Place Component
|
||||
|
||||
```
|
||||
User: "Add a 0805 resistor at position 10,20"
|
||||
|
||||
Claude's workflow:
|
||||
1. Sees place_component in direct tools
|
||||
2. Calls place_component({
|
||||
componentId: "R_0805",
|
||||
position: { x: 10, y: 20, unit: "mm" }
|
||||
})
|
||||
→ Returns: { success: true, reference: "R1" }
|
||||
|
||||
Claude: "Added R1 (0805 resistor) at position (10, 20) mm"
|
||||
```
|
||||
|
||||
### Example 3: User Wants Unknown Operation
|
||||
|
||||
```
|
||||
User: "Check the board for design rule violations"
|
||||
|
||||
Claude's workflow:
|
||||
1. Uncertain which tool to use
|
||||
2. Calls search_tools({ query: "design rule violations" })
|
||||
→ Returns: { category: "drc", tool: "run_drc", ...}
|
||||
3. Calls get_category_tools({ category: "drc" })
|
||||
→ Returns full DRC category tools with parameters
|
||||
4. Calls execute_tool({
|
||||
tool_name: "run_drc",
|
||||
params: {}
|
||||
})
|
||||
→ Returns: DRC results
|
||||
|
||||
Claude: "I ran the design rule check. Found 3 violations: ..."
|
||||
```
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- ✅ Token usage: ~12K (vs 40K before)
|
||||
- ✅ Tool discovery time: <2 calls (search → execute)
|
||||
- ✅ User experience: Unchanged (seamless)
|
||||
- ✅ Maintainability: Improved (organized categories)
|
||||
- ✅ Scalability: Can add 100+ more tools easily
|
||||
|
||||
@@ -1,165 +1,197 @@
|
||||
# Router Quick Start Guide
|
||||
|
||||
## What is the Router?
|
||||
|
||||
The KiCAD MCP Server includes an intelligent tool router that organizes 122+ tools into 8 discoverable categories. This reduces AI context usage by up to 70% while maintaining full access to all functionality.
|
||||
|
||||
## How It Works
|
||||
|
||||
Instead of loading all 59 tool schemas into every conversation, Claude now sees:
|
||||
- **12 direct tools** for high-frequency operations (always visible)
|
||||
- **4 router tools** for discovering and executing the other 47 tools
|
||||
|
||||
When you ask Claude to do something (like "export gerber files"), it will:
|
||||
1. Search for relevant tools using `search_tools`
|
||||
2. Find the `export_gerber` tool in the "export" category
|
||||
3. Execute it via `execute_tool` with your parameters
|
||||
4. Return the results
|
||||
|
||||
**You don't need to change how you interact with Claude** - the discovery happens automatically!
|
||||
|
||||
## Tool Categories
|
||||
|
||||
The 110+ routed tools are organized into these categories:
|
||||
|
||||
### 1. board (9 tools)
|
||||
Board configuration: layers, mounting holes, zones, visualization
|
||||
- add_layer, set_active_layer, get_layer_list
|
||||
- add_mounting_hole, add_board_text
|
||||
- add_zone, get_board_extents, get_board_2d_view
|
||||
- launch_kicad_ui
|
||||
|
||||
### 2. component (8 tools)
|
||||
Advanced component operations: edit, delete, search, group, annotate
|
||||
- rotate_component, delete_component, edit_component
|
||||
- find_component, get_component_properties
|
||||
- add_component_annotation, group_components, replace_component
|
||||
|
||||
### 3. export (8 tools)
|
||||
File export for fabrication and documentation
|
||||
- export_gerber, export_pdf, export_svg, export_3d
|
||||
- export_bom, export_netlist, export_position_file, export_vrml
|
||||
|
||||
### 4. drc (8 tools)
|
||||
Design rule checking and electrical validation
|
||||
- set_design_rules, get_design_rules, run_drc
|
||||
- add_net_class, assign_net_to_class, set_layer_constraints
|
||||
- check_clearance, get_drc_violations
|
||||
|
||||
### 5. schematic (8 tools)
|
||||
Schematic operations: create, add components, wire connections
|
||||
- create_schematic, add_schematic_component, add_wire
|
||||
- add_schematic_connection, add_schematic_net_label
|
||||
- connect_to_net, get_net_connections, generate_netlist
|
||||
|
||||
### 6. library (4 tools)
|
||||
Footprint library access and search
|
||||
- list_libraries, search_footprints
|
||||
- list_library_footprints, get_footprint_info
|
||||
|
||||
### 7. routing (2 tools)
|
||||
Advanced routing operations
|
||||
- add_via, add_copper_pour
|
||||
|
||||
## Direct Tools (Always Available)
|
||||
|
||||
These 12 tools are always visible for common operations:
|
||||
|
||||
**Project Lifecycle:**
|
||||
- create_project, open_project, save_project, get_project_info
|
||||
|
||||
**Core PCB Operations:**
|
||||
- place_component, move_component
|
||||
- add_net, route_trace
|
||||
- get_board_info, set_board_size
|
||||
- add_board_outline
|
||||
|
||||
**UI Management:**
|
||||
- check_kicad_ui
|
||||
|
||||
## Router Tools
|
||||
|
||||
### list_tool_categories
|
||||
Browse all available tool categories.
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Claude, what tool categories are available?
|
||||
```
|
||||
|
||||
### get_category_tools
|
||||
View all tools in a specific category.
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Show me all export tools available.
|
||||
```
|
||||
|
||||
### search_tools
|
||||
Find tools by keyword.
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Search for tools related to "gerber" or "mounting holes"
|
||||
```
|
||||
|
||||
### execute_tool
|
||||
Execute any routed tool with parameters.
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Execute the export_gerber tool with outputDir set to ./fabrication
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Natural Interaction (Recommended)
|
||||
Just ask Claude what you want - it handles discovery automatically:
|
||||
|
||||
```
|
||||
"Export gerber files to ./output"
|
||||
"Add a mounting hole at x=10, y=10"
|
||||
"Run a design rule check"
|
||||
"Create a copper pour on the ground layer"
|
||||
```
|
||||
|
||||
### Manual Discovery (Optional)
|
||||
You can also browse tools explicitly:
|
||||
|
||||
```
|
||||
"List all tool categories"
|
||||
"What export tools are available?"
|
||||
"Search for DRC tools"
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Reduced Context Usage**: 70% less AI context consumed per conversation
|
||||
2. **Organized Tools**: Logical categorization makes tools easy to find
|
||||
3. **Seamless Experience**: Works transparently - no changes to how you interact
|
||||
4. **Extensible**: Easy to add new tools and categories
|
||||
5. **Backwards Compatible**: All existing tools still work
|
||||
|
||||
## Technical Details
|
||||
|
||||
- **Registry**: `src/tools/registry.ts` - Tool categorization and lookup
|
||||
- **Router**: `src/tools/router.ts` - Discovery and execution implementation
|
||||
- **Server Integration**: `src/server.ts` - Router tools registered at startup
|
||||
|
||||
For implementation details, see:
|
||||
- [ROUTER_ARCHITECTURE.md](ROUTER_ARCHITECTURE.md) - Design specification
|
||||
- [ROUTER_IMPLEMENTATION_STATUS.md](ROUTER_IMPLEMENTATION_STATUS.md) - Current status
|
||||
- [TOOL_INVENTORY.md](TOOL_INVENTORY.md) - Complete tool catalog
|
||||
|
||||
## Token Savings
|
||||
|
||||
**Before Router:**
|
||||
- 122 tools × ~700 tokens each = ~85K tokens per conversation
|
||||
|
||||
**After Router (Current):**
|
||||
- 12 direct tools + 4 router tools = 16 tools visible
|
||||
- Routed tools discovered on-demand
|
||||
- ~12-15K tokens per conversation
|
||||
- **~80% reduction** in context usage
|
||||
|
||||
The router pattern is complete and functional, providing efficient tool discovery while maintaining full access to all 122+ tools.
|
||||
# Router Quick Start Guide
|
||||
|
||||
## What is the Router?
|
||||
|
||||
The KiCAD MCP Server includes an intelligent tool router that organizes 122+ tools into 8 discoverable categories. This reduces AI context usage by up to 70% while maintaining full access to all functionality.
|
||||
|
||||
## How It Works
|
||||
|
||||
Instead of loading all 59 tool schemas into every conversation, Claude now sees:
|
||||
|
||||
- **12 direct tools** for high-frequency operations (always visible)
|
||||
- **4 router tools** for discovering and executing the other 47 tools
|
||||
|
||||
When you ask Claude to do something (like "export gerber files"), it will:
|
||||
|
||||
1. Search for relevant tools using `search_tools`
|
||||
2. Find the `export_gerber` tool in the "export" category
|
||||
3. Execute it via `execute_tool` with your parameters
|
||||
4. Return the results
|
||||
|
||||
**You don't need to change how you interact with Claude** - the discovery happens automatically!
|
||||
|
||||
## Tool Categories
|
||||
|
||||
The 110+ routed tools are organized into these categories:
|
||||
|
||||
### 1. board (9 tools)
|
||||
|
||||
Board configuration: layers, mounting holes, zones, visualization
|
||||
|
||||
- add_layer, set_active_layer, get_layer_list
|
||||
- add_mounting_hole, add_board_text
|
||||
- add_zone, get_board_extents, get_board_2d_view
|
||||
- launch_kicad_ui
|
||||
|
||||
### 2. component (8 tools)
|
||||
|
||||
Advanced component operations: edit, delete, search, group, annotate
|
||||
|
||||
- rotate_component, delete_component, edit_component
|
||||
- find_component, get_component_properties
|
||||
- add_component_annotation, group_components, replace_component
|
||||
|
||||
### 3. export (8 tools)
|
||||
|
||||
File export for fabrication and documentation
|
||||
|
||||
- export_gerber, export_pdf, export_svg, export_3d
|
||||
- export_bom, export_netlist, export_position_file, export_vrml
|
||||
|
||||
### 4. drc (8 tools)
|
||||
|
||||
Design rule checking and electrical validation
|
||||
|
||||
- set_design_rules, get_design_rules, run_drc
|
||||
- add_net_class, assign_net_to_class, set_layer_constraints
|
||||
- check_clearance, get_drc_violations
|
||||
|
||||
### 5. schematic (8 tools)
|
||||
|
||||
Schematic operations: create, add components, wire connections
|
||||
|
||||
- create_schematic, add_schematic_component, add_wire
|
||||
- add_schematic_connection, add_schematic_net_label
|
||||
- connect_to_net, get_net_connections, generate_netlist
|
||||
|
||||
### 6. library (4 tools)
|
||||
|
||||
Footprint library access and search
|
||||
|
||||
- list_libraries, search_footprints
|
||||
- list_library_footprints, get_footprint_info
|
||||
|
||||
### 7. routing (2 tools)
|
||||
|
||||
Advanced routing operations
|
||||
|
||||
- add_via, add_copper_pour
|
||||
|
||||
## Direct Tools (Always Available)
|
||||
|
||||
These 12 tools are always visible for common operations:
|
||||
|
||||
**Project Lifecycle:**
|
||||
|
||||
- create_project, open_project, save_project, get_project_info
|
||||
|
||||
**Core PCB Operations:**
|
||||
|
||||
- place_component, move_component
|
||||
- add_net, route_trace
|
||||
- get_board_info, set_board_size
|
||||
- add_board_outline
|
||||
|
||||
**UI Management:**
|
||||
|
||||
- check_kicad_ui
|
||||
|
||||
## Router Tools
|
||||
|
||||
### list_tool_categories
|
||||
|
||||
Browse all available tool categories.
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
Claude, what tool categories are available?
|
||||
```
|
||||
|
||||
### get_category_tools
|
||||
|
||||
View all tools in a specific category.
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
Show me all export tools available.
|
||||
```
|
||||
|
||||
### search_tools
|
||||
|
||||
Find tools by keyword.
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
Search for tools related to "gerber" or "mounting holes"
|
||||
```
|
||||
|
||||
### execute_tool
|
||||
|
||||
Execute any routed tool with parameters.
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
Execute the export_gerber tool with outputDir set to ./fabrication
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Natural Interaction (Recommended)
|
||||
|
||||
Just ask Claude what you want - it handles discovery automatically:
|
||||
|
||||
```
|
||||
"Export gerber files to ./output"
|
||||
"Add a mounting hole at x=10, y=10"
|
||||
"Run a design rule check"
|
||||
"Create a copper pour on the ground layer"
|
||||
```
|
||||
|
||||
### Manual Discovery (Optional)
|
||||
|
||||
You can also browse tools explicitly:
|
||||
|
||||
```
|
||||
"List all tool categories"
|
||||
"What export tools are available?"
|
||||
"Search for DRC tools"
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Reduced Context Usage**: 70% less AI context consumed per conversation
|
||||
2. **Organized Tools**: Logical categorization makes tools easy to find
|
||||
3. **Seamless Experience**: Works transparently - no changes to how you interact
|
||||
4. **Extensible**: Easy to add new tools and categories
|
||||
5. **Backwards Compatible**: All existing tools still work
|
||||
|
||||
## Technical Details
|
||||
|
||||
- **Registry**: `src/tools/registry.ts` - Tool categorization and lookup
|
||||
- **Router**: `src/tools/router.ts` - Discovery and execution implementation
|
||||
- **Server Integration**: `src/server.ts` - Router tools registered at startup
|
||||
|
||||
For implementation details, see:
|
||||
|
||||
- [ROUTER_ARCHITECTURE.md](ROUTER_ARCHITECTURE.md) - Design specification
|
||||
- [ROUTER_IMPLEMENTATION_STATUS.md](ROUTER_IMPLEMENTATION_STATUS.md) - Current status
|
||||
- [TOOL_INVENTORY.md](TOOL_INVENTORY.md) - Complete tool catalog
|
||||
|
||||
## Token Savings
|
||||
|
||||
**Before Router:**
|
||||
|
||||
- 122 tools × ~700 tokens each = ~85K tokens per conversation
|
||||
|
||||
**After Router (Current):**
|
||||
|
||||
- 12 direct tools + 4 router tools = 16 tools visible
|
||||
- Routed tools discovered on-demand
|
||||
- ~12-15K tokens per conversation
|
||||
- **~80% reduction** in context usage
|
||||
|
||||
The router pattern is complete and functional, providing efficient tool discovery while maintaining full access to all 122+ tools.
|
||||
|
||||
@@ -12,17 +12,19 @@ Create a new net on the PCB.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| name | string | Yes | Net name |
|
||||
| netClass | string | No | Net class name |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------ | -------- | -------------- |
|
||||
| name | string | Yes | Net name |
|
||||
| netClass | string | No | Net class name |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- Creates a new net that can be assigned to traces and pads
|
||||
- If the net already exists, it will be reused
|
||||
- Net class assignment is optional; defaults to "Default" if not specified
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "VCC_3V3",
|
||||
@@ -38,25 +40,27 @@ Route a trace segment between two XY points on a fixed layer.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| start | object | Yes | Start position with x, y, and optional unit |
|
||||
| end | object | Yes | End position with x, y, and optional unit |
|
||||
| layer | string | Yes | PCB layer |
|
||||
| width | number | Yes | Trace width in mm |
|
||||
| net | string | Yes | Net name |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------ | -------- | ------------------------------------------- |
|
||||
| start | object | Yes | Start position with x, y, and optional unit |
|
||||
| end | object | Yes | End position with x, y, and optional unit |
|
||||
| layer | string | Yes | PCB layer |
|
||||
| width | number | Yes | Trace width in mm |
|
||||
| net | string | Yes | Net name |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- WARNING: Does NOT handle layer changes
|
||||
- If start and end are on different copper layers, use `route_pad_to_pad` instead, which automatically inserts a via
|
||||
- Coordinates use mm by default unless unit is specified
|
||||
- This is a low-level tool; prefer `route_pad_to_pad` for component-to-component routing
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"start": {"x": 100.0, "y": 50.0, "unit": "mm"},
|
||||
"end": {"x": 120.0, "y": 50.0, "unit": "mm"},
|
||||
"start": { "x": 100.0, "y": 50.0, "unit": "mm" },
|
||||
"end": { "x": 120.0, "y": 50.0, "unit": "mm" },
|
||||
"layer": "F.Cu",
|
||||
"width": 0.25,
|
||||
"net": "GND"
|
||||
@@ -71,17 +75,18 @@ PREFERRED tool for pad-to-pad routing. Looks up pad positions automatically, det
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| fromRef | string | Yes | Reference of the source component (e.g. 'U2') |
|
||||
| fromPad | string/number | Yes | Pad number on the source component (e.g. '6' or 6) |
|
||||
| toRef | string | Yes | Reference of the target component (e.g. 'U1') |
|
||||
| toPad | string/number | Yes | Pad number on the target component (e.g. '15' or 15) |
|
||||
| layer | string | No | PCB layer (default: F.Cu) |
|
||||
| width | number | No | Trace width in mm (default: board default) |
|
||||
| net | string | No | Net name override (default: auto-detected from pad) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------------- | -------- | ---------------------------------------------------- |
|
||||
| fromRef | string | Yes | Reference of the source component (e.g. 'U2') |
|
||||
| fromPad | string/number | Yes | Pad number on the source component (e.g. '6' or 6) |
|
||||
| toRef | string | Yes | Reference of the target component (e.g. 'U1') |
|
||||
| toPad | string/number | Yes | Pad number on the target component (e.g. '15' or 15) |
|
||||
| layer | string | No | PCB layer (default: F.Cu) |
|
||||
| width | number | No | Trace width in mm (default: board default) |
|
||||
| net | string | No | Net name override (default: auto-detected from pad) |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- This is the PREFERRED tool for routing between component pads
|
||||
- Automatically looks up pad positions - no need to query them separately
|
||||
- Auto-detects the net from the source pad
|
||||
@@ -90,6 +95,7 @@ PREFERRED tool for pad-to-pad routing. Looks up pad positions automatically, det
|
||||
- Via is placed at the start pad's X coordinate to avoid stacking issues with back-to-back mirrored connectors
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"fromRef": "U2",
|
||||
@@ -110,22 +116,24 @@ Add a via to the PCB.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| position | object | Yes | Via position with x, y, and optional unit |
|
||||
| net | string | Yes | Net name |
|
||||
| viaType | string | No | Via type: "through", "blind", or "buried" |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------ | -------- | ----------------------------------------- |
|
||||
| position | object | Yes | Via position with x, y, and optional unit |
|
||||
| net | string | Yes | Net name |
|
||||
| viaType | string | No | Via type: "through", "blind", or "buried" |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- Through vias connect all layers (default)
|
||||
- Blind vias connect an outer layer to one or more inner layers
|
||||
- Buried vias connect two or more inner layers without reaching outer layers
|
||||
- Position coordinates use mm by default
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"position": {"x": 110.0, "y": 50.0, "unit": "mm"},
|
||||
"position": { "x": 110.0, "y": 50.0, "unit": "mm" },
|
||||
"net": "GND",
|
||||
"viaType": "through"
|
||||
}
|
||||
@@ -141,27 +149,29 @@ Route a differential pair between two sets of points.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| positivePad | object | Yes | Positive pad with reference and pad number |
|
||||
| negativePad | object | Yes | Negative pad with reference and pad number |
|
||||
| layer | string | Yes | PCB layer |
|
||||
| width | number | Yes | Trace width in mm |
|
||||
| gap | number | Yes | Gap between traces in mm |
|
||||
| positiveNet | string | Yes | Positive net name |
|
||||
| negativeNet | string | Yes | Negative net name |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ----------- | ------ | -------- | ------------------------------------------ |
|
||||
| positivePad | object | Yes | Positive pad with reference and pad number |
|
||||
| negativePad | object | Yes | Negative pad with reference and pad number |
|
||||
| layer | string | Yes | PCB layer |
|
||||
| width | number | Yes | Trace width in mm |
|
||||
| gap | number | Yes | Gap between traces in mm |
|
||||
| positiveNet | string | Yes | Positive net name |
|
||||
| negativeNet | string | Yes | Negative net name |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- Used for high-speed signals like USB, Ethernet, HDMI, etc.
|
||||
- Maintains controlled impedance through consistent trace width and gap
|
||||
- Both traces are routed in parallel with specified separation
|
||||
- Pad object format: `{"reference": "U1", "pad": "1"}`
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"positivePad": {"reference": "J1", "pad": "2"},
|
||||
"negativePad": {"reference": "J1", "pad": "3"},
|
||||
"positivePad": { "reference": "J1", "pad": "2" },
|
||||
"negativePad": { "reference": "J1", "pad": "3" },
|
||||
"layer": "F.Cu",
|
||||
"width": 0.2,
|
||||
"gap": 0.2,
|
||||
@@ -178,14 +188,15 @@ Copy routing pattern (traces and vias) from a group of source components to a ma
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| sourceRefs | array[string] | Yes | References of the source components (e.g. ['U1', 'R1', 'C1']) |
|
||||
| targetRefs | array[string] | Yes | References of the target components in same order as sourceRefs (e.g. ['U2', 'R2', 'C2']) |
|
||||
| includeVias | boolean | No | Also copy vias (default: true) |
|
||||
| traceWidth | number | No | Override trace width in mm (default: keep original width) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ----------- | ------------- | -------- | ----------------------------------------------------------------------------------------- |
|
||||
| sourceRefs | array[string] | Yes | References of the source components (e.g. ['U1', 'R1', 'C1']) |
|
||||
| targetRefs | array[string] | Yes | References of the target components in same order as sourceRefs (e.g. ['U2', 'R2', 'C2']) |
|
||||
| includeVias | boolean | No | Also copy vias (default: true) |
|
||||
| traceWidth | number | No | Override trace width in mm (default: keep original width) |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- The offset is calculated automatically from the position difference between the first source and first target component
|
||||
- Useful for replicating routing between identical circuit blocks
|
||||
- Component arrays must be in matching order (sourceRefs[0] maps to targetRefs[0], etc.)
|
||||
@@ -194,6 +205,7 @@ Copy routing pattern (traces and vias) from a group of source components to a ma
|
||||
- Original trace widths are preserved unless traceWidth override is specified
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"sourceRefs": ["U1", "R1", "C1"],
|
||||
@@ -212,18 +224,20 @@ Get a list of all nets in the PCB with optional statistics.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| includeStats | boolean | No | Include statistics (track count, total length, etc.) |
|
||||
| unit | string | No | Unit for length measurements: "mm" or "inch" |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------ | ------- | -------- | ---------------------------------------------------- |
|
||||
| includeStats | boolean | No | Include statistics (track count, total length, etc.) |
|
||||
| unit | string | No | Unit for length measurements: "mm" or "inch" |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- Returns all nets present in the board
|
||||
- Statistics include track count, via count, and total trace length
|
||||
- Useful for verifying net connectivity and routing completeness
|
||||
- Length measurements default to mm
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"includeStats": true,
|
||||
@@ -239,21 +253,23 @@ Create a new net class with custom design rules.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| name | string | Yes | Net class name |
|
||||
| traceWidth | number | No | Default trace width in mm |
|
||||
| clearance | number | No | Clearance in mm |
|
||||
| viaDiameter | number | No | Via diameter in mm |
|
||||
| viaDrill | number | No | Via drill size in mm |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ----------- | ------ | -------- | ------------------------- |
|
||||
| name | string | Yes | Net class name |
|
||||
| traceWidth | number | No | Default trace width in mm |
|
||||
| clearance | number | No | Clearance in mm |
|
||||
| viaDiameter | number | No | Via diameter in mm |
|
||||
| viaDrill | number | No | Via drill size in mm |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- Net classes define design rules for groups of nets
|
||||
- Common use cases: power nets (wider traces), high-speed signals (controlled impedance)
|
||||
- Once created, assign nets to the class using the netClass parameter in `add_net`
|
||||
- All measurements in mm
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Power",
|
||||
@@ -274,21 +290,23 @@ Delete traces from the PCB. Can delete by UUID, position, or bulk-delete all tra
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| traceUuid | string | No | UUID of a specific trace to delete |
|
||||
| position | object | No | Delete trace nearest to this position (x, y, optional unit) |
|
||||
| net | string | No | Delete all traces on this net (bulk delete) |
|
||||
| layer | string | No | Filter by layer when using net-based deletion |
|
||||
| includeVias | boolean | No | Include vias in net-based deletion |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ----------- | ------- | -------- | ----------------------------------------------------------- |
|
||||
| traceUuid | string | No | UUID of a specific trace to delete |
|
||||
| position | object | No | Delete trace nearest to this position (x, y, optional unit) |
|
||||
| net | string | No | Delete all traces on this net (bulk delete) |
|
||||
| layer | string | No | Filter by layer when using net-based deletion |
|
||||
| includeVias | boolean | No | Include vias in net-based deletion |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- Three deletion modes: by UUID (specific), by position (nearest), or by net (bulk)
|
||||
- Position-based deletion finds the closest trace to the specified coordinates
|
||||
- Net-based deletion can be filtered by layer
|
||||
- Vias are excluded from net-based deletion by default unless includeVias is true
|
||||
|
||||
**Example (bulk delete):**
|
||||
|
||||
```json
|
||||
{
|
||||
"net": "GND",
|
||||
@@ -305,20 +323,22 @@ Query traces on the board with optional filters by net, layer, or bounding box.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| net | string | No | Filter by net name |
|
||||
| layer | string | No | Filter by layer name |
|
||||
| boundingBox | object | No | Filter by bounding box region (x1, y1, x2, y2, optional unit) |
|
||||
| unit | string | No | Unit for coordinates: "mm" or "inch" |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ----------- | ------ | -------- | ------------------------------------------------------------- |
|
||||
| net | string | No | Filter by net name |
|
||||
| layer | string | No | Filter by layer name |
|
||||
| boundingBox | object | No | Filter by bounding box region (x1, y1, x2, y2, optional unit) |
|
||||
| unit | string | No | Unit for coordinates: "mm" or "inch" |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- Returns trace information including UUID, position, width, layer, and net
|
||||
- Filters can be combined (e.g., specific net on specific layer)
|
||||
- Bounding box uses rectangular region defined by opposite corners
|
||||
- Useful for analyzing routing in specific board regions or on specific nets
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"net": "VCC_3V3",
|
||||
@@ -334,20 +354,22 @@ Modify an existing trace (change width, layer, or net).
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| traceUuid | string | Yes | UUID of the trace to modify |
|
||||
| width | number | No | New trace width in mm |
|
||||
| layer | string | No | New layer name |
|
||||
| net | string | No | New net name |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------ | -------- | --------------------------- |
|
||||
| traceUuid | string | Yes | UUID of the trace to modify |
|
||||
| width | number | No | New trace width in mm |
|
||||
| layer | string | No | New layer name |
|
||||
| net | string | No | New net name |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- Requires the trace UUID, which can be obtained from `query_traces`
|
||||
- At least one modification parameter (width, layer, or net) must be provided
|
||||
- Use with caution when changing nets - ensure electrical correctness
|
||||
- Width changes are useful for adjusting impedance or current capacity
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"traceUuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
@@ -365,14 +387,15 @@ Add a copper pour (ground/power plane) to the PCB.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| layer | string | Yes | PCB layer |
|
||||
| net | string | Yes | Net name |
|
||||
| clearance | number | No | Clearance in mm |
|
||||
| outline | array[object] | No | Array of {x, y} points defining the pour boundary. If omitted, the board outline is used. |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------------- | -------- | ----------------------------------------------------------------------------------------- |
|
||||
| layer | string | Yes | PCB layer |
|
||||
| net | string | Yes | Net name |
|
||||
| clearance | number | No | Clearance in mm |
|
||||
| outline | array[object] | No | Array of {x, y} points defining the pour boundary. If omitted, the board outline is used. |
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- Copper pours are typically used for ground and power planes
|
||||
- If no outline is specified, the pour fills the entire board area
|
||||
- Custom outlines are defined as arrays of coordinate points
|
||||
@@ -380,16 +403,17 @@ Add a copper pour (ground/power plane) to the PCB.
|
||||
- After adding a pour, use `refill_zones` to fill it
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"layer": "B.Cu",
|
||||
"net": "GND",
|
||||
"clearance": 0.2,
|
||||
"outline": [
|
||||
{"x": 10.0, "y": 10.0},
|
||||
{"x": 90.0, "y": 10.0},
|
||||
{"x": 90.0, "y": 60.0},
|
||||
{"x": 10.0, "y": 60.0}
|
||||
{ "x": 10.0, "y": 10.0 },
|
||||
{ "x": 90.0, "y": 10.0 },
|
||||
{ "x": 90.0, "y": 60.0 },
|
||||
{ "x": 10.0, "y": 60.0 }
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -405,6 +429,7 @@ Refill all copper zones on the board.
|
||||
None
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- WARNING: SWIG path has known segfault risk (see KNOWN_ISSUES.md)
|
||||
- Prefer using IPC backend (KiCAD open) or triggering zone fill via KiCAD UI instead
|
||||
- Required after adding or modifying copper pours to calculate the filled areas
|
||||
@@ -412,6 +437,7 @@ None
|
||||
- May take several seconds on complex boards with many zones
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{}
|
||||
```
|
||||
@@ -439,6 +465,7 @@ The simplest and most robust approach for connecting component pads:
|
||||
```
|
||||
|
||||
This automatically:
|
||||
|
||||
- Looks up the exact pad positions
|
||||
- Detects the net from the pads
|
||||
- Creates the trace on the appropriate layer
|
||||
|
||||
@@ -8,268 +8,296 @@ This document provides a complete reference for the 27 schematic tools in the Ki
|
||||
## Component Operations (8 tools)
|
||||
|
||||
### add_schematic_component
|
||||
|
||||
Add a component to the schematic. Symbol format is 'Library:SymbolName' (e.g., 'Device:R', 'EDA-MCP:ESP32-C3').
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| symbol | string | Yes | Symbol library:name reference (e.g., Device:R, EDA-MCP:ESP32-C3) |
|
||||
| reference | string | Yes | Component reference (e.g., R1, U1) |
|
||||
| value | string | No | Component value |
|
||||
| footprint | string | No | KiCAD footprint (e.g. Resistor_SMD:R_0603_1608Metric) |
|
||||
| position | object | No | Position on schematic with x and y coordinates |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ---------------------------------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| symbol | string | Yes | Symbol library:name reference (e.g., Device:R, EDA-MCP:ESP32-C3) |
|
||||
| reference | string | Yes | Component reference (e.g., R1, U1) |
|
||||
| value | string | No | Component value |
|
||||
| footprint | string | No | KiCAD footprint (e.g. Resistor_SMD:R_0603_1608Metric) |
|
||||
| position | object | No | Position on schematic with x and y coordinates |
|
||||
|
||||
**Usage Notes:** The dynamic symbol loader provides access to ~10,000 KiCad standard symbols. If a symbol is not in the static template map, it will be loaded dynamically from the specified library.
|
||||
|
||||
### delete_schematic_component
|
||||
|
||||
Remove a placed symbol from a KiCAD schematic (.kicad_sch). This removes the symbol instance (the placed component) from the schematic. It does NOT remove the symbol definition from lib_symbols. Note: This tool operates on schematic files (.kicad_sch). To remove a footprint from a PCB, use delete_component instead.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| reference | string | Yes | Reference designator of the component to remove (e.g. R1, U3) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ------------------------------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| reference | string | Yes | Reference designator of the component to remove (e.g. R1, U3) |
|
||||
|
||||
### edit_schematic_component
|
||||
|
||||
Update properties of a placed symbol in a KiCAD schematic (.kicad_sch) in-place. Use this tool to assign or update a footprint, change the value, or rename the reference of an already-placed component. This is more efficient than delete + re-add because it preserves the component's position and UUID. Note: operates on .kicad_sch files only. To modify a PCB footprint use edit_component.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| reference | string | Yes | Current reference designator of the component (e.g. R1, U3) |
|
||||
| footprint | string | No | New KiCAD footprint string (e.g. Resistor_SMD:R_0603_1608Metric) |
|
||||
| value | string | No | New value string (e.g. 10k, 100nF) |
|
||||
| newReference | string | No | Rename the reference designator (e.g. R1 → R10) |
|
||||
| fieldPositions | object | No | Reposition field labels: map of field name to {x, y, angle} (e.g. {"Reference": {"x": 12.5, "y": 17.0}}) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| -------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| reference | string | Yes | Current reference designator of the component (e.g. R1, U3) |
|
||||
| footprint | string | No | New KiCAD footprint string (e.g. Resistor_SMD:R_0603_1608Metric) |
|
||||
| value | string | No | New value string (e.g. 10k, 100nF) |
|
||||
| newReference | string | No | Rename the reference designator (e.g. R1 → R10) |
|
||||
| fieldPositions | object | No | Reposition field labels: map of field name to {x, y, angle} (e.g. {"Reference": {"x": 12.5, "y": 17.0}}) |
|
||||
|
||||
### get_schematic_component
|
||||
|
||||
Get full component info from a schematic: position, field values, and each field's label position (at x/y/angle). Use this to inspect or prepare repositioning of Reference/Value labels.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| reference | string | Yes | Component reference designator (e.g. R1, U1) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | -------------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| reference | string | Yes | Component reference designator (e.g. R1, U1) |
|
||||
|
||||
### list_schematic_components
|
||||
|
||||
List all components in a schematic with their references, values, positions, and pins. Essential for inspecting what's on the schematic before making edits.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| filter | object | No | Optional filters with libId and/or referencePrefix fields |
|
||||
| filter.libId | string | No | Filter by library ID (e.g., 'Device:R') |
|
||||
| filter.referencePrefix | string | No | Filter by reference prefix (e.g., 'R', 'C', 'U') |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ---------------------- | ------ | -------- | --------------------------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| filter | object | No | Optional filters with libId and/or referencePrefix fields |
|
||||
| filter.libId | string | No | Filter by library ID (e.g., 'Device:R') |
|
||||
| filter.referencePrefix | string | No | Filter by reference prefix (e.g., 'R', 'C', 'U') |
|
||||
|
||||
### move_schematic_component
|
||||
|
||||
Move a placed symbol to a new position in the schematic.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| reference | string | Yes | Reference designator (e.g., R1, U1) |
|
||||
| position | object | Yes | New position with x and y coordinates |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| reference | string | Yes | Reference designator (e.g., R1, U1) |
|
||||
| position | object | Yes | New position with x and y coordinates |
|
||||
|
||||
### rotate_schematic_component
|
||||
|
||||
Rotate a placed symbol in the schematic.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| reference | string | Yes | Reference designator (e.g., R1, U1) |
|
||||
| angle | number | Yes | Rotation angle in degrees (0, 90, 180, 270) |
|
||||
| mirror | enum | No | Optional mirror axis ("x" or "y") |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ------------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| reference | string | Yes | Reference designator (e.g., R1, U1) |
|
||||
| angle | number | Yes | Rotation angle in degrees (0, 90, 180, 270) |
|
||||
| mirror | enum | No | Optional mirror axis ("x" or "y") |
|
||||
|
||||
### annotate_schematic
|
||||
|
||||
Assign reference designators to unannotated components (R? → R1, R2, ...). Must be called before tools that require known references.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | --------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
|
||||
## Wiring and Connections (8 tools)
|
||||
|
||||
### add_wire
|
||||
|
||||
Add a wire connection in the schematic.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| start | object | Yes | Start position with x and y coordinates |
|
||||
| end | object | Yes | End position with x and y coordinates |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------ | -------- | --------------------------------------- |
|
||||
| start | object | Yes | Start position with x and y coordinates |
|
||||
| end | object | Yes | End position with x and y coordinates |
|
||||
|
||||
### add_schematic_connection
|
||||
|
||||
Connect two component pins with a wire. Use this for individual connections between components with different pin roles (e.g. U1.SDA → J3.2). WARNING: Do NOT use this in a loop to wire N passthrough pins — use connect_passthrough instead (single call, cleaner layout, far fewer tokens).
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| sourceRef | string | Yes | Source component reference (e.g., R1) |
|
||||
| sourcePin | string | Yes | Source pin name/number (e.g., 1, 2, GND) |
|
||||
| targetRef | string | Yes | Target component reference (e.g., C1) |
|
||||
| targetPin | string | Yes | Target pin name/number (e.g., 1, 2, VCC) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ---------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| sourceRef | string | Yes | Source component reference (e.g., R1) |
|
||||
| sourcePin | string | Yes | Source pin name/number (e.g., 1, 2, GND) |
|
||||
| targetRef | string | Yes | Target component reference (e.g., C1) |
|
||||
| targetPin | string | Yes | Target pin name/number (e.g., 1, 2, VCC) |
|
||||
|
||||
### add_schematic_net_label
|
||||
|
||||
Add a net label to the schematic.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| netName | string | Yes | Name of the net (e.g., VCC, GND, SIGNAL_1) |
|
||||
| position | array | Yes | Position [x, y] for the label |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ------------------------------------------ |
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| netName | string | Yes | Name of the net (e.g., VCC, GND, SIGNAL_1) |
|
||||
| position | array | Yes | Position [x, y] for the label |
|
||||
|
||||
### connect_to_net
|
||||
|
||||
Connect a component pin to a named net.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| componentRef | string | Yes | Component reference (e.g., U1, R1) |
|
||||
| pinName | string | Yes | Pin name/number to connect |
|
||||
| netName | string | Yes | Name of the net to connect to |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ---------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| componentRef | string | Yes | Component reference (e.g., U1, R1) |
|
||||
| pinName | string | Yes | Pin name/number to connect |
|
||||
| netName | string | Yes | Name of the net to connect to |
|
||||
|
||||
**Usage Notes:** Creates a wire stub from the pin and places a net label at the stub endpoint. The stub direction follows the pin's outward angle. Default stub length is 2.54mm (0.1 inch, standard grid spacing).
|
||||
|
||||
### connect_passthrough
|
||||
Connects all pins of a source connector (e.g. J1) to matching pins of a target connector (e.g. J2) via shared net labels — pin N gets net '{netPrefix}_{N}'. Use this for FFC/ribbon cable passthrough adapters instead of calling connect_to_net for every pin.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| sourceRef | string | Yes | Source connector reference (e.g. J1) |
|
||||
| targetRef | string | Yes | Target connector reference (e.g. J2) |
|
||||
| netPrefix | string | No | Net name prefix, e.g. 'CSI' → CSI_1, CSI_2 (default: PIN) |
|
||||
| pinOffset | number | No | Add to pin number when building net name (default: 0) |
|
||||
Connects all pins of a source connector (e.g. J1) to matching pins of a target connector (e.g. J2) via shared net labels — pin N gets net '{netPrefix}\_{N}'. Use this for FFC/ribbon cable passthrough adapters instead of calling connect_to_net for every pin.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | --------------------------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| sourceRef | string | Yes | Source connector reference (e.g. J1) |
|
||||
| targetRef | string | Yes | Target connector reference (e.g. J2) |
|
||||
| netPrefix | string | No | Net name prefix, e.g. 'CSI' → CSI_1, CSI_2 (default: PIN) |
|
||||
| pinOffset | number | No | Add to pin number when building net name (default: 0) |
|
||||
|
||||
**Usage Notes:** This is the most efficient way to wire passthrough adapters. For an N-pin connector, this replaces N individual connect_to_net calls with a single operation.
|
||||
|
||||
### get_schematic_pin_locations
|
||||
|
||||
Returns the exact x/y coordinates of every pin on a schematic component. Use this before add_schematic_net_label to place labels correctly on pin endpoints.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| reference | string | Yes | Component reference designator (e.g. U1, R1, J2) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ------------------------------------------------ |
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| reference | string | Yes | Component reference designator (e.g. U1, R1, J2) |
|
||||
|
||||
### delete_schematic_wire
|
||||
|
||||
Remove a wire from the schematic by start and end coordinates.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| start | object | Yes | Wire start position with x and y coordinates |
|
||||
| end | object | Yes | Wire end position with x and y coordinates |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | -------------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| start | object | Yes | Wire start position with x and y coordinates |
|
||||
| end | object | Yes | Wire end position with x and y coordinates |
|
||||
|
||||
### delete_schematic_net_label
|
||||
|
||||
Remove a net label from the schematic.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| netName | string | Yes | Name of the net label to remove |
|
||||
| position | object | No | Position to disambiguate if multiple labels with same name (x and y coordinates) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | -------------------------------------------------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| netName | string | Yes | Name of the net label to remove |
|
||||
| position | object | No | Position to disambiguate if multiple labels with same name (x and y coordinates) |
|
||||
|
||||
## Net Analysis (4 tools)
|
||||
|
||||
### get_net_connections
|
||||
|
||||
Get all connections for a named net.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| netName | string | Yes | Name of the net to query |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | -------------------------- |
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| netName | string | Yes | Name of the net to query |
|
||||
|
||||
**Usage Notes:** Uses wire graph analysis to find all component pins connected to the specified net. Returns a list of {component, pin} pairs.
|
||||
|
||||
### list_schematic_nets
|
||||
|
||||
List all nets in the schematic with their connections.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | --------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
|
||||
### list_schematic_wires
|
||||
|
||||
List all wires in the schematic with start/end coordinates.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | --------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
|
||||
### list_schematic_labels
|
||||
|
||||
List all net labels, global labels, and power flags in the schematic.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | --------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
|
||||
## Schematic Creation and Export (5 tools)
|
||||
|
||||
### create_schematic
|
||||
|
||||
Create a new schematic.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| name | string | Yes | Schematic name |
|
||||
| path | string | No | Optional path |
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ------ | -------- | -------------- |
|
||||
| name | string | Yes | Schematic name |
|
||||
| path | string | No | Optional path |
|
||||
|
||||
### export_schematic_svg
|
||||
|
||||
Export schematic to SVG format using kicad-cli.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| outputPath | string | Yes | Output SVG file path |
|
||||
| blackAndWhite | boolean | No | Export in black and white |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------- | -------- | --------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| outputPath | string | Yes | Output SVG file path |
|
||||
| blackAndWhite | boolean | No | Export in black and white |
|
||||
|
||||
### export_schematic_pdf
|
||||
|
||||
Export schematic to PDF format using kicad-cli.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| outputPath | string | Yes | Output PDF file path |
|
||||
| blackAndWhite | boolean | No | Export in black and white |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------- | -------- | --------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| outputPath | string | Yes | Output PDF file path |
|
||||
| blackAndWhite | boolean | No | Export in black and white |
|
||||
|
||||
### get_schematic_view
|
||||
|
||||
Return a rasterized image of the schematic (PNG by default, or SVG). Uses kicad-cli to export SVG, then converts to PNG via cairosvg. Use this for visual feedback after placing or wiring components.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| format | enum | No | Output format ("png" or "svg", default: png) |
|
||||
| width | number | No | Image width in pixels (default: 1200) |
|
||||
| height | number | No | Image height in pixels (default: 900) |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | -------------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch file |
|
||||
| format | enum | No | Output format ("png" or "svg", default: png) |
|
||||
| width | number | No | Image width in pixels (default: 1200) |
|
||||
| height | number | No | Image height in pixels (default: 900) |
|
||||
|
||||
### generate_netlist
|
||||
|
||||
Generate a netlist from the schematic.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | -------------------------- |
|
||||
| schematicPath | string | Yes | Path to the schematic file |
|
||||
|
||||
**Usage Notes:** Returns a complete netlist with component information (reference, value, footprint) and net connections (net name with all connected component/pin pairs).
|
||||
|
||||
## Validation and Synchronization (3 tools)
|
||||
|
||||
### run_erc
|
||||
|
||||
Runs the KiCAD Electrical Rules Check (ERC) on a schematic and returns all violations. Use after wiring to verify the schematic before generating a netlist.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch schematic file |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ------------------------------------- |
|
||||
| schematicPath | string | Yes | Path to the .kicad_sch schematic file |
|
||||
|
||||
**Usage Notes:** Returns violations categorized by severity (error, warning, info) with location coordinates. Essential for catching design errors before PCB layout.
|
||||
|
||||
### sync_schematic_to_board
|
||||
|
||||
Import the schematic netlist into the PCB board — equivalent to pressing F8 in KiCAD (Tools → Update PCB from Schematic). MUST be called after the schematic is complete and before placing or routing components on the PCB. Without this step, the board has no footprints and no net assignments — place_component and route_pad_to_pad will produce an empty, unroutable board.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| schematicPath | string | Yes | Absolute path to the .kicad_sch schematic file |
|
||||
| boardPath | string | Yes | Absolute path to the .kicad_pcb board file |
|
||||
| Parameter | Type | Required | Description |
|
||||
| ------------- | ------ | -------- | ---------------------------------------------- |
|
||||
| schematicPath | string | Yes | Absolute path to the .kicad_sch schematic file |
|
||||
| boardPath | string | Yes | Absolute path to the .kicad_pcb board file |
|
||||
|
||||
**Usage Notes:** This is the F8 equivalent. It synchronizes the schematic design to the PCB, creating footprints on the board and assigning nets. This step is critical in the workflow: design in schematic → sync_schematic_to_board → place and route on PCB.
|
||||
|
||||
## Example Workflows
|
||||
|
||||
### Basic Circuit Design
|
||||
|
||||
1. **Create project:** Use `create_schematic` to initialize a new schematic file
|
||||
2. **Add components:** Use `add_schematic_component` to place resistors, capacitors, ICs, etc.
|
||||
- Example: Add a resistor with `symbol: "Device:R"`, `reference: "R1"`, `value: "10k"`
|
||||
@@ -281,6 +309,7 @@ Import the schematic netlist into the PCB board — equivalent to pressing F8 in
|
||||
7. **Sync to PCB:** Use `sync_schematic_to_board` to transfer the design to the PCB layout
|
||||
|
||||
### FFC Passthrough Adapter
|
||||
|
||||
1. **Add connectors:** Place two FFC connectors using `add_schematic_component`
|
||||
- Example: J1 and J2, both 20-pin FFC connectors
|
||||
2. **Connect passthrough:** Use `connect_passthrough` with `sourceRef: "J1"`, `targetRef: "J2"`, `netPrefix: "CSI"`
|
||||
|
||||
@@ -8,46 +8,47 @@
|
||||
|
||||
## Quick Stats
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Total MCP Tools | 122 |
|
||||
| Tool Categories | 16 |
|
||||
| KiCAD 9.0 Compatible | Yes (verified) |
|
||||
| Platforms | Linux, Windows, macOS |
|
||||
| JLCPCB Parts Catalog | 2.5M+ components |
|
||||
| Symbol Access | ~10,000 via dynamic loading |
|
||||
| Footprint Libraries | 153+ auto-discovered |
|
||||
| Contributors | 10+ |
|
||||
| MCP Protocol Version | 2025-06-18 |
|
||||
| Metric | Value |
|
||||
| -------------------- | --------------------------- |
|
||||
| Total MCP Tools | 122 |
|
||||
| Tool Categories | 16 |
|
||||
| KiCAD 9.0 Compatible | Yes (verified) |
|
||||
| Platforms | Linux, Windows, macOS |
|
||||
| JLCPCB Parts Catalog | 2.5M+ components |
|
||||
| Symbol Access | ~10,000 via dynamic loading |
|
||||
| Footprint Libraries | 153+ auto-discovered |
|
||||
| Contributors | 10+ |
|
||||
| MCP Protocol Version | 2025-06-18 |
|
||||
|
||||
---
|
||||
|
||||
## Feature Completion Matrix
|
||||
|
||||
| Feature Category | Status | Tool Count | Details |
|
||||
|-----------------|--------|------------|---------|
|
||||
| Project Management | Complete | 5 | Create, open, save, info, snapshot |
|
||||
| Board Setup | Complete | 12 | Size, outline, layers, mounting holes, zones, text, 2D view, SVG import |
|
||||
| Component Placement | Complete | 16 | Place, move, rotate, delete, edit, find, pads, arrays, align, duplicate |
|
||||
| Routing | Complete | 13 | Traces, vias, pad-to-pad, differential pairs, netclasses, copy pattern |
|
||||
| Design Rules / DRC | Complete | 8 | Set/get rules, DRC, net classes, clearance checks |
|
||||
| Export | Complete | 8 | Gerber, PDF, SVG, 3D, BOM, netlist, position file, VRML |
|
||||
| Schematic | Complete | 27 | Components, wiring, net labels, connections, ERC, export, sync to board |
|
||||
| Footprint Libraries | Complete | 4 | List, search, browse, info |
|
||||
| Symbol Libraries | Complete | 4 | List, search, browse, info |
|
||||
| Footprint Creator | Complete | 4 | Create custom footprints, edit pads, register libraries |
|
||||
| Symbol Creator | Complete | 4 | Create custom symbols, register libraries |
|
||||
| Datasheet Tools | Complete | 2 | LCSC datasheet enrichment |
|
||||
| JLCPCB Integration | Complete | 5 | Local DB, search, part details, stats, alternatives |
|
||||
| Freerouting | Complete | 4 | Autoroute, DSN export, SES import, availability check |
|
||||
| UI Management | Complete | 2 | Check/launch KiCAD |
|
||||
| Router Tools | Complete | 4 | Category browsing, tool search, execute |
|
||||
| Feature Category | Status | Tool Count | Details |
|
||||
| ------------------- | -------- | ---------- | ----------------------------------------------------------------------- |
|
||||
| Project Management | Complete | 5 | Create, open, save, info, snapshot |
|
||||
| Board Setup | Complete | 12 | Size, outline, layers, mounting holes, zones, text, 2D view, SVG import |
|
||||
| Component Placement | Complete | 16 | Place, move, rotate, delete, edit, find, pads, arrays, align, duplicate |
|
||||
| Routing | Complete | 13 | Traces, vias, pad-to-pad, differential pairs, netclasses, copy pattern |
|
||||
| Design Rules / DRC | Complete | 8 | Set/get rules, DRC, net classes, clearance checks |
|
||||
| Export | Complete | 8 | Gerber, PDF, SVG, 3D, BOM, netlist, position file, VRML |
|
||||
| Schematic | Complete | 27 | Components, wiring, net labels, connections, ERC, export, sync to board |
|
||||
| Footprint Libraries | Complete | 4 | List, search, browse, info |
|
||||
| Symbol Libraries | Complete | 4 | List, search, browse, info |
|
||||
| Footprint Creator | Complete | 4 | Create custom footprints, edit pads, register libraries |
|
||||
| Symbol Creator | Complete | 4 | Create custom symbols, register libraries |
|
||||
| Datasheet Tools | Complete | 2 | LCSC datasheet enrichment |
|
||||
| JLCPCB Integration | Complete | 5 | Local DB, search, part details, stats, alternatives |
|
||||
| Freerouting | Complete | 4 | Autoroute, DSN export, SES import, availability check |
|
||||
| UI Management | Complete | 2 | Check/launch KiCAD |
|
||||
| Router Tools | Complete | 4 | Category browsing, tool search, execute |
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
### SWIG Backend (File-based) -- Default
|
||||
|
||||
- **Status:** Stable
|
||||
- Direct pcbnew API access via KiCAD's Python bindings
|
||||
- Requires manual KiCAD UI reload to see changes
|
||||
@@ -55,13 +56,16 @@
|
||||
- Auto-saves after every board-modifying command
|
||||
|
||||
### IPC Backend (Real-time) -- Experimental
|
||||
|
||||
- **Status:** Functional, 21 commands implemented
|
||||
- Real-time UI synchronization with KiCAD 9+
|
||||
- Requires KiCAD running with IPC API enabled
|
||||
- Automatic fallback to SWIG when unavailable
|
||||
|
||||
### Hybrid Approach
|
||||
|
||||
The server automatically selects the best backend:
|
||||
|
||||
- IPC when KiCAD is running with IPC enabled
|
||||
- SWIG fallback when IPC is unavailable
|
||||
- Some operations use both (e.g., footprint placement)
|
||||
@@ -71,18 +75,21 @@ The server automatically selects the best backend:
|
||||
## Platform Support
|
||||
|
||||
### Linux -- Primary Platform
|
||||
|
||||
- KiCAD 9.0 detection: Working
|
||||
- Process management: Working
|
||||
- Library discovery: Working (153+ libraries)
|
||||
- IPC backend: Working
|
||||
|
||||
### Windows -- Fully Supported
|
||||
|
||||
- Automated setup script (setup-windows.ps1)
|
||||
- Process detection via Toolhelp32 API
|
||||
- Library paths auto-detected
|
||||
- Troubleshooting guide available (WINDOWS_TROUBLESHOOTING.md)
|
||||
|
||||
### macOS -- Community Supported
|
||||
|
||||
- Configuration provided
|
||||
- Process detection implemented
|
||||
- Library paths configured
|
||||
@@ -93,6 +100,7 @@ The server automatically selects the best backend:
|
||||
## Recent Development Highlights
|
||||
|
||||
### v2.2.3 (2026-03-11)
|
||||
|
||||
- FFC/ribbon cable passthrough workflow (connect_passthrough, sync_schematic_to_board)
|
||||
- Project snapshot system
|
||||
- SVG logo import
|
||||
@@ -101,20 +109,24 @@ The server automatically selects the best backend:
|
||||
- Critical B.Cu routing fixes
|
||||
|
||||
### v2.2.2-alpha (2026-03-01)
|
||||
|
||||
- route_pad_to_pad with auto-via insertion
|
||||
- copy_routing_pattern for trace replication
|
||||
- Project-local library resolution
|
||||
|
||||
### v2.2.1-alpha (2026-02-28)
|
||||
|
||||
- edit_schematic_component with field position support
|
||||
- Footprint and symbol creator tools
|
||||
|
||||
### v2.2.0-alpha (2026-02-27)
|
||||
|
||||
- 13 new routing/component tools
|
||||
- Datasheet enrichment tools
|
||||
- SWIG/UUID bug fixes
|
||||
|
||||
### v2.1.0-alpha (2026-01-10)
|
||||
|
||||
- Complete schematic wiring system
|
||||
- Dynamic symbol loading (~10,000 symbols)
|
||||
- JLCPCB parts integration
|
||||
@@ -124,35 +136,38 @@ The server automatically selects the best backend:
|
||||
|
||||
## Community Contributors
|
||||
|
||||
| Contributor | Key Contributions |
|
||||
|------------|-------------------|
|
||||
| Kletternaut | Routing tools, footprint/symbol creators, passthrough workflow, template fixes |
|
||||
| Mehanik | Schematic inspection/editing tools, component field positions |
|
||||
| jflaflamme | Freerouting autorouter integration with Docker/Podman |
|
||||
| l3wi | Local symbol library search, JLCPCB third-party library support |
|
||||
| gwall-ceres | MCP protocol compliance, Windows compatibility |
|
||||
| fariouche | Bug fixes |
|
||||
| shuofengzhang | XDG relative path handling |
|
||||
| sid115 | Windows setup script improvements |
|
||||
| pasrom | MCP server bug fixes |
|
||||
| Contributor | Key Contributions |
|
||||
| ------------- | ------------------------------------------------------------------------------ |
|
||||
| Kletternaut | Routing tools, footprint/symbol creators, passthrough workflow, template fixes |
|
||||
| Mehanik | Schematic inspection/editing tools, component field positions |
|
||||
| jflaflamme | Freerouting autorouter integration with Docker/Podman |
|
||||
| l3wi | Local symbol library search, JLCPCB third-party library support |
|
||||
| gwall-ceres | MCP protocol compliance, Windows compatibility |
|
||||
| fariouche | Bug fixes |
|
||||
| shuofengzhang | XDG relative path handling |
|
||||
| sid115 | Windows setup script improvements |
|
||||
| pasrom | MCP server bug fixes |
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
**For Users:**
|
||||
|
||||
1. Check [README.md](../README.md) for installation
|
||||
2. Review [KNOWN_ISSUES.md](KNOWN_ISSUES.md) for common problems
|
||||
3. Check logs: `~/.kicad-mcp/logs/kicad_interface.log`
|
||||
|
||||
**For Contributors:**
|
||||
|
||||
1. Read [CONTRIBUTING.md](../CONTRIBUTING.md) for development setup
|
||||
2. Check [ARCHITECTURE.md](ARCHITECTURE.md) for system design
|
||||
3. Review the [Documentation Index](INDEX.md) for all available docs
|
||||
|
||||
**Issues:**
|
||||
|
||||
- Open an issue on GitHub with OS, KiCAD version, and error details
|
||||
|
||||
---
|
||||
|
||||
*Last Updated: 2026-03-21*
|
||||
_Last Updated: 2026-03-21_
|
||||
|
||||
@@ -14,18 +14,19 @@ Imports an SVG file as filled graphic polygons onto a PCB layer. Curves are line
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Required | Default | Description |
|
||||
|-----------|------|----------|---------|-------------|
|
||||
| `pcbPath` | string | Yes | -- | Path to the .kicad_pcb file |
|
||||
| `svgPath` | string | Yes | -- | Path to the SVG logo file |
|
||||
| `x` | number | Yes | -- | X position of the logo top-left corner in mm |
|
||||
| `y` | number | Yes | -- | Y position of the logo top-left corner in mm |
|
||||
| `width` | number | Yes | -- | Target width of the logo in mm (height scales to preserve aspect ratio) |
|
||||
| `layer` | string | No | F.SilkS | PCB layer name (e.g., F.SilkS, B.SilkS, F.Cu, B.Cu) |
|
||||
| `strokeWidth` | number | No | 0 | Outline stroke width in mm (0 = no outline) |
|
||||
| `filled` | boolean | No | true | Fill polygons with solid color |
|
||||
| Parameter | Type | Required | Default | Description |
|
||||
| ------------- | ------- | -------- | ------- | ----------------------------------------------------------------------- |
|
||||
| `pcbPath` | string | Yes | -- | Path to the .kicad_pcb file |
|
||||
| `svgPath` | string | Yes | -- | Path to the SVG logo file |
|
||||
| `x` | number | Yes | -- | X position of the logo top-left corner in mm |
|
||||
| `y` | number | Yes | -- | Y position of the logo top-left corner in mm |
|
||||
| `width` | number | Yes | -- | Target width of the logo in mm (height scales to preserve aspect ratio) |
|
||||
| `layer` | string | No | F.SilkS | PCB layer name (e.g., F.SilkS, B.SilkS, F.Cu, B.Cu) |
|
||||
| `strokeWidth` | number | No | 0 | Outline stroke width in mm (0 = no outline) |
|
||||
| `filled` | boolean | No | true | Fill polygons with solid color |
|
||||
|
||||
**Returns:**
|
||||
|
||||
- Polygon count
|
||||
- Final dimensions (width x height in mm)
|
||||
- Layer used
|
||||
@@ -35,18 +36,21 @@ Imports an SVG file as filled graphic polygons onto a PCB layer. Curves are line
|
||||
## SVG Requirements
|
||||
|
||||
### Supported Features
|
||||
|
||||
- Path elements with M, L, H, V, C, S, Q, T, A, Z commands
|
||||
- Filled shapes (polygons, rectangles, circles, ellipses)
|
||||
- Nested groups and transforms
|
||||
- Cubic and quadratic Bezier curves (linearized automatically)
|
||||
|
||||
### Recommendations
|
||||
|
||||
- Use simple, solid shapes -- avoid complex gradients or filters
|
||||
- Convert text to paths/outlines before importing
|
||||
- Ensure shapes are filled (not just stroked) for best results
|
||||
- Keep the SVG clean -- remove unnecessary metadata and layers
|
||||
|
||||
### What Will Not Work
|
||||
|
||||
- Raster images embedded in SVG
|
||||
- CSS-based styling (inline style attributes are preferred)
|
||||
- Complex SVG filters or effects
|
||||
@@ -59,11 +63,13 @@ Imports an SVG file as filled graphic polygons onto a PCB layer. Curves are line
|
||||
### 1. Prepare Your SVG
|
||||
|
||||
If starting from a raster image (PNG, JPG):
|
||||
|
||||
- Use a vector graphics editor (Inkscape, Illustrator, Figma) to trace the image
|
||||
- In Inkscape: Path > Trace Bitmap to convert
|
||||
- Export as plain SVG
|
||||
|
||||
If starting from a vector logo:
|
||||
|
||||
- Open in a vector editor
|
||||
- Convert all text to paths (Object to Path / Create Outlines)
|
||||
- Remove unnecessary layers and hidden elements
|
||||
@@ -87,14 +93,14 @@ Re-run `import_svg_logo` with different position, width, or layer parameters.
|
||||
|
||||
## Layer Options
|
||||
|
||||
| Layer | Use Case |
|
||||
|-------|----------|
|
||||
| `F.SilkS` | Front silkscreen (most common for logos) |
|
||||
| `B.SilkS` | Back silkscreen |
|
||||
| `F.Cu` | Front copper (logo as exposed copper) |
|
||||
| `B.Cu` | Back copper |
|
||||
| `F.Mask` | Front solder mask opening (exposes copper underneath) |
|
||||
| `B.Mask` | Back solder mask opening |
|
||||
| Layer | Use Case |
|
||||
| --------- | ----------------------------------------------------- |
|
||||
| `F.SilkS` | Front silkscreen (most common for logos) |
|
||||
| `B.SilkS` | Back silkscreen |
|
||||
| `F.Cu` | Front copper (logo as exposed copper) |
|
||||
| `B.Cu` | Back copper |
|
||||
| `F.Mask` | Front solder mask opening (exposes copper underneath) |
|
||||
| `B.Mask` | Back solder mask opening |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -16,325 +16,325 @@ The server uses a **router pattern** to reduce AI context usage. Tools fall into
|
||||
|
||||
## Project Management (5 tools)
|
||||
|
||||
*Source: `src/tools/project.ts`*
|
||||
_Source: `src/tools/project.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `create_project` | Create a new KiCAD project (.kicad_pro, .kicad_pcb, .kicad_sch) | Direct |
|
||||
| `open_project` | Open an existing KiCAD project | Direct |
|
||||
| `save_project` | Save the current project | Direct |
|
||||
| `get_project_info` | Get project metadata and information | Direct |
|
||||
| Tool | Description | Access |
|
||||
| ------------------ | ---------------------------------------------------------------- | ------ |
|
||||
| `create_project` | Create a new KiCAD project (.kicad_pro, .kicad_pcb, .kicad_sch) | Direct |
|
||||
| `open_project` | Open an existing KiCAD project | Direct |
|
||||
| `save_project` | Save the current project | Direct |
|
||||
| `get_project_info` | Get project metadata and information | Direct |
|
||||
| `snapshot_project` | Save a named checkpoint snapshot (renders PDF, saves step label) | Direct |
|
||||
|
||||
---
|
||||
|
||||
## Board Management (12 tools)
|
||||
|
||||
*Source: `src/tools/board.ts`*
|
||||
_Source: `src/tools/board.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `set_board_size` | Set PCB dimensions (width, height, unit) | Direct |
|
||||
| `add_board_outline` | Add board outline (rectangle, circle, polygon, rounded_rectangle) | Direct |
|
||||
| `get_board_info` | Get board metadata and properties | Direct |
|
||||
| `add_layer` | Add copper/technical/signal layer | Routed (board) |
|
||||
| `set_active_layer` | Change the active working layer | Routed (board) |
|
||||
| `get_layer_list` | List all layers on the board | Routed (board) |
|
||||
| `add_mounting_hole` | Add mounting hole with optional pad | Routed (board) |
|
||||
| `add_board_text` | Add text annotation to board | Routed (board) |
|
||||
| `add_zone` | Add copper zone/pour with clearance settings | Routed (board) |
|
||||
| `get_board_extents` | Get bounding box of board | Routed (board) |
|
||||
| `get_board_2d_view` | Render 2D board view (PNG/JPG/SVG) | Routed (board) |
|
||||
| `import_svg_logo` | Import SVG file as polygons on silkscreen layer | Additional |
|
||||
| Tool | Description | Access |
|
||||
| ------------------- | ----------------------------------------------------------------- | -------------- |
|
||||
| `set_board_size` | Set PCB dimensions (width, height, unit) | Direct |
|
||||
| `add_board_outline` | Add board outline (rectangle, circle, polygon, rounded_rectangle) | Direct |
|
||||
| `get_board_info` | Get board metadata and properties | Direct |
|
||||
| `add_layer` | Add copper/technical/signal layer | Routed (board) |
|
||||
| `set_active_layer` | Change the active working layer | Routed (board) |
|
||||
| `get_layer_list` | List all layers on the board | Routed (board) |
|
||||
| `add_mounting_hole` | Add mounting hole with optional pad | Routed (board) |
|
||||
| `add_board_text` | Add text annotation to board | Routed (board) |
|
||||
| `add_zone` | Add copper zone/pour with clearance settings | Routed (board) |
|
||||
| `get_board_extents` | Get bounding box of board | Routed (board) |
|
||||
| `get_board_2d_view` | Render 2D board view (PNG/JPG/SVG) | Routed (board) |
|
||||
| `import_svg_logo` | Import SVG file as polygons on silkscreen layer | Additional |
|
||||
|
||||
---
|
||||
|
||||
## Component Management (16 tools)
|
||||
|
||||
*Source: `src/tools/component.ts`*
|
||||
_Source: `src/tools/component.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `place_component` | Place footprint on PCB (position, rotation, reference, value) | Direct |
|
||||
| `move_component` | Move component to new position | Direct |
|
||||
| `rotate_component` | Rotate component (absolute angle) | Routed (component) |
|
||||
| `delete_component` | Remove component from board | Routed (component) |
|
||||
| `edit_component` | Edit component properties (reference, value, footprint) | Routed (component) |
|
||||
| `find_component` | Search components by reference or value | Routed (component) |
|
||||
| `get_component_properties` | Get all properties of a component | Routed (component) |
|
||||
| `add_component_annotation` | Add annotation/comment to component | Routed (component) |
|
||||
| `group_components` | Group multiple components together | Routed (component) |
|
||||
| `replace_component` | Replace component with different footprint | Routed (component) |
|
||||
| `get_component_pads` | Get all pad information for a component | Additional |
|
||||
| `get_component_list` | List all components with optional filters | Additional |
|
||||
| `get_pad_position` | Get precise position of a specific pad | Additional |
|
||||
| `place_component_array` | Place array of components (rows x columns) | Additional |
|
||||
| `align_components` | Align components (horizontal, vertical, grid) | Additional |
|
||||
| `duplicate_component` | Duplicate component with offset | Additional |
|
||||
| Tool | Description | Access |
|
||||
| -------------------------- | ------------------------------------------------------------- | ------------------ |
|
||||
| `place_component` | Place footprint on PCB (position, rotation, reference, value) | Direct |
|
||||
| `move_component` | Move component to new position | Direct |
|
||||
| `rotate_component` | Rotate component (absolute angle) | Routed (component) |
|
||||
| `delete_component` | Remove component from board | Routed (component) |
|
||||
| `edit_component` | Edit component properties (reference, value, footprint) | Routed (component) |
|
||||
| `find_component` | Search components by reference or value | Routed (component) |
|
||||
| `get_component_properties` | Get all properties of a component | Routed (component) |
|
||||
| `add_component_annotation` | Add annotation/comment to component | Routed (component) |
|
||||
| `group_components` | Group multiple components together | Routed (component) |
|
||||
| `replace_component` | Replace component with different footprint | Routed (component) |
|
||||
| `get_component_pads` | Get all pad information for a component | Additional |
|
||||
| `get_component_list` | List all components with optional filters | Additional |
|
||||
| `get_pad_position` | Get precise position of a specific pad | Additional |
|
||||
| `place_component_array` | Place array of components (rows x columns) | Additional |
|
||||
| `align_components` | Align components (horizontal, vertical, grid) | Additional |
|
||||
| `duplicate_component` | Duplicate component with offset | Additional |
|
||||
|
||||
---
|
||||
|
||||
## Routing (13 tools)
|
||||
|
||||
*Source: `src/tools/routing.ts`*
|
||||
_Source: `src/tools/routing.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `add_net` | Create a new net on the PCB | Direct |
|
||||
| `route_trace` | Route trace segment between XY points (single layer) | Direct |
|
||||
| `add_via` | Add via (through/blind/buried) | Routed (routing) |
|
||||
| `add_copper_pour` | Add copper pour / ground plane | Routed (routing) |
|
||||
| `delete_trace` | Delete traces by UUID, position, or bulk by net | Additional |
|
||||
| `query_traces` | Query/filter traces by net, layer, or bounding box | Additional |
|
||||
| `get_nets_list` | List all nets with statistics | Additional |
|
||||
| `modify_trace` | Modify existing trace (width, layer, net) | Additional |
|
||||
| `create_netclass` | Create net class with design rules | Additional |
|
||||
| `route_differential_pair` | Route differential pair traces | Additional |
|
||||
| `refill_zones` | Refill all copper zones | Additional |
|
||||
| `route_pad_to_pad` | Route trace between two pads with auto-via insertion | Additional |
|
||||
| `copy_routing_pattern` | Copy routing from source to target component groups | Additional |
|
||||
| Tool | Description | Access |
|
||||
| ------------------------- | ---------------------------------------------------- | ---------------- |
|
||||
| `add_net` | Create a new net on the PCB | Direct |
|
||||
| `route_trace` | Route trace segment between XY points (single layer) | Direct |
|
||||
| `add_via` | Add via (through/blind/buried) | Routed (routing) |
|
||||
| `add_copper_pour` | Add copper pour / ground plane | Routed (routing) |
|
||||
| `delete_trace` | Delete traces by UUID, position, or bulk by net | Additional |
|
||||
| `query_traces` | Query/filter traces by net, layer, or bounding box | Additional |
|
||||
| `get_nets_list` | List all nets with statistics | Additional |
|
||||
| `modify_trace` | Modify existing trace (width, layer, net) | Additional |
|
||||
| `create_netclass` | Create net class with design rules | Additional |
|
||||
| `route_differential_pair` | Route differential pair traces | Additional |
|
||||
| `refill_zones` | Refill all copper zones | Additional |
|
||||
| `route_pad_to_pad` | Route trace between two pads with auto-via insertion | Additional |
|
||||
| `copy_routing_pattern` | Copy routing from source to target component groups | Additional |
|
||||
|
||||
---
|
||||
|
||||
## Design Rules and DRC (8 tools)
|
||||
|
||||
*Source: `src/tools/design-rules.ts`*
|
||||
_Source: `src/tools/design-rules.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `set_design_rules` | Set global design rules (clearance, track width, via sizes) | Routed (drc) |
|
||||
| `get_design_rules` | Get current design rules | Routed (drc) |
|
||||
| `run_drc` | Run design rule check | Routed (drc) |
|
||||
| `add_net_class` | Add net class with custom rules | Routed (drc) |
|
||||
| `assign_net_to_class` | Assign net to a net class | Routed (drc) |
|
||||
| `set_layer_constraints` | Set layer-specific constraints | Routed (drc) |
|
||||
| `check_clearance` | Check clearance between two items | Routed (drc) |
|
||||
| `get_drc_violations` | Get DRC violation list (filter by severity) | Routed (drc) |
|
||||
| Tool | Description | Access |
|
||||
| ----------------------- | ----------------------------------------------------------- | ------------ |
|
||||
| `set_design_rules` | Set global design rules (clearance, track width, via sizes) | Routed (drc) |
|
||||
| `get_design_rules` | Get current design rules | Routed (drc) |
|
||||
| `run_drc` | Run design rule check | Routed (drc) |
|
||||
| `add_net_class` | Add net class with custom rules | Routed (drc) |
|
||||
| `assign_net_to_class` | Assign net to a net class | Routed (drc) |
|
||||
| `set_layer_constraints` | Set layer-specific constraints | Routed (drc) |
|
||||
| `check_clearance` | Check clearance between two items | Routed (drc) |
|
||||
| `get_drc_violations` | Get DRC violation list (filter by severity) | Routed (drc) |
|
||||
|
||||
---
|
||||
|
||||
## Export (8 tools)
|
||||
|
||||
*Source: `src/tools/export.ts`*
|
||||
_Source: `src/tools/export.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `export_gerber` | Export Gerber files for fabrication | Routed (export) |
|
||||
| `export_pdf` | Export PDF with layer selection and page size | Routed (export) |
|
||||
| `export_svg` | Export SVG vector graphics | Routed (export) |
|
||||
| `export_3d` | Export 3D model (STEP, STL, VRML, OBJ) | Routed (export) |
|
||||
| `export_bom` | Export Bill of Materials (CSV, XML, HTML, JSON) | Routed (export) |
|
||||
| `export_netlist` | Export netlist (KiCad, Spice, Cadstar, OrcadPCB2) | Routed (export) |
|
||||
| Tool | Description | Access |
|
||||
| ---------------------- | ------------------------------------------------- | --------------- |
|
||||
| `export_gerber` | Export Gerber files for fabrication | Routed (export) |
|
||||
| `export_pdf` | Export PDF with layer selection and page size | Routed (export) |
|
||||
| `export_svg` | Export SVG vector graphics | Routed (export) |
|
||||
| `export_3d` | Export 3D model (STEP, STL, VRML, OBJ) | Routed (export) |
|
||||
| `export_bom` | Export Bill of Materials (CSV, XML, HTML, JSON) | Routed (export) |
|
||||
| `export_netlist` | Export netlist (KiCad, Spice, Cadstar, OrcadPCB2) | Routed (export) |
|
||||
| `export_position_file` | Export component position file for pick and place | Routed (export) |
|
||||
| `export_vrml` | Export VRML 3D model | Routed (export) |
|
||||
| `export_vrml` | Export VRML 3D model | Routed (export) |
|
||||
|
||||
---
|
||||
|
||||
## Schematic (27 tools)
|
||||
|
||||
*Source: `src/tools/schematic.ts`*
|
||||
_Source: `src/tools/schematic.ts`_
|
||||
|
||||
### Component Operations
|
||||
|
||||
| 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 component properties (footprint, value, reference) | Additional |
|
||||
| `get_schematic_component` | Get component info with field 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 component properties (footprint, value, reference) | Additional |
|
||||
| `get_schematic_component` | Get component info with field 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
|
||||
|
||||
| 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_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 |
|
||||
|
||||
### Net Analysis
|
||||
|
||||
| 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 |
|
||||
| ----------------------- | ----------------------------- | ------------------ |
|
||||
| `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) |
|
||||
|
||||
### Schematic Creation and Export
|
||||
|
||||
| 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 |
|
||||
| ---------------------- | -------------------------------- | ------------------ |
|
||||
| `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) |
|
||||
|
||||
### Validation and Synchronization
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `run_erc` | Run electrical rule check | Additional |
|
||||
| `generate_netlist` | Generate netlist from schematic | Routed (schematic) |
|
||||
| `sync_schematic_to_board` | Sync schematic components/nets to PCB (F8 equivalent) | Direct |
|
||||
| Tool | Description | Access |
|
||||
| ------------------------- | ----------------------------------------------------- | ------------------ |
|
||||
| `run_erc` | Run electrical rule check | Additional |
|
||||
| `generate_netlist` | Generate netlist from schematic | Routed (schematic) |
|
||||
| `sync_schematic_to_board` | Sync schematic components/nets to PCB (F8 equivalent) | Direct |
|
||||
|
||||
---
|
||||
|
||||
## Footprint Libraries (4 tools)
|
||||
|
||||
*Source: `src/tools/library.ts`*
|
||||
_Source: `src/tools/library.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `list_libraries` | List all footprint libraries | Routed (library) |
|
||||
| `search_footprints` | Search footprints across libraries | Routed (library) |
|
||||
| Tool | Description | Access |
|
||||
| ------------------------- | ------------------------------------- | ---------------- |
|
||||
| `list_libraries` | List all footprint libraries | Routed (library) |
|
||||
| `search_footprints` | Search footprints across libraries | Routed (library) |
|
||||
| `list_library_footprints` | List footprints in a specific library | Routed (library) |
|
||||
| `get_footprint_info` | Get detailed footprint information | Routed (library) |
|
||||
| `get_footprint_info` | Get detailed footprint information | Routed (library) |
|
||||
|
||||
---
|
||||
|
||||
## Symbol Libraries (4 tools)
|
||||
|
||||
*Source: `src/tools/library-symbol.ts`*
|
||||
_Source: `src/tools/library-symbol.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `list_symbol_libraries` | List all symbol libraries from sym-lib-table | Additional |
|
||||
| `search_symbols` | Search symbols by name, LCSC ID, or description | Additional |
|
||||
| `list_library_symbols` | List symbols in a specific library | Additional |
|
||||
| `get_symbol_info` | Get detailed symbol information | Additional |
|
||||
| Tool | Description | Access |
|
||||
| ----------------------- | ----------------------------------------------- | ---------- |
|
||||
| `list_symbol_libraries` | List all symbol libraries from sym-lib-table | Additional |
|
||||
| `search_symbols` | Search symbols by name, LCSC ID, or description | Additional |
|
||||
| `list_library_symbols` | List symbols in a specific library | Additional |
|
||||
| `get_symbol_info` | Get detailed symbol information | Additional |
|
||||
|
||||
---
|
||||
|
||||
## Footprint Creator (4 tools)
|
||||
|
||||
*Source: `src/tools/footprint.ts`*
|
||||
_Source: `src/tools/footprint.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `create_footprint` | Create custom .kicad_mod footprint (SMD/THT pads, courtyard, silkscreen) | Additional |
|
||||
| `edit_footprint_pad` | Edit pad in existing footprint (size, position, drill, shape) | Additional |
|
||||
| `register_footprint_library` | Register .pretty library in fp-lib-table | Additional |
|
||||
| `list_footprint_libraries` | List available .pretty libraries | Additional |
|
||||
| Tool | Description | Access |
|
||||
| ---------------------------- | ------------------------------------------------------------------------ | ---------- |
|
||||
| `create_footprint` | Create custom .kicad_mod footprint (SMD/THT pads, courtyard, silkscreen) | Additional |
|
||||
| `edit_footprint_pad` | Edit pad in existing footprint (size, position, drill, shape) | Additional |
|
||||
| `register_footprint_library` | Register .pretty library in fp-lib-table | Additional |
|
||||
| `list_footprint_libraries` | List available .pretty libraries | Additional |
|
||||
|
||||
---
|
||||
|
||||
## Symbol Creator (4 tools)
|
||||
|
||||
*Source: `src/tools/symbol-creator.ts`*
|
||||
_Source: `src/tools/symbol-creator.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `create_symbol` | Create custom .kicad_sym symbol (pins, rectangles, polylines) | Additional |
|
||||
| `delete_symbol` | Remove symbol from library | Additional |
|
||||
| `list_symbols_in_library` | List all symbols in a .kicad_sym file | Additional |
|
||||
| `register_symbol_library` | Register library in sym-lib-table | Additional |
|
||||
| Tool | Description | Access |
|
||||
| ------------------------- | ------------------------------------------------------------- | ---------- |
|
||||
| `create_symbol` | Create custom .kicad_sym symbol (pins, rectangles, polylines) | Additional |
|
||||
| `delete_symbol` | Remove symbol from library | Additional |
|
||||
| `list_symbols_in_library` | List all symbols in a .kicad_sym file | Additional |
|
||||
| `register_symbol_library` | Register library in sym-lib-table | Additional |
|
||||
|
||||
---
|
||||
|
||||
## Datasheet Tools (2 tools)
|
||||
|
||||
*Source: `src/tools/datasheet.ts`*
|
||||
_Source: `src/tools/datasheet.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| Tool | Description | Access |
|
||||
| ------------------- | --------------------------------------------------- | ---------- |
|
||||
| `enrich_datasheets` | Fill missing datasheet URLs using LCSC part numbers | Additional |
|
||||
| `get_datasheet_url` | Get LCSC datasheet URL for a component | Additional |
|
||||
| `get_datasheet_url` | Get LCSC datasheet URL for a component | Additional |
|
||||
|
||||
---
|
||||
|
||||
## JLCPCB Integration (5 tools)
|
||||
|
||||
*Source: `src/tools/jlcpcb-api.ts`*
|
||||
_Source: `src/tools/jlcpcb-api.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `download_jlcpcb_database` | Download 2.5M+ parts catalog to local SQLite database | Additional |
|
||||
| `search_jlcpcb_parts` | Search parts by specs (category, package, library type) | Additional |
|
||||
| `get_jlcpcb_part` | Get detailed part info with pricing | Additional |
|
||||
| `get_jlcpcb_database_stats` | Get database statistics | Additional |
|
||||
| `suggest_jlcpcb_alternatives` | Find cheaper or in-stock alternatives | Additional |
|
||||
| Tool | Description | Access |
|
||||
| ----------------------------- | ------------------------------------------------------- | ---------- |
|
||||
| `download_jlcpcb_database` | Download 2.5M+ parts catalog to local SQLite database | Additional |
|
||||
| `search_jlcpcb_parts` | Search parts by specs (category, package, library type) | Additional |
|
||||
| `get_jlcpcb_part` | Get detailed part info with pricing | Additional |
|
||||
| `get_jlcpcb_database_stats` | Get database statistics | Additional |
|
||||
| `suggest_jlcpcb_alternatives` | Find cheaper or in-stock alternatives | Additional |
|
||||
|
||||
---
|
||||
|
||||
## Freerouting Autorouter (4 tools)
|
||||
|
||||
*Source: `src/tools/freerouting.ts`*
|
||||
_Source: `src/tools/freerouting.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `autoroute` | Run Freerouting autorouter (export DSN, route, import SES) | Routed (autoroute) |
|
||||
| `export_dsn` | Export Specctra DSN file for manual routing | Routed (autoroute) |
|
||||
| `import_ses` | Import routed SES file back into PCB | Routed (autoroute) |
|
||||
| `check_freerouting` | Check Java and Freerouting JAR availability | Routed (autoroute) |
|
||||
| Tool | Description | Access |
|
||||
| ------------------- | ---------------------------------------------------------- | ------------------ |
|
||||
| `autoroute` | Run Freerouting autorouter (export DSN, route, import SES) | Routed (autoroute) |
|
||||
| `export_dsn` | Export Specctra DSN file for manual routing | Routed (autoroute) |
|
||||
| `import_ses` | Import routed SES file back into PCB | Routed (autoroute) |
|
||||
| `check_freerouting` | Check Java and Freerouting JAR availability | Routed (autoroute) |
|
||||
|
||||
---
|
||||
|
||||
## UI Management (2 tools)
|
||||
|
||||
*Source: `src/tools/ui.ts`*
|
||||
_Source: `src/tools/ui.ts`_
|
||||
|
||||
| Tool | Description | Access |
|
||||
|------|-------------|--------|
|
||||
| `check_kicad_ui` | Check if KiCAD UI is running | Direct |
|
||||
| Tool | Description | Access |
|
||||
| ----------------- | ----------------------------------------- | -------------- |
|
||||
| `check_kicad_ui` | Check if KiCAD UI is running | Direct |
|
||||
| `launch_kicad_ui` | Launch KiCAD UI (optionally with project) | Routed (board) |
|
||||
|
||||
---
|
||||
|
||||
## Router Tools (4 tools)
|
||||
|
||||
*Source: `src/tools/router.ts`*
|
||||
_Source: `src/tools/router.ts`_
|
||||
|
||||
These meta-tools provide discovery and execution of routed tools:
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| 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 |
|
||||
| `get_category_tools` | View tools in a specific category |
|
||||
| `search_tools` | Find tools by keyword |
|
||||
| `execute_tool` | Run any routed tool with parameters |
|
||||
|
||||
---
|
||||
|
||||
## 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 | 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** | |
|
||||
|
||||
## Summary by Category
|
||||
|
||||
| Category | Tool Count |
|
||||
|----------|------------|
|
||||
| Project Management | 5 |
|
||||
| Board Management | 12 |
|
||||
| Component Management | 16 |
|
||||
| Routing | 13 |
|
||||
| Design Rules / DRC | 8 |
|
||||
| Export | 8 |
|
||||
| Schematic | 27 |
|
||||
| Footprint Libraries | 4 |
|
||||
| Symbol Libraries | 4 |
|
||||
| Footprint Creator | 4 |
|
||||
| Symbol Creator | 4 |
|
||||
| Datasheet | 2 |
|
||||
| JLCPCB Integration | 5 |
|
||||
| Freerouting | 4 |
|
||||
| UI Management | 2 |
|
||||
| Router | 4 |
|
||||
| **Total** | **122** |
|
||||
| Category | Tool Count |
|
||||
| -------------------- | ---------- |
|
||||
| Project Management | 5 |
|
||||
| Board Management | 12 |
|
||||
| Component Management | 16 |
|
||||
| Routing | 13 |
|
||||
| Design Rules / DRC | 8 |
|
||||
| Export | 8 |
|
||||
| Schematic | 27 |
|
||||
| Footprint Libraries | 4 |
|
||||
| Symbol Libraries | 4 |
|
||||
| Footprint Creator | 4 |
|
||||
| Symbol Creator | 4 |
|
||||
| Datasheet | 2 |
|
||||
| JLCPCB Integration | 5 |
|
||||
| Freerouting | 4 |
|
||||
| UI Management | 2 |
|
||||
| Router | 4 |
|
||||
| **Total** | **122** |
|
||||
|
||||
## Token Impact
|
||||
|
||||
|
||||
@@ -1,399 +1,425 @@
|
||||
# KiCAD UI Auto-Launch Feature
|
||||
|
||||
Automatically detect and launch KiCAD UI when needed, providing seamless visual feedback for PCB design operations.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
The KiCAD MCP server can now:
|
||||
- ✅ Detect if KiCAD UI is running
|
||||
- ✅ Launch KiCAD automatically when needed
|
||||
- ✅ Open projects directly in the UI
|
||||
- ✅ Work across Linux, macOS, and Windows
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Enable Auto-Launch
|
||||
|
||||
Add to your MCP configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"command": "node",
|
||||
"args": ["/path/to/KiCAD-MCP-Server/dist/index.js"],
|
||||
"env": {
|
||||
"KICAD_AUTO_LAUNCH": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Manual Control (Default)
|
||||
|
||||
Without `KICAD_AUTO_LAUNCH=true`, you manually control when KiCAD launches using the new MCP tools.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ New MCP Tools
|
||||
|
||||
### 1. `check_kicad_ui`
|
||||
|
||||
Check if KiCAD is currently running.
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
{
|
||||
"command": "check_kicad_ui",
|
||||
"params": {}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"running": true,
|
||||
"processes": [
|
||||
{
|
||||
"pid": "12345",
|
||||
"name": "pcbnew",
|
||||
"command": "/usr/bin/pcbnew /tmp/project.kicad_pcb"
|
||||
}
|
||||
],
|
||||
"message": "KiCAD is running"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. `launch_kicad_ui`
|
||||
|
||||
Launch KiCAD UI, optionally with a project file.
|
||||
|
||||
**Parameters:**
|
||||
- `projectPath` (optional): Path to `.kicad_pcb` file to open
|
||||
- `autoLaunch` (optional): Whether to launch if not running (default: true)
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
{
|
||||
"command": "launch_kicad_ui",
|
||||
"params": {
|
||||
"projectPath": "/tmp/mcp_demo/New_Project.kicad_pcb"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"running": true,
|
||||
"launched": true,
|
||||
"message": "KiCAD launched successfully",
|
||||
"project": "/tmp/mcp_demo/New_Project.kicad_pcb",
|
||||
"processes": [...]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Workflow Examples
|
||||
|
||||
### Example 1: Manual Launch
|
||||
|
||||
```
|
||||
User: "Check if KiCAD is running"
|
||||
Claude: Uses check_kicad_ui → "KiCAD is not running"
|
||||
|
||||
User: "Launch it with the demo project"
|
||||
Claude: Uses launch_kicad_ui → KiCAD opens with project loaded!
|
||||
```
|
||||
|
||||
### Example 2: Auto-Launch Mode
|
||||
|
||||
With `KICAD_AUTO_LAUNCH=true`:
|
||||
|
||||
```
|
||||
User: "Create a new Arduino shield PCB"
|
||||
Claude:
|
||||
1. Creates project
|
||||
2. Detects KiCAD not running
|
||||
3. Automatically launches KiCAD with the new project
|
||||
4. You see the board in real-time as it's designed!
|
||||
```
|
||||
|
||||
### Example 3: Side-by-Side Design
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────┐
|
||||
│ Workflow: AI-Assisted PCB Design │
|
||||
├────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. User: "Create a 100mm square board" │
|
||||
│ → Claude creates project │
|
||||
│ → KiCAD auto-launches if not running │
|
||||
│ │
|
||||
│ 2. User: "Add 4 mounting holes at corners" │
|
||||
│ → Claude adds holes │
|
||||
│ → KiCAD detects file change, prompts to reload │
|
||||
│ → User clicks "Yes" → sees holes appear! │
|
||||
│ │
|
||||
│ 3. User: "Perfect! Now add a circular outline..." │
|
||||
│ → Iterative design continues... │
|
||||
│ │
|
||||
└────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Configuration Options
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `KICAD_AUTO_LAUNCH` | `false` | Auto-launch KiCAD when needed |
|
||||
| `KICAD_EXECUTABLE` | auto-detect | Override KiCAD executable path |
|
||||
|
||||
### Custom Executable Path
|
||||
|
||||
If KiCAD is installed in a non-standard location:
|
||||
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"KICAD_AUTO_LAUNCH": "true",
|
||||
"KICAD_EXECUTABLE": "/opt/kicad/bin/pcbnew"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 How It Works
|
||||
|
||||
### Process Detection
|
||||
|
||||
**Linux:**
|
||||
```bash
|
||||
pgrep -f "pcbnew|kicad"
|
||||
```
|
||||
|
||||
**macOS:**
|
||||
```bash
|
||||
pgrep -f "KiCad|pcbnew"
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
```powershell
|
||||
tasklist /FI "IMAGENAME eq pcbnew.exe"
|
||||
```
|
||||
|
||||
### Auto-Discovery of Executable
|
||||
|
||||
The system searches for KiCAD in:
|
||||
|
||||
**Linux:**
|
||||
- `/usr/bin/pcbnew`
|
||||
- `/usr/local/bin/pcbnew`
|
||||
- `/usr/bin/kicad`
|
||||
|
||||
**macOS:**
|
||||
- `/Applications/KiCad/KiCad.app/Contents/MacOS/kicad`
|
||||
- `/Applications/KiCad/pcbnew.app/Contents/MacOS/pcbnew`
|
||||
|
||||
**Windows:**
|
||||
- `C:/Program Files/KiCad/9.0/bin/pcbnew.exe`
|
||||
- `C:/Program Files/KiCad/8.0/bin/pcbnew.exe`
|
||||
|
||||
### Launch Process
|
||||
|
||||
1. Check if KiCAD is already running
|
||||
2. If not, find executable path
|
||||
3. Spawn process with optional project path
|
||||
4. Wait up to 5 seconds for process to start
|
||||
5. Verify process is running
|
||||
6. Return status to MCP client
|
||||
|
||||
---
|
||||
|
||||
## 💡 Use Cases
|
||||
|
||||
### 1. Beginner-Friendly Workflow
|
||||
|
||||
User doesn't need to know how to launch KiCAD manually:
|
||||
```
|
||||
User: "Help me design a simple LED board"
|
||||
Claude: [Auto-launches KiCAD, creates project, designs board]
|
||||
```
|
||||
|
||||
### 2. Streamlined Iteration
|
||||
|
||||
For rapid prototyping with visual feedback:
|
||||
```
|
||||
1. Claude creates board → KiCAD opens
|
||||
2. User sees board, requests changes
|
||||
3. Claude modifies → KiCAD reloads
|
||||
4. Repeat until satisfied
|
||||
```
|
||||
|
||||
### 3. Batch Processing
|
||||
|
||||
Process multiple designs without manual intervention:
|
||||
```python
|
||||
for design in designs:
|
||||
create_project(design)
|
||||
# KiCAD auto-launches and loads each one
|
||||
add_components(design)
|
||||
route_board(design)
|
||||
export_gerbers(design)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### KiCAD Doesn't Launch
|
||||
|
||||
**Check executable path:**
|
||||
```bash
|
||||
# Linux/macOS
|
||||
which pcbnew
|
||||
|
||||
# Windows
|
||||
where pcbnew.exe
|
||||
```
|
||||
|
||||
**Override if needed:**
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"KICAD_EXECUTABLE": "/path/to/pcbnew"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Process Detection Fails
|
||||
|
||||
**Manual check:**
|
||||
```bash
|
||||
# Linux/macOS
|
||||
ps aux | grep kicad
|
||||
|
||||
# Windows
|
||||
tasklist | findstr kicad
|
||||
```
|
||||
|
||||
**Verify permissions:**
|
||||
- Ensure user can execute `pgrep` (Linux/macOS)
|
||||
- Ensure user can execute `tasklist` (Windows)
|
||||
|
||||
### Auto-Launch Doesn't Work
|
||||
|
||||
1. Check `KICAD_AUTO_LAUNCH` is set to `"true"` (string, not boolean)
|
||||
2. Verify KiCAD is in PATH or set `KICAD_EXECUTABLE`
|
||||
3. Check MCP server logs for errors
|
||||
4. Try manual launch first: `launch_kicad_ui`
|
||||
|
||||
---
|
||||
|
||||
## 📊 Implementation Details
|
||||
|
||||
### Files Modified/Created
|
||||
|
||||
**New Files:**
|
||||
- `python/utils/kicad_process.py` - Process management utilities
|
||||
- `src/tools/ui.ts` - MCP tool definitions
|
||||
- `docs/UI_AUTO_LAUNCH.md` - This documentation
|
||||
|
||||
**Modified Files:**
|
||||
- `python/kicad_interface.py` - Added UI command handlers
|
||||
- `src/server.ts` - Registered UI tools
|
||||
|
||||
### API Reference
|
||||
|
||||
**Python:**
|
||||
```python
|
||||
from utils.kicad_process import KiCADProcessManager, check_and_launch_kicad
|
||||
|
||||
# Check if running
|
||||
manager = KiCADProcessManager()
|
||||
is_running = manager.is_running()
|
||||
|
||||
# Launch KiCAD
|
||||
success = manager.launch(project_path="/path/to/file.kicad_pcb")
|
||||
|
||||
# Get process info
|
||||
processes = manager.get_process_info()
|
||||
|
||||
# High-level helper
|
||||
result = check_and_launch_kicad(
|
||||
project_path=Path("/path/to/file.kicad_pcb"),
|
||||
auto_launch=True
|
||||
)
|
||||
```
|
||||
|
||||
**MCP Tools:**
|
||||
```typescript
|
||||
// Check status
|
||||
await callKicadScript("check_kicad_ui", {});
|
||||
|
||||
// Launch
|
||||
await callKicadScript("launch_kicad_ui", {
|
||||
projectPath: "/path/to/project.kicad_pcb",
|
||||
autoLaunch: true
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔮 Future Enhancements
|
||||
|
||||
### Planned Features
|
||||
|
||||
- **Window Management:** Bring KiCAD to front, minimize/maximize
|
||||
- **Multi-Instance:** Handle multiple KiCAD instances
|
||||
- **IPC Integration:** Seamless integration with IPC backend
|
||||
- **Status Notifications:** Push notifications when KiCAD state changes
|
||||
- **Auto-Close:** Option to close KiCAD after operations complete
|
||||
|
||||
### IPC Mode (Coming Weeks 2-3)
|
||||
|
||||
When IPC backend is fully implemented:
|
||||
```
|
||||
KiCAD runs in background → MCP connects via IPC → Real-time updates
|
||||
No file reloading needed! Changes appear instantly.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Summary
|
||||
|
||||
**Before this feature:**
|
||||
```
|
||||
User manually launches KiCAD
|
||||
User manually opens project
|
||||
Claude makes changes
|
||||
User manually reloads
|
||||
```
|
||||
|
||||
**After this feature:**
|
||||
```
|
||||
User: "Design a board"
|
||||
→ KiCAD auto-launches with project
|
||||
→ Changes appear (with quick reload)
|
||||
→ Seamless AI-assisted design!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-10-26
|
||||
**Version:** 2.0.0-alpha.1
|
||||
**Status:** ✅ Production Ready
|
||||
# KiCAD UI Auto-Launch Feature
|
||||
|
||||
Automatically detect and launch KiCAD UI when needed, providing seamless visual feedback for PCB design operations.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
The KiCAD MCP server can now:
|
||||
|
||||
- ✅ Detect if KiCAD UI is running
|
||||
- ✅ Launch KiCAD automatically when needed
|
||||
- ✅ Open projects directly in the UI
|
||||
- ✅ Work across Linux, macOS, and Windows
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Enable Auto-Launch
|
||||
|
||||
Add to your MCP configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"command": "node",
|
||||
"args": ["/path/to/KiCAD-MCP-Server/dist/index.js"],
|
||||
"env": {
|
||||
"KICAD_AUTO_LAUNCH": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Manual Control (Default)
|
||||
|
||||
Without `KICAD_AUTO_LAUNCH=true`, you manually control when KiCAD launches using the new MCP tools.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ New MCP Tools
|
||||
|
||||
### 1. `check_kicad_ui`
|
||||
|
||||
Check if KiCAD is currently running.
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Example:**
|
||||
|
||||
```typescript
|
||||
{
|
||||
"command": "check_kicad_ui",
|
||||
"params": {}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"running": true,
|
||||
"processes": [
|
||||
{
|
||||
"pid": "12345",
|
||||
"name": "pcbnew",
|
||||
"command": "/usr/bin/pcbnew /tmp/project.kicad_pcb"
|
||||
}
|
||||
],
|
||||
"message": "KiCAD is running"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. `launch_kicad_ui`
|
||||
|
||||
Launch KiCAD UI, optionally with a project file.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `projectPath` (optional): Path to `.kicad_pcb` file to open
|
||||
- `autoLaunch` (optional): Whether to launch if not running (default: true)
|
||||
|
||||
**Example:**
|
||||
|
||||
```typescript
|
||||
{
|
||||
"command": "launch_kicad_ui",
|
||||
"params": {
|
||||
"projectPath": "/tmp/mcp_demo/New_Project.kicad_pcb"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"running": true,
|
||||
"launched": true,
|
||||
"message": "KiCAD launched successfully",
|
||||
"project": "/tmp/mcp_demo/New_Project.kicad_pcb",
|
||||
"processes": [...]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Workflow Examples
|
||||
|
||||
### Example 1: Manual Launch
|
||||
|
||||
```
|
||||
User: "Check if KiCAD is running"
|
||||
Claude: Uses check_kicad_ui → "KiCAD is not running"
|
||||
|
||||
User: "Launch it with the demo project"
|
||||
Claude: Uses launch_kicad_ui → KiCAD opens with project loaded!
|
||||
```
|
||||
|
||||
### Example 2: Auto-Launch Mode
|
||||
|
||||
With `KICAD_AUTO_LAUNCH=true`:
|
||||
|
||||
```
|
||||
User: "Create a new Arduino shield PCB"
|
||||
Claude:
|
||||
1. Creates project
|
||||
2. Detects KiCAD not running
|
||||
3. Automatically launches KiCAD with the new project
|
||||
4. You see the board in real-time as it's designed!
|
||||
```
|
||||
|
||||
### Example 3: Side-by-Side Design
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────┐
|
||||
│ Workflow: AI-Assisted PCB Design │
|
||||
├────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. User: "Create a 100mm square board" │
|
||||
│ → Claude creates project │
|
||||
│ → KiCAD auto-launches if not running │
|
||||
│ │
|
||||
│ 2. User: "Add 4 mounting holes at corners" │
|
||||
│ → Claude adds holes │
|
||||
│ → KiCAD detects file change, prompts to reload │
|
||||
│ → User clicks "Yes" → sees holes appear! │
|
||||
│ │
|
||||
│ 3. User: "Perfect! Now add a circular outline..." │
|
||||
│ → Iterative design continues... │
|
||||
│ │
|
||||
└────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Configuration Options
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
| ------------------- | ----------- | ------------------------------ |
|
||||
| `KICAD_AUTO_LAUNCH` | `false` | Auto-launch KiCAD when needed |
|
||||
| `KICAD_EXECUTABLE` | auto-detect | Override KiCAD executable path |
|
||||
|
||||
### Custom Executable Path
|
||||
|
||||
If KiCAD is installed in a non-standard location:
|
||||
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"KICAD_AUTO_LAUNCH": "true",
|
||||
"KICAD_EXECUTABLE": "/opt/kicad/bin/pcbnew"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 How It Works
|
||||
|
||||
### Process Detection
|
||||
|
||||
**Linux:**
|
||||
|
||||
```bash
|
||||
pgrep -f "pcbnew|kicad"
|
||||
```
|
||||
|
||||
**macOS:**
|
||||
|
||||
```bash
|
||||
pgrep -f "KiCad|pcbnew"
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
|
||||
```powershell
|
||||
tasklist /FI "IMAGENAME eq pcbnew.exe"
|
||||
```
|
||||
|
||||
### Auto-Discovery of Executable
|
||||
|
||||
The system searches for KiCAD in:
|
||||
|
||||
**Linux:**
|
||||
|
||||
- `/usr/bin/pcbnew`
|
||||
- `/usr/local/bin/pcbnew`
|
||||
- `/usr/bin/kicad`
|
||||
|
||||
**macOS:**
|
||||
|
||||
- `/Applications/KiCad/KiCad.app/Contents/MacOS/kicad`
|
||||
- `/Applications/KiCad/pcbnew.app/Contents/MacOS/pcbnew`
|
||||
|
||||
**Windows:**
|
||||
|
||||
- `C:/Program Files/KiCad/9.0/bin/pcbnew.exe`
|
||||
- `C:/Program Files/KiCad/8.0/bin/pcbnew.exe`
|
||||
|
||||
### Launch Process
|
||||
|
||||
1. Check if KiCAD is already running
|
||||
2. If not, find executable path
|
||||
3. Spawn process with optional project path
|
||||
4. Wait up to 5 seconds for process to start
|
||||
5. Verify process is running
|
||||
6. Return status to MCP client
|
||||
|
||||
---
|
||||
|
||||
## 💡 Use Cases
|
||||
|
||||
### 1. Beginner-Friendly Workflow
|
||||
|
||||
User doesn't need to know how to launch KiCAD manually:
|
||||
|
||||
```
|
||||
User: "Help me design a simple LED board"
|
||||
Claude: [Auto-launches KiCAD, creates project, designs board]
|
||||
```
|
||||
|
||||
### 2. Streamlined Iteration
|
||||
|
||||
For rapid prototyping with visual feedback:
|
||||
|
||||
```
|
||||
1. Claude creates board → KiCAD opens
|
||||
2. User sees board, requests changes
|
||||
3. Claude modifies → KiCAD reloads
|
||||
4. Repeat until satisfied
|
||||
```
|
||||
|
||||
### 3. Batch Processing
|
||||
|
||||
Process multiple designs without manual intervention:
|
||||
|
||||
```python
|
||||
for design in designs:
|
||||
create_project(design)
|
||||
# KiCAD auto-launches and loads each one
|
||||
add_components(design)
|
||||
route_board(design)
|
||||
export_gerbers(design)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### KiCAD Doesn't Launch
|
||||
|
||||
**Check executable path:**
|
||||
|
||||
```bash
|
||||
# Linux/macOS
|
||||
which pcbnew
|
||||
|
||||
# Windows
|
||||
where pcbnew.exe
|
||||
```
|
||||
|
||||
**Override if needed:**
|
||||
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"KICAD_EXECUTABLE": "/path/to/pcbnew"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Process Detection Fails
|
||||
|
||||
**Manual check:**
|
||||
|
||||
```bash
|
||||
# Linux/macOS
|
||||
ps aux | grep kicad
|
||||
|
||||
# Windows
|
||||
tasklist | findstr kicad
|
||||
```
|
||||
|
||||
**Verify permissions:**
|
||||
|
||||
- Ensure user can execute `pgrep` (Linux/macOS)
|
||||
- Ensure user can execute `tasklist` (Windows)
|
||||
|
||||
### Auto-Launch Doesn't Work
|
||||
|
||||
1. Check `KICAD_AUTO_LAUNCH` is set to `"true"` (string, not boolean)
|
||||
2. Verify KiCAD is in PATH or set `KICAD_EXECUTABLE`
|
||||
3. Check MCP server logs for errors
|
||||
4. Try manual launch first: `launch_kicad_ui`
|
||||
|
||||
---
|
||||
|
||||
## 📊 Implementation Details
|
||||
|
||||
### Files Modified/Created
|
||||
|
||||
**New Files:**
|
||||
|
||||
- `python/utils/kicad_process.py` - Process management utilities
|
||||
- `src/tools/ui.ts` - MCP tool definitions
|
||||
- `docs/UI_AUTO_LAUNCH.md` - This documentation
|
||||
|
||||
**Modified Files:**
|
||||
|
||||
- `python/kicad_interface.py` - Added UI command handlers
|
||||
- `src/server.ts` - Registered UI tools
|
||||
|
||||
### API Reference
|
||||
|
||||
**Python:**
|
||||
|
||||
```python
|
||||
from utils.kicad_process import KiCADProcessManager, check_and_launch_kicad
|
||||
|
||||
# Check if running
|
||||
manager = KiCADProcessManager()
|
||||
is_running = manager.is_running()
|
||||
|
||||
# Launch KiCAD
|
||||
success = manager.launch(project_path="/path/to/file.kicad_pcb")
|
||||
|
||||
# Get process info
|
||||
processes = manager.get_process_info()
|
||||
|
||||
# High-level helper
|
||||
result = check_and_launch_kicad(
|
||||
project_path=Path("/path/to/file.kicad_pcb"),
|
||||
auto_launch=True
|
||||
)
|
||||
```
|
||||
|
||||
**MCP Tools:**
|
||||
|
||||
```typescript
|
||||
// Check status
|
||||
await callKicadScript("check_kicad_ui", {});
|
||||
|
||||
// Launch
|
||||
await callKicadScript("launch_kicad_ui", {
|
||||
projectPath: "/path/to/project.kicad_pcb",
|
||||
autoLaunch: true,
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔮 Future Enhancements
|
||||
|
||||
### Planned Features
|
||||
|
||||
- **Window Management:** Bring KiCAD to front, minimize/maximize
|
||||
- **Multi-Instance:** Handle multiple KiCAD instances
|
||||
- **IPC Integration:** Seamless integration with IPC backend
|
||||
- **Status Notifications:** Push notifications when KiCAD state changes
|
||||
- **Auto-Close:** Option to close KiCAD after operations complete
|
||||
|
||||
### IPC Mode (Coming Weeks 2-3)
|
||||
|
||||
When IPC backend is fully implemented:
|
||||
|
||||
```
|
||||
KiCAD runs in background → MCP connects via IPC → Real-time updates
|
||||
No file reloading needed! Changes appear instantly.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Summary
|
||||
|
||||
**Before this feature:**
|
||||
|
||||
```
|
||||
User manually launches KiCAD
|
||||
User manually opens project
|
||||
Claude makes changes
|
||||
User manually reloads
|
||||
```
|
||||
|
||||
**After this feature:**
|
||||
|
||||
```
|
||||
User: "Design a board"
|
||||
→ KiCAD auto-launches with project
|
||||
→ Changes appear (with quick reload)
|
||||
→ Seamless AI-assisted design!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-10-26
|
||||
**Version:** 2.0.0-alpha.1
|
||||
**Status:** ✅ Production Ready
|
||||
|
||||
@@ -1,184 +1,193 @@
|
||||
# Visual Feedback: Seeing MCP Changes in KiCAD UI
|
||||
|
||||
This document explains how to see changes made by the MCP server in the KiCAD UI in real-time or near-real-time.
|
||||
|
||||
## Current Status (Week 1 - SWIG Backend)
|
||||
|
||||
**Active Backend:** SWIG (legacy pcbnew Python API)
|
||||
**Real-time Updates:** Not available yet
|
||||
**IPC Backend:** Skeleton implemented, operations coming in Weeks 2-3
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Best Current Workflow (SWIG + Manual Reload)
|
||||
|
||||
### Setup
|
||||
|
||||
1. **Open your project in KiCAD PCB Editor**
|
||||
```bash
|
||||
pcbnew /tmp/kicad_test_project/New_Project.kicad_pcb
|
||||
```
|
||||
|
||||
2. **Make changes via MCP** (Claude Code, Claude Desktop, etc.)
|
||||
- Example: Add board outline, mounting holes, etc.
|
||||
- Each operation saves the file automatically
|
||||
|
||||
3. **Reload in KiCAD UI**
|
||||
- **Option A (Automatic):** KiCAD 8.0+ detects file changes and shows a reload prompt
|
||||
- **Option B (Manual):** File → Revert to reload from disk
|
||||
- **Keyboard shortcut:** None by default (but you can assign one)
|
||||
|
||||
### Workflow Example
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Terminal: Claude Code │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ You: "Create a 100x80mm board with 4 mounting holes" │
|
||||
│ │
|
||||
│ Claude: ✓ Added board outline (100x80mm) │
|
||||
│ ✓ Added mounting hole at (5,5) │
|
||||
│ ✓ Added mounting hole at (95,5) │
|
||||
│ ✓ Added mounting hole at (95,75) │
|
||||
│ ✓ Added mounting hole at (5,75) │
|
||||
│ ✓ Saved project │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ KiCAD PCB Editor │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ [Reload prompt appears] │
|
||||
│ "File has been modified. Reload?" │
|
||||
│ │
|
||||
│ Click "Yes" → Changes appear instantly! 🎉 │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔮 Future: IPC Backend (Weeks 2-3)
|
||||
|
||||
When fully implemented, the IPC backend will provide **true real-time updates**:
|
||||
|
||||
### How It Will Work
|
||||
|
||||
```
|
||||
Claude MCP → IPC Socket → Running KiCAD → Instant UI Update
|
||||
```
|
||||
|
||||
**No file reloading required** - changes appear as you make them!
|
||||
|
||||
### IPC Setup (When Available)
|
||||
|
||||
1. **Enable IPC in KiCAD**
|
||||
- Preferences → Advanced Preferences
|
||||
- Search for "IPC"
|
||||
- Enable: "Enable IPC API Server"
|
||||
- Restart KiCAD
|
||||
|
||||
2. **Install kicad-python** (Already installed ✓)
|
||||
```bash
|
||||
pip install kicad-python
|
||||
```
|
||||
|
||||
3. **Configure MCP Server**
|
||||
Add to your MCP config:
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"KICAD_BACKEND": "ipc"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. **Start KiCAD first, then use MCP**
|
||||
- Changes will appear in real-time
|
||||
- No manual reloading needed
|
||||
|
||||
### Current IPC Status
|
||||
|
||||
| Feature | Status |
|
||||
|---------|--------|
|
||||
| Connection to KiCAD | ✅ Working |
|
||||
| Version checking | ✅ Working |
|
||||
| Project operations | ⏳ Week 2-3 |
|
||||
| Board operations | ⏳ Week 2-3 |
|
||||
| Component operations | ⏳ Week 2-3 |
|
||||
| Routing operations | ⏳ Week 2-3 |
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Monitoring Helper (Optional)
|
||||
|
||||
A helper script is available to monitor file changes:
|
||||
|
||||
```bash
|
||||
# Watch for changes and notify
|
||||
./scripts/auto_refresh_kicad.sh /tmp/kicad_test_project/New_Project.kicad_pcb
|
||||
```
|
||||
|
||||
This will print a message each time the MCP server saves changes.
|
||||
|
||||
---
|
||||
|
||||
## 💡 Tips for Best Experience
|
||||
|
||||
### 1. Side-by-Side Windows
|
||||
```
|
||||
┌──────────────────┬──────────────────┐
|
||||
│ Claude Code │ KiCAD PCB │
|
||||
│ (Terminal) │ Editor │
|
||||
│ │ │
|
||||
│ Making changes │ Viewing results │
|
||||
└──────────────────┴──────────────────┘
|
||||
```
|
||||
|
||||
### 2. Quick Reload Workflow
|
||||
- Keep KiCAD focused in one window
|
||||
- Make changes via Claude in another
|
||||
- Press Alt+Tab → Click "Reload" → See changes
|
||||
- Repeat
|
||||
|
||||
### 3. Save Frequently
|
||||
The MCP server auto-saves after each operation, so changes are immediately available for reload.
|
||||
|
||||
### 4. Verify Before Complex Operations
|
||||
For complex changes (multiple components, routing, etc.):
|
||||
1. Make the change
|
||||
2. Reload in KiCAD
|
||||
3. Verify it looks correct
|
||||
4. Proceed with next change
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Troubleshooting
|
||||
|
||||
### KiCAD Doesn't Detect File Changes
|
||||
|
||||
**Cause:** Some KiCAD versions or configurations don't auto-detect
|
||||
**Solution:** Use File → Revert manually
|
||||
|
||||
### Changes Don't Appear After Reload
|
||||
|
||||
**Cause:** MCP operation may have failed
|
||||
**Solution:** Check the MCP response for success: true
|
||||
|
||||
### File is Locked
|
||||
|
||||
**Cause:** KiCAD has the file open exclusively
|
||||
**Solution:**
|
||||
- KiCAD should allow external modifications
|
||||
- If not, close the file in KiCAD, let MCP make changes, then reopen
|
||||
|
||||
---
|
||||
|
||||
## 📅 Roadmap
|
||||
|
||||
**Current (Week 1):** SWIG backend with manual reload
|
||||
**Week 2-3:** IPC backend implementation
|
||||
**Week 4+:** Real-time collaboration features
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-10-26
|
||||
**Version:** 2.0.0-alpha.1
|
||||
# Visual Feedback: Seeing MCP Changes in KiCAD UI
|
||||
|
||||
This document explains how to see changes made by the MCP server in the KiCAD UI in real-time or near-real-time.
|
||||
|
||||
## Current Status (Week 1 - SWIG Backend)
|
||||
|
||||
**Active Backend:** SWIG (legacy pcbnew Python API)
|
||||
**Real-time Updates:** Not available yet
|
||||
**IPC Backend:** Skeleton implemented, operations coming in Weeks 2-3
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Best Current Workflow (SWIG + Manual Reload)
|
||||
|
||||
### Setup
|
||||
|
||||
1. **Open your project in KiCAD PCB Editor**
|
||||
|
||||
```bash
|
||||
pcbnew /tmp/kicad_test_project/New_Project.kicad_pcb
|
||||
```
|
||||
|
||||
2. **Make changes via MCP** (Claude Code, Claude Desktop, etc.)
|
||||
- Example: Add board outline, mounting holes, etc.
|
||||
- Each operation saves the file automatically
|
||||
|
||||
3. **Reload in KiCAD UI**
|
||||
- **Option A (Automatic):** KiCAD 8.0+ detects file changes and shows a reload prompt
|
||||
- **Option B (Manual):** File → Revert to reload from disk
|
||||
- **Keyboard shortcut:** None by default (but you can assign one)
|
||||
|
||||
### Workflow Example
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Terminal: Claude Code │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ You: "Create a 100x80mm board with 4 mounting holes" │
|
||||
│ │
|
||||
│ Claude: ✓ Added board outline (100x80mm) │
|
||||
│ ✓ Added mounting hole at (5,5) │
|
||||
│ ✓ Added mounting hole at (95,5) │
|
||||
│ ✓ Added mounting hole at (95,75) │
|
||||
│ ✓ Added mounting hole at (5,75) │
|
||||
│ ✓ Saved project │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ KiCAD PCB Editor │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ [Reload prompt appears] │
|
||||
│ "File has been modified. Reload?" │
|
||||
│ │
|
||||
│ Click "Yes" → Changes appear instantly! 🎉 │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔮 Future: IPC Backend (Weeks 2-3)
|
||||
|
||||
When fully implemented, the IPC backend will provide **true real-time updates**:
|
||||
|
||||
### How It Will Work
|
||||
|
||||
```
|
||||
Claude MCP → IPC Socket → Running KiCAD → Instant UI Update
|
||||
```
|
||||
|
||||
**No file reloading required** - changes appear as you make them!
|
||||
|
||||
### IPC Setup (When Available)
|
||||
|
||||
1. **Enable IPC in KiCAD**
|
||||
- Preferences → Advanced Preferences
|
||||
- Search for "IPC"
|
||||
- Enable: "Enable IPC API Server"
|
||||
- Restart KiCAD
|
||||
|
||||
2. **Install kicad-python** (Already installed ✓)
|
||||
|
||||
```bash
|
||||
pip install kicad-python
|
||||
```
|
||||
|
||||
3. **Configure MCP Server**
|
||||
Add to your MCP config:
|
||||
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"KICAD_BACKEND": "ipc"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. **Start KiCAD first, then use MCP**
|
||||
- Changes will appear in real-time
|
||||
- No manual reloading needed
|
||||
|
||||
### Current IPC Status
|
||||
|
||||
| Feature | Status |
|
||||
| -------------------- | ----------- |
|
||||
| Connection to KiCAD | ✅ Working |
|
||||
| Version checking | ✅ Working |
|
||||
| Project operations | ⏳ Week 2-3 |
|
||||
| Board operations | ⏳ Week 2-3 |
|
||||
| Component operations | ⏳ Week 2-3 |
|
||||
| Routing operations | ⏳ Week 2-3 |
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Monitoring Helper (Optional)
|
||||
|
||||
A helper script is available to monitor file changes:
|
||||
|
||||
```bash
|
||||
# Watch for changes and notify
|
||||
./scripts/auto_refresh_kicad.sh /tmp/kicad_test_project/New_Project.kicad_pcb
|
||||
```
|
||||
|
||||
This will print a message each time the MCP server saves changes.
|
||||
|
||||
---
|
||||
|
||||
## 💡 Tips for Best Experience
|
||||
|
||||
### 1. Side-by-Side Windows
|
||||
|
||||
```
|
||||
┌──────────────────┬──────────────────┐
|
||||
│ Claude Code │ KiCAD PCB │
|
||||
│ (Terminal) │ Editor │
|
||||
│ │ │
|
||||
│ Making changes │ Viewing results │
|
||||
└──────────────────┴──────────────────┘
|
||||
```
|
||||
|
||||
### 2. Quick Reload Workflow
|
||||
|
||||
- Keep KiCAD focused in one window
|
||||
- Make changes via Claude in another
|
||||
- Press Alt+Tab → Click "Reload" → See changes
|
||||
- Repeat
|
||||
|
||||
### 3. Save Frequently
|
||||
|
||||
The MCP server auto-saves after each operation, so changes are immediately available for reload.
|
||||
|
||||
### 4. Verify Before Complex Operations
|
||||
|
||||
For complex changes (multiple components, routing, etc.):
|
||||
|
||||
1. Make the change
|
||||
2. Reload in KiCAD
|
||||
3. Verify it looks correct
|
||||
4. Proceed with next change
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Troubleshooting
|
||||
|
||||
### KiCAD Doesn't Detect File Changes
|
||||
|
||||
**Cause:** Some KiCAD versions or configurations don't auto-detect
|
||||
**Solution:** Use File → Revert manually
|
||||
|
||||
### Changes Don't Appear After Reload
|
||||
|
||||
**Cause:** MCP operation may have failed
|
||||
**Solution:** Check the MCP response for success: true
|
||||
|
||||
### File is Locked
|
||||
|
||||
**Cause:** KiCAD has the file open exclusively
|
||||
**Solution:**
|
||||
|
||||
- KiCAD should allow external modifications
|
||||
- If not, close the file in KiCAD, let MCP make changes, then reopen
|
||||
|
||||
---
|
||||
|
||||
## 📅 Roadmap
|
||||
|
||||
**Current (Week 1):** SWIG backend with manual reload
|
||||
**Week 2-3:** IPC backend implementation
|
||||
**Week 4+:** Real-time collaboration features
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-10-26
|
||||
**Version:** 2.0.0-alpha.1
|
||||
|
||||
@@ -1,475 +1,493 @@
|
||||
# Windows Troubleshooting Guide
|
||||
|
||||
This guide helps diagnose and fix common issues when setting up KiCAD MCP Server on Windows.
|
||||
|
||||
## Quick Start: Automated Setup
|
||||
|
||||
**Before manually troubleshooting, try the automated setup script:**
|
||||
|
||||
```powershell
|
||||
# Open PowerShell in the KiCAD-MCP-Server directory
|
||||
.\setup-windows.ps1
|
||||
```
|
||||
|
||||
This script will:
|
||||
- Detect your KiCAD installation
|
||||
- Verify all prerequisites
|
||||
- Install dependencies
|
||||
- Build the project
|
||||
- Generate configuration
|
||||
- Run diagnostic tests
|
||||
|
||||
If the automated setup fails, continue with the manual troubleshooting below.
|
||||
|
||||
---
|
||||
|
||||
## Common Issues and Solutions
|
||||
|
||||
### Issue 1: Server Exits Immediately (Most Common)
|
||||
|
||||
**Symptom:** Claude Desktop logs show "Server transport closed unexpectedly"
|
||||
|
||||
**Cause:** Python process crashes during startup, usually due to missing pcbnew module
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Check the log file** (this has the actual error):
|
||||
```
|
||||
%USERPROFILE%\.kicad-mcp\logs\kicad_interface.log
|
||||
```
|
||||
Open in Notepad and look at the last 50-100 lines.
|
||||
|
||||
2. **Test pcbnew import manually:**
|
||||
```powershell
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" -c "import pcbnew; print(pcbnew.GetBuildVersion())"
|
||||
```
|
||||
|
||||
**Expected:** Prints KiCAD version like `9.0.0`
|
||||
|
||||
**If it fails:**
|
||||
- KiCAD's Python module isn't installed
|
||||
- Reinstall KiCAD with default options
|
||||
- Make sure "Install Python" is checked during installation
|
||||
|
||||
3. **Verify PYTHONPATH in your config:**
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"env": {
|
||||
"PYTHONPATH": "C:\\Program Files\\KiCad\\9.0\\lib\\python3\\dist-packages"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Issue 2: KiCAD Not Found
|
||||
|
||||
**Symptom:** Log shows "No KiCAD installations found"
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Check if KiCAD is installed:**
|
||||
```powershell
|
||||
Test-Path "C:\Program Files\KiCad\9.0"
|
||||
```
|
||||
|
||||
2. **If KiCAD is installed elsewhere:**
|
||||
- Find your KiCAD installation directory
|
||||
- Update PYTHONPATH in config to match your installation
|
||||
- Example for version 8.0:
|
||||
```
|
||||
"PYTHONPATH": "C:\\Program Files\\KiCad\\8.0\\lib\\python3\\dist-packages"
|
||||
```
|
||||
|
||||
3. **If KiCAD is not installed:**
|
||||
- Download from https://www.kicad.org/download/windows/
|
||||
- Install version 9.0 or higher
|
||||
- Use default installation path
|
||||
|
||||
---
|
||||
|
||||
### Issue 3: Node.js Not Found
|
||||
|
||||
**Symptom:** Cannot run `npm install` or `npm run build`
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Check if Node.js is installed:**
|
||||
```powershell
|
||||
node --version
|
||||
npm --version
|
||||
```
|
||||
|
||||
2. **If not installed:**
|
||||
- Download Node.js 18+ from https://nodejs.org/
|
||||
- Install with default options
|
||||
- Restart PowerShell after installation
|
||||
|
||||
3. **If installed but not in PATH:**
|
||||
```powershell
|
||||
# Add to PATH temporarily
|
||||
$env:PATH += ";C:\Program Files\nodejs"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Issue 4: Build Fails with TypeScript Errors
|
||||
|
||||
**Symptom:** `npm run build` shows TypeScript compilation errors
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Clean and reinstall dependencies:**
|
||||
```powershell
|
||||
Remove-Item node_modules -Recurse -Force
|
||||
Remove-Item package-lock.json -Force
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
2. **Check Node.js version:**
|
||||
```powershell
|
||||
node --version # Should be v18.0.0 or higher
|
||||
```
|
||||
|
||||
3. **If still failing:**
|
||||
```powershell
|
||||
# Try with legacy peer deps
|
||||
npm install --legacy-peer-deps
|
||||
npm run build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Issue 5: Python Dependencies Missing
|
||||
|
||||
**Symptom:** Log shows errors about missing Python packages (Pillow, cairosvg, etc.)
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Install with KiCAD's Python:**
|
||||
```powershell
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
2. **If pip is not available:**
|
||||
```powershell
|
||||
# Download get-pip.py
|
||||
Invoke-WebRequest -Uri https://bootstrap.pypa.io/get-pip.py -OutFile get-pip.py
|
||||
|
||||
# Install pip
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" get-pip.py
|
||||
|
||||
# Then install requirements
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Issue 6: Permission Denied Errors
|
||||
|
||||
**Symptom:** Cannot write to Program Files or access certain directories
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Run PowerShell as Administrator:**
|
||||
- Right-click PowerShell icon
|
||||
- Select "Run as Administrator"
|
||||
- Navigate to KiCAD-MCP-Server directory
|
||||
- Run setup again
|
||||
|
||||
2. **Or clone to user directory:**
|
||||
```powershell
|
||||
cd $HOME\Documents
|
||||
git clone https://github.com/mixelpixx/KiCAD-MCP-Server.git
|
||||
cd KiCAD-MCP-Server
|
||||
.\setup-windows.ps1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Issue 7: Path Issues in Configuration
|
||||
|
||||
**Symptom:** Config file paths not working
|
||||
|
||||
**Common mistakes:**
|
||||
```json
|
||||
// ❌ Wrong - single backslashes
|
||||
"args": ["C:\Users\Name\KiCAD-MCP-Server\dist\index.js"]
|
||||
|
||||
// ❌ Wrong - mixed slashes
|
||||
"args": ["C:\Users/Name\KiCAD-MCP-Server/dist\index.js"]
|
||||
|
||||
// ✅ Correct - double backslashes
|
||||
"args": ["C:\\Users\\Name\\KiCAD-MCP-Server\\dist\\index.js"]
|
||||
|
||||
// ✅ Also correct - forward slashes
|
||||
"args": ["C:/Users/Name/KiCAD-MCP-Server/dist/index.js"]
|
||||
```
|
||||
|
||||
**Solution:** Use either double backslashes `\\` or forward slashes `/` consistently.
|
||||
|
||||
---
|
||||
|
||||
### Issue 8: Wrong Python Version
|
||||
|
||||
**Symptom:** Errors about Python 2.7 or Python 3.6
|
||||
|
||||
**Solution:**
|
||||
|
||||
KiCAD MCP requires Python 3.10+. KiCAD 9.0 includes Python 3.11, which is perfect.
|
||||
|
||||
**Always use KiCAD's bundled Python:**
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"command": "C:\\Program Files\\KiCad\\9.0\\bin\\python.exe",
|
||||
"args": ["C:\\Users\\YourName\\KiCAD-MCP-Server\\python\\kicad_interface.py"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This bypasses Node.js and runs Python directly.
|
||||
|
||||
---
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
### For Claude Desktop
|
||||
|
||||
Config location: `%APPDATA%\Claude\claude_desktop_config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"command": "node",
|
||||
"args": ["C:\\Users\\YourName\\KiCAD-MCP-Server\\dist\\index.js"],
|
||||
"env": {
|
||||
"PYTHONPATH": "C:\\Program Files\\KiCad\\9.0\\lib\\python3\\dist-packages",
|
||||
"NODE_ENV": "production",
|
||||
"LOG_LEVEL": "info"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### For Cline (VSCode)
|
||||
|
||||
Config location: `%APPDATA%\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"command": "node",
|
||||
"args": ["C:\\Users\\YourName\\KiCAD-MCP-Server\\dist\\index.js"],
|
||||
"env": {
|
||||
"PYTHONPATH": "C:\\Program Files\\KiCad\\9.0\\lib\\python3\\dist-packages"
|
||||
},
|
||||
"description": "KiCAD PCB Design Assistant"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Alternative: Python Direct Mode
|
||||
|
||||
If Node.js issues persist, run Python directly:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"command": "C:\\Program Files\\KiCad\\9.0\\bin\\python.exe",
|
||||
"args": ["C:\\Users\\YourName\\KiCAD-MCP-Server\\python\\kicad_interface.py"],
|
||||
"env": {
|
||||
"PYTHONPATH": "C:\\Program Files\\KiCad\\9.0\\lib\\python3\\dist-packages"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Manual Testing Steps
|
||||
|
||||
### Test 1: Verify KiCAD Python
|
||||
|
||||
```powershell
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" -c @"
|
||||
import sys
|
||||
print(f'Python version: {sys.version}')
|
||||
import pcbnew
|
||||
print(f'pcbnew version: {pcbnew.GetBuildVersion()}')
|
||||
print('SUCCESS!')
|
||||
"@
|
||||
```
|
||||
|
||||
Expected output:
|
||||
```
|
||||
Python version: 3.11.x ...
|
||||
pcbnew version: 9.0.0
|
||||
SUCCESS!
|
||||
```
|
||||
|
||||
### Test 2: Verify Node.js
|
||||
|
||||
```powershell
|
||||
node --version # Should be v18.0.0+
|
||||
npm --version # Should be 9.0.0+
|
||||
```
|
||||
|
||||
### Test 3: Build Project
|
||||
|
||||
```powershell
|
||||
cd C:\Users\YourName\KiCAD-MCP-Server
|
||||
npm install
|
||||
npm run build
|
||||
Test-Path .\dist\index.js # Should output: True
|
||||
```
|
||||
|
||||
### Test 4: Run Server Manually
|
||||
|
||||
```powershell
|
||||
$env:PYTHONPATH = "C:\Program Files\KiCad\9.0\lib\python3\dist-packages"
|
||||
node .\dist\index.js
|
||||
```
|
||||
|
||||
Expected: Server should start and wait for input (doesn't exit immediately)
|
||||
|
||||
**To stop:** Press Ctrl+C
|
||||
|
||||
### Test 5: Check Log File
|
||||
|
||||
```powershell
|
||||
# View log file
|
||||
Get-Content "$env:USERPROFILE\.kicad-mcp\logs\kicad_interface.log" -Tail 50
|
||||
```
|
||||
|
||||
Should show successful initialization with no errors.
|
||||
|
||||
---
|
||||
|
||||
## Advanced Diagnostics
|
||||
|
||||
### Enable Verbose Logging
|
||||
|
||||
Add to your MCP config:
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"LOG_LEVEL": "debug",
|
||||
"PYTHONUNBUFFERED": "1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Check Python sys.path
|
||||
|
||||
```powershell
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" -c @"
|
||||
import sys
|
||||
for path in sys.path:
|
||||
print(path)
|
||||
"@
|
||||
```
|
||||
|
||||
Should include: `C:\Program Files\KiCad\9.0\lib\python3\dist-packages`
|
||||
|
||||
### Test MCP Communication
|
||||
|
||||
```powershell
|
||||
# Start server
|
||||
$env:PYTHONPATH = "C:\Program Files\KiCad\9.0\lib\python3\dist-packages"
|
||||
$process = Start-Process -FilePath "node" -ArgumentList ".\dist\index.js" -NoNewWindow -PassThru
|
||||
|
||||
# Wait 3 seconds
|
||||
Start-Sleep -Seconds 3
|
||||
|
||||
# Check if still running
|
||||
if ($process.HasExited) {
|
||||
Write-Host "Server crashed!" -ForegroundColor Red
|
||||
Write-Host "Exit code: $($process.ExitCode)"
|
||||
} else {
|
||||
Write-Host "Server is running!" -ForegroundColor Green
|
||||
Stop-Process -Id $process.Id
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
If none of the above solutions work:
|
||||
|
||||
1. **Run the diagnostic script:**
|
||||
```powershell
|
||||
.\setup-windows.ps1
|
||||
```
|
||||
Copy the entire output.
|
||||
|
||||
2. **Collect log files:**
|
||||
- MCP log: `%USERPROFILE%\.kicad-mcp\logs\kicad_interface.log`
|
||||
- Claude Desktop log: `%APPDATA%\Claude\logs\mcp*.log`
|
||||
|
||||
3. **Open a GitHub issue:**
|
||||
- Go to: https://github.com/mixelpixx/KiCAD-MCP-Server/issues
|
||||
- Title: "Windows Setup Issue: [brief description]"
|
||||
- Include:
|
||||
- Windows version (10 or 11)
|
||||
- Output from setup script
|
||||
- Log file contents
|
||||
- Output from manual tests above
|
||||
|
||||
---
|
||||
|
||||
## Known Limitations on Windows
|
||||
|
||||
1. **File paths are case-insensitive** but should match actual casing for best results
|
||||
|
||||
2. **Long path support** may be needed for deeply nested projects:
|
||||
```powershell
|
||||
# Enable long paths (requires admin)
|
||||
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
|
||||
```
|
||||
|
||||
3. **Windows Defender** may slow down file operations. Add exclusion:
|
||||
```
|
||||
Settings → Windows Security → Virus & threat protection → Exclusions
|
||||
Add: C:\Users\YourName\KiCAD-MCP-Server
|
||||
```
|
||||
|
||||
4. **Antivirus software** may block Python/Node processes. Temporarily disable for testing.
|
||||
|
||||
---
|
||||
|
||||
## Success Checklist
|
||||
|
||||
When everything works, you should have:
|
||||
|
||||
- [ ] KiCAD 9.0+ installed at `C:\Program Files\KiCad\9.0`
|
||||
- [ ] Node.js 18+ installed and in PATH
|
||||
- [ ] Python can import pcbnew successfully
|
||||
- [ ] `npm run build` completes without errors
|
||||
- [ ] `dist\index.js` file exists
|
||||
- [ ] MCP config file created with correct paths
|
||||
- [ ] Server starts without immediate crash
|
||||
- [ ] Log file shows successful initialization
|
||||
- [ ] Claude Desktop/Cline recognizes the MCP server
|
||||
- [ ] Can execute: "Create a new KiCAD project"
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-11-05
|
||||
**Maintained by:** KiCAD MCP Team
|
||||
|
||||
For the latest updates, see: https://github.com/mixelpixx/KiCAD-MCP-Server
|
||||
# Windows Troubleshooting Guide
|
||||
|
||||
This guide helps diagnose and fix common issues when setting up KiCAD MCP Server on Windows.
|
||||
|
||||
## Quick Start: Automated Setup
|
||||
|
||||
**Before manually troubleshooting, try the automated setup script:**
|
||||
|
||||
```powershell
|
||||
# Open PowerShell in the KiCAD-MCP-Server directory
|
||||
.\setup-windows.ps1
|
||||
```
|
||||
|
||||
This script will:
|
||||
|
||||
- Detect your KiCAD installation
|
||||
- Verify all prerequisites
|
||||
- Install dependencies
|
||||
- Build the project
|
||||
- Generate configuration
|
||||
- Run diagnostic tests
|
||||
|
||||
If the automated setup fails, continue with the manual troubleshooting below.
|
||||
|
||||
---
|
||||
|
||||
## Common Issues and Solutions
|
||||
|
||||
### Issue 1: Server Exits Immediately (Most Common)
|
||||
|
||||
**Symptom:** Claude Desktop logs show "Server transport closed unexpectedly"
|
||||
|
||||
**Cause:** Python process crashes during startup, usually due to missing pcbnew module
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Check the log file** (this has the actual error):
|
||||
|
||||
```
|
||||
%USERPROFILE%\.kicad-mcp\logs\kicad_interface.log
|
||||
```
|
||||
|
||||
Open in Notepad and look at the last 50-100 lines.
|
||||
|
||||
2. **Test pcbnew import manually:**
|
||||
|
||||
```powershell
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" -c "import pcbnew; print(pcbnew.GetBuildVersion())"
|
||||
```
|
||||
|
||||
**Expected:** Prints KiCAD version like `9.0.0`
|
||||
|
||||
**If it fails:**
|
||||
- KiCAD's Python module isn't installed
|
||||
- Reinstall KiCAD with default options
|
||||
- Make sure "Install Python" is checked during installation
|
||||
|
||||
3. **Verify PYTHONPATH in your config:**
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"env": {
|
||||
"PYTHONPATH": "C:\\Program Files\\KiCad\\9.0\\lib\\python3\\dist-packages"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Issue 2: KiCAD Not Found
|
||||
|
||||
**Symptom:** Log shows "No KiCAD installations found"
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Check if KiCAD is installed:**
|
||||
|
||||
```powershell
|
||||
Test-Path "C:\Program Files\KiCad\9.0"
|
||||
```
|
||||
|
||||
2. **If KiCAD is installed elsewhere:**
|
||||
- Find your KiCAD installation directory
|
||||
- Update PYTHONPATH in config to match your installation
|
||||
- Example for version 8.0:
|
||||
```
|
||||
"PYTHONPATH": "C:\\Program Files\\KiCad\\8.0\\lib\\python3\\dist-packages"
|
||||
```
|
||||
|
||||
3. **If KiCAD is not installed:**
|
||||
- Download from https://www.kicad.org/download/windows/
|
||||
- Install version 9.0 or higher
|
||||
- Use default installation path
|
||||
|
||||
---
|
||||
|
||||
### Issue 3: Node.js Not Found
|
||||
|
||||
**Symptom:** Cannot run `npm install` or `npm run build`
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Check if Node.js is installed:**
|
||||
|
||||
```powershell
|
||||
node --version
|
||||
npm --version
|
||||
```
|
||||
|
||||
2. **If not installed:**
|
||||
- Download Node.js 18+ from https://nodejs.org/
|
||||
- Install with default options
|
||||
- Restart PowerShell after installation
|
||||
|
||||
3. **If installed but not in PATH:**
|
||||
```powershell
|
||||
# Add to PATH temporarily
|
||||
$env:PATH += ";C:\Program Files\nodejs"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Issue 4: Build Fails with TypeScript Errors
|
||||
|
||||
**Symptom:** `npm run build` shows TypeScript compilation errors
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Clean and reinstall dependencies:**
|
||||
|
||||
```powershell
|
||||
Remove-Item node_modules -Recurse -Force
|
||||
Remove-Item package-lock.json -Force
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
2. **Check Node.js version:**
|
||||
|
||||
```powershell
|
||||
node --version # Should be v18.0.0 or higher
|
||||
```
|
||||
|
||||
3. **If still failing:**
|
||||
```powershell
|
||||
# Try with legacy peer deps
|
||||
npm install --legacy-peer-deps
|
||||
npm run build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Issue 5: Python Dependencies Missing
|
||||
|
||||
**Symptom:** Log shows errors about missing Python packages (Pillow, cairosvg, etc.)
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Install with KiCAD's Python:**
|
||||
|
||||
```powershell
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
2. **If pip is not available:**
|
||||
|
||||
```powershell
|
||||
# Download get-pip.py
|
||||
Invoke-WebRequest -Uri https://bootstrap.pypa.io/get-pip.py -OutFile get-pip.py
|
||||
|
||||
# Install pip
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" get-pip.py
|
||||
|
||||
# Then install requirements
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Issue 6: Permission Denied Errors
|
||||
|
||||
**Symptom:** Cannot write to Program Files or access certain directories
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. **Run PowerShell as Administrator:**
|
||||
- Right-click PowerShell icon
|
||||
- Select "Run as Administrator"
|
||||
- Navigate to KiCAD-MCP-Server directory
|
||||
- Run setup again
|
||||
|
||||
2. **Or clone to user directory:**
|
||||
```powershell
|
||||
cd $HOME\Documents
|
||||
git clone https://github.com/mixelpixx/KiCAD-MCP-Server.git
|
||||
cd KiCAD-MCP-Server
|
||||
.\setup-windows.ps1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Issue 7: Path Issues in Configuration
|
||||
|
||||
**Symptom:** Config file paths not working
|
||||
|
||||
**Common mistakes:**
|
||||
|
||||
```json
|
||||
// ❌ Wrong - single backslashes
|
||||
"args": ["C:\Users\Name\KiCAD-MCP-Server\dist\index.js"]
|
||||
|
||||
// ❌ Wrong - mixed slashes
|
||||
"args": ["C:\Users/Name\KiCAD-MCP-Server/dist\index.js"]
|
||||
|
||||
// ✅ Correct - double backslashes
|
||||
"args": ["C:\\Users\\Name\\KiCAD-MCP-Server\\dist\\index.js"]
|
||||
|
||||
// ✅ Also correct - forward slashes
|
||||
"args": ["C:/Users/Name/KiCAD-MCP-Server/dist/index.js"]
|
||||
```
|
||||
|
||||
**Solution:** Use either double backslashes `\\` or forward slashes `/` consistently.
|
||||
|
||||
---
|
||||
|
||||
### Issue 8: Wrong Python Version
|
||||
|
||||
**Symptom:** Errors about Python 2.7 or Python 3.6
|
||||
|
||||
**Solution:**
|
||||
|
||||
KiCAD MCP requires Python 3.10+. KiCAD 9.0 includes Python 3.11, which is perfect.
|
||||
|
||||
**Always use KiCAD's bundled Python:**
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"command": "C:\\Program Files\\KiCad\\9.0\\bin\\python.exe",
|
||||
"args": ["C:\\Users\\YourName\\KiCAD-MCP-Server\\python\\kicad_interface.py"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This bypasses Node.js and runs Python directly.
|
||||
|
||||
---
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
### For Claude Desktop
|
||||
|
||||
Config location: `%APPDATA%\Claude\claude_desktop_config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"command": "node",
|
||||
"args": ["C:\\Users\\YourName\\KiCAD-MCP-Server\\dist\\index.js"],
|
||||
"env": {
|
||||
"PYTHONPATH": "C:\\Program Files\\KiCad\\9.0\\lib\\python3\\dist-packages",
|
||||
"NODE_ENV": "production",
|
||||
"LOG_LEVEL": "info"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### For Cline (VSCode)
|
||||
|
||||
Config location: `%APPDATA%\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"command": "node",
|
||||
"args": ["C:\\Users\\YourName\\KiCAD-MCP-Server\\dist\\index.js"],
|
||||
"env": {
|
||||
"PYTHONPATH": "C:\\Program Files\\KiCad\\9.0\\lib\\python3\\dist-packages"
|
||||
},
|
||||
"description": "KiCAD PCB Design Assistant"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Alternative: Python Direct Mode
|
||||
|
||||
If Node.js issues persist, run Python directly:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"kicad": {
|
||||
"command": "C:\\Program Files\\KiCad\\9.0\\bin\\python.exe",
|
||||
"args": ["C:\\Users\\YourName\\KiCAD-MCP-Server\\python\\kicad_interface.py"],
|
||||
"env": {
|
||||
"PYTHONPATH": "C:\\Program Files\\KiCad\\9.0\\lib\\python3\\dist-packages"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Manual Testing Steps
|
||||
|
||||
### Test 1: Verify KiCAD Python
|
||||
|
||||
```powershell
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" -c @"
|
||||
import sys
|
||||
print(f'Python version: {sys.version}')
|
||||
import pcbnew
|
||||
print(f'pcbnew version: {pcbnew.GetBuildVersion()}')
|
||||
print('SUCCESS!')
|
||||
"@
|
||||
```
|
||||
|
||||
Expected output:
|
||||
|
||||
```
|
||||
Python version: 3.11.x ...
|
||||
pcbnew version: 9.0.0
|
||||
SUCCESS!
|
||||
```
|
||||
|
||||
### Test 2: Verify Node.js
|
||||
|
||||
```powershell
|
||||
node --version # Should be v18.0.0+
|
||||
npm --version # Should be 9.0.0+
|
||||
```
|
||||
|
||||
### Test 3: Build Project
|
||||
|
||||
```powershell
|
||||
cd C:\Users\YourName\KiCAD-MCP-Server
|
||||
npm install
|
||||
npm run build
|
||||
Test-Path .\dist\index.js # Should output: True
|
||||
```
|
||||
|
||||
### Test 4: Run Server Manually
|
||||
|
||||
```powershell
|
||||
$env:PYTHONPATH = "C:\Program Files\KiCad\9.0\lib\python3\dist-packages"
|
||||
node .\dist\index.js
|
||||
```
|
||||
|
||||
Expected: Server should start and wait for input (doesn't exit immediately)
|
||||
|
||||
**To stop:** Press Ctrl+C
|
||||
|
||||
### Test 5: Check Log File
|
||||
|
||||
```powershell
|
||||
# View log file
|
||||
Get-Content "$env:USERPROFILE\.kicad-mcp\logs\kicad_interface.log" -Tail 50
|
||||
```
|
||||
|
||||
Should show successful initialization with no errors.
|
||||
|
||||
---
|
||||
|
||||
## Advanced Diagnostics
|
||||
|
||||
### Enable Verbose Logging
|
||||
|
||||
Add to your MCP config:
|
||||
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"LOG_LEVEL": "debug",
|
||||
"PYTHONUNBUFFERED": "1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Check Python sys.path
|
||||
|
||||
```powershell
|
||||
& "C:\Program Files\KiCad\9.0\bin\python.exe" -c @"
|
||||
import sys
|
||||
for path in sys.path:
|
||||
print(path)
|
||||
"@
|
||||
```
|
||||
|
||||
Should include: `C:\Program Files\KiCad\9.0\lib\python3\dist-packages`
|
||||
|
||||
### Test MCP Communication
|
||||
|
||||
```powershell
|
||||
# Start server
|
||||
$env:PYTHONPATH = "C:\Program Files\KiCad\9.0\lib\python3\dist-packages"
|
||||
$process = Start-Process -FilePath "node" -ArgumentList ".\dist\index.js" -NoNewWindow -PassThru
|
||||
|
||||
# Wait 3 seconds
|
||||
Start-Sleep -Seconds 3
|
||||
|
||||
# Check if still running
|
||||
if ($process.HasExited) {
|
||||
Write-Host "Server crashed!" -ForegroundColor Red
|
||||
Write-Host "Exit code: $($process.ExitCode)"
|
||||
} else {
|
||||
Write-Host "Server is running!" -ForegroundColor Green
|
||||
Stop-Process -Id $process.Id
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
If none of the above solutions work:
|
||||
|
||||
1. **Run the diagnostic script:**
|
||||
|
||||
```powershell
|
||||
.\setup-windows.ps1
|
||||
```
|
||||
|
||||
Copy the entire output.
|
||||
|
||||
2. **Collect log files:**
|
||||
- MCP log: `%USERPROFILE%\.kicad-mcp\logs\kicad_interface.log`
|
||||
- Claude Desktop log: `%APPDATA%\Claude\logs\mcp*.log`
|
||||
|
||||
3. **Open a GitHub issue:**
|
||||
- Go to: https://github.com/mixelpixx/KiCAD-MCP-Server/issues
|
||||
- Title: "Windows Setup Issue: [brief description]"
|
||||
- Include:
|
||||
- Windows version (10 or 11)
|
||||
- Output from setup script
|
||||
- Log file contents
|
||||
- Output from manual tests above
|
||||
|
||||
---
|
||||
|
||||
## Known Limitations on Windows
|
||||
|
||||
1. **File paths are case-insensitive** but should match actual casing for best results
|
||||
|
||||
2. **Long path support** may be needed for deeply nested projects:
|
||||
|
||||
```powershell
|
||||
# Enable long paths (requires admin)
|
||||
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
|
||||
```
|
||||
|
||||
3. **Windows Defender** may slow down file operations. Add exclusion:
|
||||
|
||||
```
|
||||
Settings → Windows Security → Virus & threat protection → Exclusions
|
||||
Add: C:\Users\YourName\KiCAD-MCP-Server
|
||||
```
|
||||
|
||||
4. **Antivirus software** may block Python/Node processes. Temporarily disable for testing.
|
||||
|
||||
---
|
||||
|
||||
## Success Checklist
|
||||
|
||||
When everything works, you should have:
|
||||
|
||||
- [ ] KiCAD 9.0+ installed at `C:\Program Files\KiCad\9.0`
|
||||
- [ ] Node.js 18+ installed and in PATH
|
||||
- [ ] Python can import pcbnew successfully
|
||||
- [ ] `npm run build` completes without errors
|
||||
- [ ] `dist\index.js` file exists
|
||||
- [ ] MCP config file created with correct paths
|
||||
- [ ] Server starts without immediate crash
|
||||
- [ ] Log file shows successful initialization
|
||||
- [ ] Claude Desktop/Cline recognizes the MCP server
|
||||
- [ ] Can execute: "Create a new KiCAD project"
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-11-05
|
||||
**Maintained by:** KiCAD MCP Team
|
||||
|
||||
For the latest updates, see: https://github.com/mixelpixx/KiCAD-MCP-Server
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,485 +1,509 @@
|
||||
# Option 2: Dynamic Library Loading Plan
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Replace the template-based schematic workflow with dynamic symbol loading from KiCad's installed symbol libraries. This would eliminate the 13-component limitation and provide access to ALL KiCad symbols (~10,000+ symbols from standard libraries).
|
||||
|
||||
**Current Status (Option 1):**
|
||||
- ✅ Template-based approach working
|
||||
- ✅ 13 component types supported
|
||||
- ❌ Limited symbol variety
|
||||
- ❌ Requires manual template updates for new types
|
||||
|
||||
**Proposed (Option 2):**
|
||||
- 🎯 Dynamic loading from `.kicad_sym` library files
|
||||
- 🎯 Access to ~10,000+ KiCad symbols
|
||||
- 🎯 No template maintenance required
|
||||
- 🎯 User can specify any library/symbol combination
|
||||
|
||||
---
|
||||
|
||||
## Problem Analysis
|
||||
|
||||
### kicad-skip Library Limitation
|
||||
|
||||
**Core Issue:** kicad-skip **cannot create symbols from scratch**. It can only:
|
||||
1. Clone existing symbols from a loaded schematic
|
||||
2. Modify properties of cloned symbols
|
||||
|
||||
**Current Workaround:** Pre-load template symbols in schematic file
|
||||
|
||||
**Proposed Solution:** Load symbols from KiCad's `.kicad_sym` library files, inject them into the schematic's `lib_symbols` section, then clone from there.
|
||||
|
||||
---
|
||||
|
||||
## KiCad Symbol Library Architecture
|
||||
|
||||
### Symbol Library File Format (`.kicad_sym`)
|
||||
|
||||
KiCad symbol libraries are S-expression files containing symbol definitions:
|
||||
|
||||
```lisp
|
||||
(kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor)
|
||||
(symbol "Device:R"
|
||||
(pin_numbers hide)
|
||||
(pin_names (offset 0))
|
||||
(in_bom yes)
|
||||
(on_board yes)
|
||||
(property "Reference" "R" ...)
|
||||
(property "Value" "R" ...)
|
||||
;; Graphics definitions
|
||||
(symbol "R_0_1" ...)
|
||||
(symbol "R_1_1"
|
||||
(pin passive line ...)
|
||||
)
|
||||
)
|
||||
(symbol "Device:C" ...)
|
||||
(symbol "Device:L" ...)
|
||||
;; ... thousands more
|
||||
)
|
||||
```
|
||||
|
||||
### Standard KiCad Library Locations
|
||||
|
||||
**Linux:**
|
||||
- System libraries: `/usr/share/kicad/symbols/`
|
||||
- User libraries: `~/.local/share/kicad/8.0/symbols/` or `~/.config/kicad/8.0/symbols/`
|
||||
|
||||
**Windows:**
|
||||
- System libraries: `C:\Program Files\KiCad\9.0\share\kicad\symbols\`
|
||||
- User libraries: `%APPDATA%\kicad\8.0\symbols\`
|
||||
|
||||
**macOS:**
|
||||
- System libraries: `/Applications/KiCad/KiCad.app/Contents/SharedSupport/symbols/`
|
||||
- User libraries: `~/Library/Preferences/kicad/8.0/symbols/`
|
||||
|
||||
### Standard Library Files
|
||||
|
||||
Common libraries (each containing 50-500 symbols):
|
||||
- `Device.kicad_sym` - Passives (R, C, L, D, LED, Crystal, etc.)
|
||||
- `Connector.kicad_sym` - Connectors (headers, USB, etc.)
|
||||
- `Connector_Generic.kicad_sym` - Generic connectors
|
||||
- `Transistor_BJT.kicad_sym` - Bipolar transistors
|
||||
- `Transistor_FET.kicad_sym` - MOSFETs
|
||||
- `Amplifier_Operational.kicad_sym` - Op-amps
|
||||
- `Regulator_Linear.kicad_sym` - Voltage regulators
|
||||
- `MCU_*.kicad_sym` - Microcontrollers
|
||||
- `Interface_*.kicad_sym` - Interface ICs
|
||||
- ... 100+ more libraries
|
||||
|
||||
---
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
### Phase 1: Library Discovery & Indexing
|
||||
|
||||
**Goal:** Build an index of all available symbols and their locations
|
||||
|
||||
**Implementation:**
|
||||
```python
|
||||
class SymbolLibraryManager:
|
||||
def __init__(self):
|
||||
self.library_paths = []
|
||||
self.symbol_index = {} # {"Device:R": "/path/to/Device.kicad_sym", ...}
|
||||
|
||||
def discover_libraries(self):
|
||||
"""Find all KiCad symbol libraries on the system"""
|
||||
search_paths = [
|
||||
"/usr/share/kicad/symbols/",
|
||||
os.path.expanduser("~/.local/share/kicad/8.0/symbols/"),
|
||||
os.path.expanduser("~/.config/kicad/8.0/symbols/"),
|
||||
]
|
||||
|
||||
for search_path in search_paths:
|
||||
if os.path.exists(search_path):
|
||||
for lib_file in os.listdir(search_path):
|
||||
if lib_file.endswith('.kicad_sym'):
|
||||
self.library_paths.append(os.path.join(search_path, lib_file))
|
||||
|
||||
def index_symbols(self):
|
||||
"""Parse all libraries and build symbol index"""
|
||||
for lib_path in self.library_paths:
|
||||
lib_name = os.path.basename(lib_path).replace('.kicad_sym', '')
|
||||
symbols = self._parse_library(lib_path)
|
||||
|
||||
for symbol_name in symbols:
|
||||
full_name = f"{lib_name}:{symbol_name}"
|
||||
self.symbol_index[full_name] = {
|
||||
'library': lib_name,
|
||||
'library_path': lib_path,
|
||||
'symbol_name': symbol_name
|
||||
}
|
||||
|
||||
def _parse_library(self, lib_path):
|
||||
"""Parse .kicad_sym file and extract symbol names"""
|
||||
# Use sexpdata (already a dependency of kicad-skip)
|
||||
import sexpdata
|
||||
|
||||
with open(lib_path, 'r') as f:
|
||||
data = sexpdata.load(f)
|
||||
|
||||
symbols = []
|
||||
for item in data[2:]: # Skip header
|
||||
if isinstance(item, list) and item[0] == Symbol('symbol'):
|
||||
symbol_name = item[1] # e.g., "Device:R"
|
||||
# Extract just the symbol part after ':'
|
||||
if ':' in symbol_name:
|
||||
symbol_name = symbol_name.split(':')[1]
|
||||
symbols.append(symbol_name)
|
||||
|
||||
return symbols
|
||||
```
|
||||
|
||||
### Phase 2: Dynamic Symbol Injection
|
||||
|
||||
**Goal:** Load symbol definition from library file and inject into schematic
|
||||
|
||||
**Challenge:** kicad-skip works with loaded schematics, but we need to dynamically add symbols to the `lib_symbols` section.
|
||||
|
||||
**Solution:** Modify the schematic's S-expression data directly before loading with kicad-skip:
|
||||
|
||||
```python
|
||||
def inject_symbol_into_schematic(schematic_path, library_path, symbol_name):
|
||||
"""
|
||||
1. Read schematic S-expression
|
||||
2. Read library S-expression
|
||||
3. Extract symbol definition from library
|
||||
4. Inject into schematic's lib_symbols section
|
||||
5. Save modified schematic
|
||||
6. Reload with kicad-skip
|
||||
"""
|
||||
import sexpdata
|
||||
|
||||
# Load schematic
|
||||
with open(schematic_path, 'r') as f:
|
||||
sch_data = sexpdata.load(f)
|
||||
|
||||
# Load library
|
||||
with open(library_path, 'r') as f:
|
||||
lib_data = sexpdata.load(f)
|
||||
|
||||
# Find symbol definition in library
|
||||
symbol_def = None
|
||||
for item in lib_data[2:]:
|
||||
if isinstance(item, list) and item[0] == Symbol('symbol'):
|
||||
if symbol_name in str(item[1]):
|
||||
symbol_def = item
|
||||
break
|
||||
|
||||
if not symbol_def:
|
||||
raise ValueError(f"Symbol {symbol_name} not found in {library_path}")
|
||||
|
||||
# Find lib_symbols section in schematic
|
||||
lib_symbols_index = None
|
||||
for i, item in enumerate(sch_data):
|
||||
if isinstance(item, list) and item[0] == Symbol('lib_symbols'):
|
||||
lib_symbols_index = i
|
||||
break
|
||||
|
||||
# Inject symbol definition
|
||||
if lib_symbols_index:
|
||||
sch_data[lib_symbols_index].append(symbol_def)
|
||||
|
||||
# Save modified schematic
|
||||
with open(schematic_path, 'w') as f:
|
||||
sexpdata.dump(sch_data, f)
|
||||
|
||||
# Reload with kicad-skip
|
||||
return Schematic(schematic_path)
|
||||
```
|
||||
|
||||
### Phase 3: Template Instance Creation
|
||||
|
||||
**Goal:** Create offscreen template instances that can be cloned
|
||||
|
||||
**After injection:** Symbol definition is in `lib_symbols`, but we need an instance to clone from:
|
||||
|
||||
```python
|
||||
def create_template_instance(schematic, library_name, symbol_name):
|
||||
"""
|
||||
Create an offscreen template instance that can be cloned
|
||||
Similar to our current _TEMPLATE_R approach
|
||||
"""
|
||||
# This requires directly manipulating the S-expression
|
||||
# Add a symbol instance at offscreen position with special reference
|
||||
|
||||
template_ref = f"_TEMPLATE_{library_name}_{symbol_name}"
|
||||
|
||||
# Create symbol instance (S-expression)
|
||||
symbol_instance = [
|
||||
Symbol('symbol'),
|
||||
[Symbol('lib_id'), f"{library_name}:{symbol_name}"],
|
||||
[Symbol('at'), -100, -100 - (len(schematic.symbol) * 10), 0],
|
||||
[Symbol('unit'), 1],
|
||||
[Symbol('in_bom'), Symbol('no')],
|
||||
[Symbol('on_board'), Symbol('no')],
|
||||
[Symbol('dnp'), Symbol('yes')],
|
||||
[Symbol('uuid'), str(uuid.uuid4())],
|
||||
[Symbol('property'), "Reference", template_ref, ...],
|
||||
# ... more properties
|
||||
]
|
||||
|
||||
# Inject into schematic and reload
|
||||
# ... (similar to inject_symbol_into_schematic)
|
||||
|
||||
return template_ref
|
||||
```
|
||||
|
||||
### Phase 4: User-Facing API
|
||||
|
||||
**Goal:** Simple interface for users to add any KiCad symbol
|
||||
|
||||
**New MCP Tool: `add_schematic_component_dynamic`**
|
||||
|
||||
```python
|
||||
def add_schematic_component_dynamic(params):
|
||||
"""
|
||||
Add component by library:symbol notation
|
||||
|
||||
Example:
|
||||
{
|
||||
"library": "Device",
|
||||
"symbol": "R",
|
||||
"reference": "R1",
|
||||
"value": "10k",
|
||||
"x": 100,
|
||||
"y": 100
|
||||
}
|
||||
|
||||
OR using full notation:
|
||||
{
|
||||
"lib_symbol": "Device:R", # Full notation
|
||||
"reference": "R1",
|
||||
...
|
||||
}
|
||||
"""
|
||||
lib_symbol = params.get('lib_symbol') or f"{params['library']}:{params['symbol']}"
|
||||
|
||||
# 1. Check if symbol is already in schematic's lib_symbols
|
||||
# 2. If not, inject it from library file
|
||||
# 3. Create template instance if needed
|
||||
# 4. Clone template and set properties
|
||||
|
||||
return {"success": True, "reference": params['reference']}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advantages Over Template Approach
|
||||
|
||||
### ✅ Unlimited Symbol Access
|
||||
- Access to ~10,000+ standard KiCad symbols
|
||||
- Support for custom user libraries
|
||||
- Support for 3rd-party libraries (JLCPCB, Espressif, etc.)
|
||||
|
||||
### ✅ No Maintenance Required
|
||||
- Template doesn't need updates for new component types
|
||||
- Automatically supports new KiCad library additions
|
||||
- Works with custom symbol libraries
|
||||
|
||||
### ✅ Better User Experience
|
||||
```
|
||||
User: "Add an STM32F103C8T6 microcontroller at position 100,100"
|
||||
AI: *Searches symbol index*
|
||||
*Finds MCU_ST_STM32F1:STM32F103C8Tx*
|
||||
*Loads from library*
|
||||
*Injects into schematic*
|
||||
*Places component*
|
||||
✓ Done!
|
||||
```
|
||||
|
||||
### ✅ Flexible Symbol Search
|
||||
```python
|
||||
# Find all resistors
|
||||
symbols = lib_manager.search_symbols(query="resistor")
|
||||
# Returns: ["Device:R", "Device:R_Small", "Device:R_Network", ...]
|
||||
|
||||
# Find all STM32 MCUs
|
||||
symbols = lib_manager.search_symbols(query="STM32", library="MCU_ST_STM32F1")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Challenges & Mitigations
|
||||
|
||||
### Challenge 1: S-expression Manipulation Complexity
|
||||
|
||||
**Problem:** Directly manipulating S-expression data is error-prone
|
||||
|
||||
**Mitigation:**
|
||||
- Use `sexpdata` library (already a dependency)
|
||||
- Create helper functions for common operations
|
||||
- Add comprehensive validation and error handling
|
||||
- Extensive testing with various symbol types
|
||||
|
||||
### Challenge 2: Performance
|
||||
|
||||
**Problem:** Loading/reloading schematics after injection could be slow
|
||||
|
||||
**Mitigation:**
|
||||
- **Cache loaded symbols**: Once injected, symbol stays in schematic
|
||||
- **Batch injection**: Inject multiple symbols at once
|
||||
- **Lazy loading**: Only inject symbols when first used
|
||||
|
||||
### Challenge 3: Symbol Compatibility
|
||||
|
||||
**Problem:** Some symbols may have complex pin configurations or multiple units
|
||||
|
||||
**Mitigation:**
|
||||
- Start with simple 2-pin passives (R, C, L)
|
||||
- Gradually add support for multi-pin ICs
|
||||
- Handle multi-unit symbols (gates, OpAmp sections) explicitly
|
||||
- Document supported symbol types
|
||||
|
||||
### Challenge 4: Library Version Compatibility
|
||||
|
||||
**Problem:** KiCad symbol format may change between versions
|
||||
|
||||
**Mitigation:**
|
||||
- Parse KiCad version from library files
|
||||
- Version-specific handling if needed
|
||||
- Fallback to template approach for unsupported formats
|
||||
|
||||
---
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
### Phase A: Proof of Concept (1-2 weeks)
|
||||
- [ ] Create `SymbolLibraryManager` class
|
||||
- [ ] Implement library discovery (Linux paths only)
|
||||
- [ ] Implement symbol indexing
|
||||
- [ ] Test with Device.kicad_sym (R, C, L)
|
||||
- [ ] Implement basic S-expression injection
|
||||
- [ ] Test end-to-end with simple components
|
||||
|
||||
### Phase B: Core Functionality (2-3 weeks)
|
||||
- [ ] Cross-platform library discovery (Windows, macOS)
|
||||
- [ ] Symbol search functionality
|
||||
- [ ] Template instance creation automation
|
||||
- [ ] Multi-pin component support
|
||||
- [ ] Error handling and validation
|
||||
- [ ] Unit tests for all operations
|
||||
|
||||
### Phase C: MCP Integration (1 week)
|
||||
- [ ] Create `add_schematic_component_dynamic` tool
|
||||
- [ ] Update `search_symbols` to use library index
|
||||
- [ ] Add `list_available_symbols` tool
|
||||
- [ ] Add `list_symbol_libraries` tool
|
||||
- [ ] Documentation and examples
|
||||
|
||||
### Phase D: Advanced Features (2-3 weeks)
|
||||
- [ ] Multi-unit symbol support (e.g., quad OpAmps)
|
||||
- [ ] Custom library registration
|
||||
- [ ] Symbol caching and optimization
|
||||
- [ ] 3rd-party library support (JLCPCB, etc.)
|
||||
- [ ] Symbol preview generation
|
||||
|
||||
---
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### Backward Compatibility
|
||||
|
||||
Keep template-based approach as fallback:
|
||||
|
||||
```python
|
||||
def add_schematic_component(params):
|
||||
"""Smart component addition with fallback"""
|
||||
# Try dynamic loading first
|
||||
try:
|
||||
if 'library' in params or 'lib_symbol' in params:
|
||||
return add_schematic_component_dynamic(params)
|
||||
except Exception as e:
|
||||
logger.warning(f"Dynamic loading failed: {e}, falling back to template")
|
||||
|
||||
# Fallback to template-based
|
||||
return add_schematic_component_template(params)
|
||||
```
|
||||
|
||||
### Gradual Rollout
|
||||
|
||||
1. **Week 1-2:** Implement basic dynamic loading
|
||||
2. **Week 3-4:** Test with power users, gather feedback
|
||||
3. **Week 5-6:** Make dynamic loading the default
|
||||
4. **Week 7+:** Deprecate template-only approach (keep as fallback)
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### Must Have
|
||||
- [ ] Load symbols from Device.kicad_sym (passives)
|
||||
- [ ] Support R, C, L, D, LED (5 core types)
|
||||
- [ ] Cross-platform library discovery
|
||||
- [ ] Proper error handling
|
||||
|
||||
### Should Have
|
||||
- [ ] Support for all Device.kicad_sym symbols (~50 symbols)
|
||||
- [ ] Support for Connector.kicad_sym symbols
|
||||
- [ ] Symbol search by name/keyword
|
||||
- [ ] Performance: < 1 second per symbol injection
|
||||
|
||||
### Nice to Have
|
||||
- [ ] Support for all standard libraries (~10,000 symbols)
|
||||
- [ ] Multi-unit symbol support
|
||||
- [ ] Custom library registration
|
||||
- [ ] Symbol preview/documentation
|
||||
|
||||
---
|
||||
|
||||
## Risk Assessment
|
||||
|
||||
| Risk | Probability | Impact | Mitigation |
|
||||
|------|-------------|--------|------------|
|
||||
| S-expression parsing complexity | High | High | Use proven `sexpdata` library, extensive testing |
|
||||
| Performance degradation | Medium | Medium | Implement caching, lazy loading |
|
||||
| KiCad version incompatibility | Low | High | Version detection, format validation |
|
||||
| Template fallback breaks | Low | Medium | Maintain template approach in parallel |
|
||||
| User confusion | Medium | Low | Clear documentation, gradual rollout |
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
Dynamic library loading is **feasible and highly beneficial** for the schematic workflow. While the template-based approach (Option 1) provides immediate value with 13 component types, Option 2 would:
|
||||
|
||||
1. **Eliminate the 13-component limitation**
|
||||
2. **Provide access to 10,000+ KiCad symbols**
|
||||
3. **Remove manual template maintenance**
|
||||
4. **Enable true "natural language PCB design"**
|
||||
|
||||
**Recommendation:**
|
||||
- ✅ **Keep Option 1 (expanded template) for immediate use**
|
||||
- ✅ **Implement Option 2 (dynamic loading) over 6-8 weeks**
|
||||
- ✅ **Maintain template fallback for compatibility**
|
||||
|
||||
This gives users immediate value while we build the robust long-term solution.
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [KiCad File Formats Documentation](https://dev-docs.kicad.org/en/file-formats/)
|
||||
- [kicad-skip GitHub](https://github.com/mvnmgrx/kicad-skip)
|
||||
- [sexpdata Python Library](https://github.com/jd-boyd/sexpdata)
|
||||
- [KiCad Symbol Library Format Spec](https://dev-docs.kicad.org/en/file-formats/sexpr-intro/)
|
||||
# Option 2: Dynamic Library Loading Plan
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Replace the template-based schematic workflow with dynamic symbol loading from KiCad's installed symbol libraries. This would eliminate the 13-component limitation and provide access to ALL KiCad symbols (~10,000+ symbols from standard libraries).
|
||||
|
||||
**Current Status (Option 1):**
|
||||
|
||||
- ✅ Template-based approach working
|
||||
- ✅ 13 component types supported
|
||||
- ❌ Limited symbol variety
|
||||
- ❌ Requires manual template updates for new types
|
||||
|
||||
**Proposed (Option 2):**
|
||||
|
||||
- 🎯 Dynamic loading from `.kicad_sym` library files
|
||||
- 🎯 Access to ~10,000+ KiCad symbols
|
||||
- 🎯 No template maintenance required
|
||||
- 🎯 User can specify any library/symbol combination
|
||||
|
||||
---
|
||||
|
||||
## Problem Analysis
|
||||
|
||||
### kicad-skip Library Limitation
|
||||
|
||||
**Core Issue:** kicad-skip **cannot create symbols from scratch**. It can only:
|
||||
|
||||
1. Clone existing symbols from a loaded schematic
|
||||
2. Modify properties of cloned symbols
|
||||
|
||||
**Current Workaround:** Pre-load template symbols in schematic file
|
||||
|
||||
**Proposed Solution:** Load symbols from KiCad's `.kicad_sym` library files, inject them into the schematic's `lib_symbols` section, then clone from there.
|
||||
|
||||
---
|
||||
|
||||
## KiCad Symbol Library Architecture
|
||||
|
||||
### Symbol Library File Format (`.kicad_sym`)
|
||||
|
||||
KiCad symbol libraries are S-expression files containing symbol definitions:
|
||||
|
||||
```lisp
|
||||
(kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor)
|
||||
(symbol "Device:R"
|
||||
(pin_numbers hide)
|
||||
(pin_names (offset 0))
|
||||
(in_bom yes)
|
||||
(on_board yes)
|
||||
(property "Reference" "R" ...)
|
||||
(property "Value" "R" ...)
|
||||
;; Graphics definitions
|
||||
(symbol "R_0_1" ...)
|
||||
(symbol "R_1_1"
|
||||
(pin passive line ...)
|
||||
)
|
||||
)
|
||||
(symbol "Device:C" ...)
|
||||
(symbol "Device:L" ...)
|
||||
;; ... thousands more
|
||||
)
|
||||
```
|
||||
|
||||
### Standard KiCad Library Locations
|
||||
|
||||
**Linux:**
|
||||
|
||||
- System libraries: `/usr/share/kicad/symbols/`
|
||||
- User libraries: `~/.local/share/kicad/8.0/symbols/` or `~/.config/kicad/8.0/symbols/`
|
||||
|
||||
**Windows:**
|
||||
|
||||
- System libraries: `C:\Program Files\KiCad\9.0\share\kicad\symbols\`
|
||||
- User libraries: `%APPDATA%\kicad\8.0\symbols\`
|
||||
|
||||
**macOS:**
|
||||
|
||||
- System libraries: `/Applications/KiCad/KiCad.app/Contents/SharedSupport/symbols/`
|
||||
- User libraries: `~/Library/Preferences/kicad/8.0/symbols/`
|
||||
|
||||
### Standard Library Files
|
||||
|
||||
Common libraries (each containing 50-500 symbols):
|
||||
|
||||
- `Device.kicad_sym` - Passives (R, C, L, D, LED, Crystal, etc.)
|
||||
- `Connector.kicad_sym` - Connectors (headers, USB, etc.)
|
||||
- `Connector_Generic.kicad_sym` - Generic connectors
|
||||
- `Transistor_BJT.kicad_sym` - Bipolar transistors
|
||||
- `Transistor_FET.kicad_sym` - MOSFETs
|
||||
- `Amplifier_Operational.kicad_sym` - Op-amps
|
||||
- `Regulator_Linear.kicad_sym` - Voltage regulators
|
||||
- `MCU_*.kicad_sym` - Microcontrollers
|
||||
- `Interface_*.kicad_sym` - Interface ICs
|
||||
- ... 100+ more libraries
|
||||
|
||||
---
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
### Phase 1: Library Discovery & Indexing
|
||||
|
||||
**Goal:** Build an index of all available symbols and their locations
|
||||
|
||||
**Implementation:**
|
||||
|
||||
```python
|
||||
class SymbolLibraryManager:
|
||||
def __init__(self):
|
||||
self.library_paths = []
|
||||
self.symbol_index = {} # {"Device:R": "/path/to/Device.kicad_sym", ...}
|
||||
|
||||
def discover_libraries(self):
|
||||
"""Find all KiCad symbol libraries on the system"""
|
||||
search_paths = [
|
||||
"/usr/share/kicad/symbols/",
|
||||
os.path.expanduser("~/.local/share/kicad/8.0/symbols/"),
|
||||
os.path.expanduser("~/.config/kicad/8.0/symbols/"),
|
||||
]
|
||||
|
||||
for search_path in search_paths:
|
||||
if os.path.exists(search_path):
|
||||
for lib_file in os.listdir(search_path):
|
||||
if lib_file.endswith('.kicad_sym'):
|
||||
self.library_paths.append(os.path.join(search_path, lib_file))
|
||||
|
||||
def index_symbols(self):
|
||||
"""Parse all libraries and build symbol index"""
|
||||
for lib_path in self.library_paths:
|
||||
lib_name = os.path.basename(lib_path).replace('.kicad_sym', '')
|
||||
symbols = self._parse_library(lib_path)
|
||||
|
||||
for symbol_name in symbols:
|
||||
full_name = f"{lib_name}:{symbol_name}"
|
||||
self.symbol_index[full_name] = {
|
||||
'library': lib_name,
|
||||
'library_path': lib_path,
|
||||
'symbol_name': symbol_name
|
||||
}
|
||||
|
||||
def _parse_library(self, lib_path):
|
||||
"""Parse .kicad_sym file and extract symbol names"""
|
||||
# Use sexpdata (already a dependency of kicad-skip)
|
||||
import sexpdata
|
||||
|
||||
with open(lib_path, 'r') as f:
|
||||
data = sexpdata.load(f)
|
||||
|
||||
symbols = []
|
||||
for item in data[2:]: # Skip header
|
||||
if isinstance(item, list) and item[0] == Symbol('symbol'):
|
||||
symbol_name = item[1] # e.g., "Device:R"
|
||||
# Extract just the symbol part after ':'
|
||||
if ':' in symbol_name:
|
||||
symbol_name = symbol_name.split(':')[1]
|
||||
symbols.append(symbol_name)
|
||||
|
||||
return symbols
|
||||
```
|
||||
|
||||
### Phase 2: Dynamic Symbol Injection
|
||||
|
||||
**Goal:** Load symbol definition from library file and inject into schematic
|
||||
|
||||
**Challenge:** kicad-skip works with loaded schematics, but we need to dynamically add symbols to the `lib_symbols` section.
|
||||
|
||||
**Solution:** Modify the schematic's S-expression data directly before loading with kicad-skip:
|
||||
|
||||
```python
|
||||
def inject_symbol_into_schematic(schematic_path, library_path, symbol_name):
|
||||
"""
|
||||
1. Read schematic S-expression
|
||||
2. Read library S-expression
|
||||
3. Extract symbol definition from library
|
||||
4. Inject into schematic's lib_symbols section
|
||||
5. Save modified schematic
|
||||
6. Reload with kicad-skip
|
||||
"""
|
||||
import sexpdata
|
||||
|
||||
# Load schematic
|
||||
with open(schematic_path, 'r') as f:
|
||||
sch_data = sexpdata.load(f)
|
||||
|
||||
# Load library
|
||||
with open(library_path, 'r') as f:
|
||||
lib_data = sexpdata.load(f)
|
||||
|
||||
# Find symbol definition in library
|
||||
symbol_def = None
|
||||
for item in lib_data[2:]:
|
||||
if isinstance(item, list) and item[0] == Symbol('symbol'):
|
||||
if symbol_name in str(item[1]):
|
||||
symbol_def = item
|
||||
break
|
||||
|
||||
if not symbol_def:
|
||||
raise ValueError(f"Symbol {symbol_name} not found in {library_path}")
|
||||
|
||||
# Find lib_symbols section in schematic
|
||||
lib_symbols_index = None
|
||||
for i, item in enumerate(sch_data):
|
||||
if isinstance(item, list) and item[0] == Symbol('lib_symbols'):
|
||||
lib_symbols_index = i
|
||||
break
|
||||
|
||||
# Inject symbol definition
|
||||
if lib_symbols_index:
|
||||
sch_data[lib_symbols_index].append(symbol_def)
|
||||
|
||||
# Save modified schematic
|
||||
with open(schematic_path, 'w') as f:
|
||||
sexpdata.dump(sch_data, f)
|
||||
|
||||
# Reload with kicad-skip
|
||||
return Schematic(schematic_path)
|
||||
```
|
||||
|
||||
### Phase 3: Template Instance Creation
|
||||
|
||||
**Goal:** Create offscreen template instances that can be cloned
|
||||
|
||||
**After injection:** Symbol definition is in `lib_symbols`, but we need an instance to clone from:
|
||||
|
||||
```python
|
||||
def create_template_instance(schematic, library_name, symbol_name):
|
||||
"""
|
||||
Create an offscreen template instance that can be cloned
|
||||
Similar to our current _TEMPLATE_R approach
|
||||
"""
|
||||
# This requires directly manipulating the S-expression
|
||||
# Add a symbol instance at offscreen position with special reference
|
||||
|
||||
template_ref = f"_TEMPLATE_{library_name}_{symbol_name}"
|
||||
|
||||
# Create symbol instance (S-expression)
|
||||
symbol_instance = [
|
||||
Symbol('symbol'),
|
||||
[Symbol('lib_id'), f"{library_name}:{symbol_name}"],
|
||||
[Symbol('at'), -100, -100 - (len(schematic.symbol) * 10), 0],
|
||||
[Symbol('unit'), 1],
|
||||
[Symbol('in_bom'), Symbol('no')],
|
||||
[Symbol('on_board'), Symbol('no')],
|
||||
[Symbol('dnp'), Symbol('yes')],
|
||||
[Symbol('uuid'), str(uuid.uuid4())],
|
||||
[Symbol('property'), "Reference", template_ref, ...],
|
||||
# ... more properties
|
||||
]
|
||||
|
||||
# Inject into schematic and reload
|
||||
# ... (similar to inject_symbol_into_schematic)
|
||||
|
||||
return template_ref
|
||||
```
|
||||
|
||||
### Phase 4: User-Facing API
|
||||
|
||||
**Goal:** Simple interface for users to add any KiCad symbol
|
||||
|
||||
**New MCP Tool: `add_schematic_component_dynamic`**
|
||||
|
||||
```python
|
||||
def add_schematic_component_dynamic(params):
|
||||
"""
|
||||
Add component by library:symbol notation
|
||||
|
||||
Example:
|
||||
{
|
||||
"library": "Device",
|
||||
"symbol": "R",
|
||||
"reference": "R1",
|
||||
"value": "10k",
|
||||
"x": 100,
|
||||
"y": 100
|
||||
}
|
||||
|
||||
OR using full notation:
|
||||
{
|
||||
"lib_symbol": "Device:R", # Full notation
|
||||
"reference": "R1",
|
||||
...
|
||||
}
|
||||
"""
|
||||
lib_symbol = params.get('lib_symbol') or f"{params['library']}:{params['symbol']}"
|
||||
|
||||
# 1. Check if symbol is already in schematic's lib_symbols
|
||||
# 2. If not, inject it from library file
|
||||
# 3. Create template instance if needed
|
||||
# 4. Clone template and set properties
|
||||
|
||||
return {"success": True, "reference": params['reference']}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advantages Over Template Approach
|
||||
|
||||
### ✅ Unlimited Symbol Access
|
||||
|
||||
- Access to ~10,000+ standard KiCad symbols
|
||||
- Support for custom user libraries
|
||||
- Support for 3rd-party libraries (JLCPCB, Espressif, etc.)
|
||||
|
||||
### ✅ No Maintenance Required
|
||||
|
||||
- Template doesn't need updates for new component types
|
||||
- Automatically supports new KiCad library additions
|
||||
- Works with custom symbol libraries
|
||||
|
||||
### ✅ Better User Experience
|
||||
|
||||
```
|
||||
User: "Add an STM32F103C8T6 microcontroller at position 100,100"
|
||||
AI: *Searches symbol index*
|
||||
*Finds MCU_ST_STM32F1:STM32F103C8Tx*
|
||||
*Loads from library*
|
||||
*Injects into schematic*
|
||||
*Places component*
|
||||
✓ Done!
|
||||
```
|
||||
|
||||
### ✅ Flexible Symbol Search
|
||||
|
||||
```python
|
||||
# Find all resistors
|
||||
symbols = lib_manager.search_symbols(query="resistor")
|
||||
# Returns: ["Device:R", "Device:R_Small", "Device:R_Network", ...]
|
||||
|
||||
# Find all STM32 MCUs
|
||||
symbols = lib_manager.search_symbols(query="STM32", library="MCU_ST_STM32F1")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Challenges & Mitigations
|
||||
|
||||
### Challenge 1: S-expression Manipulation Complexity
|
||||
|
||||
**Problem:** Directly manipulating S-expression data is error-prone
|
||||
|
||||
**Mitigation:**
|
||||
|
||||
- Use `sexpdata` library (already a dependency)
|
||||
- Create helper functions for common operations
|
||||
- Add comprehensive validation and error handling
|
||||
- Extensive testing with various symbol types
|
||||
|
||||
### Challenge 2: Performance
|
||||
|
||||
**Problem:** Loading/reloading schematics after injection could be slow
|
||||
|
||||
**Mitigation:**
|
||||
|
||||
- **Cache loaded symbols**: Once injected, symbol stays in schematic
|
||||
- **Batch injection**: Inject multiple symbols at once
|
||||
- **Lazy loading**: Only inject symbols when first used
|
||||
|
||||
### Challenge 3: Symbol Compatibility
|
||||
|
||||
**Problem:** Some symbols may have complex pin configurations or multiple units
|
||||
|
||||
**Mitigation:**
|
||||
|
||||
- Start with simple 2-pin passives (R, C, L)
|
||||
- Gradually add support for multi-pin ICs
|
||||
- Handle multi-unit symbols (gates, OpAmp sections) explicitly
|
||||
- Document supported symbol types
|
||||
|
||||
### Challenge 4: Library Version Compatibility
|
||||
|
||||
**Problem:** KiCad symbol format may change between versions
|
||||
|
||||
**Mitigation:**
|
||||
|
||||
- Parse KiCad version from library files
|
||||
- Version-specific handling if needed
|
||||
- Fallback to template approach for unsupported formats
|
||||
|
||||
---
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
### Phase A: Proof of Concept (1-2 weeks)
|
||||
|
||||
- [ ] Create `SymbolLibraryManager` class
|
||||
- [ ] Implement library discovery (Linux paths only)
|
||||
- [ ] Implement symbol indexing
|
||||
- [ ] Test with Device.kicad_sym (R, C, L)
|
||||
- [ ] Implement basic S-expression injection
|
||||
- [ ] Test end-to-end with simple components
|
||||
|
||||
### Phase B: Core Functionality (2-3 weeks)
|
||||
|
||||
- [ ] Cross-platform library discovery (Windows, macOS)
|
||||
- [ ] Symbol search functionality
|
||||
- [ ] Template instance creation automation
|
||||
- [ ] Multi-pin component support
|
||||
- [ ] Error handling and validation
|
||||
- [ ] Unit tests for all operations
|
||||
|
||||
### Phase C: MCP Integration (1 week)
|
||||
|
||||
- [ ] Create `add_schematic_component_dynamic` tool
|
||||
- [ ] Update `search_symbols` to use library index
|
||||
- [ ] Add `list_available_symbols` tool
|
||||
- [ ] Add `list_symbol_libraries` tool
|
||||
- [ ] Documentation and examples
|
||||
|
||||
### Phase D: Advanced Features (2-3 weeks)
|
||||
|
||||
- [ ] Multi-unit symbol support (e.g., quad OpAmps)
|
||||
- [ ] Custom library registration
|
||||
- [ ] Symbol caching and optimization
|
||||
- [ ] 3rd-party library support (JLCPCB, etc.)
|
||||
- [ ] Symbol preview generation
|
||||
|
||||
---
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### Backward Compatibility
|
||||
|
||||
Keep template-based approach as fallback:
|
||||
|
||||
```python
|
||||
def add_schematic_component(params):
|
||||
"""Smart component addition with fallback"""
|
||||
# Try dynamic loading first
|
||||
try:
|
||||
if 'library' in params or 'lib_symbol' in params:
|
||||
return add_schematic_component_dynamic(params)
|
||||
except Exception as e:
|
||||
logger.warning(f"Dynamic loading failed: {e}, falling back to template")
|
||||
|
||||
# Fallback to template-based
|
||||
return add_schematic_component_template(params)
|
||||
```
|
||||
|
||||
### Gradual Rollout
|
||||
|
||||
1. **Week 1-2:** Implement basic dynamic loading
|
||||
2. **Week 3-4:** Test with power users, gather feedback
|
||||
3. **Week 5-6:** Make dynamic loading the default
|
||||
4. **Week 7+:** Deprecate template-only approach (keep as fallback)
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### Must Have
|
||||
|
||||
- [ ] Load symbols from Device.kicad_sym (passives)
|
||||
- [ ] Support R, C, L, D, LED (5 core types)
|
||||
- [ ] Cross-platform library discovery
|
||||
- [ ] Proper error handling
|
||||
|
||||
### Should Have
|
||||
|
||||
- [ ] Support for all Device.kicad_sym symbols (~50 symbols)
|
||||
- [ ] Support for Connector.kicad_sym symbols
|
||||
- [ ] Symbol search by name/keyword
|
||||
- [ ] Performance: < 1 second per symbol injection
|
||||
|
||||
### Nice to Have
|
||||
|
||||
- [ ] Support for all standard libraries (~10,000 symbols)
|
||||
- [ ] Multi-unit symbol support
|
||||
- [ ] Custom library registration
|
||||
- [ ] Symbol preview/documentation
|
||||
|
||||
---
|
||||
|
||||
## Risk Assessment
|
||||
|
||||
| Risk | Probability | Impact | Mitigation |
|
||||
| ------------------------------- | ----------- | ------ | ------------------------------------------------ |
|
||||
| S-expression parsing complexity | High | High | Use proven `sexpdata` library, extensive testing |
|
||||
| Performance degradation | Medium | Medium | Implement caching, lazy loading |
|
||||
| KiCad version incompatibility | Low | High | Version detection, format validation |
|
||||
| Template fallback breaks | Low | Medium | Maintain template approach in parallel |
|
||||
| User confusion | Medium | Low | Clear documentation, gradual rollout |
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
Dynamic library loading is **feasible and highly beneficial** for the schematic workflow. While the template-based approach (Option 1) provides immediate value with 13 component types, Option 2 would:
|
||||
|
||||
1. **Eliminate the 13-component limitation**
|
||||
2. **Provide access to 10,000+ KiCad symbols**
|
||||
3. **Remove manual template maintenance**
|
||||
4. **Enable true "natural language PCB design"**
|
||||
|
||||
**Recommendation:**
|
||||
|
||||
- ✅ **Keep Option 1 (expanded template) for immediate use**
|
||||
- ✅ **Implement Option 2 (dynamic loading) over 6-8 weeks**
|
||||
- ✅ **Maintain template fallback for compatibility**
|
||||
|
||||
This gives users immediate value while we build the robust long-term solution.
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [KiCad File Formats Documentation](https://dev-docs.kicad.org/en/file-formats/)
|
||||
- [kicad-skip GitHub](https://github.com/mvnmgrx/kicad-skip)
|
||||
- [sexpdata Python Library](https://github.com/jd-boyd/sexpdata)
|
||||
- [KiCad Symbol Library Format Spec](https://dev-docs.kicad.org/en/file-formats/sexpr-intro/)
|
||||
|
||||
@@ -1,390 +1,413 @@
|
||||
# Dynamic Symbol Loading - Implementation Status
|
||||
|
||||
**Date:** 2026-01-10
|
||||
**Status:** Phase A-C - ✅ **COMPLETE AND PRODUCTION-READY!**
|
||||
|
||||
## 🚀 BREAKTHROUGH: Full MCP Integration Complete!
|
||||
|
||||
We went from **planning** to **full production integration** in a single session!
|
||||
|
||||
**Phase A** (Proof of Concept): ✅ Complete - Core dynamic loading works
|
||||
**Phase B** (Core Functionality): ✅ ~60% Complete - Cross-platform, caching working
|
||||
**Phase C** (MCP Integration): ✅ **COMPLETE!** - Fully integrated through MCP interface
|
||||
|
||||
The dynamic symbol loading is now **FULLY OPERATIONAL** and accessible through the MCP interface!
|
||||
|
||||
---
|
||||
|
||||
## What's Working (Core Functionality)
|
||||
|
||||
### ✅ Symbol Extraction
|
||||
- Parse `.kicad_sym` library files using S-expression parser
|
||||
- Extract specific symbol definitions by name
|
||||
- Cache parsed libraries for performance
|
||||
- Tested with Device.kicad_sym (533 symbols)
|
||||
|
||||
### ✅ S-Expression Manipulation
|
||||
- Load schematic files as S-expression trees
|
||||
- Inject symbol definitions into `lib_symbols` section
|
||||
- Preserve schematic structure and formatting
|
||||
- Write modified schematics back to disk
|
||||
|
||||
### ✅ Template Instance Creation
|
||||
- Create offscreen template instances at negative Y coordinates
|
||||
- Generate unique UUIDs for each template
|
||||
- Set proper properties (Reference, Value, Footprint, Datasheet)
|
||||
- Templates marked as: `in_bom: no`, `on_board: no`, `dnp: yes`
|
||||
|
||||
### ✅ Component Cloning
|
||||
- kicad-skip successfully clones from dynamic templates
|
||||
- Components inherit symbol structure from injected definitions
|
||||
- Properties can be modified after cloning
|
||||
- Full integration with existing ComponentManager
|
||||
|
||||
### ✅ Cross-Platform Library Discovery
|
||||
- Linux: `/usr/share/kicad/symbols`, `~/.local/share/kicad/*/symbols`
|
||||
- Windows: `C:/Program Files/KiCad/*/share/kicad/symbols`
|
||||
- macOS: `/Applications/KiCad/KiCad.app/Contents/SharedSupport/symbols`
|
||||
- Environment variable support: `KICAD9_SYMBOL_DIR`, etc.
|
||||
|
||||
---
|
||||
|
||||
## Test Results
|
||||
|
||||
### End-to-End Test (Successful)
|
||||
|
||||
**Test:** Load 5 symbols dynamically and create components
|
||||
|
||||
```python
|
||||
Symbols Tested:
|
||||
- Device:R ✓ Injected, template created, cloned successfully
|
||||
- Device:C ✓ Injected, template created, cloned successfully
|
||||
- Device:LED ✓ Injected, template created, cloned successfully
|
||||
- Device:L ✓ Injected, template created, cloned successfully
|
||||
- Device:D ✓ Injected, template created, cloned successfully
|
||||
|
||||
Results:
|
||||
✓ All 5 symbols extracted from Device.kicad_sym
|
||||
✓ All 5 symbol definitions injected into schematic
|
||||
✓ All 5 template instances created
|
||||
✓ kicad-skip loaded modified schematic without errors
|
||||
✓ Components successfully cloned from dynamic templates
|
||||
```
|
||||
|
||||
### Performance Metrics
|
||||
|
||||
- **Library parsing:** ~0.3s for Device.kicad_sym (first time)
|
||||
- **Library parsing:** ~0.001s (cached)
|
||||
- **Symbol extraction:** <0.01s
|
||||
- **Symbol injection:** ~0.05s
|
||||
- **Template creation:** ~0.02s
|
||||
- **Total per symbol:** ~0.08s (first time), ~0.03s (cached)
|
||||
|
||||
**Conclusion:** Fast enough for real-time use!
|
||||
|
||||
---
|
||||
|
||||
## Code Structure
|
||||
|
||||
### New File: `python/commands/dynamic_symbol_loader.py`
|
||||
|
||||
**Class:** `DynamicSymbolLoader`
|
||||
|
||||
**Key Methods:**
|
||||
```python
|
||||
# Library Discovery
|
||||
find_kicad_symbol_libraries() -> List[Path]
|
||||
find_library_file(library_name: str) -> Optional[Path]
|
||||
|
||||
# Parsing & Extraction
|
||||
parse_library_file(library_path: Path) -> List # Returns S-expression
|
||||
extract_symbol_definition(library_path: Path, symbol_name: str) -> Optional[List]
|
||||
|
||||
# Injection & Template Creation
|
||||
inject_symbol_into_schematic(schematic_path: Path, library: str, symbol: str) -> bool
|
||||
create_template_instance(schematic_path: Path, library: str, symbol: str) -> str
|
||||
|
||||
# Complete Workflow
|
||||
load_symbol_dynamically(schematic_path: Path, library: str, symbol: str) -> str
|
||||
```
|
||||
|
||||
**Caching:**
|
||||
- `library_cache`: Parsed library files (path → S-expression data)
|
||||
- `symbol_cache`: Extracted symbols (lib:symbol → symbol definition)
|
||||
|
||||
---
|
||||
|
||||
## What's NOT Yet Done (Integration Layer)
|
||||
|
||||
### ⏳ MCP Tool Integration
|
||||
- Need to create `add_schematic_component_dynamic` MCP tool
|
||||
- Wire dynamic loader through MCP interface (has schematic path)
|
||||
- Update existing `add_schematic_component` to auto-detect and use dynamic loading
|
||||
|
||||
### ⏳ Smart Symbol Discovery
|
||||
- Automatic library detection from component type
|
||||
- Search across all libraries for symbol names
|
||||
- Fuzzy matching for symbol names
|
||||
|
||||
### ⏳ Advanced Features
|
||||
- Multi-unit symbol support (e.g., quad op-amps)
|
||||
- Pin configuration handling
|
||||
- Custom library registration
|
||||
- Symbol preview generation
|
||||
|
||||
---
|
||||
|
||||
## Technical Challenges Solved
|
||||
|
||||
### Challenge 1: S-Expression Parsing
|
||||
**Problem:** KiCad files use Lisp-style S-expressions, complex to parse
|
||||
**Solution:** Used `sexpdata` library (already a dependency of kicad-skip)
|
||||
**Result:** ✅ Robust parsing with proper handling of nested structures
|
||||
|
||||
### Challenge 2: Symbol Structure Complexity
|
||||
**Problem:** Symbols have complex nested structure with multiple sub-symbols
|
||||
**Solution:** Extract entire symbol tree as-is, inject without modification
|
||||
**Result:** ✅ Preserves all symbol details (graphics, pins, properties)
|
||||
|
||||
### Challenge 3: kicad-skip Integration
|
||||
**Problem:** kicad-skip can only clone existing symbols, can't create from scratch
|
||||
**Solution:** Inject symbol into lib_symbols, create template instance, then clone
|
||||
**Result:** ✅ Seamless integration, kicad-skip unaware of dynamic loading
|
||||
|
||||
### Challenge 4: Schematic File Path Access
|
||||
**Problem:** kicad-skip Schematic object doesn't expose file path
|
||||
**Solution:** Pass schematic path explicitly at MCP interface layer
|
||||
**Result:** ⏳ Workaround identified, integration pending
|
||||
|
||||
---
|
||||
|
||||
## Example Usage (Current)
|
||||
|
||||
### Direct Python Usage
|
||||
|
||||
```python
|
||||
from commands.dynamic_symbol_loader import DynamicSymbolLoader
|
||||
from pathlib import Path
|
||||
|
||||
# Initialize loader
|
||||
loader = DynamicSymbolLoader()
|
||||
|
||||
# Load a symbol dynamically
|
||||
schematic_path = Path("/path/to/project.kicad_sch")
|
||||
template_ref = loader.load_symbol_dynamically(
|
||||
schematic_path,
|
||||
library_name="Device",
|
||||
symbol_name="R"
|
||||
)
|
||||
|
||||
# Now use template_ref with kicad-skip to clone components
|
||||
# template_ref will be something like "_TEMPLATE_Device_R"
|
||||
```
|
||||
|
||||
### Future MCP Tool Usage
|
||||
|
||||
```typescript
|
||||
// This is what it WILL look like after integration:
|
||||
|
||||
await mcpServer.callTool("add_schematic_component_dynamic", {
|
||||
library: "MCU_ST_STM32F1",
|
||||
symbol: "STM32F103C8Tx",
|
||||
reference: "U1",
|
||||
x: 100,
|
||||
y: 100,
|
||||
footprint: "Package_QFP:LQFP-48_7x7mm_P0.5mm"
|
||||
});
|
||||
|
||||
// The tool will:
|
||||
// 1. Check if symbol exists in static templates (no)
|
||||
// 2. Dynamically load from MCU_ST_STM32F1.kicad_sym
|
||||
// 3. Inject symbol definition
|
||||
// 4. Create template instance
|
||||
// 5. Clone to create actual component
|
||||
// 6. Set properties (reference, position, footprint)
|
||||
// All of this happens AUTOMATICALLY!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Comparison: Before vs After
|
||||
|
||||
| Feature | Static Templates (Current) | Dynamic Loading (New) |
|
||||
|---------|---------------------------|----------------------|
|
||||
| **Available Symbols** | 13 types | ~10,000+ types |
|
||||
| **Maintenance** | Manual template updates | Zero maintenance |
|
||||
| **Custom Symbols** | Not supported | Fully supported |
|
||||
| **3rd Party Libs** | Not supported | Fully supported |
|
||||
| **Setup Time** | Pre-created templates | On-demand loading |
|
||||
| **Performance** | Instant (pre-loaded) | ~80ms first time, ~30ms cached |
|
||||
| **Flexibility** | Limited to template list | Any .kicad_sym file |
|
||||
|
||||
---
|
||||
|
||||
## Phase Progress
|
||||
|
||||
### ✅ Phase A: Proof of Concept (COMPLETE)
|
||||
- [x] Create `DynamicSymbolLoader` class
|
||||
- [x] Implement library discovery (Linux paths)
|
||||
- [x] Implement symbol indexing
|
||||
- [x] Test with Device.kicad_sym (R, C, L)
|
||||
- [x] Implement basic S-expression injection
|
||||
- [x] Test end-to-end with simple components
|
||||
|
||||
**Time Estimate:** 1-2 weeks
|
||||
**Actual Time:** 4 hours! 🎉
|
||||
|
||||
### ⏳ Phase B: Core Functionality (IN PROGRESS)
|
||||
- [ ] Cross-platform library discovery (Windows, macOS)
|
||||
- [ ] Symbol search functionality
|
||||
- [ ] Template instance creation automation
|
||||
- [ ] Multi-pin component support
|
||||
- [ ] Error handling and validation
|
||||
- [ ] Unit tests for all operations
|
||||
|
||||
**Time Estimate:** 2-3 weeks
|
||||
**Progress:** 25% (cross-platform discovery done)
|
||||
|
||||
### ✅ Phase C: MCP Integration (COMPLETE!)
|
||||
- [x] Integrate dynamic loading into `add_schematic_component` MCP handler
|
||||
- [x] Implement save → inject → reload → clone orchestration
|
||||
- [x] Add schematic_path parameter throughout component chain
|
||||
- [x] Smart detection of when dynamic loading is needed
|
||||
- [x] Proper error handling and fallback to static templates
|
||||
- [x] End-to-end integration testing (100% passing!)
|
||||
|
||||
**Time Estimate:** 1 week
|
||||
**Actual Time:** 2 hours! 🎉
|
||||
**Status:** PRODUCTION READY!
|
||||
|
||||
**What Works Now:**
|
||||
- ✅ Users can add ANY symbol from KiCad libraries via MCP interface
|
||||
- ✅ Automatic detection and dynamic loading
|
||||
- ✅ Seamless fallback to static templates
|
||||
- ✅ Response includes dynamic_loading_used flag and symbol_source info
|
||||
- ✅ Compatible with all existing MCP clients
|
||||
|
||||
### ⏸️ Phase D: Advanced Features (PENDING)
|
||||
- [ ] Multi-unit symbol support (e.g., quad OpAmps)
|
||||
- [ ] Custom library registration
|
||||
- [ ] Symbol caching and optimization
|
||||
- [ ] 3rd-party library support (JLCPCB, etc.)
|
||||
- [ ] Symbol preview generation
|
||||
|
||||
**Time Estimate:** 2-3 weeks
|
||||
|
||||
---
|
||||
|
||||
## Next Immediate Steps
|
||||
|
||||
1. **Wire Through MCP Interface** (2-3 hours)
|
||||
- Update `python/kicad_interface.py` to pass schematic path
|
||||
- Create wrapper function that combines dynamic loading + cloning
|
||||
- Test with MCP client
|
||||
|
||||
2. **Create MCP Tool** (1-2 hours)
|
||||
- Define `add_schematic_component_dynamic` tool schema
|
||||
- Register in tool registry
|
||||
- Add to documentation
|
||||
|
||||
3. **Integration Testing** (1-2 hours)
|
||||
- Test with Claude Desktop/Cline
|
||||
- Test with complex symbols (ICs, connectors)
|
||||
- Verify error handling
|
||||
|
||||
**Total Time to Full Integration:** ~6 hours
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### Phase A Metrics (All Achieved ✅)
|
||||
- [x] Load symbols from Device.kicad_sym (passives)
|
||||
- [x] Support R, C, L, D, LED (5 core types)
|
||||
- [x] Cross-platform library discovery
|
||||
- [x] Proper error handling
|
||||
|
||||
### Phase B Metrics (Target)
|
||||
- [ ] Support for all Device.kicad_sym symbols (~500 symbols)
|
||||
- [ ] Support for Connector.kicad_sym symbols
|
||||
- [ ] Symbol search by name/keyword
|
||||
- [ ] Performance: < 1 second per symbol injection
|
||||
|
||||
### Overall Success Criteria
|
||||
- [ ] Access to all standard libraries (~10,000 symbols)
|
||||
- [ ] Works on Linux, Windows, macOS
|
||||
- [ ] <100ms latency for cached symbols
|
||||
- [ ] Zero template maintenance required
|
||||
- [ ] Backward compatible with static templates
|
||||
|
||||
---
|
||||
|
||||
## Risks & Mitigations
|
||||
|
||||
| Risk | Status | Mitigation |
|
||||
|------|--------|------------|
|
||||
| S-expression complexity | ✅ RESOLVED | Used proven sexpdata library |
|
||||
| Performance degradation | ✅ RESOLVED | Caching works great (<30ms cached) |
|
||||
| KiCad version compatibility | ⚠️ TESTING | Version detection, format validation |
|
||||
| Template fallback breaks | ✅ PREVENTED | Maintained static templates in parallel |
|
||||
| Integration complexity | ⏳ IN PROGRESS | Clean separation of concerns |
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
**We did it!** The core dynamic symbol loading is **fully functional**. This is a game-changer for the KiCAD MCP Server:
|
||||
|
||||
- ✅ No more 13-component limitation
|
||||
- ✅ Access to thousands of symbols
|
||||
- ✅ Zero template maintenance
|
||||
- ✅ Production-ready performance
|
||||
|
||||
**The hardest part is DONE.** What remains is integration work (wiring through MCP interface), which is straightforward plumbing.
|
||||
|
||||
**Estimated time to full production deployment:** 6-8 hours of integration work.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 MCP Integration Test Results (2026-01-10)
|
||||
|
||||
**Test:** Full MCP interface with dynamic symbol loading
|
||||
**Status:** ✅ **100% PASSING**
|
||||
|
||||
### Test Components
|
||||
|
||||
| Component | Type | Library | Dynamic? | Result |
|
||||
|-----------|------|---------|----------|--------|
|
||||
| R1 | Resistor | Device | Yes | ✅ Added successfully |
|
||||
| C1 | Capacitor | Device | Yes | ✅ Added successfully |
|
||||
| BT1 | Battery | Device | **Yes** | ✅ **Dynamic load + clone** |
|
||||
| F1 | Fuse | Device | **Yes** | ✅ **Dynamic load + clone** |
|
||||
| T1 | Transformer_1P_1S | Device | **Yes** | ✅ **Dynamic load + clone** |
|
||||
|
||||
### Results Summary
|
||||
|
||||
- **Static templates:** 2/2 successful (R, C)
|
||||
- **Dynamic loading:** 3/3 successful (Battery, Fuse, Transformer)
|
||||
- **Total success rate:** 5/5 (100%)
|
||||
- **Templates created:** 5 (all persisted correctly)
|
||||
- **Reload orchestration:** Working perfectly
|
||||
- **Error handling:** No failures, all fallbacks untested (no errors!)
|
||||
|
||||
### What This Means
|
||||
|
||||
✅ Users can now add **ANY symbol from ~10,000 KiCad symbols** through the MCP interface!
|
||||
|
||||
✅ The system automatically:
|
||||
1. Detects if symbol needs dynamic loading
|
||||
2. Saves current schematic
|
||||
3. Injects symbol definition from library
|
||||
4. Creates template instance
|
||||
5. Reloads schematic
|
||||
6. Clones template to create component
|
||||
7. Saves final result
|
||||
|
||||
✅ **Zero configuration required** - just specify library and symbol name!
|
||||
|
||||
---
|
||||
|
||||
**Amazing progress! From planning to full production in one session!** 🚀 🎉
|
||||
# Dynamic Symbol Loading - Implementation Status
|
||||
|
||||
**Date:** 2026-01-10
|
||||
**Status:** Phase A-C - ✅ **COMPLETE AND PRODUCTION-READY!**
|
||||
|
||||
## 🚀 BREAKTHROUGH: Full MCP Integration Complete!
|
||||
|
||||
We went from **planning** to **full production integration** in a single session!
|
||||
|
||||
**Phase A** (Proof of Concept): ✅ Complete - Core dynamic loading works
|
||||
**Phase B** (Core Functionality): ✅ ~60% Complete - Cross-platform, caching working
|
||||
**Phase C** (MCP Integration): ✅ **COMPLETE!** - Fully integrated through MCP interface
|
||||
|
||||
The dynamic symbol loading is now **FULLY OPERATIONAL** and accessible through the MCP interface!
|
||||
|
||||
---
|
||||
|
||||
## What's Working (Core Functionality)
|
||||
|
||||
### ✅ Symbol Extraction
|
||||
|
||||
- Parse `.kicad_sym` library files using S-expression parser
|
||||
- Extract specific symbol definitions by name
|
||||
- Cache parsed libraries for performance
|
||||
- Tested with Device.kicad_sym (533 symbols)
|
||||
|
||||
### ✅ S-Expression Manipulation
|
||||
|
||||
- Load schematic files as S-expression trees
|
||||
- Inject symbol definitions into `lib_symbols` section
|
||||
- Preserve schematic structure and formatting
|
||||
- Write modified schematics back to disk
|
||||
|
||||
### ✅ Template Instance Creation
|
||||
|
||||
- Create offscreen template instances at negative Y coordinates
|
||||
- Generate unique UUIDs for each template
|
||||
- Set proper properties (Reference, Value, Footprint, Datasheet)
|
||||
- Templates marked as: `in_bom: no`, `on_board: no`, `dnp: yes`
|
||||
|
||||
### ✅ Component Cloning
|
||||
|
||||
- kicad-skip successfully clones from dynamic templates
|
||||
- Components inherit symbol structure from injected definitions
|
||||
- Properties can be modified after cloning
|
||||
- Full integration with existing ComponentManager
|
||||
|
||||
### ✅ Cross-Platform Library Discovery
|
||||
|
||||
- Linux: `/usr/share/kicad/symbols`, `~/.local/share/kicad/*/symbols`
|
||||
- Windows: `C:/Program Files/KiCad/*/share/kicad/symbols`
|
||||
- macOS: `/Applications/KiCad/KiCad.app/Contents/SharedSupport/symbols`
|
||||
- Environment variable support: `KICAD9_SYMBOL_DIR`, etc.
|
||||
|
||||
---
|
||||
|
||||
## Test Results
|
||||
|
||||
### End-to-End Test (Successful)
|
||||
|
||||
**Test:** Load 5 symbols dynamically and create components
|
||||
|
||||
```python
|
||||
Symbols Tested:
|
||||
- Device:R ✓ Injected, template created, cloned successfully
|
||||
- Device:C ✓ Injected, template created, cloned successfully
|
||||
- Device:LED ✓ Injected, template created, cloned successfully
|
||||
- Device:L ✓ Injected, template created, cloned successfully
|
||||
- Device:D ✓ Injected, template created, cloned successfully
|
||||
|
||||
Results:
|
||||
✓ All 5 symbols extracted from Device.kicad_sym
|
||||
✓ All 5 symbol definitions injected into schematic
|
||||
✓ All 5 template instances created
|
||||
✓ kicad-skip loaded modified schematic without errors
|
||||
✓ Components successfully cloned from dynamic templates
|
||||
```
|
||||
|
||||
### Performance Metrics
|
||||
|
||||
- **Library parsing:** ~0.3s for Device.kicad_sym (first time)
|
||||
- **Library parsing:** ~0.001s (cached)
|
||||
- **Symbol extraction:** <0.01s
|
||||
- **Symbol injection:** ~0.05s
|
||||
- **Template creation:** ~0.02s
|
||||
- **Total per symbol:** ~0.08s (first time), ~0.03s (cached)
|
||||
|
||||
**Conclusion:** Fast enough for real-time use!
|
||||
|
||||
---
|
||||
|
||||
## Code Structure
|
||||
|
||||
### New File: `python/commands/dynamic_symbol_loader.py`
|
||||
|
||||
**Class:** `DynamicSymbolLoader`
|
||||
|
||||
**Key Methods:**
|
||||
|
||||
```python
|
||||
# Library Discovery
|
||||
find_kicad_symbol_libraries() -> List[Path]
|
||||
find_library_file(library_name: str) -> Optional[Path]
|
||||
|
||||
# Parsing & Extraction
|
||||
parse_library_file(library_path: Path) -> List # Returns S-expression
|
||||
extract_symbol_definition(library_path: Path, symbol_name: str) -> Optional[List]
|
||||
|
||||
# Injection & Template Creation
|
||||
inject_symbol_into_schematic(schematic_path: Path, library: str, symbol: str) -> bool
|
||||
create_template_instance(schematic_path: Path, library: str, symbol: str) -> str
|
||||
|
||||
# Complete Workflow
|
||||
load_symbol_dynamically(schematic_path: Path, library: str, symbol: str) -> str
|
||||
```
|
||||
|
||||
**Caching:**
|
||||
|
||||
- `library_cache`: Parsed library files (path → S-expression data)
|
||||
- `symbol_cache`: Extracted symbols (lib:symbol → symbol definition)
|
||||
|
||||
---
|
||||
|
||||
## What's NOT Yet Done (Integration Layer)
|
||||
|
||||
### ⏳ MCP Tool Integration
|
||||
|
||||
- Need to create `add_schematic_component_dynamic` MCP tool
|
||||
- Wire dynamic loader through MCP interface (has schematic path)
|
||||
- Update existing `add_schematic_component` to auto-detect and use dynamic loading
|
||||
|
||||
### ⏳ Smart Symbol Discovery
|
||||
|
||||
- Automatic library detection from component type
|
||||
- Search across all libraries for symbol names
|
||||
- Fuzzy matching for symbol names
|
||||
|
||||
### ⏳ Advanced Features
|
||||
|
||||
- Multi-unit symbol support (e.g., quad op-amps)
|
||||
- Pin configuration handling
|
||||
- Custom library registration
|
||||
- Symbol preview generation
|
||||
|
||||
---
|
||||
|
||||
## Technical Challenges Solved
|
||||
|
||||
### Challenge 1: S-Expression Parsing
|
||||
|
||||
**Problem:** KiCad files use Lisp-style S-expressions, complex to parse
|
||||
**Solution:** Used `sexpdata` library (already a dependency of kicad-skip)
|
||||
**Result:** ✅ Robust parsing with proper handling of nested structures
|
||||
|
||||
### Challenge 2: Symbol Structure Complexity
|
||||
|
||||
**Problem:** Symbols have complex nested structure with multiple sub-symbols
|
||||
**Solution:** Extract entire symbol tree as-is, inject without modification
|
||||
**Result:** ✅ Preserves all symbol details (graphics, pins, properties)
|
||||
|
||||
### Challenge 3: kicad-skip Integration
|
||||
|
||||
**Problem:** kicad-skip can only clone existing symbols, can't create from scratch
|
||||
**Solution:** Inject symbol into lib_symbols, create template instance, then clone
|
||||
**Result:** ✅ Seamless integration, kicad-skip unaware of dynamic loading
|
||||
|
||||
### Challenge 4: Schematic File Path Access
|
||||
|
||||
**Problem:** kicad-skip Schematic object doesn't expose file path
|
||||
**Solution:** Pass schematic path explicitly at MCP interface layer
|
||||
**Result:** ⏳ Workaround identified, integration pending
|
||||
|
||||
---
|
||||
|
||||
## Example Usage (Current)
|
||||
|
||||
### Direct Python Usage
|
||||
|
||||
```python
|
||||
from commands.dynamic_symbol_loader import DynamicSymbolLoader
|
||||
from pathlib import Path
|
||||
|
||||
# Initialize loader
|
||||
loader = DynamicSymbolLoader()
|
||||
|
||||
# Load a symbol dynamically
|
||||
schematic_path = Path("/path/to/project.kicad_sch")
|
||||
template_ref = loader.load_symbol_dynamically(
|
||||
schematic_path,
|
||||
library_name="Device",
|
||||
symbol_name="R"
|
||||
)
|
||||
|
||||
# Now use template_ref with kicad-skip to clone components
|
||||
# template_ref will be something like "_TEMPLATE_Device_R"
|
||||
```
|
||||
|
||||
### Future MCP Tool Usage
|
||||
|
||||
```typescript
|
||||
// This is what it WILL look like after integration:
|
||||
|
||||
await mcpServer.callTool("add_schematic_component_dynamic", {
|
||||
library: "MCU_ST_STM32F1",
|
||||
symbol: "STM32F103C8Tx",
|
||||
reference: "U1",
|
||||
x: 100,
|
||||
y: 100,
|
||||
footprint: "Package_QFP:LQFP-48_7x7mm_P0.5mm",
|
||||
});
|
||||
|
||||
// The tool will:
|
||||
// 1. Check if symbol exists in static templates (no)
|
||||
// 2. Dynamically load from MCU_ST_STM32F1.kicad_sym
|
||||
// 3. Inject symbol definition
|
||||
// 4. Create template instance
|
||||
// 5. Clone to create actual component
|
||||
// 6. Set properties (reference, position, footprint)
|
||||
// All of this happens AUTOMATICALLY!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Comparison: Before vs After
|
||||
|
||||
| Feature | Static Templates (Current) | Dynamic Loading (New) |
|
||||
| --------------------- | -------------------------- | ------------------------------ |
|
||||
| **Available Symbols** | 13 types | ~10,000+ types |
|
||||
| **Maintenance** | Manual template updates | Zero maintenance |
|
||||
| **Custom Symbols** | Not supported | Fully supported |
|
||||
| **3rd Party Libs** | Not supported | Fully supported |
|
||||
| **Setup Time** | Pre-created templates | On-demand loading |
|
||||
| **Performance** | Instant (pre-loaded) | ~80ms first time, ~30ms cached |
|
||||
| **Flexibility** | Limited to template list | Any .kicad_sym file |
|
||||
|
||||
---
|
||||
|
||||
## Phase Progress
|
||||
|
||||
### ✅ Phase A: Proof of Concept (COMPLETE)
|
||||
|
||||
- [x] Create `DynamicSymbolLoader` class
|
||||
- [x] Implement library discovery (Linux paths)
|
||||
- [x] Implement symbol indexing
|
||||
- [x] Test with Device.kicad_sym (R, C, L)
|
||||
- [x] Implement basic S-expression injection
|
||||
- [x] Test end-to-end with simple components
|
||||
|
||||
**Time Estimate:** 1-2 weeks
|
||||
**Actual Time:** 4 hours! 🎉
|
||||
|
||||
### ⏳ Phase B: Core Functionality (IN PROGRESS)
|
||||
|
||||
- [ ] Cross-platform library discovery (Windows, macOS)
|
||||
- [ ] Symbol search functionality
|
||||
- [ ] Template instance creation automation
|
||||
- [ ] Multi-pin component support
|
||||
- [ ] Error handling and validation
|
||||
- [ ] Unit tests for all operations
|
||||
|
||||
**Time Estimate:** 2-3 weeks
|
||||
**Progress:** 25% (cross-platform discovery done)
|
||||
|
||||
### ✅ Phase C: MCP Integration (COMPLETE!)
|
||||
|
||||
- [x] Integrate dynamic loading into `add_schematic_component` MCP handler
|
||||
- [x] Implement save → inject → reload → clone orchestration
|
||||
- [x] Add schematic_path parameter throughout component chain
|
||||
- [x] Smart detection of when dynamic loading is needed
|
||||
- [x] Proper error handling and fallback to static templates
|
||||
- [x] End-to-end integration testing (100% passing!)
|
||||
|
||||
**Time Estimate:** 1 week
|
||||
**Actual Time:** 2 hours! 🎉
|
||||
**Status:** PRODUCTION READY!
|
||||
|
||||
**What Works Now:**
|
||||
|
||||
- ✅ Users can add ANY symbol from KiCad libraries via MCP interface
|
||||
- ✅ Automatic detection and dynamic loading
|
||||
- ✅ Seamless fallback to static templates
|
||||
- ✅ Response includes dynamic_loading_used flag and symbol_source info
|
||||
- ✅ Compatible with all existing MCP clients
|
||||
|
||||
### ⏸️ Phase D: Advanced Features (PENDING)
|
||||
|
||||
- [ ] Multi-unit symbol support (e.g., quad OpAmps)
|
||||
- [ ] Custom library registration
|
||||
- [ ] Symbol caching and optimization
|
||||
- [ ] 3rd-party library support (JLCPCB, etc.)
|
||||
- [ ] Symbol preview generation
|
||||
|
||||
**Time Estimate:** 2-3 weeks
|
||||
|
||||
---
|
||||
|
||||
## Next Immediate Steps
|
||||
|
||||
1. **Wire Through MCP Interface** (2-3 hours)
|
||||
- Update `python/kicad_interface.py` to pass schematic path
|
||||
- Create wrapper function that combines dynamic loading + cloning
|
||||
- Test with MCP client
|
||||
|
||||
2. **Create MCP Tool** (1-2 hours)
|
||||
- Define `add_schematic_component_dynamic` tool schema
|
||||
- Register in tool registry
|
||||
- Add to documentation
|
||||
|
||||
3. **Integration Testing** (1-2 hours)
|
||||
- Test with Claude Desktop/Cline
|
||||
- Test with complex symbols (ICs, connectors)
|
||||
- Verify error handling
|
||||
|
||||
**Total Time to Full Integration:** ~6 hours
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### Phase A Metrics (All Achieved ✅)
|
||||
|
||||
- [x] Load symbols from Device.kicad_sym (passives)
|
||||
- [x] Support R, C, L, D, LED (5 core types)
|
||||
- [x] Cross-platform library discovery
|
||||
- [x] Proper error handling
|
||||
|
||||
### Phase B Metrics (Target)
|
||||
|
||||
- [ ] Support for all Device.kicad_sym symbols (~500 symbols)
|
||||
- [ ] Support for Connector.kicad_sym symbols
|
||||
- [ ] Symbol search by name/keyword
|
||||
- [ ] Performance: < 1 second per symbol injection
|
||||
|
||||
### Overall Success Criteria
|
||||
|
||||
- [ ] Access to all standard libraries (~10,000 symbols)
|
||||
- [ ] Works on Linux, Windows, macOS
|
||||
- [ ] <100ms latency for cached symbols
|
||||
- [ ] Zero template maintenance required
|
||||
- [ ] Backward compatible with static templates
|
||||
|
||||
---
|
||||
|
||||
## Risks & Mitigations
|
||||
|
||||
| Risk | Status | Mitigation |
|
||||
| --------------------------- | -------------- | --------------------------------------- |
|
||||
| S-expression complexity | ✅ RESOLVED | Used proven sexpdata library |
|
||||
| Performance degradation | ✅ RESOLVED | Caching works great (<30ms cached) |
|
||||
| KiCad version compatibility | ⚠️ TESTING | Version detection, format validation |
|
||||
| Template fallback breaks | ✅ PREVENTED | Maintained static templates in parallel |
|
||||
| Integration complexity | ⏳ IN PROGRESS | Clean separation of concerns |
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
**We did it!** The core dynamic symbol loading is **fully functional**. This is a game-changer for the KiCAD MCP Server:
|
||||
|
||||
- ✅ No more 13-component limitation
|
||||
- ✅ Access to thousands of symbols
|
||||
- ✅ Zero template maintenance
|
||||
- ✅ Production-ready performance
|
||||
|
||||
**The hardest part is DONE.** What remains is integration work (wiring through MCP interface), which is straightforward plumbing.
|
||||
|
||||
**Estimated time to full production deployment:** 6-8 hours of integration work.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 MCP Integration Test Results (2026-01-10)
|
||||
|
||||
**Test:** Full MCP interface with dynamic symbol loading
|
||||
**Status:** ✅ **100% PASSING**
|
||||
|
||||
### Test Components
|
||||
|
||||
| Component | Type | Library | Dynamic? | Result |
|
||||
| --------- | ----------------- | ------- | -------- | --------------------------- |
|
||||
| R1 | Resistor | Device | Yes | ✅ Added successfully |
|
||||
| C1 | Capacitor | Device | Yes | ✅ Added successfully |
|
||||
| BT1 | Battery | Device | **Yes** | ✅ **Dynamic load + clone** |
|
||||
| F1 | Fuse | Device | **Yes** | ✅ **Dynamic load + clone** |
|
||||
| T1 | Transformer_1P_1S | Device | **Yes** | ✅ **Dynamic load + clone** |
|
||||
|
||||
### Results Summary
|
||||
|
||||
- **Static templates:** 2/2 successful (R, C)
|
||||
- **Dynamic loading:** 3/3 successful (Battery, Fuse, Transformer)
|
||||
- **Total success rate:** 5/5 (100%)
|
||||
- **Templates created:** 5 (all persisted correctly)
|
||||
- **Reload orchestration:** Working perfectly
|
||||
- **Error handling:** No failures, all fallbacks untested (no errors!)
|
||||
|
||||
### What This Means
|
||||
|
||||
✅ Users can now add **ANY symbol from ~10,000 KiCad symbols** through the MCP interface!
|
||||
|
||||
✅ The system automatically:
|
||||
|
||||
1. Detects if symbol needs dynamic loading
|
||||
2. Saves current schematic
|
||||
3. Injects symbol definition from library
|
||||
4. Creates template instance
|
||||
5. Reloads schematic
|
||||
6. Clones template to create component
|
||||
7. Saves final result
|
||||
|
||||
✅ **Zero configuration required** - just specify library and symbol name!
|
||||
|
||||
---
|
||||
|
||||
**Amazing progress! From planning to full production in one session!** 🚀 🎉
|
||||
|
||||
@@ -1,477 +1,493 @@
|
||||
# KiCAD IPC API Migration Plan
|
||||
|
||||
**Status:** 📋 Planning
|
||||
**Target Completion:** Week 2-3 (November 1-8, 2025)
|
||||
**Priority:** 🔴 **CRITICAL** - Current SWIG API deprecated
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
The current KiCAD MCP Server uses SWIG-based Python bindings (`import pcbnew`) which are **deprecated as of KiCAD 9.0** and will be **removed in KiCAD 10.0**. We must migrate to the official **KiCAD IPC API** to future-proof the project.
|
||||
|
||||
### Why Migrate?
|
||||
|
||||
| SWIG API (Current) | IPC API (Future) |
|
||||
|-------------------|------------------|
|
||||
| ❌ Deprecated | ✅ Official & Supported |
|
||||
| ❌ Will be removed in KiCAD 10.0 | ✅ Long-term stability |
|
||||
| ❌ Python-only | ✅ Multi-language (Python, JS, etc.) |
|
||||
| ❌ Direct linking | ✅ Inter-process communication |
|
||||
| ⚠️ Synchronous only | ✅ Async support |
|
||||
| ⚠️ No versioning | ✅ Protocol Buffers versioning |
|
||||
|
||||
**Decision: Migrate immediately to avoid technical debt**
|
||||
|
||||
---
|
||||
|
||||
## IPC API Overview
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ TypeScript MCP Server (Node.js) │
|
||||
└──────────────────────┬──────────────────────────────────────┘
|
||||
│ JSON over stdin/stdout
|
||||
┌──────────────────────▼──────────────────────────────────────┐
|
||||
│ Python Interface Layer │
|
||||
│ ┌────────────────────────────────────────────────────────┐ │
|
||||
│ │ KiCAD API Abstraction (NEW) │ │
|
||||
│ └────────────────────────────────────────────────────────┘ │
|
||||
└──────────────────────┬──────────────────────────────────────┘
|
||||
│ kicad-python library
|
||||
┌──────────────────────▼──────────────────────────────────────┐
|
||||
│ KiCAD IPC Server (Protocol Buffers) │
|
||||
│ Running inside KiCAD Process │
|
||||
└──────────────────────┬──────────────────────────────────────┘
|
||||
│ UNIX Sockets / Named Pipes
|
||||
┌──────────────────────▼──────────────────────────────────────┐
|
||||
│ KiCAD 9.0+ Application │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Key Differences
|
||||
|
||||
1. **KiCAD Must Be Running**
|
||||
- SWIG: Can run headless, no KiCAD GUI needed
|
||||
- IPC: Requires KiCAD running with IPC server enabled
|
||||
|
||||
2. **Communication Method**
|
||||
- SWIG: Direct Python module import
|
||||
- IPC: Socket-based RPC (Remote Procedure Call)
|
||||
|
||||
3. **API Structure**
|
||||
- SWIG: `board.SetSize(width, height)`
|
||||
- IPC: `kicad.get_board().set_size(width, height)`
|
||||
|
||||
---
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### Phase 1: Research & Preparation (Days 1-2)
|
||||
|
||||
**Goals:**
|
||||
- Understand kicad-python library
|
||||
- Test IPC connection
|
||||
- Document API differences
|
||||
|
||||
**Tasks:**
|
||||
```bash
|
||||
# Install kicad-python
|
||||
pip install kicad-python>=0.5.0
|
||||
|
||||
# Test basic connection
|
||||
python3 << EOF
|
||||
from kicad import KiCad
|
||||
kicad = KiCad()
|
||||
print(f"Connected to KiCAD: {kicad.check_version()}")
|
||||
EOF
|
||||
|
||||
# Read official documentation
|
||||
# https://docs.kicad.org/kicad-python-main
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] kicad-python installed and tested
|
||||
- [ ] Connection test script
|
||||
- [ ] API comparison document (SWIG vs IPC)
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: Abstraction Layer (Days 3-4)
|
||||
|
||||
**Goal:** Create an abstraction layer to support both APIs during transition
|
||||
|
||||
**File Structure:**
|
||||
```
|
||||
python/kicad_api/
|
||||
├── __init__.py
|
||||
├── base.py # Abstract base class
|
||||
├── ipc_backend.py # NEW: IPC API implementation
|
||||
├── swig_backend.py # Legacy SWIG implementation
|
||||
└── factory.py # Backend selector
|
||||
```
|
||||
|
||||
**Abstract Interface:**
|
||||
```python
|
||||
# python/kicad_api/base.py
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Optional
|
||||
from pathlib import Path
|
||||
|
||||
class KiCADBackend(ABC):
|
||||
"""Abstract base class for KiCAD API backends"""
|
||||
|
||||
@abstractmethod
|
||||
def connect(self) -> bool:
|
||||
"""Connect to KiCAD"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def disconnect(self) -> None:
|
||||
"""Disconnect from KiCAD"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def is_connected(self) -> bool:
|
||||
"""Check if connected"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def create_project(self, path: Path, name: str) -> dict:
|
||||
"""Create a new KiCAD project"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def open_project(self, path: Path) -> dict:
|
||||
"""Open existing project"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_board(self) -> 'BoardAPI':
|
||||
"""Get board API"""
|
||||
pass
|
||||
|
||||
# ... more abstract methods
|
||||
```
|
||||
|
||||
**IPC Implementation:**
|
||||
```python
|
||||
# python/kicad_api/ipc_backend.py
|
||||
from kicad import KiCad
|
||||
from kicad_api.base import KiCADBackend
|
||||
|
||||
class IPCBackend(KiCADBackend):
|
||||
"""KiCAD IPC API backend"""
|
||||
|
||||
def __init__(self):
|
||||
self.kicad = None
|
||||
|
||||
def connect(self) -> bool:
|
||||
"""Connect to running KiCAD instance"""
|
||||
try:
|
||||
self.kicad = KiCad()
|
||||
# Verify connection
|
||||
version = self.kicad.check_version()
|
||||
logger.info(f"Connected to KiCAD via IPC: {version}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to connect via IPC: {e}")
|
||||
return False
|
||||
|
||||
def create_project(self, path: Path, name: str) -> dict:
|
||||
"""Create project using IPC API"""
|
||||
# Implementation here
|
||||
pass
|
||||
```
|
||||
|
||||
**Backend Factory:**
|
||||
```python
|
||||
# python/kicad_api/factory.py
|
||||
from typing import Optional
|
||||
from kicad_api.base import KiCADBackend
|
||||
from kicad_api.ipc_backend import IPCBackend
|
||||
from kicad_api.swig_backend import SWIGBackend
|
||||
|
||||
def create_backend(backend_type: Optional[str] = None) -> KiCADBackend:
|
||||
"""
|
||||
Create appropriate KiCAD backend
|
||||
|
||||
Args:
|
||||
backend_type: 'ipc', 'swig', or None for auto-detect
|
||||
|
||||
Returns:
|
||||
KiCADBackend instance
|
||||
"""
|
||||
if backend_type == 'ipc':
|
||||
return IPCBackend()
|
||||
elif backend_type == 'swig':
|
||||
return SWIGBackend()
|
||||
else:
|
||||
# Auto-detect: Try IPC first, fall back to SWIG
|
||||
try:
|
||||
backend = IPCBackend()
|
||||
if backend.connect():
|
||||
return backend
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Fall back to SWIG
|
||||
return SWIGBackend()
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] Abstract base class defined
|
||||
- [ ] IPC backend implemented
|
||||
- [ ] SWIG backend (wrapper around existing code)
|
||||
- [ ] Factory with auto-detection
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: Port Core Modules (Days 5-8)
|
||||
|
||||
**Migration Order** (by complexity):
|
||||
|
||||
1. **project.py** (Simple - good starting point)
|
||||
- Create, open, save projects
|
||||
- Estimated: 2 hours
|
||||
|
||||
2. **board.py** (Medium - board properties)
|
||||
- Set size, layers, outline
|
||||
- Estimated: 4 hours
|
||||
|
||||
3. **component.py** (Complex - many operations)
|
||||
- Place, move, rotate, delete
|
||||
- Component arrays and alignment
|
||||
- Estimated: 8 hours
|
||||
|
||||
4. **routing.py** (Complex - trace routing)
|
||||
- Nets, traces, vias
|
||||
- Copper pours, differential pairs
|
||||
- Estimated: 8 hours
|
||||
|
||||
5. **design_rules.py** (Medium - DRC)
|
||||
- Set rules, run DRC
|
||||
- Estimated: 4 hours
|
||||
|
||||
6. **export.py** (Medium - file exports)
|
||||
- Gerber, PDF, SVG, 3D
|
||||
- Estimated: 4 hours
|
||||
|
||||
**Total Estimated Time: 30 hours (~4 days)**
|
||||
|
||||
**Migration Template:**
|
||||
```python
|
||||
# OLD (SWIG)
|
||||
import pcbnew
|
||||
board = pcbnew.LoadBoard(filename)
|
||||
board.SetBoardSize(width, height)
|
||||
|
||||
# NEW (IPC via abstraction)
|
||||
from kicad_api import create_backend
|
||||
backend = create_backend('ipc')
|
||||
backend.connect()
|
||||
board_api = backend.get_board()
|
||||
board_api.set_size(width, height)
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] project.py migrated
|
||||
- [ ] board.py migrated
|
||||
- [ ] component.py migrated
|
||||
- [ ] routing.py migrated
|
||||
- [ ] design_rules.py migrated
|
||||
- [ ] export.py migrated
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: Testing & Validation (Days 9-10)
|
||||
|
||||
**Testing Strategy:**
|
||||
|
||||
1. **Unit Tests**
|
||||
```python
|
||||
@pytest.mark.parametrize("backend_type", ["ipc", "swig"])
|
||||
def test_create_project(backend_type):
|
||||
backend = create_backend(backend_type)
|
||||
result = backend.create_project(Path("/tmp/test"), "TestProject")
|
||||
assert result["success"] is True
|
||||
```
|
||||
|
||||
2. **Integration Tests**
|
||||
- Run side-by-side: IPC vs SWIG
|
||||
- Compare outputs for identical operations
|
||||
- Verify file compatibility
|
||||
|
||||
3. **Performance Benchmarks**
|
||||
```python
|
||||
# Measure: operations/second for each backend
|
||||
# Expected: IPC slightly slower due to IPC overhead
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] 50+ unit tests passing for IPC backend
|
||||
- [ ] Side-by-side comparison tests
|
||||
- [ ] Performance benchmarks documented
|
||||
|
||||
---
|
||||
|
||||
## API Comparison Reference
|
||||
|
||||
### Project Operations
|
||||
|
||||
| Operation | SWIG | IPC |
|
||||
|-----------|------|-----|
|
||||
| Create project | Custom file creation | `kicad.create_project()` |
|
||||
| Open project | `pcbnew.LoadBoard()` | `kicad.open_project()` |
|
||||
| Save project | `board.Save()` | `board.save()` |
|
||||
|
||||
### Board Operations
|
||||
|
||||
| Operation | SWIG | IPC |
|
||||
|-----------|------|-----|
|
||||
| Get board | `pcbnew.LoadBoard()` | `kicad.get_board()` |
|
||||
| Set size | `board.SetBoardSize()` | `board.set_size()` |
|
||||
| Add layer | `board.GetLayerCount()` | `board.layers.add()` |
|
||||
|
||||
### Component Operations
|
||||
|
||||
| Operation | SWIG | IPC |
|
||||
|-----------|------|-----|
|
||||
| Place component | `pcbnew.FOOTPRINT()` | `board.add_footprint()` |
|
||||
| Move component | `fp.SetPosition()` | `footprint.set_position()` |
|
||||
| Rotate component | `fp.SetOrientation()` | `footprint.set_rotation()` |
|
||||
|
||||
### Routing Operations
|
||||
|
||||
| Operation | SWIG | IPC |
|
||||
|-----------|------|-----|
|
||||
| Add net | `board.GetNetCount()` | `board.nets.add()` |
|
||||
| Route trace | `pcbnew.PCB_TRACK()` | `board.add_track()` |
|
||||
| Add via | `pcbnew.PCB_VIA()` | `board.add_via()` |
|
||||
|
||||
---
|
||||
|
||||
## Configuration Changes
|
||||
|
||||
### Update requirements.txt
|
||||
|
||||
```diff
|
||||
+ # KiCAD IPC API (official Python bindings)
|
||||
+ kicad-python>=0.5.0
|
||||
|
||||
# Legacy SWIG support (for backward compatibility)
|
||||
kicad-skip>=0.1.0
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# Enable IPC API in KiCAD preferences
|
||||
# Preferences > Plugins > Enable IPC API Server
|
||||
|
||||
# Set backend preference (optional)
|
||||
export KICAD_BACKEND=ipc # or 'swig' or 'auto'
|
||||
```
|
||||
|
||||
### User Migration Guide
|
||||
|
||||
Create `docs/MIGRATING_TO_IPC.md`:
|
||||
- How to enable IPC in KiCAD
|
||||
- What changes for users
|
||||
- Troubleshooting IPC connection issues
|
||||
|
||||
---
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If IPC migration fails:
|
||||
|
||||
1. **Keep SWIG backend** - Already abstracted
|
||||
2. **Default to SWIG** - Change factory auto-detection
|
||||
3. **Document limitations** - Note that SWIG will be removed eventually
|
||||
4. **Plan retry** - Schedule IPC migration for later
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- [ ] ✅ All existing functionality works with IPC backend
|
||||
- [ ] ✅ Tests pass with both IPC and SWIG backends
|
||||
- [ ] ✅ Performance acceptable (< 20% slowdown vs SWIG)
|
||||
- [ ] ✅ Documentation updated
|
||||
- [ ] ✅ Migration guide created
|
||||
- [ ] ✅ User-facing tools work without changes
|
||||
|
||||
---
|
||||
|
||||
## Timeline
|
||||
|
||||
| Week | Days | Tasks |
|
||||
|------|------|-------|
|
||||
| **Week 2** | Mon-Tue | Research, install kicad-python, test connection |
|
||||
| | Wed-Thu | Build abstraction layer |
|
||||
| | Fri | Port project.py and board.py |
|
||||
| **Week 3** | Mon-Tue | Port component.py and routing.py |
|
||||
| | Wed | Port design_rules.py and export.py |
|
||||
| | Thu-Fri | Testing, validation, documentation |
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
- **Official Docs:** https://docs.kicad.org/kicad-python-main
|
||||
- **kicad-python PyPI:** https://pypi.org/project/kicad-python/
|
||||
- **IPC API Spec:** https://dev-docs.kicad.org/en/apis-and-binding/ipc-api/
|
||||
- **Protocol Buffers:** Used by IPC for message format
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **How to handle KiCAD not running?**
|
||||
- Option A: Auto-launch KiCAD in background
|
||||
- Option B: Require user to launch KiCAD first
|
||||
- Option C: Fall back to SWIG if IPC unavailable
|
||||
- **Decision: Option C for now, A later**
|
||||
|
||||
2. **Connection management**
|
||||
- Should we keep connection open or connect per-operation?
|
||||
- **Decision: Keep alive with reconnect logic**
|
||||
|
||||
3. **Performance vs reliability**
|
||||
- IPC has overhead but more stable
|
||||
- **Decision: Reliability > performance**
|
||||
|
||||
---
|
||||
|
||||
## Next Steps (This Week)
|
||||
|
||||
1. **Install kicad-python**
|
||||
```bash
|
||||
pip install kicad-python
|
||||
```
|
||||
|
||||
2. **Test IPC connection**
|
||||
```bash
|
||||
# Launch KiCAD
|
||||
# Enable IPC in preferences
|
||||
python3 -c "from kicad import KiCad; k=KiCad(); print(k.check_version())"
|
||||
```
|
||||
|
||||
3. **Create abstraction layer structure**
|
||||
```bash
|
||||
mkdir -p python/kicad_api
|
||||
touch python/kicad_api/{__init__,base,ipc_backend,swig_backend,factory}.py
|
||||
```
|
||||
|
||||
4. **Begin project.py migration**
|
||||
- Start with simplest module
|
||||
- Establish patterns for others
|
||||
|
||||
---
|
||||
|
||||
**Prepared by:** Claude Code
|
||||
**Last Updated:** October 25, 2025
|
||||
**Status:** 📋 Ready to execute
|
||||
# KiCAD IPC API Migration Plan
|
||||
|
||||
**Status:** 📋 Planning
|
||||
**Target Completion:** Week 2-3 (November 1-8, 2025)
|
||||
**Priority:** 🔴 **CRITICAL** - Current SWIG API deprecated
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
The current KiCAD MCP Server uses SWIG-based Python bindings (`import pcbnew`) which are **deprecated as of KiCAD 9.0** and will be **removed in KiCAD 10.0**. We must migrate to the official **KiCAD IPC API** to future-proof the project.
|
||||
|
||||
### Why Migrate?
|
||||
|
||||
| SWIG API (Current) | IPC API (Future) |
|
||||
| -------------------------------- | ------------------------------------ |
|
||||
| ❌ Deprecated | ✅ Official & Supported |
|
||||
| ❌ Will be removed in KiCAD 10.0 | ✅ Long-term stability |
|
||||
| ❌ Python-only | ✅ Multi-language (Python, JS, etc.) |
|
||||
| ❌ Direct linking | ✅ Inter-process communication |
|
||||
| ⚠️ Synchronous only | ✅ Async support |
|
||||
| ⚠️ No versioning | ✅ Protocol Buffers versioning |
|
||||
|
||||
**Decision: Migrate immediately to avoid technical debt**
|
||||
|
||||
---
|
||||
|
||||
## IPC API Overview
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ TypeScript MCP Server (Node.js) │
|
||||
└──────────────────────┬──────────────────────────────────────┘
|
||||
│ JSON over stdin/stdout
|
||||
┌──────────────────────▼──────────────────────────────────────┐
|
||||
│ Python Interface Layer │
|
||||
│ ┌────────────────────────────────────────────────────────┐ │
|
||||
│ │ KiCAD API Abstraction (NEW) │ │
|
||||
│ └────────────────────────────────────────────────────────┘ │
|
||||
└──────────────────────┬──────────────────────────────────────┘
|
||||
│ kicad-python library
|
||||
┌──────────────────────▼──────────────────────────────────────┐
|
||||
│ KiCAD IPC Server (Protocol Buffers) │
|
||||
│ Running inside KiCAD Process │
|
||||
└──────────────────────┬──────────────────────────────────────┘
|
||||
│ UNIX Sockets / Named Pipes
|
||||
┌──────────────────────▼──────────────────────────────────────┐
|
||||
│ KiCAD 9.0+ Application │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Key Differences
|
||||
|
||||
1. **KiCAD Must Be Running**
|
||||
- SWIG: Can run headless, no KiCAD GUI needed
|
||||
- IPC: Requires KiCAD running with IPC server enabled
|
||||
|
||||
2. **Communication Method**
|
||||
- SWIG: Direct Python module import
|
||||
- IPC: Socket-based RPC (Remote Procedure Call)
|
||||
|
||||
3. **API Structure**
|
||||
- SWIG: `board.SetSize(width, height)`
|
||||
- IPC: `kicad.get_board().set_size(width, height)`
|
||||
|
||||
---
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
### Phase 1: Research & Preparation (Days 1-2)
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Understand kicad-python library
|
||||
- Test IPC connection
|
||||
- Document API differences
|
||||
|
||||
**Tasks:**
|
||||
|
||||
```bash
|
||||
# Install kicad-python
|
||||
pip install kicad-python>=0.5.0
|
||||
|
||||
# Test basic connection
|
||||
python3 << EOF
|
||||
from kicad import KiCad
|
||||
kicad = KiCad()
|
||||
print(f"Connected to KiCAD: {kicad.check_version()}")
|
||||
EOF
|
||||
|
||||
# Read official documentation
|
||||
# https://docs.kicad.org/kicad-python-main
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
|
||||
- [ ] kicad-python installed and tested
|
||||
- [ ] Connection test script
|
||||
- [ ] API comparison document (SWIG vs IPC)
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: Abstraction Layer (Days 3-4)
|
||||
|
||||
**Goal:** Create an abstraction layer to support both APIs during transition
|
||||
|
||||
**File Structure:**
|
||||
|
||||
```
|
||||
python/kicad_api/
|
||||
├── __init__.py
|
||||
├── base.py # Abstract base class
|
||||
├── ipc_backend.py # NEW: IPC API implementation
|
||||
├── swig_backend.py # Legacy SWIG implementation
|
||||
└── factory.py # Backend selector
|
||||
```
|
||||
|
||||
**Abstract Interface:**
|
||||
|
||||
```python
|
||||
# python/kicad_api/base.py
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Optional
|
||||
from pathlib import Path
|
||||
|
||||
class KiCADBackend(ABC):
|
||||
"""Abstract base class for KiCAD API backends"""
|
||||
|
||||
@abstractmethod
|
||||
def connect(self) -> bool:
|
||||
"""Connect to KiCAD"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def disconnect(self) -> None:
|
||||
"""Disconnect from KiCAD"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def is_connected(self) -> bool:
|
||||
"""Check if connected"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def create_project(self, path: Path, name: str) -> dict:
|
||||
"""Create a new KiCAD project"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def open_project(self, path: Path) -> dict:
|
||||
"""Open existing project"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_board(self) -> 'BoardAPI':
|
||||
"""Get board API"""
|
||||
pass
|
||||
|
||||
# ... more abstract methods
|
||||
```
|
||||
|
||||
**IPC Implementation:**
|
||||
|
||||
```python
|
||||
# python/kicad_api/ipc_backend.py
|
||||
from kicad import KiCad
|
||||
from kicad_api.base import KiCADBackend
|
||||
|
||||
class IPCBackend(KiCADBackend):
|
||||
"""KiCAD IPC API backend"""
|
||||
|
||||
def __init__(self):
|
||||
self.kicad = None
|
||||
|
||||
def connect(self) -> bool:
|
||||
"""Connect to running KiCAD instance"""
|
||||
try:
|
||||
self.kicad = KiCad()
|
||||
# Verify connection
|
||||
version = self.kicad.check_version()
|
||||
logger.info(f"Connected to KiCAD via IPC: {version}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to connect via IPC: {e}")
|
||||
return False
|
||||
|
||||
def create_project(self, path: Path, name: str) -> dict:
|
||||
"""Create project using IPC API"""
|
||||
# Implementation here
|
||||
pass
|
||||
```
|
||||
|
||||
**Backend Factory:**
|
||||
|
||||
```python
|
||||
# python/kicad_api/factory.py
|
||||
from typing import Optional
|
||||
from kicad_api.base import KiCADBackend
|
||||
from kicad_api.ipc_backend import IPCBackend
|
||||
from kicad_api.swig_backend import SWIGBackend
|
||||
|
||||
def create_backend(backend_type: Optional[str] = None) -> KiCADBackend:
|
||||
"""
|
||||
Create appropriate KiCAD backend
|
||||
|
||||
Args:
|
||||
backend_type: 'ipc', 'swig', or None for auto-detect
|
||||
|
||||
Returns:
|
||||
KiCADBackend instance
|
||||
"""
|
||||
if backend_type == 'ipc':
|
||||
return IPCBackend()
|
||||
elif backend_type == 'swig':
|
||||
return SWIGBackend()
|
||||
else:
|
||||
# Auto-detect: Try IPC first, fall back to SWIG
|
||||
try:
|
||||
backend = IPCBackend()
|
||||
if backend.connect():
|
||||
return backend
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Fall back to SWIG
|
||||
return SWIGBackend()
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
|
||||
- [ ] Abstract base class defined
|
||||
- [ ] IPC backend implemented
|
||||
- [ ] SWIG backend (wrapper around existing code)
|
||||
- [ ] Factory with auto-detection
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: Port Core Modules (Days 5-8)
|
||||
|
||||
**Migration Order** (by complexity):
|
||||
|
||||
1. **project.py** (Simple - good starting point)
|
||||
- Create, open, save projects
|
||||
- Estimated: 2 hours
|
||||
|
||||
2. **board.py** (Medium - board properties)
|
||||
- Set size, layers, outline
|
||||
- Estimated: 4 hours
|
||||
|
||||
3. **component.py** (Complex - many operations)
|
||||
- Place, move, rotate, delete
|
||||
- Component arrays and alignment
|
||||
- Estimated: 8 hours
|
||||
|
||||
4. **routing.py** (Complex - trace routing)
|
||||
- Nets, traces, vias
|
||||
- Copper pours, differential pairs
|
||||
- Estimated: 8 hours
|
||||
|
||||
5. **design_rules.py** (Medium - DRC)
|
||||
- Set rules, run DRC
|
||||
- Estimated: 4 hours
|
||||
|
||||
6. **export.py** (Medium - file exports)
|
||||
- Gerber, PDF, SVG, 3D
|
||||
- Estimated: 4 hours
|
||||
|
||||
**Total Estimated Time: 30 hours (~4 days)**
|
||||
|
||||
**Migration Template:**
|
||||
|
||||
```python
|
||||
# OLD (SWIG)
|
||||
import pcbnew
|
||||
board = pcbnew.LoadBoard(filename)
|
||||
board.SetBoardSize(width, height)
|
||||
|
||||
# NEW (IPC via abstraction)
|
||||
from kicad_api import create_backend
|
||||
backend = create_backend('ipc')
|
||||
backend.connect()
|
||||
board_api = backend.get_board()
|
||||
board_api.set_size(width, height)
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
|
||||
- [ ] project.py migrated
|
||||
- [ ] board.py migrated
|
||||
- [ ] component.py migrated
|
||||
- [ ] routing.py migrated
|
||||
- [ ] design_rules.py migrated
|
||||
- [ ] export.py migrated
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: Testing & Validation (Days 9-10)
|
||||
|
||||
**Testing Strategy:**
|
||||
|
||||
1. **Unit Tests**
|
||||
|
||||
```python
|
||||
@pytest.mark.parametrize("backend_type", ["ipc", "swig"])
|
||||
def test_create_project(backend_type):
|
||||
backend = create_backend(backend_type)
|
||||
result = backend.create_project(Path("/tmp/test"), "TestProject")
|
||||
assert result["success"] is True
|
||||
```
|
||||
|
||||
2. **Integration Tests**
|
||||
- Run side-by-side: IPC vs SWIG
|
||||
- Compare outputs for identical operations
|
||||
- Verify file compatibility
|
||||
|
||||
3. **Performance Benchmarks**
|
||||
```python
|
||||
# Measure: operations/second for each backend
|
||||
# Expected: IPC slightly slower due to IPC overhead
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
|
||||
- [ ] 50+ unit tests passing for IPC backend
|
||||
- [ ] Side-by-side comparison tests
|
||||
- [ ] Performance benchmarks documented
|
||||
|
||||
---
|
||||
|
||||
## API Comparison Reference
|
||||
|
||||
### Project Operations
|
||||
|
||||
| Operation | SWIG | IPC |
|
||||
| -------------- | -------------------- | ------------------------ |
|
||||
| Create project | Custom file creation | `kicad.create_project()` |
|
||||
| Open project | `pcbnew.LoadBoard()` | `kicad.open_project()` |
|
||||
| Save project | `board.Save()` | `board.save()` |
|
||||
|
||||
### Board Operations
|
||||
|
||||
| Operation | SWIG | IPC |
|
||||
| --------- | ----------------------- | -------------------- |
|
||||
| Get board | `pcbnew.LoadBoard()` | `kicad.get_board()` |
|
||||
| Set size | `board.SetBoardSize()` | `board.set_size()` |
|
||||
| Add layer | `board.GetLayerCount()` | `board.layers.add()` |
|
||||
|
||||
### Component Operations
|
||||
|
||||
| Operation | SWIG | IPC |
|
||||
| ---------------- | --------------------- | -------------------------- |
|
||||
| Place component | `pcbnew.FOOTPRINT()` | `board.add_footprint()` |
|
||||
| Move component | `fp.SetPosition()` | `footprint.set_position()` |
|
||||
| Rotate component | `fp.SetOrientation()` | `footprint.set_rotation()` |
|
||||
|
||||
### Routing Operations
|
||||
|
||||
| Operation | SWIG | IPC |
|
||||
| ----------- | --------------------- | ------------------- |
|
||||
| Add net | `board.GetNetCount()` | `board.nets.add()` |
|
||||
| Route trace | `pcbnew.PCB_TRACK()` | `board.add_track()` |
|
||||
| Add via | `pcbnew.PCB_VIA()` | `board.add_via()` |
|
||||
|
||||
---
|
||||
|
||||
## Configuration Changes
|
||||
|
||||
### Update requirements.txt
|
||||
|
||||
```diff
|
||||
+ # KiCAD IPC API (official Python bindings)
|
||||
+ kicad-python>=0.5.0
|
||||
|
||||
# Legacy SWIG support (for backward compatibility)
|
||||
kicad-skip>=0.1.0
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# Enable IPC API in KiCAD preferences
|
||||
# Preferences > Plugins > Enable IPC API Server
|
||||
|
||||
# Set backend preference (optional)
|
||||
export KICAD_BACKEND=ipc # or 'swig' or 'auto'
|
||||
```
|
||||
|
||||
### User Migration Guide
|
||||
|
||||
Create `docs/MIGRATING_TO_IPC.md`:
|
||||
|
||||
- How to enable IPC in KiCAD
|
||||
- What changes for users
|
||||
- Troubleshooting IPC connection issues
|
||||
|
||||
---
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If IPC migration fails:
|
||||
|
||||
1. **Keep SWIG backend** - Already abstracted
|
||||
2. **Default to SWIG** - Change factory auto-detection
|
||||
3. **Document limitations** - Note that SWIG will be removed eventually
|
||||
4. **Plan retry** - Schedule IPC migration for later
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- [ ] ✅ All existing functionality works with IPC backend
|
||||
- [ ] ✅ Tests pass with both IPC and SWIG backends
|
||||
- [ ] ✅ Performance acceptable (< 20% slowdown vs SWIG)
|
||||
- [ ] ✅ Documentation updated
|
||||
- [ ] ✅ Migration guide created
|
||||
- [ ] ✅ User-facing tools work without changes
|
||||
|
||||
---
|
||||
|
||||
## Timeline
|
||||
|
||||
| Week | Days | Tasks |
|
||||
| ---------- | ------- | ----------------------------------------------- |
|
||||
| **Week 2** | Mon-Tue | Research, install kicad-python, test connection |
|
||||
| | Wed-Thu | Build abstraction layer |
|
||||
| | Fri | Port project.py and board.py |
|
||||
| **Week 3** | Mon-Tue | Port component.py and routing.py |
|
||||
| | Wed | Port design_rules.py and export.py |
|
||||
| | Thu-Fri | Testing, validation, documentation |
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
- **Official Docs:** https://docs.kicad.org/kicad-python-main
|
||||
- **kicad-python PyPI:** https://pypi.org/project/kicad-python/
|
||||
- **IPC API Spec:** https://dev-docs.kicad.org/en/apis-and-binding/ipc-api/
|
||||
- **Protocol Buffers:** Used by IPC for message format
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **How to handle KiCAD not running?**
|
||||
- Option A: Auto-launch KiCAD in background
|
||||
- Option B: Require user to launch KiCAD first
|
||||
- Option C: Fall back to SWIG if IPC unavailable
|
||||
- **Decision: Option C for now, A later**
|
||||
|
||||
2. **Connection management**
|
||||
- Should we keep connection open or connect per-operation?
|
||||
- **Decision: Keep alive with reconnect logic**
|
||||
|
||||
3. **Performance vs reliability**
|
||||
- IPC has overhead but more stable
|
||||
- **Decision: Reliability > performance**
|
||||
|
||||
---
|
||||
|
||||
## Next Steps (This Week)
|
||||
|
||||
1. **Install kicad-python**
|
||||
|
||||
```bash
|
||||
pip install kicad-python
|
||||
```
|
||||
|
||||
2. **Test IPC connection**
|
||||
|
||||
```bash
|
||||
# Launch KiCAD
|
||||
# Enable IPC in preferences
|
||||
python3 -c "from kicad import KiCad; k=KiCad(); print(k.check_version())"
|
||||
```
|
||||
|
||||
3. **Create abstraction layer structure**
|
||||
|
||||
```bash
|
||||
mkdir -p python/kicad_api
|
||||
touch python/kicad_api/{__init__,base,ipc_backend,swig_backend,factory}.py
|
||||
```
|
||||
|
||||
4. **Begin project.py migration**
|
||||
- Start with simplest module
|
||||
- Establish patterns for others
|
||||
|
||||
---
|
||||
|
||||
**Prepared by:** Claude Code
|
||||
**Last Updated:** October 25, 2025
|
||||
**Status:** 📋 Ready to execute
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,222 +1,241 @@
|
||||
# Router Implementation Status
|
||||
|
||||
## ✅ Phase 1 Complete: Foundation & Infrastructure
|
||||
|
||||
**Date:** December 28, 2025
|
||||
|
||||
### What Was Implemented
|
||||
|
||||
#### 1. Tool Registry (`src/tools/registry.ts`)
|
||||
- ✅ Complete tool categorization (59 tools → 7 categories)
|
||||
- ✅ Direct tools list (12 high-frequency tools)
|
||||
- ✅ Category lookup maps for O(1) access
|
||||
- ✅ Tool search functionality
|
||||
- ✅ Registry statistics and metadata
|
||||
|
||||
#### 2. Router Tools (`src/tools/router.ts`)
|
||||
- ✅ `list_tool_categories` - Browse all categories
|
||||
- ✅ `get_category_tools` - View tools in a category
|
||||
- ✅ `execute_tool` - Execute any routed tool
|
||||
- ✅ `search_tools` - Search tools by keyword
|
||||
|
||||
#### 3. Server Integration (`src/server.ts`)
|
||||
- ✅ Router tools registered at server startup
|
||||
- ✅ All tools remain functional (backwards compatible)
|
||||
- ✅ Logging added for router pattern status
|
||||
|
||||
#### 4. Documentation
|
||||
- ✅ `TOOL_INVENTORY.md` - Complete tool catalog
|
||||
- ✅ `ROUTER_ARCHITECTURE.md` - Design specification
|
||||
- ✅ `ROUTER_IMPLEMENTATION_STATUS.md` - This file
|
||||
|
||||
### Current State
|
||||
|
||||
**Status:** ✅ **Router Infrastructure Complete**
|
||||
|
||||
**Build:** ✅ Compiles successfully (`npm run build`)
|
||||
|
||||
**Tool Count:**
|
||||
- Total Tools: 59 (ALL still registered and visible)
|
||||
- Direct Tools: 12
|
||||
- Routed Tools: 47
|
||||
- Router Tools: 4
|
||||
- **Currently Visible to Claude:** 63 tools (59 + 4 router)
|
||||
|
||||
**Token Impact:**
|
||||
- **Current:** ~42K tokens (still showing all tools)
|
||||
- **Target:** ~12K tokens (Phase 2 optimization)
|
||||
- **Potential Savings:** ~30K tokens (71% reduction)
|
||||
|
||||
## 🔄 Phase 2: Token Optimization (Next Step)
|
||||
|
||||
### Objective
|
||||
Hide routed tools from Claude's context while keeping them accessible via `execute_tool`.
|
||||
|
||||
### Two Approaches
|
||||
|
||||
#### Option A: Registration Filtering (Recommended)
|
||||
Modify tool registration to conditionally register tools based on whether they're in the direct list.
|
||||
|
||||
**Changes needed:**
|
||||
1. Update each `register*Tools` function to check `isDirectTool()`
|
||||
2. Only call `server.tool()` for direct tools
|
||||
3. Routed tools remain accessible via `execute_tool` calling `callKicadScript`
|
||||
|
||||
**Pros:**
|
||||
- Clean separation
|
||||
- True token savings
|
||||
- No behavior changes
|
||||
|
||||
**Cons:**
|
||||
- Requires modifying 9 tool files
|
||||
|
||||
#### Option B: MCP Filter (If Supported)
|
||||
If MCP SDK supports tool filtering/hiding, use that instead.
|
||||
|
||||
**Pros:**
|
||||
- No tool file changes
|
||||
- Centralized control
|
||||
|
||||
**Cons:**
|
||||
- May not be supported by SDK
|
||||
- Needs investigation
|
||||
|
||||
### Implementation Plan for Phase 2
|
||||
|
||||
1. **Create Helper Function** (`src/tools/conditional-register.ts`)
|
||||
```typescript
|
||||
export function registerToolConditionally(
|
||||
server: McpServer,
|
||||
toolName: string,
|
||||
definition: ToolDefinition,
|
||||
handler: Function
|
||||
) {
|
||||
if (isDirectTool(toolName)) {
|
||||
// Register with MCP (visible to Claude)
|
||||
server.tool(toolName, definition, handler);
|
||||
} else {
|
||||
// Register handler for execute_tool (hidden from Claude)
|
||||
registerToolHandler(toolName, handler);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **Update Tool Registration Functions**
|
||||
Modify each `register*Tools` function to use conditional registration.
|
||||
|
||||
3. **Test**
|
||||
- Verify direct tools work normally
|
||||
- Verify routed tools work via `execute_tool`
|
||||
- Verify token count reduction
|
||||
|
||||
4. **Measure Impact**
|
||||
Count tools visible to Claude before/after.
|
||||
|
||||
## 📊 Categories & Distribution
|
||||
|
||||
| Category | Tools | Description |
|
||||
|----------|-------|-------------|
|
||||
| **board** | 9 | Board configuration, layers, zones, visualization |
|
||||
| **component** | 8 | Advanced component operations |
|
||||
| **export** | 8 | Manufacturing file generation |
|
||||
| **drc** | 9 | Design rule checking & validation |
|
||||
| **schematic** | 9 | Schematic editor operations |
|
||||
| **library** | 4 | Footprint library access |
|
||||
| **routing** | 3 | Advanced routing (vias, copper pours) |
|
||||
| **TOTAL** | **47** | **Routed tools** |
|
||||
| **direct** | **12** | **Always visible tools** |
|
||||
| **router** | **4** | **Discovery tools** |
|
||||
|
||||
## 🧪 Testing the Router
|
||||
|
||||
### Test 1: List Categories
|
||||
```
|
||||
User: "What tool categories are available?"
|
||||
|
||||
Expected: Claude calls list_tool_categories
|
||||
Result: Returns 7 categories with descriptions
|
||||
```
|
||||
|
||||
### Test 2: Browse Category
|
||||
```
|
||||
User: "What export tools are available?"
|
||||
|
||||
Expected: Claude calls get_category_tools({ category: "export" })
|
||||
Result: Returns 8 export tools
|
||||
```
|
||||
|
||||
### Test 3: Search Tools
|
||||
```
|
||||
User: "How do I export gerber files?"
|
||||
|
||||
Expected: Claude calls search_tools({ query: "gerber" })
|
||||
Result: Finds export_gerber in export category
|
||||
```
|
||||
|
||||
### Test 4: Execute Tool
|
||||
```
|
||||
User: "Export gerbers to ./output"
|
||||
|
||||
Expected: Claude calls execute_tool({
|
||||
tool_name: "export_gerber",
|
||||
params: { outputDir: "./output" }
|
||||
})
|
||||
Result: Executes via router, returns gerber export result
|
||||
```
|
||||
|
||||
## 📝 Benefits Achieved (Phase 1)
|
||||
|
||||
1. ✅ **Foundation Ready**: All infrastructure in place
|
||||
2. ✅ **Organized**: 59 tools categorized into logical groups
|
||||
3. ✅ **Discoverable**: Tools easily found via search/browse
|
||||
4. ✅ **Backwards Compatible**: All existing tools still work
|
||||
5. ✅ **Extensible**: Easy to add new tools and categories
|
||||
6. ✅ **Documented**: Complete architecture and usage docs
|
||||
|
||||
## 🚀 Next Actions
|
||||
|
||||
1. **Optional: Complete Phase 2** (Token Optimization)
|
||||
- Implement conditional registration
|
||||
- Hide routed tools from context
|
||||
- Achieve 71% token reduction
|
||||
|
||||
2. **Or: Ship Phase 1 As-Is**
|
||||
- Router tools work perfectly now
|
||||
- Users can discover and execute tools
|
||||
- Optimization can be done later
|
||||
- No breaking changes
|
||||
|
||||
## 📚 Related Files
|
||||
|
||||
- `src/tools/registry.ts` - Tool registry and categories
|
||||
- `src/tools/router.ts` - Router tool implementations
|
||||
- `src/server.ts` - Server integration
|
||||
- `docs/TOOL_INVENTORY.md` - Complete tool list
|
||||
- `docs/ROUTER_ARCHITECTURE.md` - Design specification
|
||||
- `docs/mcp-router-guide.md` - Original implementation guide
|
||||
|
||||
## 💡 Usage Example
|
||||
|
||||
```typescript
|
||||
// User: "I need to export gerber files"
|
||||
|
||||
// Claude's interaction:
|
||||
// 1. Sees "export" and "gerber" keywords
|
||||
// 2. Calls search_tools({ query: "gerber" })
|
||||
// → Returns: { category: "export", tool: "export_gerber", ... }
|
||||
// 3. Calls execute_tool({
|
||||
// tool_name: "export_gerber",
|
||||
// params: { outputDir: "./gerbers" }
|
||||
// })
|
||||
// → Executes and returns result
|
||||
// 4. "I've exported your Gerber files to ./gerbers/"
|
||||
```
|
||||
|
||||
## Status Summary
|
||||
|
||||
✅ **Router Pattern: IMPLEMENTED**
|
||||
✅ **Build: PASSING**
|
||||
✅ **Backwards Compatible: YES**
|
||||
⏳ **Token Optimization: PENDING (Phase 2)**
|
||||
|
||||
The router infrastructure is complete and functional. The system now supports tool discovery and organized access to all 59 tools. Phase 2 optimization (hiding routed tools) can be implemented when ready for maximum token savings.
|
||||
# Router Implementation Status
|
||||
|
||||
## ✅ Phase 1 Complete: Foundation & Infrastructure
|
||||
|
||||
**Date:** December 28, 2025
|
||||
|
||||
### What Was Implemented
|
||||
|
||||
#### 1. Tool Registry (`src/tools/registry.ts`)
|
||||
|
||||
- ✅ Complete tool categorization (59 tools → 7 categories)
|
||||
- ✅ Direct tools list (12 high-frequency tools)
|
||||
- ✅ Category lookup maps for O(1) access
|
||||
- ✅ Tool search functionality
|
||||
- ✅ Registry statistics and metadata
|
||||
|
||||
#### 2. Router Tools (`src/tools/router.ts`)
|
||||
|
||||
- ✅ `list_tool_categories` - Browse all categories
|
||||
- ✅ `get_category_tools` - View tools in a category
|
||||
- ✅ `execute_tool` - Execute any routed tool
|
||||
- ✅ `search_tools` - Search tools by keyword
|
||||
|
||||
#### 3. Server Integration (`src/server.ts`)
|
||||
|
||||
- ✅ Router tools registered at server startup
|
||||
- ✅ All tools remain functional (backwards compatible)
|
||||
- ✅ Logging added for router pattern status
|
||||
|
||||
#### 4. Documentation
|
||||
|
||||
- ✅ `TOOL_INVENTORY.md` - Complete tool catalog
|
||||
- ✅ `ROUTER_ARCHITECTURE.md` - Design specification
|
||||
- ✅ `ROUTER_IMPLEMENTATION_STATUS.md` - This file
|
||||
|
||||
### Current State
|
||||
|
||||
**Status:** ✅ **Router Infrastructure Complete**
|
||||
|
||||
**Build:** ✅ Compiles successfully (`npm run build`)
|
||||
|
||||
**Tool Count:**
|
||||
|
||||
- Total Tools: 59 (ALL still registered and visible)
|
||||
- Direct Tools: 12
|
||||
- Routed Tools: 47
|
||||
- Router Tools: 4
|
||||
- **Currently Visible to Claude:** 63 tools (59 + 4 router)
|
||||
|
||||
**Token Impact:**
|
||||
|
||||
- **Current:** ~42K tokens (still showing all tools)
|
||||
- **Target:** ~12K tokens (Phase 2 optimization)
|
||||
- **Potential Savings:** ~30K tokens (71% reduction)
|
||||
|
||||
## 🔄 Phase 2: Token Optimization (Next Step)
|
||||
|
||||
### Objective
|
||||
|
||||
Hide routed tools from Claude's context while keeping them accessible via `execute_tool`.
|
||||
|
||||
### Two Approaches
|
||||
|
||||
#### Option A: Registration Filtering (Recommended)
|
||||
|
||||
Modify tool registration to conditionally register tools based on whether they're in the direct list.
|
||||
|
||||
**Changes needed:**
|
||||
|
||||
1. Update each `register*Tools` function to check `isDirectTool()`
|
||||
2. Only call `server.tool()` for direct tools
|
||||
3. Routed tools remain accessible via `execute_tool` calling `callKicadScript`
|
||||
|
||||
**Pros:**
|
||||
|
||||
- Clean separation
|
||||
- True token savings
|
||||
- No behavior changes
|
||||
|
||||
**Cons:**
|
||||
|
||||
- Requires modifying 9 tool files
|
||||
|
||||
#### Option B: MCP Filter (If Supported)
|
||||
|
||||
If MCP SDK supports tool filtering/hiding, use that instead.
|
||||
|
||||
**Pros:**
|
||||
|
||||
- No tool file changes
|
||||
- Centralized control
|
||||
|
||||
**Cons:**
|
||||
|
||||
- May not be supported by SDK
|
||||
- Needs investigation
|
||||
|
||||
### Implementation Plan for Phase 2
|
||||
|
||||
1. **Create Helper Function** (`src/tools/conditional-register.ts`)
|
||||
|
||||
```typescript
|
||||
export function registerToolConditionally(
|
||||
server: McpServer,
|
||||
toolName: string,
|
||||
definition: ToolDefinition,
|
||||
handler: Function,
|
||||
) {
|
||||
if (isDirectTool(toolName)) {
|
||||
// Register with MCP (visible to Claude)
|
||||
server.tool(toolName, definition, handler);
|
||||
} else {
|
||||
// Register handler for execute_tool (hidden from Claude)
|
||||
registerToolHandler(toolName, handler);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **Update Tool Registration Functions**
|
||||
Modify each `register*Tools` function to use conditional registration.
|
||||
|
||||
3. **Test**
|
||||
- Verify direct tools work normally
|
||||
- Verify routed tools work via `execute_tool`
|
||||
- Verify token count reduction
|
||||
|
||||
4. **Measure Impact**
|
||||
Count tools visible to Claude before/after.
|
||||
|
||||
## 📊 Categories & Distribution
|
||||
|
||||
| Category | Tools | Description |
|
||||
| ------------- | ------ | ------------------------------------------------- |
|
||||
| **board** | 9 | Board configuration, layers, zones, visualization |
|
||||
| **component** | 8 | Advanced component operations |
|
||||
| **export** | 8 | Manufacturing file generation |
|
||||
| **drc** | 9 | Design rule checking & validation |
|
||||
| **schematic** | 9 | Schematic editor operations |
|
||||
| **library** | 4 | Footprint library access |
|
||||
| **routing** | 3 | Advanced routing (vias, copper pours) |
|
||||
| **TOTAL** | **47** | **Routed tools** |
|
||||
| **direct** | **12** | **Always visible tools** |
|
||||
| **router** | **4** | **Discovery tools** |
|
||||
|
||||
## 🧪 Testing the Router
|
||||
|
||||
### Test 1: List Categories
|
||||
|
||||
```
|
||||
User: "What tool categories are available?"
|
||||
|
||||
Expected: Claude calls list_tool_categories
|
||||
Result: Returns 7 categories with descriptions
|
||||
```
|
||||
|
||||
### Test 2: Browse Category
|
||||
|
||||
```
|
||||
User: "What export tools are available?"
|
||||
|
||||
Expected: Claude calls get_category_tools({ category: "export" })
|
||||
Result: Returns 8 export tools
|
||||
```
|
||||
|
||||
### Test 3: Search Tools
|
||||
|
||||
```
|
||||
User: "How do I export gerber files?"
|
||||
|
||||
Expected: Claude calls search_tools({ query: "gerber" })
|
||||
Result: Finds export_gerber in export category
|
||||
```
|
||||
|
||||
### Test 4: Execute Tool
|
||||
|
||||
```
|
||||
User: "Export gerbers to ./output"
|
||||
|
||||
Expected: Claude calls execute_tool({
|
||||
tool_name: "export_gerber",
|
||||
params: { outputDir: "./output" }
|
||||
})
|
||||
Result: Executes via router, returns gerber export result
|
||||
```
|
||||
|
||||
## 📝 Benefits Achieved (Phase 1)
|
||||
|
||||
1. ✅ **Foundation Ready**: All infrastructure in place
|
||||
2. ✅ **Organized**: 59 tools categorized into logical groups
|
||||
3. ✅ **Discoverable**: Tools easily found via search/browse
|
||||
4. ✅ **Backwards Compatible**: All existing tools still work
|
||||
5. ✅ **Extensible**: Easy to add new tools and categories
|
||||
6. ✅ **Documented**: Complete architecture and usage docs
|
||||
|
||||
## 🚀 Next Actions
|
||||
|
||||
1. **Optional: Complete Phase 2** (Token Optimization)
|
||||
- Implement conditional registration
|
||||
- Hide routed tools from context
|
||||
- Achieve 71% token reduction
|
||||
|
||||
2. **Or: Ship Phase 1 As-Is**
|
||||
- Router tools work perfectly now
|
||||
- Users can discover and execute tools
|
||||
- Optimization can be done later
|
||||
- No breaking changes
|
||||
|
||||
## 📚 Related Files
|
||||
|
||||
- `src/tools/registry.ts` - Tool registry and categories
|
||||
- `src/tools/router.ts` - Router tool implementations
|
||||
- `src/server.ts` - Server integration
|
||||
- `docs/TOOL_INVENTORY.md` - Complete tool list
|
||||
- `docs/ROUTER_ARCHITECTURE.md` - Design specification
|
||||
- `docs/mcp-router-guide.md` - Original implementation guide
|
||||
|
||||
## 💡 Usage Example
|
||||
|
||||
```typescript
|
||||
// User: "I need to export gerber files"
|
||||
|
||||
// Claude's interaction:
|
||||
// 1. Sees "export" and "gerber" keywords
|
||||
// 2. Calls search_tools({ query: "gerber" })
|
||||
// → Returns: { category: "export", tool: "export_gerber", ... }
|
||||
// 3. Calls execute_tool({
|
||||
// tool_name: "export_gerber",
|
||||
// params: { outputDir: "./gerbers" }
|
||||
// })
|
||||
// → Executes and returns result
|
||||
// 4. "I've exported your Gerber files to ./gerbers/"
|
||||
```
|
||||
|
||||
## Status Summary
|
||||
|
||||
✅ **Router Pattern: IMPLEMENTED**
|
||||
✅ **Build: PASSING**
|
||||
✅ **Backwards Compatible: YES**
|
||||
⏳ **Token Optimization: PENDING (Phase 2)**
|
||||
|
||||
The router infrastructure is complete and functional. The system now supports tool discovery and organized access to all 59 tools. Phase 2 optimization (hiding routed tools) can be implemented when ready for maximum token savings.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,125 +1,133 @@
|
||||
# Schematic Workflow Fix - Issue #26
|
||||
|
||||
## Problem Summary
|
||||
|
||||
The schematic workflow was completely broken due to incorrect usage of the kicad-skip library:
|
||||
|
||||
1. **`create_project`** only created PCB files, no schematic
|
||||
2. **`create_schematic`** created orphaned schematic files not linked to projects
|
||||
3. **`add_schematic_component`** called non-existent `schematic.add_symbol()` method
|
||||
4. Project files didn't reference schematics in their structure
|
||||
|
||||
## Root Cause
|
||||
|
||||
The kicad-skip library **does not support creating symbols from scratch**. The only way to add symbols is by **cloning existing symbol instances**.
|
||||
|
||||
From kicad-skip documentation:
|
||||
> "symbols: these don't have a new()" because they require complex mappings to library elements, pins, and properties.
|
||||
|
||||
## Solution
|
||||
|
||||
### 1. Template-Based Approach
|
||||
|
||||
Created a template schematic (`python/templates/template_with_symbols.kicad_sch`) with:
|
||||
- Complete `lib_symbols` section defining R, C, LED symbols
|
||||
- Three template symbol instances placed off-screen at (-100, -110, -120)
|
||||
- Template symbols marked as `dnp yes`, `in_bom no`, `on_board no` so they don't interfere
|
||||
|
||||
### 2. Updated Files
|
||||
|
||||
**python/commands/project.py:**
|
||||
- Now creates both `.kicad_pcb` AND `.kicad_sch` files
|
||||
- Project file includes schematic reference in `sheets` array
|
||||
- Copies template schematic with cloneable symbols
|
||||
|
||||
**python/commands/schematic.py:**
|
||||
- Uses template file instead of creating from scratch
|
||||
- Proper minimal schematic structure when template unavailable
|
||||
|
||||
**python/commands/component_schematic.py:**
|
||||
- Completely rewritten to use `clone()` API
|
||||
- Maps component types to template symbols
|
||||
- Proper UUID generation for each cloned symbol
|
||||
- Correct position setting: `symbol.at.value = [x, y, rotation]`
|
||||
|
||||
### 3. Correct Workflow
|
||||
|
||||
```python
|
||||
from commands.project import ProjectCommands
|
||||
from commands.schematic import SchematicManager
|
||||
from commands.component_schematic import ComponentManager
|
||||
|
||||
# Step 1: Create project (creates both PCB and schematic)
|
||||
project_cmd = ProjectCommands()
|
||||
result = project_cmd.create_project({
|
||||
"name": "MyProject",
|
||||
"path": "/path/to/project"
|
||||
})
|
||||
|
||||
# Step 2: Load the schematic
|
||||
sch = SchematicManager.load_schematic(result['project']['schematicPath'])
|
||||
|
||||
# Step 3: Add components by cloning templates
|
||||
component_def = {
|
||||
"type": "R", # Maps to _TEMPLATE_R
|
||||
"reference": "R1", # Component reference
|
||||
"value": "10k", # Component value
|
||||
"footprint": "Resistor_SMD:R_0603_1608Metric",
|
||||
"x": 50.8, # Position in mm
|
||||
"y": 50.8, # Position in mm
|
||||
"rotation": 0 # Rotation in degrees
|
||||
}
|
||||
symbol = ComponentManager.add_component(sch, component_def)
|
||||
|
||||
# Step 4: Save the schematic
|
||||
SchematicManager.save_schematic(sch, result['project']['schematicPath'])
|
||||
```
|
||||
|
||||
## Supported Component Types
|
||||
|
||||
Currently supported template symbols:
|
||||
- `R` - Resistor (maps to `_TEMPLATE_R`)
|
||||
- `C` - Capacitor (maps to `_TEMPLATE_C`)
|
||||
- `D` or `LED` - LED (maps to `_TEMPLATE_D`)
|
||||
|
||||
To add more component types, update:
|
||||
1. `python/templates/template_with_symbols.kicad_sch` - Add lib_symbol definition and template instance
|
||||
2. `python/commands/component_schematic.py` - Add mapping in `TEMPLATE_MAP`
|
||||
|
||||
## Testing
|
||||
|
||||
Comprehensive test created at `/tmp/test_schematic_workflow.py`:
|
||||
- Creates project with schematic
|
||||
- Loads schematic
|
||||
- Adds R, C, LED components
|
||||
- Saves schematic
|
||||
- Validates with `kicad-cli sch export pdf`
|
||||
|
||||
All tests passing ✓
|
||||
|
||||
## Files Modified
|
||||
|
||||
- `python/commands/project.py` - Added schematic creation
|
||||
- `python/commands/schematic.py` - Fixed template usage
|
||||
- `python/commands/component_schematic.py` - Rewritten to use clone() API
|
||||
- `python/templates/empty.kicad_sch` - Minimal template (created)
|
||||
- `python/templates/template_with_symbols.kicad_sch` - Template with cloneable symbols (created)
|
||||
|
||||
## Limitations
|
||||
|
||||
1. Can only add components that have templates defined
|
||||
2. Template symbols remain in schematic (but marked as DNP/not in BOM)
|
||||
3. Complex symbols (multi-unit, hierarchical) may need custom templates
|
||||
|
||||
## Future Improvements
|
||||
|
||||
1. Add more component templates (transistors, connectors, ICs)
|
||||
2. Dynamic template generation from KiCad symbol libraries
|
||||
3. Auto-hide template symbols in schematic
|
||||
4. Support for custom user templates
|
||||
|
||||
## References
|
||||
|
||||
- GitHub Issue: #26
|
||||
- kicad-skip documentation: https://github.com/psychogenic/kicad-skip
|
||||
- Test results: `/tmp/test_schematic_workflow/`
|
||||
# Schematic Workflow Fix - Issue #26
|
||||
|
||||
## Problem Summary
|
||||
|
||||
The schematic workflow was completely broken due to incorrect usage of the kicad-skip library:
|
||||
|
||||
1. **`create_project`** only created PCB files, no schematic
|
||||
2. **`create_schematic`** created orphaned schematic files not linked to projects
|
||||
3. **`add_schematic_component`** called non-existent `schematic.add_symbol()` method
|
||||
4. Project files didn't reference schematics in their structure
|
||||
|
||||
## Root Cause
|
||||
|
||||
The kicad-skip library **does not support creating symbols from scratch**. The only way to add symbols is by **cloning existing symbol instances**.
|
||||
|
||||
From kicad-skip documentation:
|
||||
|
||||
> "symbols: these don't have a new()" because they require complex mappings to library elements, pins, and properties.
|
||||
|
||||
## Solution
|
||||
|
||||
### 1. Template-Based Approach
|
||||
|
||||
Created a template schematic (`python/templates/template_with_symbols.kicad_sch`) with:
|
||||
|
||||
- Complete `lib_symbols` section defining R, C, LED symbols
|
||||
- Three template symbol instances placed off-screen at (-100, -110, -120)
|
||||
- Template symbols marked as `dnp yes`, `in_bom no`, `on_board no` so they don't interfere
|
||||
|
||||
### 2. Updated Files
|
||||
|
||||
**python/commands/project.py:**
|
||||
|
||||
- Now creates both `.kicad_pcb` AND `.kicad_sch` files
|
||||
- Project file includes schematic reference in `sheets` array
|
||||
- Copies template schematic with cloneable symbols
|
||||
|
||||
**python/commands/schematic.py:**
|
||||
|
||||
- Uses template file instead of creating from scratch
|
||||
- Proper minimal schematic structure when template unavailable
|
||||
|
||||
**python/commands/component_schematic.py:**
|
||||
|
||||
- Completely rewritten to use `clone()` API
|
||||
- Maps component types to template symbols
|
||||
- Proper UUID generation for each cloned symbol
|
||||
- Correct position setting: `symbol.at.value = [x, y, rotation]`
|
||||
|
||||
### 3. Correct Workflow
|
||||
|
||||
```python
|
||||
from commands.project import ProjectCommands
|
||||
from commands.schematic import SchematicManager
|
||||
from commands.component_schematic import ComponentManager
|
||||
|
||||
# Step 1: Create project (creates both PCB and schematic)
|
||||
project_cmd = ProjectCommands()
|
||||
result = project_cmd.create_project({
|
||||
"name": "MyProject",
|
||||
"path": "/path/to/project"
|
||||
})
|
||||
|
||||
# Step 2: Load the schematic
|
||||
sch = SchematicManager.load_schematic(result['project']['schematicPath'])
|
||||
|
||||
# Step 3: Add components by cloning templates
|
||||
component_def = {
|
||||
"type": "R", # Maps to _TEMPLATE_R
|
||||
"reference": "R1", # Component reference
|
||||
"value": "10k", # Component value
|
||||
"footprint": "Resistor_SMD:R_0603_1608Metric",
|
||||
"x": 50.8, # Position in mm
|
||||
"y": 50.8, # Position in mm
|
||||
"rotation": 0 # Rotation in degrees
|
||||
}
|
||||
symbol = ComponentManager.add_component(sch, component_def)
|
||||
|
||||
# Step 4: Save the schematic
|
||||
SchematicManager.save_schematic(sch, result['project']['schematicPath'])
|
||||
```
|
||||
|
||||
## Supported Component Types
|
||||
|
||||
Currently supported template symbols:
|
||||
|
||||
- `R` - Resistor (maps to `_TEMPLATE_R`)
|
||||
- `C` - Capacitor (maps to `_TEMPLATE_C`)
|
||||
- `D` or `LED` - LED (maps to `_TEMPLATE_D`)
|
||||
|
||||
To add more component types, update:
|
||||
|
||||
1. `python/templates/template_with_symbols.kicad_sch` - Add lib_symbol definition and template instance
|
||||
2. `python/commands/component_schematic.py` - Add mapping in `TEMPLATE_MAP`
|
||||
|
||||
## Testing
|
||||
|
||||
Comprehensive test created at `/tmp/test_schematic_workflow.py`:
|
||||
|
||||
- Creates project with schematic
|
||||
- Loads schematic
|
||||
- Adds R, C, LED components
|
||||
- Saves schematic
|
||||
- Validates with `kicad-cli sch export pdf`
|
||||
|
||||
All tests passing ✓
|
||||
|
||||
## Files Modified
|
||||
|
||||
- `python/commands/project.py` - Added schematic creation
|
||||
- `python/commands/schematic.py` - Fixed template usage
|
||||
- `python/commands/component_schematic.py` - Rewritten to use clone() API
|
||||
- `python/templates/empty.kicad_sch` - Minimal template (created)
|
||||
- `python/templates/template_with_symbols.kicad_sch` - Template with cloneable symbols (created)
|
||||
|
||||
## Limitations
|
||||
|
||||
1. Can only add components that have templates defined
|
||||
2. Template symbols remain in schematic (but marked as DNP/not in BOM)
|
||||
3. Complex symbols (multi-unit, hierarchical) may need custom templates
|
||||
|
||||
## Future Improvements
|
||||
|
||||
1. Add more component templates (transistors, connectors, ICs)
|
||||
2. Dynamic template generation from KiCad symbol libraries
|
||||
3. Auto-hide template symbols in schematic
|
||||
4. Support for custom user templates
|
||||
|
||||
## References
|
||||
|
||||
- GitHub Issue: #26
|
||||
- kicad-skip documentation: https://github.com/psychogenic/kicad-skip
|
||||
- Test results: `/tmp/test_schematic_workflow/`
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,422 +1,457 @@
|
||||
# Week 1 - Session 2 Summary
|
||||
**Date:** October 25, 2025 (Afternoon)
|
||||
**Status:** 🚀 **OUTSTANDING PROGRESS**
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Session Goals
|
||||
|
||||
Continue Week 1 implementation while user installs KiCAD:
|
||||
1. Update README with comprehensive Linux guide
|
||||
2. Create installation scripts
|
||||
3. Begin IPC API preparation
|
||||
4. Set up development infrastructure
|
||||
|
||||
---
|
||||
|
||||
## ✅ Completed Work
|
||||
|
||||
### 1. **README.md Major Update** 📚
|
||||
|
||||
**File:** `README.md`
|
||||
|
||||
**Changes:**
|
||||
- ✅ Updated project status to reflect v2.0 rebuild
|
||||
- ✅ Added collapsible platform-specific installation sections:
|
||||
- 🐧 **Linux (Ubuntu/Debian)** - Primary, detailed
|
||||
- 🪟 **Windows 10/11** - Fully supported
|
||||
- 🍎 **macOS** - Experimental
|
||||
- ✅ Updated system requirements (Linux primary platform)
|
||||
- ✅ Added Quick Start section with test commands
|
||||
- ✅ Better visual organization with emojis and status indicators
|
||||
|
||||
**Impact:** New users can now install on Linux in < 10 minutes!
|
||||
|
||||
---
|
||||
|
||||
### 2. **Linux Installation Script** 🛠️
|
||||
|
||||
**File:** `scripts/install-linux.sh`
|
||||
|
||||
**Features:**
|
||||
- ✅ Fully automated Ubuntu/Debian installation
|
||||
- ✅ Color-coded output (info/success/warning/error)
|
||||
- ✅ Safety checks (platform detection, command validation)
|
||||
- ✅ Installs:
|
||||
- KiCAD 9.0 from PPA
|
||||
- Node.js 20.x
|
||||
- Python dependencies
|
||||
- Builds TypeScript
|
||||
- ✅ Verification checks after installation
|
||||
- ✅ Helpful next-steps guidance
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
cd kicad-mcp-server
|
||||
./scripts/install-linux.sh
|
||||
```
|
||||
|
||||
**Lines of Code:** ~200 lines of robust shell script
|
||||
|
||||
---
|
||||
|
||||
### 3. **Pre-Commit Hooks Configuration** 🔧
|
||||
|
||||
**File:** `.pre-commit-config.yaml`
|
||||
|
||||
**Hooks Added:**
|
||||
- ✅ **Python:**
|
||||
- Black (code formatting)
|
||||
- isort (import sorting)
|
||||
- MyPy (type checking)
|
||||
- Flake8 (linting)
|
||||
- Bandit (security checks)
|
||||
- ✅ **TypeScript/JavaScript:**
|
||||
- Prettier (formatting)
|
||||
- ✅ **General:**
|
||||
- Trailing whitespace removal
|
||||
- End-of-file fixer
|
||||
- YAML/JSON validation
|
||||
- Large file detection
|
||||
- Merge conflict detection
|
||||
- Private key detection
|
||||
- ✅ **Markdown:**
|
||||
- Markdownlint (formatting)
|
||||
|
||||
**Setup:**
|
||||
```bash
|
||||
pip install pre-commit
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
**Impact:** Automatic code quality enforcement on every commit!
|
||||
|
||||
---
|
||||
|
||||
### 4. **IPC API Migration Plan** 📋
|
||||
|
||||
**File:** `docs/IPC_API_MIGRATION_PLAN.md`
|
||||
|
||||
**Comprehensive 30-page migration guide:**
|
||||
- ✅ Why migrate (SWIG deprecation analysis)
|
||||
- ✅ IPC API architecture overview
|
||||
- ✅ 4-phase migration strategy (10 days)
|
||||
- ✅ API comparison tables (SWIG vs IPC)
|
||||
- ✅ Testing strategy
|
||||
- ✅ Rollback plan
|
||||
- ✅ Success criteria
|
||||
- ✅ Timeline with day-by-day tasks
|
||||
|
||||
**Key Insights:**
|
||||
- SWIG will be removed in KiCAD 10.0
|
||||
- IPC is faster for some operations
|
||||
- Protocol Buffers ensure API stability
|
||||
- Multi-language support opens future possibilities
|
||||
|
||||
---
|
||||
|
||||
### 5. **IPC API Abstraction Layer** 🏗️
|
||||
|
||||
**New Module:** `python/kicad_api/`
|
||||
|
||||
**Files Created (5):**
|
||||
|
||||
1. **`__init__.py`** (20 lines)
|
||||
- Package exports
|
||||
- Version info
|
||||
- Usage examples
|
||||
|
||||
2. **`base.py`** (180 lines)
|
||||
- `KiCADBackend` abstract base class
|
||||
- `BoardAPI` abstract interface
|
||||
- Custom exceptions (`BackendError`, `ConnectionError`, etc.)
|
||||
- Defines contract for all backends
|
||||
|
||||
3. **`factory.py`** (160 lines)
|
||||
- `create_backend()` - Smart backend selection
|
||||
- Auto-detection (try IPC, fall back to SWIG)
|
||||
- Environment variable support (`KICAD_BACKEND`)
|
||||
- `get_available_backends()` - Diagnostic function
|
||||
- Comprehensive error handling
|
||||
|
||||
4. **`ipc_backend.py`** (210 lines)
|
||||
- `IPCBackend` class (kicad-python wrapper)
|
||||
- `IPCBoardAPI` class
|
||||
- Connection management
|
||||
- Skeleton methods (to be implemented in Week 2-3)
|
||||
- Clear TODO markers for migration
|
||||
|
||||
5. **`swig_backend.py`** (220 lines)
|
||||
- `SWIGBackend` class (wraps existing code)
|
||||
- `SWIGBoardAPI` class
|
||||
- Backward compatibility layer
|
||||
- Deprecation warnings
|
||||
- Bridges old commands to new interface
|
||||
|
||||
**Total Lines of Code:** ~800 lines
|
||||
|
||||
**Architecture:**
|
||||
```python
|
||||
from kicad_api import create_backend
|
||||
|
||||
# Auto-detect best backend
|
||||
backend = create_backend()
|
||||
|
||||
# Or specify explicitly
|
||||
backend = create_backend('ipc') # Use IPC
|
||||
backend = create_backend('swig') # Use SWIG (deprecated)
|
||||
|
||||
# Use unified interface
|
||||
if backend.connect():
|
||||
board = backend.get_board()
|
||||
board.set_size(100, 80)
|
||||
```
|
||||
|
||||
**Key Features:**
|
||||
- ✅ Abstraction allows painless migration
|
||||
- ✅ Both backends can coexist during transition
|
||||
- ✅ Easy testing (compare SWIG vs IPC outputs)
|
||||
- ✅ Future-proof (add new backends easily)
|
||||
- ✅ Type hints throughout
|
||||
- ✅ Comprehensive error handling
|
||||
|
||||
---
|
||||
|
||||
### 6. **Enhanced package.json** 📦
|
||||
|
||||
**File:** `package.json`
|
||||
|
||||
**Improvements:**
|
||||
- ✅ Version bumped to `2.0.0-alpha.1`
|
||||
- ✅ Better description
|
||||
- ✅ Enhanced npm scripts:
|
||||
```json
|
||||
"build:watch": "tsc --watch"
|
||||
"clean": "rm -rf dist"
|
||||
"rebuild": "npm run clean && npm run build"
|
||||
"test": "npm run test:ts && npm run test:py"
|
||||
"test:py": "pytest tests/ -v"
|
||||
"test:coverage": "pytest with coverage"
|
||||
"lint": "npm run lint:ts && npm run lint:py"
|
||||
"lint:py": "black + mypy + flake8"
|
||||
"format": "prettier + black"
|
||||
```
|
||||
|
||||
**Impact:** Better developer experience, easier workflows
|
||||
|
||||
---
|
||||
|
||||
## 📊 Statistics
|
||||
|
||||
### Files Created/Modified (Session 2)
|
||||
|
||||
**New Files (10):**
|
||||
```
|
||||
docs/IPC_API_MIGRATION_PLAN.md # 500+ lines
|
||||
docs/WEEK1_SESSION2_SUMMARY.md # This file
|
||||
scripts/install-linux.sh # 200 lines
|
||||
.pre-commit-config.yaml # 60 lines
|
||||
python/kicad_api/__init__.py # 20 lines
|
||||
python/kicad_api/base.py # 180 lines
|
||||
python/kicad_api/factory.py # 160 lines
|
||||
python/kicad_api/ipc_backend.py # 210 lines
|
||||
python/kicad_api/swig_backend.py # 220 lines
|
||||
```
|
||||
|
||||
**Modified Files (2):**
|
||||
```
|
||||
README.md # Major rewrite
|
||||
package.json # Enhanced scripts
|
||||
```
|
||||
|
||||
**Total New Lines:** ~1,600+ lines of code/documentation
|
||||
|
||||
---
|
||||
|
||||
### Combined Sessions 1+2 Today
|
||||
|
||||
**Files Created:** 27
|
||||
**Lines Written:** ~3,000+
|
||||
**Documentation Pages:** 8
|
||||
**Tests Created:** 20+
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Week 1 Status
|
||||
|
||||
### Progress: **95% Complete** ████████████░
|
||||
|
||||
| Task | Status |
|
||||
|------|--------|
|
||||
| Linux compatibility | ✅ Complete |
|
||||
| CI/CD pipeline | ✅ Complete |
|
||||
| Cross-platform paths | ✅ Complete |
|
||||
| Developer docs | ✅ Complete |
|
||||
| pytest framework | ✅ Complete |
|
||||
| Config templates | ✅ Complete |
|
||||
| Installation scripts | ✅ Complete |
|
||||
| Pre-commit hooks | ✅ Complete |
|
||||
| IPC migration plan | ✅ Complete |
|
||||
| IPC abstraction layer | ✅ Complete |
|
||||
| README updates | ✅ Complete |
|
||||
| Testing on Ubuntu | ⏳ Pending (needs KiCAD install) |
|
||||
|
||||
**Only Remaining:** Test with actual KiCAD 9.0 installation!
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Ready for Week 2
|
||||
|
||||
### IPC API Migration Prep ✅
|
||||
|
||||
Everything is in place to begin migration:
|
||||
- ✅ Abstraction layer architecture defined
|
||||
- ✅ Base classes and interfaces ready
|
||||
- ✅ Factory pattern for backend selection
|
||||
- ✅ SWIG wrapper for backward compatibility
|
||||
- ✅ IPC skeleton awaiting implementation
|
||||
- ✅ Comprehensive migration plan documented
|
||||
|
||||
**Week 2 kickoff tasks:**
|
||||
1. Install `kicad-python` package
|
||||
2. Test IPC connection to running KiCAD
|
||||
3. Begin porting `project.py` module
|
||||
4. Create side-by-side tests (SWIG vs IPC)
|
||||
|
||||
---
|
||||
|
||||
## 💡 Key Insights from Session 2
|
||||
|
||||
### 1. **Installation Automation**
|
||||
The bash script reduces setup time from 30+ minutes to < 10 minutes with zero manual intervention.
|
||||
|
||||
### 2. **Pre-Commit Hooks**
|
||||
Automatic code quality checks prevent bugs before they're committed. This will save hours in code review.
|
||||
|
||||
### 3. **Abstraction Pattern**
|
||||
The backend abstraction is elegant - allows gradual migration without breaking existing functionality. Users won't notice the transition.
|
||||
|
||||
### 4. **Documentation Quality**
|
||||
The IPC migration plan is thorough enough that another developer could execute it independently.
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing Readiness
|
||||
|
||||
### When KiCAD is Installed
|
||||
|
||||
You can immediately test:
|
||||
|
||||
**1. Platform Helper:**
|
||||
```bash
|
||||
python3 python/utils/platform_helper.py
|
||||
```
|
||||
|
||||
**2. Backend Detection:**
|
||||
```bash
|
||||
python3 python/kicad_api/factory.py
|
||||
```
|
||||
|
||||
**3. Installation Script:**
|
||||
```bash
|
||||
./scripts/install-linux.sh
|
||||
```
|
||||
|
||||
**4. Pytest Suite:**
|
||||
```bash
|
||||
pytest tests/ -v
|
||||
```
|
||||
|
||||
**5. Pre-commit Hooks:**
|
||||
```bash
|
||||
pre-commit run --all-files
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Impact Assessment
|
||||
|
||||
### Developer Onboarding
|
||||
- **Before:** 2-3 hours setup, Windows-only, manual steps
|
||||
- **After:** 10 minutes automated, cross-platform, one script
|
||||
|
||||
### Code Quality
|
||||
- **Before:** No automated checks, inconsistent style
|
||||
- **After:** Pre-commit hooks, 100% type hints, Black formatting
|
||||
|
||||
### Future-Proofing
|
||||
- **Before:** Deprecated SWIG API, no migration path
|
||||
- **After:** IPC API ready, abstraction layer in place
|
||||
|
||||
### Documentation
|
||||
- **Before:** README only, Windows-focused
|
||||
- **After:** 8 comprehensive docs, Linux-primary, migration guides
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Next Actions
|
||||
|
||||
### Immediate (Tonight/Tomorrow)
|
||||
1. Install KiCAD 9.0 on your system
|
||||
2. Run `./scripts/install-linux.sh`
|
||||
3. Test backend detection
|
||||
4. Verify pytest suite passes
|
||||
|
||||
### Week 2 Start (Monday)
|
||||
1. Install `kicad-python` package
|
||||
2. Test IPC connection
|
||||
3. Begin project.py migration
|
||||
4. Create first IPC API tests
|
||||
|
||||
---
|
||||
|
||||
## 🏆 Session 2 Achievements
|
||||
|
||||
### Infrastructure
|
||||
- ✅ Automated Linux installation
|
||||
- ✅ Pre-commit hooks for code quality
|
||||
- ✅ Enhanced npm scripts
|
||||
- ✅ IPC API abstraction layer (800+ lines)
|
||||
|
||||
### Documentation
|
||||
- ✅ Updated README (Linux-primary)
|
||||
- ✅ 30-page IPC migration plan
|
||||
- ✅ Session summaries
|
||||
|
||||
### Architecture
|
||||
- ✅ Backend abstraction pattern
|
||||
- ✅ Factory with auto-detection
|
||||
- ✅ SWIG backward compatibility
|
||||
- ✅ IPC skeleton ready for implementation
|
||||
|
||||
---
|
||||
|
||||
## 🎉 Overall Day Summary
|
||||
|
||||
**Sessions 1+2 Combined:**
|
||||
- ⏱️ **Time:** ~4-5 hours total
|
||||
- 📝 **Files:** 27 created
|
||||
- 💻 **Code:** ~3,000+ lines
|
||||
- 📚 **Docs:** 8 comprehensive pages
|
||||
- 🧪 **Tests:** 20+ unit tests
|
||||
- ✅ **Week 1:** 95% complete
|
||||
|
||||
**Status:** 🟢 **AHEAD OF SCHEDULE**
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Momentum Check
|
||||
|
||||
**Energy Level:** 🔋🔋🔋🔋🔋 (Maximum)
|
||||
**Code Quality:** ⭐⭐⭐⭐⭐ (Excellent)
|
||||
**Documentation:** 📖📖📖📖📖 (Comprehensive)
|
||||
**Architecture:** 🏗️🏗️🏗️🏗️🏗️ (Solid)
|
||||
|
||||
**Ready for Week 2 IPC Migration:** ✅ YES!
|
||||
|
||||
---
|
||||
|
||||
**End of Session 2**
|
||||
**Next:** KiCAD installation + testing + Week 2 kickoff
|
||||
|
||||
Let's keep this incredible momentum going! 🎉🚀
|
||||
# Week 1 - Session 2 Summary
|
||||
|
||||
**Date:** October 25, 2025 (Afternoon)
|
||||
**Status:** 🚀 **OUTSTANDING PROGRESS**
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Session Goals
|
||||
|
||||
Continue Week 1 implementation while user installs KiCAD:
|
||||
|
||||
1. Update README with comprehensive Linux guide
|
||||
2. Create installation scripts
|
||||
3. Begin IPC API preparation
|
||||
4. Set up development infrastructure
|
||||
|
||||
---
|
||||
|
||||
## ✅ Completed Work
|
||||
|
||||
### 1. **README.md Major Update** 📚
|
||||
|
||||
**File:** `README.md`
|
||||
|
||||
**Changes:**
|
||||
|
||||
- ✅ Updated project status to reflect v2.0 rebuild
|
||||
- ✅ Added collapsible platform-specific installation sections:
|
||||
- 🐧 **Linux (Ubuntu/Debian)** - Primary, detailed
|
||||
- 🪟 **Windows 10/11** - Fully supported
|
||||
- 🍎 **macOS** - Experimental
|
||||
- ✅ Updated system requirements (Linux primary platform)
|
||||
- ✅ Added Quick Start section with test commands
|
||||
- ✅ Better visual organization with emojis and status indicators
|
||||
|
||||
**Impact:** New users can now install on Linux in < 10 minutes!
|
||||
|
||||
---
|
||||
|
||||
### 2. **Linux Installation Script** 🛠️
|
||||
|
||||
**File:** `scripts/install-linux.sh`
|
||||
|
||||
**Features:**
|
||||
|
||||
- ✅ Fully automated Ubuntu/Debian installation
|
||||
- ✅ Color-coded output (info/success/warning/error)
|
||||
- ✅ Safety checks (platform detection, command validation)
|
||||
- ✅ Installs:
|
||||
- KiCAD 9.0 from PPA
|
||||
- Node.js 20.x
|
||||
- Python dependencies
|
||||
- Builds TypeScript
|
||||
- ✅ Verification checks after installation
|
||||
- ✅ Helpful next-steps guidance
|
||||
|
||||
**Usage:**
|
||||
|
||||
```bash
|
||||
cd kicad-mcp-server
|
||||
./scripts/install-linux.sh
|
||||
```
|
||||
|
||||
**Lines of Code:** ~200 lines of robust shell script
|
||||
|
||||
---
|
||||
|
||||
### 3. **Pre-Commit Hooks Configuration** 🔧
|
||||
|
||||
**File:** `.pre-commit-config.yaml`
|
||||
|
||||
**Hooks Added:**
|
||||
|
||||
- ✅ **Python:**
|
||||
- Black (code formatting)
|
||||
- isort (import sorting)
|
||||
- MyPy (type checking)
|
||||
- Flake8 (linting)
|
||||
- Bandit (security checks)
|
||||
- ✅ **TypeScript/JavaScript:**
|
||||
- Prettier (formatting)
|
||||
- ✅ **General:**
|
||||
- Trailing whitespace removal
|
||||
- End-of-file fixer
|
||||
- YAML/JSON validation
|
||||
- Large file detection
|
||||
- Merge conflict detection
|
||||
- Private key detection
|
||||
- ✅ **Markdown:**
|
||||
- Markdownlint (formatting)
|
||||
|
||||
**Setup:**
|
||||
|
||||
```bash
|
||||
pip install pre-commit
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
**Impact:** Automatic code quality enforcement on every commit!
|
||||
|
||||
---
|
||||
|
||||
### 4. **IPC API Migration Plan** 📋
|
||||
|
||||
**File:** `docs/IPC_API_MIGRATION_PLAN.md`
|
||||
|
||||
**Comprehensive 30-page migration guide:**
|
||||
|
||||
- ✅ Why migrate (SWIG deprecation analysis)
|
||||
- ✅ IPC API architecture overview
|
||||
- ✅ 4-phase migration strategy (10 days)
|
||||
- ✅ API comparison tables (SWIG vs IPC)
|
||||
- ✅ Testing strategy
|
||||
- ✅ Rollback plan
|
||||
- ✅ Success criteria
|
||||
- ✅ Timeline with day-by-day tasks
|
||||
|
||||
**Key Insights:**
|
||||
|
||||
- SWIG will be removed in KiCAD 10.0
|
||||
- IPC is faster for some operations
|
||||
- Protocol Buffers ensure API stability
|
||||
- Multi-language support opens future possibilities
|
||||
|
||||
---
|
||||
|
||||
### 5. **IPC API Abstraction Layer** 🏗️
|
||||
|
||||
**New Module:** `python/kicad_api/`
|
||||
|
||||
**Files Created (5):**
|
||||
|
||||
1. **`__init__.py`** (20 lines)
|
||||
- Package exports
|
||||
- Version info
|
||||
- Usage examples
|
||||
|
||||
2. **`base.py`** (180 lines)
|
||||
- `KiCADBackend` abstract base class
|
||||
- `BoardAPI` abstract interface
|
||||
- Custom exceptions (`BackendError`, `ConnectionError`, etc.)
|
||||
- Defines contract for all backends
|
||||
|
||||
3. **`factory.py`** (160 lines)
|
||||
- `create_backend()` - Smart backend selection
|
||||
- Auto-detection (try IPC, fall back to SWIG)
|
||||
- Environment variable support (`KICAD_BACKEND`)
|
||||
- `get_available_backends()` - Diagnostic function
|
||||
- Comprehensive error handling
|
||||
|
||||
4. **`ipc_backend.py`** (210 lines)
|
||||
- `IPCBackend` class (kicad-python wrapper)
|
||||
- `IPCBoardAPI` class
|
||||
- Connection management
|
||||
- Skeleton methods (to be implemented in Week 2-3)
|
||||
- Clear TODO markers for migration
|
||||
|
||||
5. **`swig_backend.py`** (220 lines)
|
||||
- `SWIGBackend` class (wraps existing code)
|
||||
- `SWIGBoardAPI` class
|
||||
- Backward compatibility layer
|
||||
- Deprecation warnings
|
||||
- Bridges old commands to new interface
|
||||
|
||||
**Total Lines of Code:** ~800 lines
|
||||
|
||||
**Architecture:**
|
||||
|
||||
```python
|
||||
from kicad_api import create_backend
|
||||
|
||||
# Auto-detect best backend
|
||||
backend = create_backend()
|
||||
|
||||
# Or specify explicitly
|
||||
backend = create_backend('ipc') # Use IPC
|
||||
backend = create_backend('swig') # Use SWIG (deprecated)
|
||||
|
||||
# Use unified interface
|
||||
if backend.connect():
|
||||
board = backend.get_board()
|
||||
board.set_size(100, 80)
|
||||
```
|
||||
|
||||
**Key Features:**
|
||||
|
||||
- ✅ Abstraction allows painless migration
|
||||
- ✅ Both backends can coexist during transition
|
||||
- ✅ Easy testing (compare SWIG vs IPC outputs)
|
||||
- ✅ Future-proof (add new backends easily)
|
||||
- ✅ Type hints throughout
|
||||
- ✅ Comprehensive error handling
|
||||
|
||||
---
|
||||
|
||||
### 6. **Enhanced package.json** 📦
|
||||
|
||||
**File:** `package.json`
|
||||
|
||||
**Improvements:**
|
||||
|
||||
- ✅ Version bumped to `2.0.0-alpha.1`
|
||||
- ✅ Better description
|
||||
- ✅ Enhanced npm scripts:
|
||||
```json
|
||||
"build:watch": "tsc --watch"
|
||||
"clean": "rm -rf dist"
|
||||
"rebuild": "npm run clean && npm run build"
|
||||
"test": "npm run test:ts && npm run test:py"
|
||||
"test:py": "pytest tests/ -v"
|
||||
"test:coverage": "pytest with coverage"
|
||||
"lint": "npm run lint:ts && npm run lint:py"
|
||||
"lint:py": "black + mypy + flake8"
|
||||
"format": "prettier + black"
|
||||
```
|
||||
|
||||
**Impact:** Better developer experience, easier workflows
|
||||
|
||||
---
|
||||
|
||||
## 📊 Statistics
|
||||
|
||||
### Files Created/Modified (Session 2)
|
||||
|
||||
**New Files (10):**
|
||||
|
||||
```
|
||||
docs/IPC_API_MIGRATION_PLAN.md # 500+ lines
|
||||
docs/WEEK1_SESSION2_SUMMARY.md # This file
|
||||
scripts/install-linux.sh # 200 lines
|
||||
.pre-commit-config.yaml # 60 lines
|
||||
python/kicad_api/__init__.py # 20 lines
|
||||
python/kicad_api/base.py # 180 lines
|
||||
python/kicad_api/factory.py # 160 lines
|
||||
python/kicad_api/ipc_backend.py # 210 lines
|
||||
python/kicad_api/swig_backend.py # 220 lines
|
||||
```
|
||||
|
||||
**Modified Files (2):**
|
||||
|
||||
```
|
||||
README.md # Major rewrite
|
||||
package.json # Enhanced scripts
|
||||
```
|
||||
|
||||
**Total New Lines:** ~1,600+ lines of code/documentation
|
||||
|
||||
---
|
||||
|
||||
### Combined Sessions 1+2 Today
|
||||
|
||||
**Files Created:** 27
|
||||
**Lines Written:** ~3,000+
|
||||
**Documentation Pages:** 8
|
||||
**Tests Created:** 20+
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Week 1 Status
|
||||
|
||||
### Progress: **95% Complete** ████████████░
|
||||
|
||||
| Task | Status |
|
||||
| --------------------- | -------------------------------- |
|
||||
| Linux compatibility | ✅ Complete |
|
||||
| CI/CD pipeline | ✅ Complete |
|
||||
| Cross-platform paths | ✅ Complete |
|
||||
| Developer docs | ✅ Complete |
|
||||
| pytest framework | ✅ Complete |
|
||||
| Config templates | ✅ Complete |
|
||||
| Installation scripts | ✅ Complete |
|
||||
| Pre-commit hooks | ✅ Complete |
|
||||
| IPC migration plan | ✅ Complete |
|
||||
| IPC abstraction layer | ✅ Complete |
|
||||
| README updates | ✅ Complete |
|
||||
| Testing on Ubuntu | ⏳ Pending (needs KiCAD install) |
|
||||
|
||||
**Only Remaining:** Test with actual KiCAD 9.0 installation!
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Ready for Week 2
|
||||
|
||||
### IPC API Migration Prep ✅
|
||||
|
||||
Everything is in place to begin migration:
|
||||
|
||||
- ✅ Abstraction layer architecture defined
|
||||
- ✅ Base classes and interfaces ready
|
||||
- ✅ Factory pattern for backend selection
|
||||
- ✅ SWIG wrapper for backward compatibility
|
||||
- ✅ IPC skeleton awaiting implementation
|
||||
- ✅ Comprehensive migration plan documented
|
||||
|
||||
**Week 2 kickoff tasks:**
|
||||
|
||||
1. Install `kicad-python` package
|
||||
2. Test IPC connection to running KiCAD
|
||||
3. Begin porting `project.py` module
|
||||
4. Create side-by-side tests (SWIG vs IPC)
|
||||
|
||||
---
|
||||
|
||||
## 💡 Key Insights from Session 2
|
||||
|
||||
### 1. **Installation Automation**
|
||||
|
||||
The bash script reduces setup time from 30+ minutes to < 10 minutes with zero manual intervention.
|
||||
|
||||
### 2. **Pre-Commit Hooks**
|
||||
|
||||
Automatic code quality checks prevent bugs before they're committed. This will save hours in code review.
|
||||
|
||||
### 3. **Abstraction Pattern**
|
||||
|
||||
The backend abstraction is elegant - allows gradual migration without breaking existing functionality. Users won't notice the transition.
|
||||
|
||||
### 4. **Documentation Quality**
|
||||
|
||||
The IPC migration plan is thorough enough that another developer could execute it independently.
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing Readiness
|
||||
|
||||
### When KiCAD is Installed
|
||||
|
||||
You can immediately test:
|
||||
|
||||
**1. Platform Helper:**
|
||||
|
||||
```bash
|
||||
python3 python/utils/platform_helper.py
|
||||
```
|
||||
|
||||
**2. Backend Detection:**
|
||||
|
||||
```bash
|
||||
python3 python/kicad_api/factory.py
|
||||
```
|
||||
|
||||
**3. Installation Script:**
|
||||
|
||||
```bash
|
||||
./scripts/install-linux.sh
|
||||
```
|
||||
|
||||
**4. Pytest Suite:**
|
||||
|
||||
```bash
|
||||
pytest tests/ -v
|
||||
```
|
||||
|
||||
**5. Pre-commit Hooks:**
|
||||
|
||||
```bash
|
||||
pre-commit run --all-files
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Impact Assessment
|
||||
|
||||
### Developer Onboarding
|
||||
|
||||
- **Before:** 2-3 hours setup, Windows-only, manual steps
|
||||
- **After:** 10 minutes automated, cross-platform, one script
|
||||
|
||||
### Code Quality
|
||||
|
||||
- **Before:** No automated checks, inconsistent style
|
||||
- **After:** Pre-commit hooks, 100% type hints, Black formatting
|
||||
|
||||
### Future-Proofing
|
||||
|
||||
- **Before:** Deprecated SWIG API, no migration path
|
||||
- **After:** IPC API ready, abstraction layer in place
|
||||
|
||||
### Documentation
|
||||
|
||||
- **Before:** README only, Windows-focused
|
||||
- **After:** 8 comprehensive docs, Linux-primary, migration guides
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Next Actions
|
||||
|
||||
### Immediate (Tonight/Tomorrow)
|
||||
|
||||
1. Install KiCAD 9.0 on your system
|
||||
2. Run `./scripts/install-linux.sh`
|
||||
3. Test backend detection
|
||||
4. Verify pytest suite passes
|
||||
|
||||
### Week 2 Start (Monday)
|
||||
|
||||
1. Install `kicad-python` package
|
||||
2. Test IPC connection
|
||||
3. Begin project.py migration
|
||||
4. Create first IPC API tests
|
||||
|
||||
---
|
||||
|
||||
## 🏆 Session 2 Achievements
|
||||
|
||||
### Infrastructure
|
||||
|
||||
- ✅ Automated Linux installation
|
||||
- ✅ Pre-commit hooks for code quality
|
||||
- ✅ Enhanced npm scripts
|
||||
- ✅ IPC API abstraction layer (800+ lines)
|
||||
|
||||
### Documentation
|
||||
|
||||
- ✅ Updated README (Linux-primary)
|
||||
- ✅ 30-page IPC migration plan
|
||||
- ✅ Session summaries
|
||||
|
||||
### Architecture
|
||||
|
||||
- ✅ Backend abstraction pattern
|
||||
- ✅ Factory with auto-detection
|
||||
- ✅ SWIG backward compatibility
|
||||
- ✅ IPC skeleton ready for implementation
|
||||
|
||||
---
|
||||
|
||||
## 🎉 Overall Day Summary
|
||||
|
||||
**Sessions 1+2 Combined:**
|
||||
|
||||
- ⏱️ **Time:** ~4-5 hours total
|
||||
- 📝 **Files:** 27 created
|
||||
- 💻 **Code:** ~3,000+ lines
|
||||
- 📚 **Docs:** 8 comprehensive pages
|
||||
- 🧪 **Tests:** 20+ unit tests
|
||||
- ✅ **Week 1:** 95% complete
|
||||
|
||||
**Status:** 🟢 **AHEAD OF SCHEDULE**
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Momentum Check
|
||||
|
||||
**Energy Level:** 🔋🔋🔋🔋🔋 (Maximum)
|
||||
**Code Quality:** ⭐⭐⭐⭐⭐ (Excellent)
|
||||
**Documentation:** 📖📖📖📖📖 (Comprehensive)
|
||||
**Architecture:** 🏗️🏗️🏗️🏗️🏗️ (Solid)
|
||||
|
||||
**Ready for Week 2 IPC Migration:** ✅ YES!
|
||||
|
||||
---
|
||||
|
||||
**End of Session 2**
|
||||
**Next:** KiCAD installation + testing + Week 2 kickoff
|
||||
|
||||
Let's keep this incredible momentum going! 🎉🚀
|
||||
|
||||
@@ -108,25 +108,25 @@ export const toolCategories: ToolCategory[] = [
|
||||
properties: {
|
||||
output_dir: {
|
||||
type: "string",
|
||||
description: "Output directory path"
|
||||
description: "Output directory path",
|
||||
},
|
||||
layers: {
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
description: "Layers to export (default: all copper + silkscreen + mask)"
|
||||
description: "Layers to export (default: all copper + silkscreen + mask)",
|
||||
},
|
||||
format: {
|
||||
type: "string",
|
||||
enum: ["rs274x", "x2"],
|
||||
description: "Gerber format version"
|
||||
}
|
||||
description: "Gerber format version",
|
||||
},
|
||||
},
|
||||
required: ["output_dir"]
|
||||
required: ["output_dir"],
|
||||
},
|
||||
handler: async (params) => {
|
||||
// Your implementation
|
||||
return { success: true, files: ["..."] };
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "export_drill",
|
||||
@@ -135,24 +135,31 @@ export const toolCategories: ToolCategory[] = [
|
||||
type: "object",
|
||||
properties: {
|
||||
output_dir: { type: "string" },
|
||||
format: { type: "string", enum: ["excellon", "excellon2"] }
|
||||
format: { type: "string", enum: ["excellon", "excellon2"] },
|
||||
},
|
||||
required: ["output_dir"]
|
||||
required: ["output_dir"],
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
},
|
||||
{
|
||||
name: "export_bom",
|
||||
description: "Export bill of materials as CSV or XML",
|
||||
inputSchema: { /* ... */ },
|
||||
handler: async (params) => { /* ... */ }
|
||||
inputSchema: {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
},
|
||||
// ... more export tools
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "drc",
|
||||
description: "Design rule checking: clearance validation, electrical rules, manufacturing constraints",
|
||||
description:
|
||||
"Design rule checking: clearance validation, electrical rules, manufacturing constraints",
|
||||
tools: [
|
||||
{
|
||||
name: "run_drc",
|
||||
@@ -162,17 +169,21 @@ export const toolCategories: ToolCategory[] = [
|
||||
properties: {
|
||||
report_all: {
|
||||
type: "boolean",
|
||||
description: "Report all violations or stop at first"
|
||||
}
|
||||
}
|
||||
description: "Report all violations or stop at first",
|
||||
},
|
||||
},
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
},
|
||||
{
|
||||
name: "get_drc_errors",
|
||||
description: "Get current DRC violations without re-running check",
|
||||
inputSchema: { type: "object", properties: {} },
|
||||
handler: async (params) => { /* ... */ }
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "set_design_rules",
|
||||
@@ -183,12 +194,14 @@ export const toolCategories: ToolCategory[] = [
|
||||
min_clearance: { type: "number", description: "Minimum clearance in mm" },
|
||||
min_track_width: { type: "number", description: "Minimum track width in mm" },
|
||||
min_via_diameter: { type: "number", description: "Minimum via diameter in mm" },
|
||||
min_via_drill: { type: "number", description: "Minimum via drill size in mm" }
|
||||
}
|
||||
min_via_drill: { type: "number", description: "Minimum via drill size in mm" },
|
||||
},
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
}
|
||||
]
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "zones",
|
||||
@@ -208,22 +221,26 @@ export const toolCategories: ToolCategory[] = [
|
||||
type: "object",
|
||||
properties: {
|
||||
x: { type: "number" },
|
||||
y: { type: "number" }
|
||||
}
|
||||
y: { type: "number" },
|
||||
},
|
||||
},
|
||||
description: "Polygon vertices in mm"
|
||||
description: "Polygon vertices in mm",
|
||||
},
|
||||
priority: { type: "number", description: "Fill priority (higher fills first)" }
|
||||
priority: { type: "number", description: "Fill priority (higher fills first)" },
|
||||
},
|
||||
required: ["net_name", "layer", "points"]
|
||||
required: ["net_name", "layer", "points"],
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
},
|
||||
{
|
||||
name: "fill_zones",
|
||||
description: "Recalculate and fill all copper zones",
|
||||
inputSchema: { type: "object", properties: {} },
|
||||
handler: async (params) => { /* ... */ }
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "remove_zone",
|
||||
@@ -231,13 +248,15 @@ export const toolCategories: ToolCategory[] = [
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
zone_id: { type: "string", description: "Zone identifier" }
|
||||
zone_id: { type: "string", description: "Zone identifier" },
|
||||
},
|
||||
required: ["zone_id"]
|
||||
required: ["zone_id"],
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
}
|
||||
]
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Add more categories...
|
||||
];
|
||||
@@ -293,7 +312,7 @@ export function searchTools(query: string): Array<{
|
||||
matches.push({
|
||||
category: category.name,
|
||||
tool: tool.name,
|
||||
description: tool.description
|
||||
description: tool.description,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -313,12 +332,7 @@ These are the tools that enable discovery and execution.
|
||||
```typescript
|
||||
// src/tools/router.ts
|
||||
|
||||
import {
|
||||
getAllCategories,
|
||||
getCategory,
|
||||
getTool,
|
||||
searchTools
|
||||
} from "./registry.js";
|
||||
import { getAllCategories, getCategory, getTool, searchTools } from "./registry.js";
|
||||
|
||||
export const routerTools = {
|
||||
list_tool_categories: {
|
||||
@@ -329,20 +343,20 @@ export const routerTools = {
|
||||
inputSchema: {
|
||||
type: "object" as const,
|
||||
properties: {},
|
||||
required: []
|
||||
required: [],
|
||||
},
|
||||
handler: async () => {
|
||||
const categories = getAllCategories();
|
||||
return {
|
||||
total_categories: categories.length,
|
||||
total_tools: categories.reduce((sum, c) => sum + c.tools.length, 0),
|
||||
categories: categories.map(c => ({
|
||||
categories: categories.map((c) => ({
|
||||
name: c.name,
|
||||
description: c.description,
|
||||
tool_count: c.tools.length
|
||||
}))
|
||||
tool_count: c.tools.length,
|
||||
})),
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
get_category_tools: {
|
||||
@@ -356,29 +370,29 @@ export const routerTools = {
|
||||
properties: {
|
||||
category: {
|
||||
type: "string",
|
||||
description: "Category name from list_tool_categories"
|
||||
}
|
||||
description: "Category name from list_tool_categories",
|
||||
},
|
||||
},
|
||||
required: ["category"]
|
||||
required: ["category"],
|
||||
},
|
||||
handler: async (params: { category: string }) => {
|
||||
const category = getCategory(params.category);
|
||||
if (!category) {
|
||||
return {
|
||||
error: `Unknown category: ${params.category}`,
|
||||
available_categories: getAllCategories().map(c => c.name)
|
||||
available_categories: getAllCategories().map((c) => c.name),
|
||||
};
|
||||
}
|
||||
return {
|
||||
category: category.name,
|
||||
description: category.description,
|
||||
tools: category.tools.map(t => ({
|
||||
tools: category.tools.map((t) => ({
|
||||
name: t.name,
|
||||
description: t.description,
|
||||
parameters: t.inputSchema
|
||||
}))
|
||||
parameters: t.inputSchema,
|
||||
})),
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
execute_tool: {
|
||||
@@ -391,21 +405,21 @@ export const routerTools = {
|
||||
properties: {
|
||||
tool_name: {
|
||||
type: "string",
|
||||
description: "Tool name (from get_category_tools)"
|
||||
description: "Tool name (from get_category_tools)",
|
||||
},
|
||||
params: {
|
||||
type: "object",
|
||||
description: "Tool parameters (see get_category_tools for schema)"
|
||||
}
|
||||
description: "Tool parameters (see get_category_tools for schema)",
|
||||
},
|
||||
},
|
||||
required: ["tool_name"]
|
||||
required: ["tool_name"],
|
||||
},
|
||||
handler: async (input: { tool_name: string; params?: Record<string, unknown> }) => {
|
||||
const entry = getTool(input.tool_name);
|
||||
if (!entry) {
|
||||
return {
|
||||
error: `Unknown tool: ${input.tool_name}`,
|
||||
hint: "Use list_tool_categories and get_category_tools to find available tools"
|
||||
hint: "Use list_tool_categories and get_category_tools to find available tools",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -414,16 +428,16 @@ export const routerTools = {
|
||||
return {
|
||||
tool: input.tool_name,
|
||||
category: entry.category,
|
||||
result
|
||||
result,
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
error: `Tool execution failed: ${(err as Error).message}`,
|
||||
tool: input.tool_name,
|
||||
category: entry.category
|
||||
category: entry.category,
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
search_tools: {
|
||||
@@ -436,20 +450,20 @@ export const routerTools = {
|
||||
properties: {
|
||||
query: {
|
||||
type: "string",
|
||||
description: "Search term (e.g., 'gerber', 'zone', 'differential', 'export')"
|
||||
}
|
||||
description: "Search term (e.g., 'gerber', 'zone', 'differential', 'export')",
|
||||
},
|
||||
},
|
||||
required: ["query"]
|
||||
required: ["query"],
|
||||
},
|
||||
handler: async (params: { query: string }) => {
|
||||
const matches = searchTools(params.query);
|
||||
return {
|
||||
query: params.query,
|
||||
count: matches.length,
|
||||
matches: matches.slice(0, 20) // Limit results
|
||||
matches: matches.slice(0, 20), // Limit results
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
@@ -478,15 +492,15 @@ export const directTools: ToolDefinition[] = [
|
||||
template: {
|
||||
type: "string",
|
||||
description: "Optional template to use",
|
||||
enum: ["blank", "arduino", "raspberry-pi"]
|
||||
}
|
||||
enum: ["blank", "arduino", "raspberry-pi"],
|
||||
},
|
||||
},
|
||||
required: ["name", "path"]
|
||||
required: ["name", "path"],
|
||||
},
|
||||
handler: async (params) => {
|
||||
// Implementation
|
||||
return { success: true, project_path: `${params.path}/${params.name}` };
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "open_project",
|
||||
@@ -494,29 +508,35 @@ export const directTools: ToolDefinition[] = [
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
path: { type: "string", description: "Path to project file or directory" }
|
||||
path: { type: "string", description: "Path to project file or directory" },
|
||||
},
|
||||
required: ["path"]
|
||||
required: ["path"],
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
},
|
||||
{
|
||||
name: "save_project",
|
||||
description: "Save all project files",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {}
|
||||
properties: {},
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
},
|
||||
{
|
||||
name: "get_project_info",
|
||||
description: "Get current project information: path, files, status",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {}
|
||||
properties: {},
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
},
|
||||
|
||||
// === PRIMARY OPERATIONS (your core workflow) ===
|
||||
@@ -530,11 +550,13 @@ export const directTools: ToolDefinition[] = [
|
||||
reference: { type: "string", description: "Reference designator (e.g., R1, U1)" },
|
||||
x: { type: "number", description: "X position" },
|
||||
y: { type: "number", description: "Y position" },
|
||||
rotation: { type: "number", description: "Rotation in degrees", default: 0 }
|
||||
rotation: { type: "number", description: "Rotation in degrees", default: 0 },
|
||||
},
|
||||
required: ["type", "reference", "x", "y"]
|
||||
required: ["type", "reference", "x", "y"],
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
},
|
||||
{
|
||||
name: "move_component",
|
||||
@@ -544,11 +566,13 @@ export const directTools: ToolDefinition[] = [
|
||||
properties: {
|
||||
reference: { type: "string", description: "Component reference (e.g., R1)" },
|
||||
x: { type: "number", description: "New X position" },
|
||||
y: { type: "number", description: "New Y position" }
|
||||
y: { type: "number", description: "New Y position" },
|
||||
},
|
||||
required: ["reference", "x", "y"]
|
||||
required: ["reference", "x", "y"],
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
},
|
||||
{
|
||||
name: "list_components",
|
||||
@@ -556,10 +580,12 @@ export const directTools: ToolDefinition[] = [
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
filter: { type: "string", description: "Optional filter (e.g., 'R*' for resistors)" }
|
||||
}
|
||||
filter: { type: "string", description: "Optional filter (e.g., 'R*' for resistors)" },
|
||||
},
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
},
|
||||
|
||||
// === SECONDARY OPERATIONS (still common) ===
|
||||
@@ -571,36 +597,42 @@ export const directTools: ToolDefinition[] = [
|
||||
properties: {
|
||||
start: {
|
||||
type: "object",
|
||||
properties: { x: { type: "number" }, y: { type: "number" } }
|
||||
properties: { x: { type: "number" }, y: { type: "number" } },
|
||||
},
|
||||
end: {
|
||||
type: "object",
|
||||
properties: { x: { type: "number" }, y: { type: "number" } }
|
||||
properties: { x: { type: "number" }, y: { type: "number" } },
|
||||
},
|
||||
net: { type: "string", description: "Net name" }
|
||||
net: { type: "string", description: "Net name" },
|
||||
},
|
||||
required: ["start", "end"]
|
||||
required: ["start", "end"],
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
},
|
||||
{
|
||||
name: "list_nets",
|
||||
description: "List all nets/connections",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {}
|
||||
properties: {},
|
||||
},
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
},
|
||||
{
|
||||
name: "get_info",
|
||||
description: "Get general information about current state",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {}
|
||||
properties: {},
|
||||
},
|
||||
handler: async (params) => { /* ... */ }
|
||||
}
|
||||
handler: async (params) => {
|
||||
/* ... */
|
||||
},
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
@@ -613,10 +645,7 @@ Wire everything together in your main server file.
|
||||
|
||||
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import {
|
||||
CallToolRequestSchema,
|
||||
ListToolsRequestSchema,
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
||||
|
||||
import { directTools } from "./tools/direct.js";
|
||||
import { routerTools } from "./tools/router.js";
|
||||
@@ -634,14 +663,11 @@ const server = new Server(
|
||||
capabilities: {
|
||||
tools: {},
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Combine all visible tools
|
||||
const allVisibleTools = [
|
||||
...directTools,
|
||||
...Object.values(routerTools)
|
||||
];
|
||||
const allVisibleTools = [...directTools, ...Object.values(routerTools)];
|
||||
|
||||
// Build a handler map for quick lookup
|
||||
const toolHandlers = new Map<string, (params: any) => Promise<any>>();
|
||||
@@ -656,7 +682,7 @@ for (const tool of Object.values(routerTools)) {
|
||||
// List tools handler - returns only direct + router tools
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
||||
return {
|
||||
tools: allVisibleTools.map(tool => ({
|
||||
tools: allVisibleTools.map((tool) => ({
|
||||
name: tool.name,
|
||||
description: tool.description,
|
||||
inputSchema: tool.inputSchema,
|
||||
@@ -676,9 +702,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
type: "text",
|
||||
text: JSON.stringify({
|
||||
error: `Unknown tool: ${name}`,
|
||||
hint: "Use list_tool_categories and search_tools to find available tools"
|
||||
})
|
||||
}
|
||||
hint: "Use list_tool_categories and search_tools to find available tools",
|
||||
}),
|
||||
},
|
||||
],
|
||||
isError: true,
|
||||
};
|
||||
@@ -690,8 +716,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify(result, null, 2)
|
||||
}
|
||||
text: JSON.stringify(result, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
} catch (error) {
|
||||
@@ -700,9 +726,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify({
|
||||
error: `Tool execution failed: ${(error as Error).message}`
|
||||
})
|
||||
}
|
||||
error: `Tool execution failed: ${(error as Error).message}`,
|
||||
}),
|
||||
},
|
||||
],
|
||||
isError: true,
|
||||
};
|
||||
@@ -734,12 +760,12 @@ Include tools that are:
|
||||
|
||||
**Examples by domain:**
|
||||
|
||||
| Domain | Direct Tools |
|
||||
|--------|-------------|
|
||||
| **KiCAD** | create_project, open_project, save_project, add_component, move_component, add_track, list_components, list_nets, get_board_info |
|
||||
| **IDA Pro** | open_database, save_database, get_function, list_functions, add_comment, rename, get_xrefs, decompile |
|
||||
| **Git** | status, add, commit, push, pull, checkout, branch, log |
|
||||
| **Database** | connect, query, list_tables, describe_table |
|
||||
| Domain | Direct Tools |
|
||||
| ------------ | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **KiCAD** | create_project, open_project, save_project, add_component, move_component, add_track, list_components, list_nets, get_board_info |
|
||||
| **IDA Pro** | open_database, save_database, get_function, list_functions, add_comment, rename, get_xrefs, decompile |
|
||||
| **Git** | status, add, commit, push, pull, checkout, branch, log |
|
||||
| **Database** | connect, query, list_tables, describe_table |
|
||||
|
||||
### Routed Tools (Hidden Behind Router)
|
||||
|
||||
@@ -753,13 +779,13 @@ Include tools that are:
|
||||
|
||||
**Examples:**
|
||||
|
||||
| Category | Why Route It |
|
||||
|----------|-------------|
|
||||
| `export` | Only used at end of workflow |
|
||||
| `drc/validation` | Used during review phase |
|
||||
| `advanced_*` | Specialty operations |
|
||||
| `bulk_*` | Batch operations |
|
||||
| `config/settings` | One-time setup |
|
||||
| Category | Why Route It |
|
||||
| ----------------- | ---------------------------- |
|
||||
| `export` | Only used at end of workflow |
|
||||
| `drc/validation` | Used during review phase |
|
||||
| `advanced_*` | Specialty operations |
|
||||
| `bulk_*` | Batch operations |
|
||||
| `config/settings` | One-time setup |
|
||||
|
||||
---
|
||||
|
||||
@@ -832,18 +858,18 @@ For an IDA Pro MCP server with 100+ tools:
|
||||
|
||||
```typescript
|
||||
const directTools = [
|
||||
"open_database", // Load IDB
|
||||
"save_database", // Save IDB
|
||||
"get_function", // Get function by address/name
|
||||
"list_functions", // List all functions
|
||||
"decompile", // Decompile function (Hex-Rays)
|
||||
"add_comment", // Add comment at address
|
||||
"rename", // Rename address/function
|
||||
"get_xrefs_to", // Get cross-references to address
|
||||
"get_xrefs_from", // Get cross-references from address
|
||||
"get_strings", // List strings
|
||||
"search_bytes", // Search for byte pattern
|
||||
"get_segments", // List segments
|
||||
"open_database", // Load IDB
|
||||
"save_database", // Save IDB
|
||||
"get_function", // Get function by address/name
|
||||
"list_functions", // List all functions
|
||||
"decompile", // Decompile function (Hex-Rays)
|
||||
"add_comment", // Add comment at address
|
||||
"rename", // Rename address/function
|
||||
"get_xrefs_to", // Get cross-references to address
|
||||
"get_xrefs_from", // Get cross-references from address
|
||||
"get_strings", // List strings
|
||||
"search_bytes", // Search for byte pattern
|
||||
"get_segments", // List segments
|
||||
];
|
||||
```
|
||||
|
||||
@@ -854,52 +880,52 @@ const categories = [
|
||||
{
|
||||
name: "disassembly",
|
||||
description: "Disassembly operations: undefine, make code/data, change types",
|
||||
tools: ["make_code", "make_data", "undefine", "set_type", "make_array", "make_struct"]
|
||||
tools: ["make_code", "make_data", "undefine", "set_type", "make_array", "make_struct"],
|
||||
},
|
||||
{
|
||||
name: "functions",
|
||||
description: "Function management: create, delete, modify boundaries, set types",
|
||||
tools: ["create_function", "delete_function", "set_func_end", "set_func_type", "add_func_arg"]
|
||||
tools: ["create_function", "delete_function", "set_func_end", "set_func_type", "add_func_arg"],
|
||||
},
|
||||
{
|
||||
name: "types",
|
||||
description: "Type system: structs, enums, typedefs, parse headers",
|
||||
tools: ["create_struct", "add_struct_member", "create_enum", "parse_header", "import_types"]
|
||||
tools: ["create_struct", "add_struct_member", "create_enum", "parse_header", "import_types"],
|
||||
},
|
||||
{
|
||||
name: "patching",
|
||||
description: "Binary patching: modify bytes, assemble, apply patches",
|
||||
tools: ["patch_bytes", "patch_word", "patch_dword", "assemble", "apply_patches"]
|
||||
tools: ["patch_bytes", "patch_word", "patch_dword", "assemble", "apply_patches"],
|
||||
},
|
||||
{
|
||||
name: "scripting",
|
||||
description: "IDAPython scripting: run scripts, evaluate expressions",
|
||||
tools: ["run_script", "eval_python", "get_global", "set_global"]
|
||||
tools: ["run_script", "eval_python", "get_global", "set_global"],
|
||||
},
|
||||
{
|
||||
name: "signatures",
|
||||
description: "Signatures and patterns: FLIRT, Lumina, create signatures",
|
||||
tools: ["apply_flirt", "query_lumina", "create_sig", "find_pattern"]
|
||||
tools: ["apply_flirt", "query_lumina", "create_sig", "find_pattern"],
|
||||
},
|
||||
{
|
||||
name: "debugging",
|
||||
description: "Debugger control: breakpoints, stepping, memory",
|
||||
tools: ["set_breakpoint", "step_into", "step_over", "read_memory", "write_memory", "get_regs"]
|
||||
tools: ["set_breakpoint", "step_into", "step_over", "read_memory", "write_memory", "get_regs"],
|
||||
},
|
||||
{
|
||||
name: "export",
|
||||
description: "Export: ASM listing, pseudocode, database info, reports",
|
||||
tools: ["export_asm", "export_c", "export_json", "generate_report"]
|
||||
tools: ["export_asm", "export_c", "export_json", "generate_report"],
|
||||
},
|
||||
{
|
||||
name: "import",
|
||||
description: "Import: symbols, types, comments from external sources",
|
||||
tools: ["import_symbols", "import_pdb", "import_map", "import_comments"]
|
||||
tools: ["import_symbols", "import_pdb", "import_map", "import_comments"],
|
||||
},
|
||||
{
|
||||
name: "analysis",
|
||||
description: "Analysis control: reanalyze, find patterns, auto-analysis settings",
|
||||
tools: ["reanalyze", "find_crypto", "find_strings", "analyze_calls", "set_analysis_options"]
|
||||
tools: ["reanalyze", "find_crypto", "find_strings", "analyze_calls", "set_analysis_options"],
|
||||
},
|
||||
];
|
||||
```
|
||||
@@ -962,19 +988,14 @@ Claude: "I've added length tuning meanders to match the trace lengths"
|
||||
// tests/router.test.ts
|
||||
|
||||
import { describe, it, expect } from "vitest";
|
||||
import {
|
||||
searchTools,
|
||||
getCategory,
|
||||
getTool,
|
||||
getAllCategories
|
||||
} from "../src/tools/registry.js";
|
||||
import { searchTools, getCategory, getTool, getAllCategories } from "../src/tools/registry.js";
|
||||
import { routerTools } from "../src/tools/router.js";
|
||||
|
||||
describe("Tool Registry", () => {
|
||||
it("should find tools by keyword", () => {
|
||||
const results = searchTools("export");
|
||||
expect(results.length).toBeGreaterThan(0);
|
||||
expect(results.some(r => r.tool.includes("export"))).toBe(true);
|
||||
expect(results.some((r) => r.tool.includes("export"))).toBe(true);
|
||||
});
|
||||
|
||||
it("should return category info", () => {
|
||||
@@ -998,7 +1019,7 @@ describe("Router Tools", () => {
|
||||
|
||||
it("get_category_tools returns tools for valid category", async () => {
|
||||
const result = await routerTools.get_category_tools.handler({
|
||||
category: "export"
|
||||
category: "export",
|
||||
});
|
||||
expect(result.tools).toBeDefined();
|
||||
expect(result.tools.length).toBeGreaterThan(0);
|
||||
@@ -1006,7 +1027,7 @@ describe("Router Tools", () => {
|
||||
|
||||
it("get_category_tools returns error for invalid category", async () => {
|
||||
const result = await routerTools.get_category_tools.handler({
|
||||
category: "nonexistent"
|
||||
category: "nonexistent",
|
||||
});
|
||||
expect(result.error).toBeDefined();
|
||||
});
|
||||
@@ -1014,7 +1035,7 @@ describe("Router Tools", () => {
|
||||
it("execute_tool runs valid tool", async () => {
|
||||
const result = await routerTools.execute_tool.handler({
|
||||
tool_name: "export_gerber",
|
||||
params: { output_dir: "/tmp/test" }
|
||||
params: { output_dir: "/tmp/test" },
|
||||
});
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
@@ -1022,7 +1043,7 @@ describe("Router Tools", () => {
|
||||
it("execute_tool returns error for invalid tool", async () => {
|
||||
const result = await routerTools.execute_tool.handler({
|
||||
tool_name: "nonexistent_tool",
|
||||
params: {}
|
||||
params: {},
|
||||
});
|
||||
expect(result.error).toBeDefined();
|
||||
});
|
||||
@@ -1141,11 +1162,11 @@ Before shipping your router-based MCP server:
|
||||
|
||||
## Summary
|
||||
|
||||
| Before | After |
|
||||
|--------|-------|
|
||||
| 100 tools visible | 15-18 tools visible |
|
||||
| ~60K+ tokens consumed | ~10K tokens consumed |
|
||||
| Tool selection confusion | Clear categories |
|
||||
| Context starvation | Room for conversation |
|
||||
| Before | After |
|
||||
| ------------------------ | --------------------- |
|
||||
| 100 tools visible | 15-18 tools visible |
|
||||
| ~60K+ tokens consumed | ~10K tokens consumed |
|
||||
| Tool selection confusion | Clear categories |
|
||||
| Context starvation | Room for conversation |
|
||||
|
||||
The router pattern gives you unlimited tool capacity while keeping Claude focused and efficient.
|
||||
|
||||
Reference in New Issue
Block a user