Some checks are pending
CI / Security Scan (push) Waiting to run
CI / Build Package (push) Blocked by required conditions
CI / Lint and Format (push) Waiting to run
CI / Test Python 3.11 on macos-latest (push) Waiting to run
CI / Test Python 3.12 on macos-latest (push) Waiting to run
CI / Test Python 3.13 on macos-latest (push) Waiting to run
CI / Test Python 3.10 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.11 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.12 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.13 on ubuntu-latest (push) Waiting to run
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.
141 lines
5.6 KiB
Markdown
141 lines
5.6 KiB
Markdown
# 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 file
|
|
- `make lint` - Lint with ruff + mypy (`src/mckicad/` and `tests/`)
|
|
- `make format` - Auto-format with ruff
|
|
- `make build` - Build package
|
|
- `make 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
|
|
|
|
```python
|
|
# 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
|
|
|
|
1. Choose the right module (or create one in `tools/`)
|
|
2. Import `mcp` from `mckicad.server`
|
|
3. Decorate with `@mcp.tool()` and add a clear docstring
|
|
4. If new module: add import in `server.py`
|
|
5. Write tests in `tests/test_<module>.py`
|
|
|
|
## Security
|
|
|
|
- All file paths validated via `utils/path_validator.py` before access
|
|
- External commands run through `utils/secure_subprocess.py` with timeouts
|
|
- KiCad CLI commands sanitized — no shell injection
|
|
- `main.py` inline .env loader runs before any mckicad imports
|
|
|
|
## Environment Variables
|
|
|
|
- `KICAD_USER_DIR` - KiCad user config directory
|
|
- `KICAD_SEARCH_PATHS` - Comma-separated project search paths
|
|
- `KICAD_CLI_PATH` - Explicit kicad-cli path
|
|
- `FREEROUTING_JAR_PATH` - Path to FreeRouting JAR
|
|
- `LOG_LEVEL` - Logging level (default: INFO)
|
|
|
|
## Testing
|
|
|
|
Markers: `unit`, `integration`, `requires_kicad`, `slow`, `performance`
|
|
|
|
```bash
|
|
make test # all tests
|
|
make test tests/test_schematic.py # one file
|
|
uv run pytest -m "unit" # by marker
|
|
```
|
|
|
|
## Entry Point
|
|
|
|
```toml
|
|
[project.scripts]
|
|
mckicad = "mckicad.server:main"
|
|
```
|
|
|
|
Run via `uvx mckicad`, `uv run mckicad`, or `uv run python main.py`.
|
|
|
|
## FreeRouting Setup
|
|
|
|
1. Download JAR from https://freerouting.app/
|
|
2. Place at `~/freerouting.jar`, `/usr/local/bin/freerouting.jar`, or `/opt/freerouting/freerouting.jar`
|
|
3. Install Java runtime
|
|
4. Verify with `check_routing_capability()` tool
|
|
5. Or set `FREEROUTING_JAR_PATH` in `.env`
|
|
|
|
## Logging
|
|
|
|
Logs go to `mckicad.log` in project root, overwritten each start. Never use `print()` — MCP uses stdin/stdout for JSON-RPC transport.
|