Skip to main content
Glama
kicad-mcp-layer

kicad-mcp-layer

by ShamanAndrey

kicad-mcp-layer

An AI layer for KiCad 10: a Model Context Protocol server that lets Claude Code, or any MCP client, work on KiCad designs.

It drives KiCad through three channels and says which one it is using:

Channel

Mechanism

Used for

cli

kicad-cli subprocess

ERC, DRC, netlists, BOM, renders, fabrication exports. Works with KiCad open or closed.

ipc

KiCad's official IPC API via kicad-python

The board open in the PCB editor. Edits land as undo steps.

file

Lossless edits of .kicad_sch and .kicad_pro

Schematics, which KiCad 10 exposes no API for.

The legacy SWIG pcbnew module is never used; a test enforces it.

This is the library half of kicad-ai-stack, the workspace it was built in. The stack adds the one-command setup (bootstrap.py, which clones this repository, builds its environment and registers the server with Claude Code) and the working rules for a session. Start there if you want the whole thing set up; start here if you want the server or the design package on their own.

What this is

Two layers on one core.

  • kicad_layer.design is the product. A board is Python data: parts from a catalogue, a signal table, circuits as pin-to-net statements, placement, saved copper. The KiCad files are build outputs, and KiCad's own ERC and DRC are the tests. Two boards live on it.

  • The MCP server is its check-and-view layer for Claude Code: checks, exports, renders, reviews, documentation and library search. That is the core tool tier, registered by default. The full tier adds the schematic and board edit tools and the routers.

A project holds only its data: sheets as circuits, placement, a Project, a routing plan for the pipeline in kicad_layer.routers, and the fabrication package from kicad_layer.design.fab. The whole authoring API is on one generated sheet, docs/design-api.md, so a session reads that instead of the source; python -m kicad_layer.design.inspect answers questions about a built board.

The routers (kicad_layer.routers) are frozen: fixes, not features. The intended loop routes by hand in KiCad and keeps the copper as data. tests/test_layers.py enforces the layering.

Related MCP server: kicad-mcp

Status

