Skip to content

Architecture

The project is organized as a src-based Python package with:

  • config.py for settings and path safety
  • discovery.py for CLI and project detection
  • connection.py for KiCad IPC lifecycle
  • tools/ for domain-specific MCP tools
  • resources/ and prompts/ for MCP-native context surfaces

Runtime Model

The v2 runtime is no longer just "call a KiCad command and trust the result". It is structured around four layers:

  1. Intent
  2. project-scoped design assumptions persisted by project_set_design_intent()
  3. resolved design-spec view available through project_get_design_spec()
  4. connector refs, decoupling pairs, power-tree refs, analog/digital groups, sensor clusters, RF keepouts, critical nets, and fab profile hints
  5. Builder
  6. schematic, PCB, routing, and export tools that mutate or inspect the active design
  7. Critic
  8. resources and prompts that expose quality status and a prioritized fix queue
  9. Gate
  10. hard release decisions made by the validation surface

Quality Gate Stack

project_quality_gate() is the top-level release contract. It aggregates:

  • schematic_quality_gate()
  • schematic_connectivity_gate()
  • pcb_quality_gate()
  • pcb_placement_quality_gate()
  • pcb_transfer_quality_gate()
  • manufacturing_quality_gate()
  • footprint parity checks

The release contract is intentionally strict:

  • export_manufacturing_package() is hard-blocked unless the full project gate is PASS
  • low-level exports remain available for debugging and iteration
  • agents are expected to use the fix queue and re-run gates after each repair pass

Health Surface

The MCP resource layer exposes the current review state as text-first surfaces:

  • kicad://project/quality_gate
  • kicad://project/fix_queue
  • kicad://schematic/connectivity
  • kicad://board/placement_quality

These resources exist so an agent can inspect, criticize, fix, and re-check without inventing its own hidden state model.

IPC Command Queue

Live KiCad GUI mutations must pass through kicad_mcp.ipc.command_queue so stateful IPC operations are serialized, retried only when safe, and journaled with a correlation id. The initial routed operations include board save, zone refill, item deletion, board commit/revert actions, and PCB title-block edits.

File-backed/headless writes such as schematic S-expression transactions are intentionally outside the IPC queue: they use project-local atomic file writers and rollback checkpoints instead, so they continue to work when KiCad is not running.

Placement Review

Placement review is intentionally split in two:

  • pcb_placement_quality_gate() blocks hard geometry/context failures
  • pcb_score_placement() reports softer heuristics such as density, spread, power-tree locality, analog/digital proximity, and sensor clustering

This keeps release gating deterministic while still letting agents optimize placement quality before a hard failure appears.

Benchmark Corpus

Release behavior is pinned by a small benchmark/failure corpus under tests/fixtures/benchmark_projects/.

The benchmark suite ensures that:

  • pass fixtures can reach release export
  • known failure fixtures remain blocked
  • the correct subsystem is blamed

That corpus is part of the architecture, not just a test convenience. It is the regression harness for agent-to-tool synchronization quality.

Domain Split Guard

Large implementation files are being split incrementally without changing public MCP tool names. The first extracted slices are:

  • kicad_mcp.tools.schematic_constants for schematic geometry, layout, power-net, and public-tool constants.
  • kicad_mcp.models.visual_qa, sch_transaction, and contract_verifier for pure, file-backed engines.
  • kicad_mcp.ipc.command_queue for serialized KiCad IPC mutations.
  • kicad_mcp.companion.context for dependency-free companion plugin helpers.

scripts/check_architecture_boundaries.py keeps those helpers import-light and cycle-free. It is part of check:meta, so future refactor slices must preserve the extracted-domain boundaries while the monolith split continues.