Skip to main content
Glama
IPC_API_MIGRATION_PLAN.mdโ€ข14.3 kB
# 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

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mixelpixx/KiCAD-MCP-Server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server