Files
kicad-mcp-server/docs/IPC_API_MIGRATION_PLAN.md
KiCAD MCP Bot e4c7119c51 feat: Week 1 complete - Linux support + IPC API prep
🎉 Major v2.0 rebuild kickoff - Week 1 accomplished!

## Highlights

### Cross-Platform Support 🌍
-  Linux primary platform (Ubuntu/Debian tested)
-  Windows fully supported
-  macOS experimental support
-  Platform-agnostic path handling (XDG spec)
-  Auto-detection of KiCAD installation

### Infrastructure 🏗️
-  GitHub Actions CI/CD pipeline
-  Pytest framework with 20+ tests
-  Pre-commit hooks (Black, MyPy, ESLint)
-  Automated Linux installation script
-  Enhanced npm scripts

### IPC API Migration Prep 🚀
-  Comprehensive migration plan (30 pages)
-  Backend abstraction layer (800+ lines)
-  Factory pattern with auto-detection
-  SWIG backward compatibility wrapper
-  IPC backend skeleton ready

### Documentation 📚
-  Updated README (Linux installation)
-  CONTRIBUTING.md guide
-  Linux compatibility audit
-  IPC API migration plan
-  Session summaries
-  Platform-specific config templates

## Files Changed

- 27 files created
- ~3,000 lines of code/docs
- 8 comprehensive documentation pages
- 20+ unit tests
- 5 abstraction layer modules

## Next Steps

- Week 2: IPC API migration (project.py → component.py → routing.py)
- Migrate from deprecated SWIG to official IPC API
- JLCPCB/Digikey integration prep

🤖 Generated with Claude Code
https://claude.com/claude-code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-25 20:48:00 -04:00

14 KiB

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:

# 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/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/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/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:

# 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

    @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

    # 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

+ # KiCAD IPC API (official Python bindings)
+ kicad-python>=0.5.0

  # Legacy SWIG support (for backward compatibility)
  kicad-skip>=0.1.0

Environment Variables

# 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


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

    pip install kicad-python
    
  2. Test IPC connection

    # Launch KiCAD
    # Enable IPC in preferences
    python3 -c "from kicad import KiCad; k=KiCad(); print(k.check_version())"
    
  3. Create abstraction layer structure

    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