Pre-alpha, built in the open. Done so far:

  • Rung 0: environment diagnostics, the capability matrix, project discovery, workspace confinement, read-only default mode.

  • Rung 1: every kicad-cli tool (ERC, DRC, netlist, trace, BOM, fabrication export, board render, schematic render).

  • Rung 2: reading the board open in KiCad's PCB Editor over the IPC API (summary, items, per-net statistics), with every failure classified as unreachable or rejected.

  • Writers: a lossless S-expression engine, a library loader, and schematic and board writers that generated a complete 89-LED board which passed ERC and DRC with zero findings (examples/hello_world).

  • Milestone 1: a full-text index of every library KiCad can see, including a project's own, with lib_search, sym_info, fp_info and lib_index.

  • Milestone 2: editing existing schematics losslessly. A concrete syntax tree keeps every untouched byte; edits are atomic, snapshotted, refused while KiCad holds the lock, and validated by ERC and a netlist comparison. Tools: sch_list_components, sch_get_symbol, sch_set_property, sch_add_component, sch_wire, sch_label, sch_mark, sch_delete, sch_annotate.

  • Milestone 3: editing boards. Live through KiCad's API as one undo step per operation, read back from KiCad; or losslessly in the file when the board is closed. A board seen live is never edited on disk. Tools: pcb_place_footprint, pcb_move_footprint, pcb_add_track, pcb_add_via, pcb_add_zone, pcb_refill_zones, pcb_delete_items, pcb_save. KiCad 10's own "create items from text" call is a stub, so live placement builds the footprint from the library file pad by pad.

  • Milestone 4: design review beyond DRC. review_board, review_schematic and review_project produce one report where every check says PASS, WARN, FAIL, INFO or UNVERIFIED with its evidence and the source of its limits: DRC and unrouted connections, zone fill state, parts outside the outline, manufacturability against JLCPCB's published limits, track widths on power nets, zone stitching, decoupling distance, footprints and values and annotation, power-net sources, and the honest state of SPICE. The first run on the Hello World found its vias below the fab's minimum annular ring, which is why the layer's default via is now 0.8 mm. The first run on a real project then caught the review itself: PWR_FLAGs never appear in the exported netlist, so the power-source check now follows KiCad's ERC rule instead. Checks are documented in docs/review-checks.md.

  • Writers, second round, for the first real product (a Compute Module 5 carrier): hierarchical schematics (sheet symbols with pins, hierarchical labels, per-sheet instance paths, multi-unit symbols), boards with any even number of copper layers, and project-local symbol and footprint libraries. A seven-sheet, four-layer project generated this way passes ERC with no findings; KiCad's own ERC and DRC are the tests.

  • Documentation layer: doc_fetch, doc_import, doc_list, doc_text and doc_page keep datasheets and reference designs in an indexed library under research/references with their source URL, date and hash, extract text per page, and render pages to images so pinouts, package drawings and tables can be read. When a site answers with a scripted download portal or refuses the plain client, an optional headless-Chromium tier (pip install "kicad-mcp-layer[browser]") loads the page and takes the download it offers; what still fails gets a classified error that says to save the file in a browser and import it.

  • Routing checks and parts: route_check measures every differential pair on a board (lengths, skew against the interface's limit, coupled share, class gap and width, layer changes) and the review carries it as diff_pairs; impedance_calc and stackup_info give closed-form estimates next to the fab's published geometries for JLCPCB's 4-layer stack-up; parts_search checks JLCPCB's assembly catalogue for LCSC codes and stock. The first real board's 28 pairs and 30 special parts went through them before routing started.

  • Routing: route_pairs routes differential pairs as coupled pairs (escapes planned and reserved for every pair first, a heading-aware search that never folds a pair back on itself, mitred offsets, a two-via crossover where P would land on the wrong side, tuning bumps for skew); stitch_planes drops a stub and via from every surface-mount pad on a plane net; autoroute hands the rest to FreeRouting through a Specctra DSN with the earlier copper protected and merges the session back. All three write a routes JSON next to the board rather than touching the board, so a design-as-code project re-applies it on every build. The first real board's 21 routed pairs came out with zero clearance errors; the residual skew sits on the pairs that needed a crossover.

  • Manufacturing package (milestone 5, PCBWay): kicad_layer.design.fab writes the Gerber and drill archive, the position file and a BOM in PCBWay's assembly layout from a finished build, and refuses a BOM line without a part number. The first real product ordered from it.

  • The design package became the product: kicad_layer.design holds a board as data (sheets described as circuits with a layout plan, a signal table that drives the module sheet and the root, a project with its rule set, placements, blocks) and the KiCad files are build outputs. A build writes the schematic, the project file with its constraints and net classes, the design rules, runs ERC, exports the netlist and checks every sheet against its own description and against a reference netlist, pin group for pin group. Fab rule sets for JLCPCB and AISLER (constraints, classes on the fab's published pair geometries, its own .kicad_dru rules), and review_board takes a fab name for its limits.

  • Hand layout on a generated schematic: for a board placed and routed by a person in KiCad, the build never writes the board. build.py --seed writes its first import instead of KiCad's F8, every footprint in rows and linked to its symbol; blocks (an anchor footprint, members with offsets, one KiCad group) keep parts that belong together, applied by --blocks. The routers are frozen: fixes, not features.

  • Parts and documents: doc_sections and doc_facts read a document's index and a part's fact sheet (written once from the datasheet, every number with its page); lib_fetch brings a symbol, footprint and 3D model for an LCSC code from EasyEDA's data, upgraded to KiCad's current format, for the pad-for-pad check against the drawing that follows.

Next: bring-up (milestone 6) and per-fab export profiles, driven by the first real product. See docs/tools.md for the tool list.

Requirements

  • KiCad 10.0.x (built against 10.0.6, Windows 11). kicad-cli ships with it. Upgrade KiCad deliberately: the file formats and the API move with each major, kicad_doctor reports the drift, and the full test suite is the check.

  • Python 3.12 or newer.

  • kicad-python for the IPC channel (the board open in KiCad), as the ipc extra. Without it the doctor says so and every kicad-cli and file tool still works. Other extras: parts (easyeda2kicad behind lib_fetch), preview (PyMuPDF for sheet previews), browser (headless Chromium for datasheet portals), dev (pytest).

  • Developed and tested on Windows 11; kicad-cli discovery also knows the macOS bundle and the Linux paths. One convenience is Windows-only: build.py --open starts KiCad through a scheduled task.

Install

The quick way is the stack's bootstrap: clone kicad-ai-stack and run python bootstrap.py; it clones this repository next to it, creates the environment, installs the extras and writes the Claude Code registration. On its own:

With uv:

uv sync --extra dev --extra ipc
uv run pytest

With pip:

python -m venv .venv
.venv\Scripts\python -m pip install -e ".[dev,ipc]"
.venv\Scripts\python -m pytest

The default run is the fast loop: in parallel, without the slow tests (a full library index, a whole review, a headless browser) and without the live ones. pytest -m "not gui" adds the slow tests; pytest -m "" runs everything and needs KiCad open with its API on. Tests that need kicad-cli skip themselves when it is not installed.

Register with Claude Code

Put a .mcp.json in the directory that holds your KiCad projects:

{
  "mcpServers": {
    "kicad-mcp-layer": {
      "command": "C:\\path\\to\\kicad-mcp-layer\\.venv\\Scripts\\python.exe",
      "args": ["-m", "kicad_layer"],
      "env": {
        "KICAD_LAYER_WORKSPACE": "C:\\path\\to\\your\\kicad\\projects",
        "KICAD_LAYER_MODE": "readonly"
      }
    }
  }
}

Register it in one place only. If Claude Code runs inside the Claude desktop app, quit and relaunch the app after changing MCP configuration; a new session is not enough.

Configuration

Variable

Default

Meaning

KICAD_LAYER_WORKSPACE

current directory

Every path must resolve under it

KICAD_LAYER_MODE

readonly

write allows design edits

KICAD_CLI

auto-detected

Explicit path to kicad-cli; if set and wrong, that is an error

KICAD_API_SOCKET

ipc://%TEMP%\kicad\api.sock

IPC address, honoured by kicad-python

KICAD_LAYER_CACHE_DIR

%LOCALAPPDATA%\kicad-mcp-layer\cache

Netlist and report cache

KICAD_LAYER_LOG

INFO

stderr log level

KICAD_LAYER_TOOLS

core

core registers checks, exports, renders, reviews, libraries, documents and board reads; full adds the design-edit tools and the routers

To use the board tools, enable the API in KiCad: Preferences, Plugins, "Enable KiCad API". It takes effect immediately.

Design

The architecture decisions and the research behind them live in a companion research/ folder (not part of this package): a survey of every existing KiCad MCP server, KiCad 10's file formats and API surface, and the tests that showed why no existing schematic parser could be reused. Short version:

  • Connectivity comes from kicad-cli sch export netlist, never from home-grown wire tracing.

  • Every IPC failure is classified as unreachable or rejected; file edits are allowed only when unreachable, and never for a board this process has seen live.

  • Schematic writes refuse while KiCad holds the editor lock file.

  • Verdicts can say UNVERIFIED. A missing report is never a pass.

  • Two tool tiers: core reads, checks, exports, renders, reviews and documents; full adds design edits and the frozen routers.

A word to visitors

Everything here stands on KiCad. It is free, open source, and its development is funded by donations. The KiCad developers have said what they want for the next release, and every item would let this project grow: an API for the schematic editor, which KiCad 10 does not have, headless use of that API through kicad-cli, and footprints generated through the API instead of the footprint wizard. Each one would replace a workaround in this library with a direct call into KiCad.

If this project is useful to you, please visit kicad.org and donate to KiCad. That is where the real work happens.

Acknowledgements

Ideas and, where MIT-licensed, code from kicad-mcp-pro, kicad-happy, lamaalrajih/kicad-mcp and KiCAD-MCP-Server; lessons from Konnect. Test fixtures are KiCad's own demo projects.

License

MIT. See LICENSE.

Available Tools

35 tools
capabilitiesA
Read-onlyIdempotent

What this server can do, through which channel (cli, ipc, file), and what KiCad 10 makes impossible. Consult it before promising the user something.

Inputs: query, status. Returns: gap, rows, covered, planned, +1 more

doc_factsA
Read-onlyIdempotent

A part's fact sheet: pins, limits, the values a design is built on, the recommended circuit and the package, every row with its datasheet page, written once from the datasheet and checked against the rendered pages. The cheapest answer to a datasheet question. Without a sheet the answer says how to write one (a subagent with doc_sections, doc_text and doc_page, into research/parts/).

Inputs: part (required), find, section. Returns: part, path, text, found, +3 more

doc_fetchA
Idempotent

Download a technical document into the project's documentation library (research/references by default) and index it with its source URL, date, size and hash. A plain fetch with browser-grade headers comes first; it follows redirects and a single PDF link on a viewer page. When a site answers with a scripted download portal or refuses the plain client, headless Chromium loads the page and takes the download it offers. If that fails too (login walls, bot checks), the error says so: open the URL in a browser, save the file, and use doc_import. Find URLs with web search first; manufacturer sites and distributor mirrors usually both work.

Inputs: url (required), tags, notes, title, +4 more. Returns: id, file, path, size, +8 more

doc_importB
Idempotent

Bring a document that is already on disk into the documentation library and index it.

Inputs: path (required), move, tags, notes, +3 more. Returns: id, file, path, size, +8 more

doc_listA
Read-onlyIdempotent

List or search the documentation library. Text hits include the page number, so a following doc_text or doc_page call can go straight to the right place.

Inputs: limit, query. Returns: query, total, library, documents

doc_pageA
Idempotent

Render one page of a PDF to an image and return it, for pinout drawings, package dimensions, tables and anything else text extraction cannot carry.

Inputs: doc (required), page (required), scale.

doc_sectionsA
Read-onlyIdempotent

The document's index: its bookmarks, its contents page, the headings found in the text and every table and figure caption, each with its page. Ask this first, then doc_text with those pages or doc_page for the table: a datasheet lookup then costs the rows you need, not the pages around them.

Inputs: doc (required), find, limit. Returns: doc, find, total, sections

doc_textA
Read-onlyIdempotent

Extract the text of a PDF (or read a text document), per page, or search it. With find, the answer is the matches alone: a page number and a short window per hit, so a lookup costs a few hundred tokens; add pages to read a page around a hit. Pages that are drawings or scanned images come back empty; use doc_page to look at those.

Inputs: doc (required), find, pages, max_chars. Returns: doc, text, pages, matches, +1 more

export_bomB
Idempotent

Export a bill of materials as CSV with kicad-cli and return the parsed rows.

Inputs: schematic_path (required), fields, group_by, max_rows, +1 more. Returns: rows, columns, command, csv_path, +2 more

export_fabA
Idempotent

Produce fabrication files with kicad-cli and list exactly what was written, with sizes and hashes. Reads the board file on disk: save in KiCad first if it has unsaved changes.

Inputs: board_path (required), pdf, step, drill, +4 more. Returns: files, skipped, commands, warnings, +2 more

fp_infoA
Read-onlyIdempotent

Everything about one library footprint: description, tags, mount type, courtyard size, 3D model, and every pad with number, kind, shape, position, size, drill and layers, exactly as KiCad will place it.

Inputs: lib_id (required), project_path. Returns: attr, pads, path, tags, +8 more

impedance_calcA
Read-onlyIdempotent

Estimate the impedance of an outer-layer trace or pair on a stack-up preset with closed-form microstrip formulas, and report the fab's own published number when the geometry matches one of its table entries. Closed forms are about ten percent optimistic for tightly coupled pairs; the table entry is the one to design to.

Inputs: width_mm (required), gap_mm, stackup. Returns: er, layer, gap_mm, method, +9 more

kicad_doctorA
Read-onlyIdempotent

Diagnose this server and its environment: which process is answering, which kicad-cli was found, whether KiCad's API is reachable and which documents are open, and what to do about any problem. Call this first whenever another tool fails unexpectedly.

Inputs: no named parameters. Returns: ipc, pid, mode, advice, +8 more

lib_fetchA
Idempotent

Symbol, footprint and 3D model (STEP and WRL) for one LCSC code, converted from EasyEDA's component data (EasyEDA is JLCPCB's own design tool; nearly every part in the assembly catalogue has a model there) by easyeda2kicad into a library next to the project. A part swap becomes: parts_search for the code and stock, lib_fetch for the files, then fp_info and the datasheet drawing (doc_page) for the pad-for-pad check. The models are drawn by users and JLCPCB staff: treat them as drafts, never as verified.

Inputs: lcsc (required), parts, lib_dir, lib_name, +2 more. Returns: What lib_fetch wrote for one LCSC code: names, ids, files, and the caveats that…

lib_indexA
Read-onlyIdempotent

Build or refresh the library index and report its size and age. Normally unnecessary: lib_search builds it on first use and refreshes changed libraries automatically.

Inputs: rebuild, project_path. Returns: path, seconds, symbols, built_at, +3 more

pcb_list_itemsA
Read-onlyIdempotent

List items of one kind from the board open in KiCad, in millimetres and degrees with KiCad layer names and item ids. Page with limit and offset on large boards.

Inputs: kind (required), net, ref, layer, +3 more. Returns: kind, items, total, offset, +3 more

pcb_net_statsA
Read-onlyIdempotent

Per-net routing statistics from the open board: track count and total length, widths, layers, vias, pads, a hint when a net has pads but no tracks, and differential-pair candidates with their length mismatch.

Inputs: net, limit, board_path. Returns: nets, net_count, truncated, board_path, +1 more

pcb_summaryA
Read-onlyIdempotent

Describe the board open in KiCad's PCB Editor through the live API: title block, copper layer count, enabled layers, outline size, item counts, stackup and netclass rules. Needs KiCad running with the API enabled and the board open; kicad_doctor explains if it is not.

Inputs: board_path. Returns: size, notes, counts, project, +7 more

project_openA
Read-onlyIdempotent

Locate a KiCad project and describe it: root schematic, board, all sheets, text variables, netclasses, file format versions, and any editor lock files that mean KiCad has a file open.

Inputs: path (required). Returns: name, board, boards, warnings, +10 more

render_boardA
Idempotent

Render the board in 3D to a PNG with kicad-cli and return the image so you can look at it. Reads the board file on disk.

Inputs: board_path (required), side, width, height, +2 more.

review_boardA
Read-onlyIdempotent

Review a board the way a fab and a layout reviewer would: DRC and unrouted connections, zone fill state, footprints outside the outline, manufacturability against the fab's published limits (tracks, vias, annular rings, hole spacing, edge clearance, silkscreen), track widths on power nets, zone stitching, and decoupling capacitor distance. Every check reports PASS, WARN, FAIL or UNVERIFIED with its evidence and the source of its limits.

Inputs: board_path (required), fab, schematic_parity. Returns: fab, kind, checks, counts, +4 more

review_projectA
Read-onlyIdempotent

The full review of a project: every schematic check followed by every board check, in one report with one verdict and the list of checks that could not run.

Inputs: path (required), fab. Returns: fab, kind, checks, counts, +4 more

review_schematicA
Read-onlyIdempotent

Review a schematic: ERC, footprints assigned, values set, annotation, power nets driven, decoupling present, bill-of-materials summary, and the honest state of SPICE simulation. Every check reports PASS, WARN, FAIL, INFO or UNVERIFIED with its evidence.

Inputs: schematic_path (required). Returns: fab, kind, checks, counts, +4 more

route_checkA
Read-onlyIdempotent

Measure every differential pair on a board: the routed length of each half, the skew between them against the interface's limit (Ethernet and MIPI 0.15 mm, PCIe and USB 3.0 0.1 mm, USB 2.0 0.15 mm by default, from the Compute Module 5 datasheet), the share of the pair that runs coupled at the net class's gap, width and gap deviations, and layer changes. Pairs are found by name (X_P/X_N, X_DP/X_DN, X+/X-); unrouted pairs are listed as such.

Inputs: board_path (required), project_path, skew_limit_mm, via_length_mm. Returns: notes, pairs, summary, verdict, +3 more

run_drcA
Read-onlyIdempotent

Run KiCad's Design Rules Check on a board with kicad-cli. The verdict counts clearance and other violations, unconnected items (unrouted nets), and schematic parity problems; a board with unrouted nets is never PASS. Works whether or not KiCad is open.

Inputs: board_path (required), severity, all_track_errors, schematic_parity. Returns: date, kind, notes, counts, +9 more

run_ercA
Read-onlyIdempotent

Run KiCad's Electrical Rules Check on the whole schematic hierarchy with kicad-cli and return a verdict (PASS, WARN, FAIL, or UNVERIFIED when no report was produced) with every finding, keyed by stable ids and item UUIDs. Works whether or not KiCad is open.

Inputs: schematic_path (required), severity. Returns: date, kind, notes, counts, +9 more

sch_get_symbolA
Read-onlyIdempotent

One placed symbol in full, with every pin's number, name, electrical type and sheet position, which is what you need to wire to it.

Inputs: ref (required), schematic_path (required). Returns: dnp, ref, pins, unit, +9 more

sch_list_componentsA
Read-onlyIdempotent

Every placed symbol on one sheet, read from the file: reference, library id, value, footprint, position, rotation, unit, properties and optionally pin coordinates. Works with KiCad closed.

Inputs: schematic_path (required), limit, ref_prefix, include_pins, +1 more. Returns: total, schematic, truncated, components, +2 more

sch_netlistA
Read-onlyIdempotent

The resolved connectivity of the whole schematic hierarchy: every net with its nodes (ref, pin, pin function, pin type), every component, every sheet. Exported by kicad-cli from the root sheet and cached until any schematic file changes. This is the source of truth for 'what connects to what'.

Inputs: schematic_path (required), refresh, max_nets, include_components. Returns: nets, sheets, source, command, +6 more

sch_renderA
Idempotent

Draw every sheet of the schematic to SVG (one file per sheet) or one multi-page PDF with kicad-cli, and return the file paths so the client can read and display them.

Inputs: schematic_path (required), format, output_dir. Returns: note, files, format, command

sch_traceA
Read-onlyIdempotent

For one component, list each pin's net and everything else on that net. Unconnected pins have net null. Uses the cached netlist.

Inputs: ref (required), schematic_path (required), pin. Returns: ref, pins, value, footprint, +1 more

stackup_infoB
Read-onlyIdempotent

A stack-up preset: layers with thickness and permittivity, and the fab's published trace geometries per target impedance, with the source they were read from.

Inputs: stackup. Returns: name, table, layers, source, +2 more

sym_infoA
Read-onlyIdempotent

Everything about one library symbol: description, datasheet, default footprint, footprint filters and the footprints that satisfy them, units, and every pin with its number, name and electrical type. Derived symbols are shown flattened, the way KiCad places them.

Inputs: lib_id (required), project_path. Returns: pins, power, units, lib_id, +9 more

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 35 tools

    Disambiguation4/5

    Most tools target distinct resources or workflows with clear prefixes, but the review tools overlap with specific checks such as run_erc, run_drc, and pcb_net_stats. An agent can usually distinguish them, though choosing between a focused check and a broader review may require care.

    Naming Consistency4/5

    Names are consistently snake_case and use recognizable domain prefixes such as pcb_, sch_, doc_, lib_, run_, and review_. The verb/noun pattern is not perfectly uniform, with noun phrases like pcb_summary and capabilities mixed with verb-first names, but the set remains readable.

    Tool Count2/5

    35 tools is heavy for an MCP server tool set and exceeds the rubric's 25+ threshold for likely excess. Although KiCad is a broad domain, several tools could be consolidated or exposed as subcommands to reduce selection and context burden.

    Completeness4/5

    The server covers a wide read/analyze surface: project inspection, schematic and PCB checks, libraries, fabrication outputs, documentation, parts lookup, and design reviews. If editing or modifying boards and schematics is in scope, those operations are a notable gap, but for an analysis/review layer the surface is fairly complete.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      An MCP server that gives AI agents end-to-end control of KiCad 9+ for rule checks, manufacturing exports, production-readiness certification, and live PCB editor control.
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI assistants to drive KiCAD PCB design automation through MCP, covering schematic authoring, board and routing operations, footprint/symbol libraries, vendor PCB import, validation and DRC, and manufacturing export. It exposes 236 registered tools with keyword discovery, dynamic project-state resources, and optional Streamable HTTP transport with fail-closed Bearer authentication.
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      Enables creating and editing KiCad projects through natural language, including scaffolding projects, placing schematic symbols, wires and labels, and adding PCB footprints, tracks and nets. It also runs ERC/DRC checks and exports to PDF, SVG, netlist, BOM, STEP, DXF, gerbers and drill files via kicad-cli.
      14
      1
      MIT