Copperbrain is a local MCP server for safe KiCad 10 schematic/PCB analysis, deterministic JLCPCB/LCSC sourcing, controlled changes, ERC/DRC validation, typed PCB design rules, and component-only BOM estimates.
See this README for scope and public contracts, docs/INSTALLATION.md for setup, and
docs/DEMO.md for the reproducible reference flow.
Requires Windows, Python 3.11 or newer, uv, and KiCad 10.x (kicad-cli.exe is discovered
dynamically). Controlled PCB routing uses a managed KiCadRoutingTools runtime with its
platform-specific Rust core; JLCImport and JLCPCB Tools are optional and enable local component
sourcing.
git clone https://github.com/deadbringer17/Copperbrain.git
cd Copperbrain
uv sync --all-extras
uv run python scripts/setup_dependencies.py --skip-jlc-plugins
uv run pytest
Start the server with uv run copperbrain. Configure an MCP client to execute uv with arguments
run copperbrain and this repository as its working directory. Copperbrain exposes local stdio
only and never starts a public network listener. See docs/INSTALLATION.md for the full
environment-variable reference and mutation-safety details.
To update a source checkout explicitly from the official origin/main, run:
uv run copperbrain update
The updater accepts only a clean main worktree with the official Copperbrain GitHub origin and
applies a Git fast-forward only. It refuses dirty worktrees, detached or different branches,
unexpected remotes, and divergent history; it never stashes, resets, rebases, or discards local
work. Restart Codex or open a new task after a successful update.
To fetch the pinned, hash-verified KiCadRoutingTools runtime and optional JLCImport/JLCPCB Tools integrations automatically instead of installing them by hand, run:
uv run python scripts/setup_dependencies.py
The script only ever contacts official sources over HTTPS (GitHub, Adoptium, kicad.github.io),
verifies a checksum whenever the source publishes one, and asks for confirmation before writing
anything — including the JLC plugins, which land in KiCad's own plugin directory, outside this
repository. See "Automated dependency setup" in docs/INSTALLATION.md for exactly what it does
and does not do.
Complete the installation above first. Codex (the codex CLI) reads MCP server definitions from
its config.toml — ~/.codex/config.toml on Linux/macOS, %USERPROFILE%\.codex\config.toml on
Windows. Add a [mcp_servers.copperbrain] entry:
[mcp_servers.copperbrain]
command = "uv"
args = ["run", "--directory", "C:\\path\\to\\Copperbrain", "copperbrain"]
enabled = true
Codex launches command directly, without a shell and without setting a working directory of its
own, so uv run needs --directory <repo> instead of relying on cd; use the absolute path to
where you cloned this repository. To override an environment variable from
docs/INSTALLATION.md#configuration for this server only, add it under
[mcp_servers.copperbrain.env], the same way other entries in config.toml do. Restart Codex (or
start a new session) after editing the file. Copperbrain still exposes local stdio only; registering
it this way adds no network exposure.
uv sync --all-extras
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run mypy src
Run the stdio MCP server with uv run copperbrain.
Run the non-destructive offline demo with uv run python scripts/run_demo.py.
Every tool publishes a complete JSON Schema for its arguments. Structured requests such as
request, rule_set, spec, requirements, and operations expose the underlying Pydantic
model — its fields, enumerations, bounds, and defaults — instead of a free-form object, so a client
can construct them without guessing. Fixed vocabularies (change_kind, phase, output_format,
layer and strategy choices) are enumerations, and quantities and limits carry their real bounds.
Schematic operations publish one schema variant per kind; each variant lists the required and
accepted fields inside parameters, including their scalar types. Boundary validation failures are
returned as stable invalid_input errors with field locations and corrective hints; Copperbrain
does not expose Pydantic versions or documentation URLs to MCP callers.
Each tool also publishes a human-readable title and behavior hints: readOnlyHint for the analysis
and proposal tools, destructiveHint for the three acceptances and rollback_accepted_phase,
idempotentHint, and openWorldHint for tools that reach the JLCPCB/LCSC catalog or download
assets. The server advertises the gated workflow in its initialize instructions.
Refusals keep their structure end to end: the stable error code, message, actionable hint, and details all reach the client, so failures never have to be recovered from log text.
Handlers are dispatched onto a worker thread and serialized through a single token, so shared
sessions and change-set workspaces are touched by one operation at a time. The stdio loop keeps
answering pings for the whole run. Note that a long KiCad CLI run, routing candidate, or catalog
download cannot be interrupted once started: the worker thread runs to completion, holds the
token, and a cancellation is only observed after it finishes. Size routing batches accordingly —
COPPERBRAIN_ROUTING_TIMEOUT_SECONDS (default 900) bounds a single run. get_project_creation_status
is the one tool that bypasses the token, so an in-flight project creation stays observable.
The public MCP exposes exactly three tools that accept a validated mutation:
accept_schematic for the project scaffold or schematic change set.accept_design_rules for reviewed widths, clearances, vias, netclasses, and assignments.accept_pcb for one aggregate change set composed from optional layout, placement, grounding,
and routing stages, prepared with prepare_pcb_acceptance and rechecked with
validate_pcb_acceptance.Granular PCB prepare/preview/validate/apply/rollback functions are internal and are not MCP tools.
They modify only the private aggregate workspace. rollback_accepted_phase is an explicit recovery
command, not another acceptance gate.
To start a new design safely, call prepare_project_creation with an existing parent directory
and a typed name/layer count plus a caller-selected request_id. Copperbrain persists that
idempotency key before long-running work: retrying it with the same inputs resolves to the same
change set, while get_project_creation_status remains callable during the operation and reports
in_progress, completed, or failed after an ambiguous client timeout. Copperbrain creates the schematic through kicad-sch-api, creates
the empty board through KiCad's bundled Python API, validates both files, and publishes only a
preview under <new-project>/copperbrain-output/previews/schematic/.
accept_schematic applies the validated scaffold; recovery remains hash guarded.
For an opened KiCad project, Copperbrain writes every deliverable artifact below
<project>/copperbrain-output/: at most the stable schematic, design-rules, and pcb previews
under previews/, plus BOM exports under bom/. Private mutation workspaces, caches, and rollback
snapshots are not placed in the project.
Call detect_kicad to confirm KiCad, CLI, and JLC plugin availability, then open_project to
open a project read-only and hash its sources. get_project_summary returns sheets, components,
electrical nets, and power symbols; analyze_schematic returns deterministic, evidence-backed
observations; trace_net returns every pin KiCad assigns to one exact net name. run_erc and
run_drc run KiCad's checks and normalize violations without touching project files.
Opened sessions are persisted in Copperbrain's private data directory and can be recovered after
an MCP restart; reopening the project remains necessary if the persisted record is unavailable or
the source project has changed.
prepare_schematic_change stages allowlisted operations in a private workspace and returns a
compact summary, risks, counts, and a project-local PDF preview; validate_change revalidates it
in place. Summary mode is the default for prepare, validate, and acceptance and never echoes the
input operation batch. Pass verbosity="full" only for deliberately small changes, or use
get_schematic_change_details to page through operations, semantic differences, validation
messages, or ERC violations in bounded groups of at most 20; exceptionally long scalar fields are
marked and truncated in the page response.
Applying requires the first acceptance gate, accept_schematic, with confirmed=true and
editor_closed=true.
rollback_accepted_phase requires the exact change_set_id returned by the accepted phase. Its
lock refusal identifies the detected project lock file and tells the caller which KiCad editor to
close; editor_closed=true is an attestation, never a bypass. A successful rollback of an existing
project returns a fresh session_id because the previous session's source hashes are obsolete.
Before saving a prepared schematic, Copperbrain registers project symbol libraries and preserves
connectivity-bearing constructs that the pinned kicad-sch-api cannot round-trip, including global
and hierarchical labels and unresolved embedded symbol definitions. The change is refused if a
guarded wire, junction, bus, or label would still be lost.
Readability reports distinguish wired, mixed, label_based, and empty schematics. In
label_based mode, direct pin labels and the absence of wire endpoints are intentional and do not
reduce the score or produce a false readability failure; collision and duplicate-position checks
remain active. empty reports readability as not applicable.
search_components ranks JLCPCB/LCSC candidates against typed requirements using the installed
JLCPCB Tools catalog or a recorded COPPERBRAIN_JLC_CATALOG. get_component_details returns
normalized catalog details for one exact LCSC part; compare_components and find_alternatives
rank supplied or discovered candidates against the same requirements. estimate_component_cost
estimates component-only cost at one requested quantity. import_component_assets installs the
resolved symbol/footprint/3D/datasheet assets locally from allowlisted HTTPS sources.
For parts without a library symbol, generate_symbol_from_pinout creates a deterministic,
parser-validated .kicad_sym scaffold in Copperbrain's private data directory from typed pin
numbers, names, electrical types, sides, and standard properties. It accepts no S-expression and
does not mutate the project. Review the result and pass it with the matching footprint to
import_component_assets, which still enforces exact pin-to-pad number correspondence.
generate_bom groups and enriches the schematic BOM and writes JSON/CSV/Markdown under
copperbrain-output/bom/. estimate_bom_cost returns component-only estimates at the requested
board quantities; suggest_bom_substitutions proposes requirement-motivated alternatives for the
first limit sourced BOM lines and reports sourced_line_count, examined_line_count, and
truncated so a large BOM cannot turn into an unbounded run of catalog searches.
All cost figures explicitly exclude PCB, assembly, stencil, shipping, taxes, and duties.
All three report catalog_failures: an LCSC identifier the catalog refused is named with its
structured reason instead of silently producing an unpriced line, and one refused line no longer
aborts a whole substitution report.
Use analyze_pcb_constraints to inspect current netclasses and receive evidence-backed net-role
suggestions. Pass reviewed fabrication limits and electrical intent to propose_design_rules,
then use prepare_pcb_rule_change, validate_pcb_rule_change, and
accept_design_rules. Applying requires the second acceptance and a saved, closed KiCad editor;
rollback_accepted_phase restores the phase snapshot when explicitly invoked.
ManufacturingProfile covers minimum clearance/track/via dimensions, copper thickness, allowed
temperature rise, and internal/external current layer. NetRuleRequirement covers exact net names,
role, current, voltage, explicit clearance/width, creepage, maximum routed length, and optional
differential geometry/maximum uncoupled length. Raw .kicad_dru text is never accepted through
MCP.
High-current rules require a current or reviewed width. High-voltage rules require reviewed clearance. Differential geometry is explicitly marked as not impedance-controlled unless width and gap are supplied from a verified stackup calculation.
Before proposing routing rules, Copperbrain resolves every connected footprint and measures its
electrical pads, minimum pitch, and edge-to-edge pad clearance. If a class width or clearance does
not fit the package, the generated .kicad_dru applies a narrower track width or reduced clearance
only inside that component's courtyard, never below the fabrication profile minimum. The original
class remains active outside the package. Missing project-local courtyards can be generated inside
the same previewed change set and are validated through KiCad CLI; unresolved footprints or
packages narrower than the fabrication minimum produce a safe refusal.
Use get_pcb_summary, inspect_pcb_net, and get_footprint_placement for typed board queries.
analyze_placement reports conservative courtyard overlaps, footprints outside Edge.Cuts,
estimated ratsnest length, occupied envelope, compactness, side counts, and cross-layer nets.
propose_component_placement accepts exact references, a typed optional region, spacing/grid and
routing-corridor limits, plus deterministic compact or grid, rotation, and layer policies.
Compact placement scores pad connectivity and envelope growth, keeps connectors near edges, and
allows automatic bottom placement only for small SMD passives.
Pass the returned operations directly to prepare_pcb_acceptance. Placement is applied and
validated inside its private aggregate workspace without an intermediate PDF or published copy;
no separate placement preview or acceptance is exposed.
The official kicad-python IPC binding is installed and detected dynamically for live board
transactions. PCB inspection and safe preview do not require a running editor: the typed file
adapter and kicad-cli remain the deterministic offline path. No MCP placement tool accepts raw
KiCad S-expressions, and this extension does not route traces or modify zones, keepouts, or the
board outline.
Un cambio F.Cu/B.Cu viene eseguito soltanto nella copia temporanea attraverso l'API pcbnew
inclusa in KiCad, cosi pad, grafica, testi e modelli 3D vengono trasformati insieme. Preview, DRC,
conferma esplicita, snapshot e rollback restano obbligatori.
Include the reviewed grounding request in prepare_pcb_acceptance. It targets every
pad in one or more reviewed ground domains and derives all zone outlines from the real closed
Edge.Cuts, pad geometry, fanouts, and vias. The default is always a two-copper-layer board:
PGND owns the main shaped region on F.Cu, while GND owns the main shaped region on B.Cu.
Planner-derived local regions on the opposite side are cut out of the main region with explicit
clearance and distinct priorities. A four-layer stackup is used only when
copper_layers=4 is explicitly requested; that opt-in policy uses PGND -> F.Cu/In2.Cu and
GND -> In1.Cu/B.Cu for an unambiguous pair.
The domains remain distinct KiCad nets and are connected only through two-terminal bridges such as
a 0-ohm resistor or net tie explicitly named in bridge_references. Pads that do not touch their
assigned plane receive
typed, clearance-screened pad-to-via fanouts. thermal and solid pad connections are selectable
per domain; local shaped regions are solid and power ground commonly uses solid. Via-in-pad is opt-in because it requires a reviewed
fabrication process. Existing selected-net zones are replaced only when
replace_existing_planes=true is explicitly requested.
The result is validated inside the private aggregate workspace without a grounding preview. The
KiCad Project Manager may remain open: only a PCB document lock blocks the final aggregate
mutation. rollback_accepted_phase restores the aggregate PCB snapshot. Ambiguous
domain roles, overlapping layer assignments, missing/ambiguous bridges, unsafe fanouts, or new DRC
errors cause a structured refusal.
The workflow does not accept polygons or KiCad expressions from callers, and it does not claim
thermal, return-path, EMC, SI/PI, stackup, or DFM certification.
For an empty board, prepare_pcb_acceptance accepts an optional layout stage: a typed
rectangular outline, one placement for every physical schematic footprint, and optional fixed M3
mounting holes. It synchronizes footprints, builds the unrouted PCB, and runs comparative ERC/DRC
inside the aggregate workspace. There is no separate layout preview or acceptance — it is covered
by the single PCB gate. Footprint substitutions are a schematic change: send them to
prepare_schematic_change as update_property operations before preparing the PCB.
The bounded motor-driver reference helpers demonstrate this flow for a provisional 12 V,
20 A brushed-DC H-bridge using DRV8701, four external 60 V MOSFETs, ATtiny1616, half-duplex
RS-485, and four protected 5–24 V digital sensor inputs. Its typed plan uses a compact 120 x 100 mm board,
four M3 holes, a star-separated PGND/logic GND, and a 70 um external-copper assumption. It is
a review benchmark, not a production-qualified design; high-current zones, thermal/EMC/DFM,
motor stall behavior, and the final stackup still require engineering validation.
The typed DRV8311S reference helpers describe an 85 x 50 mm four-layer BLDC driver at a provisional 9--12.6 V, 2 A continuous operating point, with 6-PWM, SPI, three current-sense outputs, fault, Hall signals, input protection, decoupling, grounding intent, thermal-pad fanout, and rule classes. The repository intentionally does not bundle generated benchmark projects. The helpers and their deterministic tests are review evidence, not a production release: power/phase copper, thermal/SOA, EMC, DFM, and final routing still require project-specific engineering validation.
After rules and placement/grounding intent are reviewed, use analyze_unrouted_nets
to identify the remaining disconnected pad groups. Ground-zone connectivity is included, so the
router does not redundantly route pads already joined by an applied plane. Check
get_routing_backend_status, then call propose_pcb_routing. KiCadRoutingTools runs locally through
its Python CLI and Rust-accelerated A* core. Copperbrain can run at most three isolated ordering
strategies: mps, inside_out, and original. One candidate is used by default and a request for
a fourth is rejected. Copperbrain ranks candidates by completion, new DRC errors, open connections,
vias, and routed length. Only the selected candidate's copper delta becomes typed segments and vias;
there is no internal routing fallback. Reviewed planes remain on the private input board as copper
obstacles, while their nets are excluded from the explicit signal-routing batch. The selected typed
copper is applied to the already-grounded private board, followed by KiCad zone refill and
comparative DRC.
Fine-pitch escape geometry is opt-in per routing batch. When enabled, Copperbrain derives short
typed stubs from pad and courtyard geometry and, for a nearby opposite-side target, a clearance-
offset dogbone via with an outside-courtyard approach. It includes these seeds in the private router
input and subjects the resulting complete copper delta to the same scope, preservation,
connectivity, and DRC gates.
When nets is empty, Copperbrain materializes the exact currently-unrouted net set before starting
the backend. KiCadRoutingTools receives those exact names through its fixed --nets argument;
non-target nets, existing routes, planes, keepouts, pads, and the board outline remain obstacles.
Copperbrain never enables the backend option that permits ripping pre-existing routes. Every result
is rejected if it removes existing copper or adds copper outside the requested net set.
Pass the reviewed routing requests with placement and grounding to prepare_pcb_acceptance.
Copperbrain stops after the bounded candidate comparison, applies only the best candidate to the
private prepared PCB, refills zones, rechecks connectivity, and runs comparative DRC inside one
private workspace without routing previews. It does not keep retrying to obtain a complete route.
Final engineering cleanup and the explicit decision to apply the prepared PCB remain with the
user. Only the complete aggregate publishes
copperbrain-output/previews/pcb/ and can be applied by accept_pcb with the third acceptance and
a closed editor. The KiCad Project Manager may remain open; only a PCB-document lock blocks the
aggregate apply/rollback. Boards containing pre-existing copper are rejected by default; explicitly select the
preserve policy only for intentional incremental routing. Wall-time and output-stall watchdogs
stop the complete router process tree. The typed delta is always applied to the original-precision
project copy.
Each proposal writes versioned baseline and per-candidate JSON metrics below the private
COPPERBRAIN_DATA_DIR/metrics/connectivity/ tree. KiCadRoutingTools attempt records retain bounded
queued/routed/failure counts, duration, routed copper, watchdog evidence, and resource data when the
backend exposes it. Backend output is bounded and sensitive net names are replaced with hashes. The returned
RoutingPlan.metrics_run_id correlates those records with preview, apply, and recovery.
Call get_connectivity_metrics with that ID for a bounded, sanitized optimization view including
the best observed pass, connection delta, failed-candidate count, stagnation, and watchdog causes.
New records use schema 5 while the reader remains compatible with persisted schema-2 records.
For the compact end-to-end surface, call prepare_pcb_acceptance, review its preview, then use
validate_pcb_acceptance and accept_pcb. assess_pcb_readiness intentionally keeps
production_ready=false when DFM, stackup,
thermal, SI/PI, EMC, or impedance checks have not been performed, even if routing/ERC/DRC pass.
The AI may explain and review the structured candidate evidence, but it cannot override connectivity, DRC, confirmation, stale-hash, or editor-state gates. This workflow does not certify impedance, SI/PI/EMC, thermal behavior, or regulatory compliance. Raw KiCad expressions, zones, and keepouts remain unavailable through the routing tools.
54 commits
2 commits
Python
100.0%
Copperbrain is a local MCP server for safe KiCad 10 schematic/PCB analysis, deterministic JLCPCB/LCSC sourcing, controlled changes, ERC/DRC validation, typed PCB design rules, and component-only BOM estimates.
See this README for scope and public contracts, docs/INSTALLATION.md for setup, and
docs/DEMO.md for the reproducible reference flow.
Requires Windows, Python 3.11 or newer, uv, and KiCad 10.x (kicad-cli.exe is discovered
dynamically). Controlled PCB routing uses a managed KiCadRoutingTools runtime with its
platform-specific Rust core; JLCImport and JLCPCB Tools are optional and enable local component
sourcing.
git clone https://github.com/deadbringer17/Copperbrain.git
cd Copperbrain
uv sync --all-extras
uv run python scripts/setup_dependencies.py --skip-jlc-plugins
uv run pytest
Start the server with uv run copperbrain. Configure an MCP client to execute uv with arguments
run copperbrain and this repository as its working directory. Copperbrain exposes local stdio
only and never starts a public network listener. See docs/INSTALLATION.md for the full
environment-variable reference and mutation-safety details.
To update a source checkout explicitly from the official origin/main, run:
uv run copperbrain update
The updater accepts only a clean main worktree with the official Copperbrain GitHub origin and
applies a Git fast-forward only. It refuses dirty worktrees, detached or different branches,
unexpected remotes, and divergent history; it never stashes, resets, rebases, or discards local
work. Restart Codex or open a new task after a successful update.
To fetch the pinned, hash-verified KiCadRoutingTools runtime and optional JLCImport/JLCPCB Tools integrations automatically instead of installing them by hand, run:
uv run python scripts/setup_dependencies.py
The script only ever contacts official sources over HTTPS (GitHub, Adoptium, kicad.github.io),
verifies a checksum whenever the source publishes one, and asks for confirmation before writing
anything — including the JLC plugins, which land in KiCad's own plugin directory, outside this
repository. See "Automated dependency setup" in docs/INSTALLATION.md for exactly what it does
and does not do.
Complete the installation above first. Codex (the codex CLI) reads MCP server definitions from
its config.toml — ~/.codex/config.toml on Linux/macOS, %USERPROFILE%\.codex\config.toml on
Windows. Add a [mcp_servers.copperbrain] entry:
[mcp_servers.copperbrain]
command = "uv"
args = ["run", "--directory", "C:\\path\\to\\Copperbrain", "copperbrain"]
enabled = true
Codex launches command directly, without a shell and without setting a working directory of its
own, so uv run needs --directory <repo> instead of relying on cd; use the absolute path to
where you cloned this repository. To override an environment variable from
docs/INSTALLATION.md#configuration for this server only, add it under
[mcp_servers.copperbrain.env], the same way other entries in config.toml do. Restart Codex (or
start a new session) after editing the file. Copperbrain still exposes local stdio only; registering
it this way adds no network exposure.
uv sync --all-extras
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run mypy src
Run the stdio MCP server with uv run copperbrain.
Run the non-destructive offline demo with uv run python scripts/run_demo.py.
Every tool publishes a complete JSON Schema for its arguments. Structured requests such as
request, rule_set, spec, requirements, and operations expose the underlying Pydantic
model — its fields, enumerations, bounds, and defaults — instead of a free-form object, so a client
can construct them without guessing. Fixed vocabularies (change_kind, phase, output_format,
layer and strategy choices) are enumerations, and quantities and limits carry their real bounds.
Schematic operations publish one schema variant per kind; each variant lists the required and
accepted fields inside parameters, including their scalar types. Boundary validation failures are
returned as stable invalid_input errors with field locations and corrective hints; Copperbrain
does not expose Pydantic versions or documentation URLs to MCP callers.
Each tool also publishes a human-readable title and behavior hints: readOnlyHint for the analysis
and proposal tools, destructiveHint for the three acceptances and rollback_accepted_phase,
idempotentHint, and openWorldHint for tools that reach the JLCPCB/LCSC catalog or download
assets. The server advertises the gated workflow in its initialize instructions.
Refusals keep their structure end to end: the stable error code, message, actionable hint, and details all reach the client, so failures never have to be recovered from log text.
Handlers are dispatched onto a worker thread and serialized through a single token, so shared
sessions and change-set workspaces are touched by one operation at a time. The stdio loop keeps
answering pings for the whole run. Note that a long KiCad CLI run, routing candidate, or catalog
download cannot be interrupted once started: the worker thread runs to completion, holds the
token, and a cancellation is only observed after it finishes. Size routing batches accordingly —
COPPERBRAIN_ROUTING_TIMEOUT_SECONDS (default 900) bounds a single run. get_project_creation_status
is the one tool that bypasses the token, so an in-flight project creation stays observable.
The public MCP exposes exactly three tools that accept a validated mutation:
accept_schematic for the project scaffold or schematic change set.accept_design_rules for reviewed widths, clearances, vias, netclasses, and assignments.accept_pcb for one aggregate change set composed from optional layout, placement, grounding,
and routing stages, prepared with prepare_pcb_acceptance and rechecked with
validate_pcb_acceptance.Granular PCB prepare/preview/validate/apply/rollback functions are internal and are not MCP tools.
They modify only the private aggregate workspace. rollback_accepted_phase is an explicit recovery
command, not another acceptance gate.
To start a new design safely, call prepare_project_creation with an existing parent directory
and a typed name/layer count plus a caller-selected request_id. Copperbrain persists that
idempotency key before long-running work: retrying it with the same inputs resolves to the same
change set, while get_project_creation_status remains callable during the operation and reports
in_progress, completed, or failed after an ambiguous client timeout. Copperbrain creates the schematic through kicad-sch-api, creates
the empty board through KiCad's bundled Python API, validates both files, and publishes only a
preview under <new-project>/copperbrain-output/previews/schematic/.
accept_schematic applies the validated scaffold; recovery remains hash guarded.
For an opened KiCad project, Copperbrain writes every deliverable artifact below
<project>/copperbrain-output/: at most the stable schematic, design-rules, and pcb previews
under previews/, plus BOM exports under bom/. Private mutation workspaces, caches, and rollback
snapshots are not placed in the project.
Call detect_kicad to confirm KiCad, CLI, and JLC plugin availability, then open_project to
open a project read-only and hash its sources. get_project_summary returns sheets, components,
electrical nets, and power symbols; analyze_schematic returns deterministic, evidence-backed
observations; trace_net returns every pin KiCad assigns to one exact net name. run_erc and
run_drc run KiCad's checks and normalize violations without touching project files.
Opened sessions are persisted in Copperbrain's private data directory and can be recovered after
an MCP restart; reopening the project remains necessary if the persisted record is unavailable or
the source project has changed.
prepare_schematic_change stages allowlisted operations in a private workspace and returns a
compact summary, risks, counts, and a project-local PDF preview; validate_change revalidates it
in place. Summary mode is the default for prepare, validate, and acceptance and never echoes the
input operation batch. Pass verbosity="full" only for deliberately small changes, or use
get_schematic_change_details to page through operations, semantic differences, validation
messages, or ERC violations in bounded groups of at most 20; exceptionally long scalar fields are
marked and truncated in the page response.
Applying requires the first acceptance gate, accept_schematic, with confirmed=true and
editor_closed=true.
rollback_accepted_phase requires the exact change_set_id returned by the accepted phase. Its
lock refusal identifies the detected project lock file and tells the caller which KiCad editor to
close; editor_closed=true is an attestation, never a bypass. A successful rollback of an existing
project returns a fresh session_id because the previous session's source hashes are obsolete.
Before saving a prepared schematic, Copperbrain registers project symbol libraries and preserves
connectivity-bearing constructs that the pinned kicad-sch-api cannot round-trip, including global
and hierarchical labels and unresolved embedded symbol definitions. The change is refused if a
guarded wire, junction, bus, or label would still be lost.
Readability reports distinguish wired, mixed, label_based, and empty schematics. In
label_based mode, direct pin labels and the absence of wire endpoints are intentional and do not
reduce the score or produce a false readability failure; collision and duplicate-position checks
remain active. empty reports readability as not applicable.
search_components ranks JLCPCB/LCSC candidates against typed requirements using the installed
JLCPCB Tools catalog or a recorded COPPERBRAIN_JLC_CATALOG. get_component_details returns
normalized catalog details for one exact LCSC part; compare_components and find_alternatives
rank supplied or discovered candidates against the same requirements. estimate_component_cost
estimates component-only cost at one requested quantity. import_component_assets installs the
resolved symbol/footprint/3D/datasheet assets locally from allowlisted HTTPS sources.
For parts without a library symbol, generate_symbol_from_pinout creates a deterministic,
parser-validated .kicad_sym scaffold in Copperbrain's private data directory from typed pin
numbers, names, electrical types, sides, and standard properties. It accepts no S-expression and
does not mutate the project. Review the result and pass it with the matching footprint to
import_component_assets, which still enforces exact pin-to-pad number correspondence.
generate_bom groups and enriches the schematic BOM and writes JSON/CSV/Markdown under
copperbrain-output/bom/. estimate_bom_cost returns component-only estimates at the requested
board quantities; suggest_bom_substitutions proposes requirement-motivated alternatives for the
first limit sourced BOM lines and reports sourced_line_count, examined_line_count, and
truncated so a large BOM cannot turn into an unbounded run of catalog searches.
All cost figures explicitly exclude PCB, assembly, stencil, shipping, taxes, and duties.
All three report catalog_failures: an LCSC identifier the catalog refused is named with its
structured reason instead of silently producing an unpriced line, and one refused line no longer
aborts a whole substitution report.
Use analyze_pcb_constraints to inspect current netclasses and receive evidence-backed net-role
suggestions. Pass reviewed fabrication limits and electrical intent to propose_design_rules,
then use prepare_pcb_rule_change, validate_pcb_rule_change, and
accept_design_rules. Applying requires the second acceptance and a saved, closed KiCad editor;
rollback_accepted_phase restores the phase snapshot when explicitly invoked.
ManufacturingProfile covers minimum clearance/track/via dimensions, copper thickness, allowed
temperature rise, and internal/external current layer. NetRuleRequirement covers exact net names,
role, current, voltage, explicit clearance/width, creepage, maximum routed length, and optional
differential geometry/maximum uncoupled length. Raw .kicad_dru text is never accepted through
MCP.
High-current rules require a current or reviewed width. High-voltage rules require reviewed clearance. Differential geometry is explicitly marked as not impedance-controlled unless width and gap are supplied from a verified stackup calculation.
Before proposing routing rules, Copperbrain resolves every connected footprint and measures its
electrical pads, minimum pitch, and edge-to-edge pad clearance. If a class width or clearance does
not fit the package, the generated .kicad_dru applies a narrower track width or reduced clearance
only inside that component's courtyard, never below the fabrication profile minimum. The original
class remains active outside the package. Missing project-local courtyards can be generated inside
the same previewed change set and are validated through KiCad CLI; unresolved footprints or
packages narrower than the fabrication minimum produce a safe refusal.
Use get_pcb_summary, inspect_pcb_net, and get_footprint_placement for typed board queries.
analyze_placement reports conservative courtyard overlaps, footprints outside Edge.Cuts,
estimated ratsnest length, occupied envelope, compactness, side counts, and cross-layer nets.
propose_component_placement accepts exact references, a typed optional region, spacing/grid and
routing-corridor limits, plus deterministic compact or grid, rotation, and layer policies.
Compact placement scores pad connectivity and envelope growth, keeps connectors near edges, and
allows automatic bottom placement only for small SMD passives.
Pass the returned operations directly to prepare_pcb_acceptance. Placement is applied and
validated inside its private aggregate workspace without an intermediate PDF or published copy;
no separate placement preview or acceptance is exposed.
The official kicad-python IPC binding is installed and detected dynamically for live board
transactions. PCB inspection and safe preview do not require a running editor: the typed file
adapter and kicad-cli remain the deterministic offline path. No MCP placement tool accepts raw
KiCad S-expressions, and this extension does not route traces or modify zones, keepouts, or the
board outline.
Un cambio F.Cu/B.Cu viene eseguito soltanto nella copia temporanea attraverso l'API pcbnew
inclusa in KiCad, cosi pad, grafica, testi e modelli 3D vengono trasformati insieme. Preview, DRC,
conferma esplicita, snapshot e rollback restano obbligatori.
Include the reviewed grounding request in prepare_pcb_acceptance. It targets every
pad in one or more reviewed ground domains and derives all zone outlines from the real closed
Edge.Cuts, pad geometry, fanouts, and vias. The default is always a two-copper-layer board:
PGND owns the main shaped region on F.Cu, while GND owns the main shaped region on B.Cu.
Planner-derived local regions on the opposite side are cut out of the main region with explicit
clearance and distinct priorities. A four-layer stackup is used only when
copper_layers=4 is explicitly requested; that opt-in policy uses PGND -> F.Cu/In2.Cu and
GND -> In1.Cu/B.Cu for an unambiguous pair.
The domains remain distinct KiCad nets and are connected only through two-terminal bridges such as
a 0-ohm resistor or net tie explicitly named in bridge_references. Pads that do not touch their
assigned plane receive
typed, clearance-screened pad-to-via fanouts. thermal and solid pad connections are selectable
per domain; local shaped regions are solid and power ground commonly uses solid. Via-in-pad is opt-in because it requires a reviewed
fabrication process. Existing selected-net zones are replaced only when
replace_existing_planes=true is explicitly requested.
The result is validated inside the private aggregate workspace without a grounding preview. The
KiCad Project Manager may remain open: only a PCB document lock blocks the final aggregate
mutation. rollback_accepted_phase restores the aggregate PCB snapshot. Ambiguous
domain roles, overlapping layer assignments, missing/ambiguous bridges, unsafe fanouts, or new DRC
errors cause a structured refusal.
The workflow does not accept polygons or KiCad expressions from callers, and it does not claim
thermal, return-path, EMC, SI/PI, stackup, or DFM certification.
For an empty board, prepare_pcb_acceptance accepts an optional layout stage: a typed
rectangular outline, one placement for every physical schematic footprint, and optional fixed M3
mounting holes. It synchronizes footprints, builds the unrouted PCB, and runs comparative ERC/DRC
inside the aggregate workspace. There is no separate layout preview or acceptance — it is covered
by the single PCB gate. Footprint substitutions are a schematic change: send them to
prepare_schematic_change as update_property operations before preparing the PCB.
The bounded motor-driver reference helpers demonstrate this flow for a provisional 12 V,
20 A brushed-DC H-bridge using DRV8701, four external 60 V MOSFETs, ATtiny1616, half-duplex
RS-485, and four protected 5–24 V digital sensor inputs. Its typed plan uses a compact 120 x 100 mm board,
four M3 holes, a star-separated PGND/logic GND, and a 70 um external-copper assumption. It is
a review benchmark, not a production-qualified design; high-current zones, thermal/EMC/DFM,
motor stall behavior, and the final stackup still require engineering validation.
The typed DRV8311S reference helpers describe an 85 x 50 mm four-layer BLDC driver at a provisional 9--12.6 V, 2 A continuous operating point, with 6-PWM, SPI, three current-sense outputs, fault, Hall signals, input protection, decoupling, grounding intent, thermal-pad fanout, and rule classes. The repository intentionally does not bundle generated benchmark projects. The helpers and their deterministic tests are review evidence, not a production release: power/phase copper, thermal/SOA, EMC, DFM, and final routing still require project-specific engineering validation.
After rules and placement/grounding intent are reviewed, use analyze_unrouted_nets
to identify the remaining disconnected pad groups. Ground-zone connectivity is included, so the
router does not redundantly route pads already joined by an applied plane. Check
get_routing_backend_status, then call propose_pcb_routing. KiCadRoutingTools runs locally through
its Python CLI and Rust-accelerated A* core. Copperbrain can run at most three isolated ordering
strategies: mps, inside_out, and original. One candidate is used by default and a request for
a fourth is rejected. Copperbrain ranks candidates by completion, new DRC errors, open connections,
vias, and routed length. Only the selected candidate's copper delta becomes typed segments and vias;
there is no internal routing fallback. Reviewed planes remain on the private input board as copper
obstacles, while their nets are excluded from the explicit signal-routing batch. The selected typed
copper is applied to the already-grounded private board, followed by KiCad zone refill and
comparative DRC.
Fine-pitch escape geometry is opt-in per routing batch. When enabled, Copperbrain derives short
typed stubs from pad and courtyard geometry and, for a nearby opposite-side target, a clearance-
offset dogbone via with an outside-courtyard approach. It includes these seeds in the private router
input and subjects the resulting complete copper delta to the same scope, preservation,
connectivity, and DRC gates.
When nets is empty, Copperbrain materializes the exact currently-unrouted net set before starting
the backend. KiCadRoutingTools receives those exact names through its fixed --nets argument;
non-target nets, existing routes, planes, keepouts, pads, and the board outline remain obstacles.
Copperbrain never enables the backend option that permits ripping pre-existing routes. Every result
is rejected if it removes existing copper or adds copper outside the requested net set.
Pass the reviewed routing requests with placement and grounding to prepare_pcb_acceptance.
Copperbrain stops after the bounded candidate comparison, applies only the best candidate to the
private prepared PCB, refills zones, rechecks connectivity, and runs comparative DRC inside one
private workspace without routing previews. It does not keep retrying to obtain a complete route.
Final engineering cleanup and the explicit decision to apply the prepared PCB remain with the
user. Only the complete aggregate publishes
copperbrain-output/previews/pcb/ and can be applied by accept_pcb with the third acceptance and
a closed editor. The KiCad Project Manager may remain open; only a PCB-document lock blocks the
aggregate apply/rollback. Boards containing pre-existing copper are rejected by default; explicitly select the
preserve policy only for intentional incremental routing. Wall-time and output-stall watchdogs
stop the complete router process tree. The typed delta is always applied to the original-precision
project copy.
Each proposal writes versioned baseline and per-candidate JSON metrics below the private
COPPERBRAIN_DATA_DIR/metrics/connectivity/ tree. KiCadRoutingTools attempt records retain bounded
queued/routed/failure counts, duration, routed copper, watchdog evidence, and resource data when the
backend exposes it. Backend output is bounded and sensitive net names are replaced with hashes. The returned
RoutingPlan.metrics_run_id correlates those records with preview, apply, and recovery.
Call get_connectivity_metrics with that ID for a bounded, sanitized optimization view including
the best observed pass, connection delta, failed-candidate count, stagnation, and watchdog causes.
New records use schema 5 while the reader remains compatible with persisted schema-2 records.
For the compact end-to-end surface, call prepare_pcb_acceptance, review its preview, then use
validate_pcb_acceptance and accept_pcb. assess_pcb_readiness intentionally keeps
production_ready=false when DFM, stackup,
thermal, SI/PI, EMC, or impedance checks have not been performed, even if routing/ERC/DRC pass.
The AI may explain and review the structured candidate evidence, but it cannot override connectivity, DRC, confirmation, stale-hash, or editor-state gates. This workflow does not certify impedance, SI/PI/EMC, thermal behavior, or regulatory compliance. Raw KiCad expressions, zones, and keepouts remain unavailable through the routing tools.
54 commits
2 commits
Python
100.0%