Autowire guide covers the decision tree, threshold tuning, workflow patterns, and troubleshooting. CLAUDE.md updated to reflect the new autowire/ package and tools/autowire.py.
5.6 KiB
CLAUDE.md
This file provides guidance to Claude Code when working with the mckicad codebase.
Development Commands
make install- Install dependencies with uv (creates .venv)make run- Start the MCP server (uv run python main.py)make test- Run all tests (uv run pytest tests/ -v)make test <file>- Run a specific test filemake lint- Lint with ruff + mypy (src/mckicad/andtests/)make format- Auto-format with ruffmake build- Build packagemake clean- Remove build artifacts and caches
Python 3.10+ required. Uses uv for everything. Configure via .env (copy .env.example).
Architecture
mckicad is a FastMCP 3 server for KiCad electronic design automation. It uses src-layout packaging with hatchling as the build backend.
Project Structure
src/mckicad/
__init__.py # __version__ only
server.py # FastMCP 3 server + lifespan + module imports
config.py # Lazy config functions (no module-level env reads)
autowire/
__init__.py # Package init
strategy.py # Wiring decision tree: classify_net, crossing estimation
planner.py # NetPlan → apply_batch JSON conversion
tools/
autowire.py # autowire_schematic MCP tool (1 tool)
schematic.py # kicad-sch-api: create/edit schematics (9 tools)
project.py # Project discovery and structure (3 tools)
drc.py # DRC checking + manufacturing constraints (4 tools)
bom.py # BOM generation and export (2 tools)
export.py # Gerber, drill, PDF, SVG via kicad-cli (4 tools)
routing.py # FreeRouting autorouter integration (3 tools)
analysis.py # Board validation + real-time analysis (3 tools)
pcb.py # IPC-based PCB manipulation via kipy (5 tools)
resources/
projects.py # kicad://projects resource
files.py # kicad://project/{path} resource
prompts/
templates.py # debug_pcb, analyze_bom, design_circuit, debug_schematic
utils/
kicad_cli.py # KiCad CLI detection and execution
path_validator.py # Path security / directory traversal prevention
secure_subprocess.py # Safe subprocess execution with timeouts
ipc_client.py # kipy IPC wrapper for live KiCad connection
freerouting.py # FreeRouting JAR engine
file_utils.py # Project file discovery
kicad_utils.py # KiCad path detection, project search
tests/
conftest.py # Shared fixtures (tmp dirs, project paths)
test_*.py # Per-module test files
main.py # Entry point: .env loader + server start
Key Design Decisions
Lazy config (config.py): All environment-dependent values are accessed via functions (get_search_paths(), get_kicad_user_dir()) called at runtime, not at import time. Static constants (KICAD_EXTENSIONS, TIMEOUT_CONSTANTS, COMMON_LIBRARIES) remain as module-level dicts since they don't read env vars. This eliminates the .env load-order race condition.
Decorator-based tool registration: Each tool module imports mcp from server.py and decorates functions with @mcp.tool() at module level. server.py imports the modules to trigger registration. No register_*_tools() boilerplate.
Schematic abstraction point: tools/schematic.py uses kicad-sch-api for file-level schematic manipulation. The _get_schematic_engine() helper exists as a swap point for when kipy adds schematic IPC support.
Dual-mode operation: PCB tools work via IPC (kipy, requires running KiCad) or CLI (kicad-cli, batch mode). Tools degrade gracefully when KiCad isn't running.
Tool Registration Pattern
# tools/example.py
from mckicad.server import mcp
@mcp.tool()
def my_tool(param: str) -> dict:
"""Tool description for the calling LLM."""
return {"success": True, "data": "..."}
Tool Return Convention
All tools return dicts with at least success: bool. On failure, include error: str. On success, include relevant data fields.
Adding New Features
- Choose the right module (or create one in
tools/) - Import
mcpfrommckicad.server - Decorate with
@mcp.tool()and add a clear docstring - If new module: add import in
server.py - Write tests in
tests/test_<module>.py
Security
- All file paths validated via
utils/path_validator.pybefore access - External commands run through
utils/secure_subprocess.pywith timeouts - KiCad CLI commands sanitized — no shell injection
main.pyinline .env loader runs before any mckicad imports
Environment Variables
KICAD_USER_DIR- KiCad user config directoryKICAD_SEARCH_PATHS- Comma-separated project search pathsKICAD_CLI_PATH- Explicit kicad-cli pathFREEROUTING_JAR_PATH- Path to FreeRouting JARLOG_LEVEL- Logging level (default: INFO)
Testing
Markers: unit, integration, requires_kicad, slow, performance
make test # all tests
make test tests/test_schematic.py # one file
uv run pytest -m "unit" # by marker
Entry Point
[project.scripts]
mckicad = "mckicad.server:main"
Run via uvx mckicad, uv run mckicad, or uv run python main.py.
FreeRouting Setup
- Download JAR from https://freerouting.app/
- Place at
~/freerouting.jar,/usr/local/bin/freerouting.jar, or/opt/freerouting/freerouting.jar - Install Java runtime
- Verify with
check_routing_capability()tool - Or set
FREEROUTING_JAR_PATHin.env
Logging
Logs go to mckicad.log in project root, overwritten each start. Never use print() — MCP uses stdin/stdout for JSON-RPC transport.