MCP API and tool reference
KiPilot is a stdio Model Context Protocol server for a live KiCad PCB session. This page documents the transport model, runtime configuration, safety controls, operational expectations, and the full tool surface exposed to MCP-aware hosts.
KiPilot exposes 135 KiCad PCB and schematic actions as JSON-serializable MCP tools over stdio.
KiPilot is designed for MCP hosts such as GitHub Copilot in VS Code, Claude, or any other client that can launch a stdio MCP server and exchange tool calls. It does not expose an HTTP API, it does not launch KiCad for you, and it assumes that the board or schematic you want to inspect or edit is already open inside a user-controlled KiCad GUI session.
Need a visual walkthrough instead of raw tool reference?
The public site now includes a dedicated Gallery page for recorded KiCad sessions and future image-based media. Use the gallery for visual proof and demos; use this page as the normative reference for the MCP surface and runtime behavior.
What KiPilot provides
- Stdio MCP transport with a stable, agent-friendly tool surface of 135 tools.
- Read-heavy PCB inspection for documents, footprints, pads, nets, net classes, connectivity, graphics, dimensions, groups, reference images, barcodes, tables, grid items, constraints, reference points, text, origins, and title blocks.
- Full schematic authoring on a KiCad 11 (master/nightly) build: create wires, buses, junctions, no-connects, labels, text, and symbol instances, edit and delete items, save the document, and drive the live editor selection.
- Schematic inspection and reporting: hierarchy, netlist, page settings, title block, hit-testing, s-expression document and selection dumps, and dirty-state checks.
- Design variants: list, add, rename, copy, describe, activate, and delete schematic variants.
- Schematic export jobs for SVG, DXF, PDF, PS, netlist, and BOM.
- Controlled mutations with dry-run previews, mutation gating, and explicit force guards for destructive actions.
- Higher-level agent-facing helpers such as footprint side flips, footprint pad net reassignment, and polyline-to-segment schematic creation built from lower-level KiCad objects.
- Operational logging to stderr and optionally to a file.
What KiPilot does not provide
- No headless KiCad management or GUI automation. KiCad must be running.
- No HTTP API and no stdout logging, because stdout is reserved for MCP protocol traffic.
- No generic unrestricted arbitrary-item updater. Writes go through explicit, validated tool parameters.
- No multi-call transactions. Each tool call opens and closes its own IPC connection and its own commit group, so a half-finished multi-step edit can leave partial state until you fix it.
- No ERC, DRC, or design-rule checking runs.
- No symbol, footprint, or library authoring. Schematic symbol placement places an instance and needs the library symbol to already be resolvable by KiCad.
- No hierarchical sheet creation, bus entries, rule areas, or tables in the schematic creation tool. Supported creation kinds are wire, bus, junction, no_connect, label, global_label, hierarchical_label, text, and symbol.
- No blanket schematic parity across all KiCad 10 builds. Upstream KiCad 10.0.x registers only GetOpenDocuments on the schematic API handler, so the schematic tools need a KiCad 11 (master/nightly) build.
- Launch KiCad yourself Open the target project and the PCB Editor and/or Schematic Editor before running the matching MCP tools.
- Start KiPilot through an MCP host Point the host either at the extracted Windows executable or at the KiPilot Python environment and run the stdio server.
- Verify reachability first Use ping_kicad or get_kicad_version before any geometry or mutation request.
- Query, preview, then apply Round-trip item IDs from read tools, prefer dry_run=true first, then apply and save deliberately.
The PCB baseline targets KiCad 10, while the schematic surface needs a KiCad 11 (master/nightly) build with a running GUI instance.
KiPilot is built around the official kicad-python binding and the KiCad GUI IPC endpoint. The implementation is intentionally scoped to the capabilities validated against the current repository baseline.
Validated baseline
- Python 3.11+ is supported for source installs and local builds. The Windows ZIP release bundles its own runtime.
- KiCad 10.x (10.0.6 or later recommended) is the documented target for the PCB tool surface.
- The schematic tool surface needs a KiCad build that implements the schematic IPC handlers. KiCad 10.0.x is not enough: upstream registers only GetOpenDocuments on the schematic API handler.
- Schematic support ships on the KiCad master branch, which is the KiCad 11 development line. KiCad 11.0.0 has no announced release date yet, so use a master/nightly build.
- On the Python side, the schematic client bindings exist in kicad-python 0.9.0.dev0 (upstream main). The 0.9.0 release is not on PyPI yet, so packages that need them must vendor or pin the wrapper. The Windows ZIP release already bundles it.
- One running KiCad instance at a time is strongly recommended during setup and debugging.
- Board-context tools assume the PCB Editor endpoint is available, not only the Project Manager.
- The current schematic tools were live-validated against a locally built KiCad master snapshot in this environment; the installed official KiCad 10.0.1 build did not expose the same reliable external schematic IPC behavior.
Scope boundaries
- GUI IPC only. Headless document open/create/close tools are exposed, but they only work against a headless KiCad API server session.
- PCB Editor first: 88 PCB tools plus the shared session tools run on stable KiCad 10.x.
- The schematic surface adds 37 tools and needs a KiCad 11 (master/nightly) build rather than the stable 10.0.x series.
- Schematic export currently covers SVG, DXF, PDF, PS, netlist, and BOM jobs when the running build exposes the newer schematic job handlers.
- Some queries depend on KiCad 10.0.1+ level APIs inside the running application.
Avoid preview or alpha Python interpreters because the native dependency chain may not publish compatible wheels for them yet.
Where to get the KiCad builds
- Stable KiCad 10.x for the PCB tools: kicad.org/download. Use 10.0.6 or later.
- KiCad 11 master/nightly for the schematic tools: the same download page has a Nightly Development Builds section, and 10.0.x installs do not have to be replaced — nightly builds install side by side.
- KiCad must have the API server enabled in Preferences > Plugins.
- You can verify which capabilities the running build exposes with get_kicad_version and by calling any schematic tool once; a stable 10.x build answers with a clear capability error instead of a crash or a silent failure.
The server is a FastMCP stdio process that creates a fresh KiCad IPC client per tool call.
This design keeps tool execution isolated, aligns well with MCP host process models, and keeps error boundaries simple. Blocking KiCad calls are wrapped behind an async-friendly interface so MCP hosts still see normal asynchronous tool execution.
MCP host
-> stdio transport
-> KiPilot FastMCP server
-> per-tool KiCadIpcClient
-> official kicad-python binding
-> running KiCad GUI IPC endpoint
-> active project / active PCB board objects
Transport model
- The public integration surface is MCP over stdio only.
- MCP hosts discover tools automatically; users normally do not handcraft raw protocol frames.
- Stdout must remain protocol-clean, which is why logs go to stderr or to a file.
Connection model
- Every tool call builds a fresh runtime config and client instance.
- The server uses the official KiCad socket and token when provided.
- If those variables are absent, the binding falls back to platform defaults.
Why this matters for agents
- Failures stay local to a single tool call.
- Dry-run previews can be executed without unlocking write access.
- Mutation operations can include narrow commit messages and deterministic guardrails.
- The MCP surface can expose higher-level board actions even when KiCad IPC only exposes the lower-level mutable objects underneath.
Logging model
- Server startup is logged once per process.
- Each tool call records start, finish, duration, and warning/error outcomes.
- Long argument payloads are summarized to keep logs useful without becoming unreadable.
Install KiPilot from a Windows ZIP or from source, then verify that KiCad is already running.
On Windows, the fastest install path is the prebuilt ZIP release. Source installation stays available for development, auditing, and non-Windows environments.
Windows ZIP release
Download the latest kipilot-mcp-VERSION-windows-x64.zip asset from GitHub Releases, extract it to a stable location such as C:\Tools, and point your MCP host at kipilot-mcp.exe.
The current release is v0.3.0 (kipilot-mcp-0.3.0-windows-x64.zip) with 135 MCP tools, a bundled Python runtime, and the bundled kicad-python binding.
https://github.com/belaszalontai/kipilot-mcp/releases/latest
{
"servers": {
"kipilot-mcp": {
"type": "stdio",
"command": "C:\\Tools\\kipilot-mcp-VERSION-windows-x64\\kipilot-mcp.exe",
"env": {
"KIPILOT_KICAD_CLIENT_NAME": "kipilot-mcp",
"KIPILOT_KICAD_TIMEOUT_MS": "60000",
"KIPILOT_LOG_LEVEL": "INFO",
"KIPILOT_LOG_FILE": ".logs/kipilot-mcp.log"
}
}
}
}
The ZIP release bundles the Python runtime and the official kicad-python binding used by the server, so local Python is not required for this install path. For normal use, let the MCP host start the executable instead of double-clicking it directly.
Source install
Use an isolated Python environment when possible. A virtual environment is recommended because it keeps KiPilot's runtime dependencies separate from system Python, but it is not a product requirement if your team already manages Python environments another way.
Windows helper
.\start-kipilot-mcp.ps1 -SkipRun
The helper creates or reuses .venv, installs the KiPilot runtime package, applies conservative default environment variables, and exits before starting the server. Run the same script without -SkipRun for a manual terminal launch.
Manual install
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install .
On macOS or Linux, activate the environment with source .venv/bin/activate. For development, install the editable package with test and lint dependencies:
python -m pip install -e ".[dev]"
You can run the server directly for manual checks, although most users will launch it through their MCP host:
kipilot-mcp
# or
python -m kipilot_mcp.server
Before first use
- Start KiCad and open the target project yourself.
- Open the PCB Editor, not only the project window, for the board tools.
- Open the Schematic Editor for the schematic tools, and use a KiCad 11 (master/nightly) build, because stable KiCad 10.0.x does not expose the schematic APIs.
- If needed in your KiCad build, enable the API under Preferences -> Plugins -> Enable KiCad API.
- Keep the setup simple by using one KiCad instance at a time.
Endpoint resolution
- When KiCad launches an API plugin, it can provide KICAD_API_SOCKET and KICAD_API_TOKEN.
- When launching from VS Code or another host, you may need to pass those values yourself.
- If ping_kicad works but board tools do not, you are likely connected to the wrong endpoint and need the PCB Editor endpoint.
- Schematic tools need the Schematic Editor endpoint, so open that editor before calling them.
Runtime behavior is controlled entirely by environment variables.
KiPilot reads configuration at startup and again for each tool call. That makes MCP host configuration the source of truth for endpoint selection, timeouts, mutation permissions, commit prefixes, and logging.
# Official KiCad IPC values when available
KICAD_API_SOCKET=...
KICAD_API_TOKEN=...
# KiPilot runtime values
KIPILOT_KICAD_CLIENT_NAME=kipilot-mcp
KIPILOT_KICAD_TIMEOUT_MS=60000
KIPILOT_ENABLE_MUTATIONS=0
KIPILOT_COMMIT_MESSAGE_PREFIX=KiPilot MCP
KIPILOT_LOG_LEVEL=INFO
KIPILOT_LOG_FILE=.logs/kipilot-mcp.log
Endpoint and identity settings
- KICAD_API_SOCKET: explicit socket or named-pipe endpoint when the default is not correct.
- KICAD_API_TOKEN: token for KiCad API authentication when provided by KiCad.
- KIPILOT_KICAD_CLIENT_NAME: the logical client name sent to KiCad. Defaults to kipilot-mcp.
Performance and timeout settings
- KIPILOT_KICAD_TIMEOUT_MS: IPC timeout in milliseconds. Default is 60000.
- The default is intentionally high because zone refills and some board operations can take tens of seconds on large designs.
- Increase the timeout further on slower machines or unusually large boards.
Mutation controls
- KIPILOT_ENABLE_MUTATIONS: when false, write tools only work in dry-run mode.
- KIPILOT_COMMIT_MESSAGE_PREFIX: prefix for grouped write commits such as KiPilot MCP: move_footprint.
- Destructive tools and high-risk board-state changes still require force=true even when mutations are enabled.
Logging controls
- KIPILOT_LOG_LEVEL: one of DEBUG, INFO, WARNING, ERROR, or CRITICAL.
- KIPILOT_LOG_FILE: optional path for persistent structured logs in addition to stderr.
- Never redirect logs to stdout, because stdout is the MCP wire.
Any stdio-capable MCP client can launch KiPilot with either the Windows executable or the Python command model.
The exact configuration file format depends on the host, but the transport model is identical in both cases: either run the extracted kipilot-mcp.exe from the Windows ZIP release, or run the Python interpreter inside the KiPilot environment and execute -m kipilot_mcp.server.
GitHub Copilot in VS Code (Windows ZIP release)
{
"servers": {
"kipilot-mcp": {
"type": "stdio",
"command": "C:\\Tools\\kipilot-mcp-VERSION-windows-x64\\kipilot-mcp.exe",
"env": {
"KIPILOT_KICAD_CLIENT_NAME": "kipilot-mcp",
"KIPILOT_KICAD_TIMEOUT_MS": "60000",
"KIPILOT_LOG_LEVEL": "INFO",
"KIPILOT_LOG_FILE": ".logs/kipilot-mcp.log"
}
}
}
}
GitHub Copilot in VS Code (source install)
{
"servers": {
"kipilot-mcp": {
"type": "stdio",
"command": "${workspaceFolder}\\.venv\\Scripts\\python.exe",
"args": ["-m", "kipilot_mcp.server"],
"env": {
"KIPILOT_KICAD_CLIENT_NAME": "kipilot-mcp",
"KIPILOT_KICAD_TIMEOUT_MS": "60000",
"KIPILOT_LOG_LEVEL": "INFO",
"KIPILOT_LOG_FILE": ".logs/kipilot-mcp.log"
}
}
}
}
Generic stdio MCP host
{
"mcpServers": {
"kipilot-mcp": {
"command": "C:\\absolute\\path\\to\\.venv\\Scripts\\python.exe",
"args": ["-m", "kipilot_mcp.server"],
"env": {
"KIPILOT_KICAD_CLIENT_NAME": "kipilot-mcp",
"KIPILOT_KICAD_TIMEOUT_MS": "60000",
"KIPILOT_LOG_LEVEL": "INFO",
"KIPILOT_LOG_FILE": ".logs/kipilot-mcp.log"
}
}
}
}
- Use the Windows ZIP release when you want a self-contained Windows MCP server command without managing Python locally.
- Restart the host after changing server configuration.
- Add KICAD_API_SOCKET and KICAD_API_TOKEN only when the default endpoint is not correct.
- Use a workspace-relative log file only when the host launches the server from a predictable working directory.
All tools return JSON objects with predictable success, error, identity, and unit conventions.
The server is optimized for MCP hosts and agent workflows, so responses deliberately echo target identifiers, requested changes, and normalized geometry. That makes it easier for an agent to preview, explain, and then safely apply the same change.
Not every MCP tool is a raw IPC 1:1 wrapper
KiPilot does not limit itself to exposing only operations that already exist as one direct KiCad IPC call. When the binding exposes enough mutable board state to build a safe higher-level action, KiPilot can present that as one MCP tool for the agent.
- kicad_flip_footprint is the current concrete example.
- The KiCad binding exposes mutable footprint placement, child graphics, text, pads, and zones, but not one native footprint-flip call.
- KiPilot composes those lower-level mutations into one footprint-side flip tool that mirrors child geometry and swaps paired front/back layers.
- kicad_update_footprint_pad_net is another high-level example.
- The binding exposes mutable footprint child pads and board net objects, but KiPilot adds footprint-scoped pad resolution, dry-run preview, and stale-data guards as one agent-friendly pad-net reassignment tool.
- kicad_sch_create_items is the schematic example: one call takes a mixed list of item specifications, expands a points polyline into one wire or bus segment per vertex pair, resolves label shape and rotation names into KiCad enums, and returns the previewed items in one response.
Success and failure shape
Failure responses are uniform across every tool. Success responses are not: state-changing and connection tools report an explicit ok: true, while read-only tools return their payload directly, so check the documented fields for those instead of testing ok.
# Success from a state-changing or connection tool
{
"ok": true,
"mutation": "sch_create_items",
"dry_run": false,
"commit_message": "KiPilot MCP: sch_create_items",
"...": "tool-specific fields"
}
# Success from a read-only tool (no "ok" field)
{
"schematic": { "...": "document identity" },
"total": 12,
"count": 12,
"truncated": false,
"items": [ "..." ]
}
# Failure (every tool)
{
"ok": false,
"message": "Human-readable explanation",
"error": "Underlying error when available"
}
Common serialization patterns
# Position or point
{
"x_nm": 1500000,
"y_nm": 2500000,
"x_mm": 1.5,
"y_mm": 2.5
}
# Layer
{
"id": 0,
"name": "F.Cu"
}
# Net
{
"name": "+3V3",
"code": 7
}
Units and coordinates
- Tool inputs use millimeters for geometry fields such as x_mm, y_mm, width_mm, and diameter_mm.
- Most outputs provide both millimeters and nanometers for deterministic round-tripping.
- Outline and polyline inputs are lists of point objects with x_mm and y_mm.
Identity and lookup rules
- Use the returned item IDs from read tools for later mutation calls whenever possible.
- Footprint operations typically allow either reference or footprint_id.
- Track, zone, via, and generic item operations are ID-driven.
- Schematic item operations are ID-driven too: edits and deletions take item_id or item_ids from kicad_sch_get_items, kicad_sch_get_symbols, kicad_sch_get_labels, or kicad_sch_get_selection.
Dry runs and commit groups
- Most write tools accept dry_run and return a preview of the post-change state without persisting it.
- When mutations are enabled, many write tools wrap operations in a KiCad commit group; a dry run does not open a commit at all.
- kicad_save_board and kicad_sch_save persist the current document and do not create a separate commit group.
- The schematic variant tools run outside item commit transactions on purpose, so they do not leave empty undo steps behind.
Dangerous operations
- kicad_revert_board, kicad_delete_items, kicad_sch_remove_items, and live kicad_set_enabled_layers calls require force=true.
- These tools also report dangerous: true in their response payloads.
- Enabling mutations does not bypass the force guard.
- kicad_sch_delete_variant is destructive but not force-gated: it removes variant metadata that only becomes unrecoverable once you save the schematic.
The current MCP surface contains 135 tools. This reference groups them by domain first, then by workflow level.
Start with common session tools, then schematic tools, then PCB tools from inspection through high-level workflows and low-level editing. The MCP host still sees each item as a flat callable tool.
Common session tools
Reachability, version, open-document discovery, KiCad paths, TOOL_ACTION execution, and headless document lifecycle across PCB and schematic sessions. 10 tools.
Schematic tools
Inspection, hit-testing, item creation and editing, document access, selection, metadata updates, lifecycle (save-as/revert), design variants, and export jobs. 37 tools on a KiCad 11 (master/nightly) build.
PCB inspection tools
Board context, project metadata, geometry, connectivity, manufacturing exports, design rules, embedded files, and low-level lookup helpers. 88 PCB tools in total.
High-level PCB workflow tools
Agent-friendly footprint, pad-net, title-block, and text operations built above raw IPC primitives.
PCB editor-state tools
Selection, layer visibility, active layer, origins, and rendering preferences inside the live board editor.
Low-level PCB editing and persistence
Tracks, vias, zones, whitelisted batch updates, deletion, refill, save, save-as, and revert flows.
Common session and discovery tools
ping_kicad() is the primary health probe. It takes no arguments and verifies that the KiCad IPC endpoint is reachable.
- Returns socket_path, client_name, kicad_version, api_version, and api_version_matches_binding.
- Typical success message: KiCad IPC endpoint is reachable.
- Typical failure explains that KiCad is not reachable and includes the underlying error when available.
- If the running KiCad is newer than the kicad-python binding was built against, the probe still reports ok: true and adds a version_warning field with the version mismatch. The transport is healthy in that case; only the binding is older.
get_kicad_version() uses the same underlying reachability and version probe, but is named for hosts and prompts that specifically ask for version data.
- No arguments.
- Useful as the second validation check after ping_kicad.
kicad_list_open_documents(document_types=None) returns the active board and project documents or filters by explicit KiCad document type IDs.
- document_types is optional and accepts a list of integer type IDs.
- Returns documents, count, and a source indicator describing how the active document set was resolved.
Schematic read and inspection tools
kicad_sch_get_hierarchy() returns the top-level schematic hierarchy tree for the active schematic.
- No arguments.
- Returns serialized sheet-instance entries that can be reused when a workflow needs sheet-aware context.
- This tool is available only on a KiCad 11 (master/nightly) build, because upstream KiCad 10.0.x does not expose the schematic item APIs.
kicad_sch_get_netlist(item_types=None) returns the current schematic netlist, optionally filtered by KiCad schematic item type IDs.
- item_types is optional and narrows the returned item classes.
- Use this when a board-side reasoning flow needs to compare current schematic connectivity against PCB state.
kicad_sch_hit_test(item_id, x_mm, y_mm, tolerance_mm=0.0) checks whether one schematic item is hit at a given schematic-space position.
- item_id, x_mm, and y_mm are required.
- Use this when an agent needs to confirm whether a previously resolved schematic object really occupies a target coordinate before reasoning about local edits or annotations.
kicad_sch_get_page_settings() and kicad_sch_get_title_block() expose the current schematic page layout metadata.
- The page-settings tool returns page size, orientation, drawing sheet, and user page size fields.
- The title-block tool returns title, revision, date, company, and comment slots.
Schematic metadata and export tools
kicad_sch_set_page_settings(page_size=None, orientation=None, drawing_sheet=None, user_page_size_mm=None, dry_run=False, commit_message=None) merges page-layout changes into the current schematic.
- At least one page-settings field must change.
- user_page_size_mm expects both x_mm and y_mm.
- Dry-run responses include both the previous and resulting page-settings state.
kicad_sch_set_title_block(title=None, revision=None, date=None, company=None, comments=None, dry_run=False, commit_message=None) merges partial schematic title-block edits.
- At least one field or comment change must be provided.
- comments is a mapping keyed by title-block comment slot numbers.
- Dry-run responses include both the previous title block and the merged result.
kicad_sch_export_svg(output_dir, plot_settings=None), kicad_sch_export_dxf(output_dir, plot_settings=None), and kicad_sch_export_ps(output_dir, plot_settings=None) export the current schematic as one file per plotted sheet into an output directory.
- output_dir is required and must be a directory path, not a file-like path such as demo.svg.
- The response echoes both output_dir and a normalized output_kind: "directory".
- These jobs can emit multiple files for hierarchical schematics because KiCad plots one file per sheet.
kicad_sch_export_pdf(output_file, plot_settings=None, property_popups=False, hierarchical_links=False, include_metadata=True) exports the current schematic to a PDF file.
- output_file is required and must be a file path, not a directory path.
- The response echoes both output_file and a normalized output_kind: "file".
- property_popups, hierarchical_links, and include_metadata map directly to the underlying KiCad PDF export job options.
- For a full export, plot_all=true with omitted plot_pages is the safest default unless you already know the exact sheet-instance paths to filter.
kicad_sch_export_netlist(output_file, netlist_format=2, variant_name="") exports the current schematic netlist to one file.
- output_file is required and must be a file path.
- netlist_format accepts KiCad netlist format IDs or names supported by the MCP server.
- variant_name is optional and lets a workflow request a variant-specific export when the project defines one.
kicad_sch_export_bom(output_file, format_settings=None, field_settings=None, exclude_dnp=False, group_symbols=False, variant_name="") exports the current schematic BOM to one file.
- output_file is required and must be a file path.
- format_settings and field_settings are optional structured settings that control BOM output shape and included fields.
- exclude_dnp, group_symbols, and variant_name map directly to the underlying KiCad BOM job options.
Schematic selection tools
kicad_sch_get_selection(limit=200) returns the current schematic selection.
- Inspect live editor context before deciding whether selection-sensitive schematic flows are safe.
- Each item is serialized with its KiCad item ID and type.
kicad_sch_add_to_selection(item_ids, dry_run=False) adds one or more schematic items to the current selection by their IDs.
- item_ids is required and must reference existing schematic items.
- Dry-run mode previews the resulting selection set without modifying the editor.
kicad_sch_remove_from_selection(item_ids, dry_run=False) removes one or more schematic items from the current selection by their IDs.
- Mirrors the board-side selection tools but operates on the active schematic editor.
kicad_sch_clear_selection(dry_run=False) clears the current schematic selection.
- Returns the previous selection count before clearing.
Schematic editing tools
kicad_sch_create_items(items, dry_run=False, commit_message=None) creates wires, buses, junctions, no-connects, labels, text and symbol instances in the active schematic.
- Each entry is an object with a kind plus geometry in millimeters.
- wire and bus take a points polyline and are split into one segment per consecutive vertex pair.
- label, global_label and hierarchical_label accept text, spin_style and, where the KiCad build supports it, shape.
- text, junction and no_connect are single-item kinds with an x_mm/y_mm anchor.
- symbol entries place a symbol instance with reference, value, unit, body_style and lib_id; lib_id must use the library:symbol form, and the library definition itself must already be resolvable by the running KiCad build.
- Dry-run returns the exact item previews that would be created without touching the document.
kicad_sch_update_items(updates, dry_run=False, commit_message=None) moves and edits existing schematic items by ID.
- Supported fields: x_mm and y_mm (both required together), text, reference, value, unit, spin_style, shape, diameter_mm and locked.
- Each update echoes back the list of fields it actually changed, so agents can confirm the applied delta.
kicad_sch_remove_items(item_ids, dry_run=False, commit_message=None, force=False) deletes schematic items by ID.
- Destructive: it requires force=true even when mutations are enabled.
kicad_sch_save(dry_run=False) persists the schematic document to disk.
- Item writes stay in the editor session until this tool runs, matching the board-side save flow.
Schematic item and document tools
kicad_sch_get_items(limit=200, kinds=None) lists schematic items, optionally filtered by kind.
- Valid kinds are the same values accepted by kicad_sch_create_items.
- Reports total, count and a truncated flag so agents can page through large sheets.
kicad_sch_get_symbols(limit=200) and kicad_sch_get_labels(limit=200) return symbol instances and local, global and hierarchical labels on the active sheet.
- Use these before symbol or label edits instead of scanning the full item list.
kicad_sch_get_as_string() and kicad_sch_get_selection_as_string() return the document, or just the current selection, as KiCad s-expression text.
- Handy for diffing a planned edit against the live document before applying it.
kicad_sch_is_document_modified() reports whether the schematic has unsaved modifications.
- Use it to decide whether kicad_sch_save is needed before handing the document back to a human.
Schematic design variant tools
kicad_sch_get_variants() and kicad_sch_get_current_variant() list the design variants defined on the schematic and report the active one.
- Each entry reports the variant name and description.
kicad_sch_add_variant(name, description=None, dry_run=False) adds a variant, and kicad_sch_delete_variant(name, dry_run=False) removes one.
- Duplicate or unknown variant names are rejected with a clear error listing the known variants.
kicad_sch_rename_variant(old_name, new_name, dry_run=False) and kicad_sch_copy_variant(old_name, new_name, new_description=None, dry_run=False) reorganize existing variants.
- Copying keeps the source variant's assembly configuration and can override the description.
kicad_sch_set_variant_description(name, description, dry_run=False) updates the description, and kicad_sch_set_current_variant(name=None, dry_run=False) activates a variant, or the default variant when name is omitted or an empty string.
- Variant commands are version-gated: they need a KiCad build that exposes the variant IPC commands and report a capability error otherwise.
PCB context and project tools
kicad_get_board_summary() is the high-level board inventory tool.
- No arguments.
- Returns serialized board metadata plus counts for footprints, nets, tracks, vias, zones, graphics, and text items.
- Also returns copper_layer_count and the active layer ID.
kicad_get_board_outline() extracts Edge.Cuts-derived geometry for the current PCB.
- No arguments.
- Use this to understand overall board extents and shape before placement or routing changes.
kicad_get_stackup() returns stackup layers together with visible and enabled layer sets.
- No arguments.
- Returns physical or logical stackup entries, including dielectric information when exposed by the binding.
- Also returns visible_layers and enabled_layers as serialized layer objects.
kicad_get_project_text_variables() returns project-scoped text variables for the active board project.
- No arguments.
- Returns a project descriptor plus both a map and an array representation of available text variables.
kicad_expand_project_text_variables(text) expands project variables inside one text fragment.
- text is required and is returned back as input_text beside the expanded result.
- Use this when an agent needs to preview the concrete value of title-block or project-driven strings before writing them elsewhere.
kicad_get_project_net_classes() returns project net classes with serialized rule values.
- No arguments.
- Returns the project descriptor, a count, and per-netclass rule fields such as clearance, track width, via diameter, and via drill in both nanometers and millimeters.
kicad_get_board_origins() and kicad_get_title_block() expose board metadata often needed in automation workflows.
- The origin tool returns both grid and drill origins.
- The title block tool returns title, revision, date, company, and comment slots.
PCB inspection and lookup tools
kicad_get_footprints(limit=200) returns placed footprints with IDs, references, values, positions, orientations, layers, and lock state.
- limit defaults to 200.
- Use returned footprint IDs in later mutation tools for exact targeting.
kicad_find_footprints(reference=None, footprint_id=None, text_query=None, layer=None, area=None, limit=200) performs focused footprint lookup.
- reference and footprint_id narrow by identity.
- text_query searches text-bearing footprint fields exposed by the binding.
- layer accepts a numeric ID or canonical name such as F.Cu.
- area expects x_min_mm, y_min_mm, x_max_mm, and y_max_mm.
- Returns the normalized query block so clients can see how the request was resolved.
kicad_get_nets(limit=200) returns serialized net names and codes.
- Use net names from this tool as safe inputs for routing or track-editing tools.
kicad_get_items_by_net(net_name, item_types=None, layer=None, area=None, limit=200) returns heterogeneous board items attached to a named net.
- net_name is required.
- item_types can narrow the KiCad item classes to include.
- layer and area work as additional geometry filters.
- This is useful when an agent must find all board objects associated with a signal before editing.
kicad_get_items_by_netclass(netclass_name, item_types=None, layer=None, area=None, limit=200) returns heterogeneous board items associated with a named net class.
- netclass_name is required and is resolved against the active project.
- Use this when inspection should follow design-rule intent rather than a single explicit net.
- layer, area, and optional KiCad item_types behave like the net-based lookup tool.
kicad_get_netclass_for_nets(net_names) returns the effective net class for one or more named nets.
- net_names is a required non-empty string array.
- Useful for validating whether a proposed routing change belongs to the expected design-rule bucket before editing geometry.
kicad_get_connected_items(item_id, item_types=None, layer=None, area=None, limit=200) traces copper-connected items from a source item.
- item_id is required and should come from an earlier read tool.
- The response includes the serialized source_item plus the connected item set, making it suitable for explainable agent workflows.
kicad_get_tracks(limit=200), kicad_get_vias(limit=200), and kicad_get_zones(limit=200) return serialized geometry collections.
- Tracks include start and end points, layer, net, lock state, width, length, and bounding box.
- Vias include position, net, diameter, drill diameter, lock state, and via type.
- Zones include net, layers, fill status, priority, type, bounding box, and outline geometry.
kicad_get_pads(net_name=None, layer=None, area=None, limit=200, reference=None, footprint_id=None) returns serialized pads with optional net, layer, area, and footprint filters.
- reference and footprint_id let an agent ask for pads belonging to one exact footprint, which is especially useful for connector and header workflows.
- Results include pad ID, number, position, pad type, net, and padstack-derived layer presence.
- When a footprint filter is used, each result also echoes the parent footprint ID and reference.
- This is the right starting point for pad-aware review flows before any future pad-geometry helpers are introduced.
kicad_get_graphics(layer=None, area=None, limit=200) returns generic board graphics beyond the derived board outline.
- Use it to inspect silkscreen, fabrication, or other board-shape graphics directly instead of only the Edge.Cuts outline.
- Each result includes its item ID, kind, layer, lock state, bounding box, and shape points exposed by the binding.
kicad_get_dimensions(limit=200), kicad_get_groups(limit=200), kicad_get_reference_images(limit=200), and kicad_get_barcodes(limit=200) close out additional board object classes that are useful in review and reverse-engineering workflows.
- Dimensions expose measured annotation objects rather than raw geometry primitives.
- Groups are useful when an agent needs to preserve designer grouping intent during localized edits.
- Reference images expose non-plotting placement aids on the board.
- Barcodes expose encoded production or traceability markings placed on the board.
kicad_get_board_text(text_id=None, text_query=None, layer=None, exact=False, limit=200) returns standalone board text and board text box items.
- Use text_query for substring search or set exact=true for an exact text match.
- layer accepts a numeric ID or canonical name such as F.SilkS.
- Results return the text item ID, current text content, layer, lock state, and position or text box corners.
kicad_get_items(item_kinds=None, limit=200) and kicad_get_items_by_id(item_ids, limit=200) expose low-level heterogeneous item lookup across footprints, pads, tracks, vias, zones, graphics, and related board objects.
- kicad_get_items is the broad inventory tool for one or more item kinds.
- kicad_get_items_by_id is the exact-resolution tool when an earlier read step already captured concrete KiCad item IDs.
kicad_hit_test(item_id, x_mm, y_mm, tolerance_mm=0.0) checks whether one board item is hit at a given board-space position.
- item_id, x_mm, and y_mm are required.
- Use this when an agent needs to confirm whether a previously found object really occupies a target coordinate before editing around it.
kicad_get_text_extents(text_item_id) and kicad_get_text_as_shapes(text_item_ids) expose derived text geometry.
- The extents tool returns the bounding box for one board text item.
- The shape-conversion tool returns polygonal outlines for one or more board text items, which is useful for downstream geometry reasoning or export workflows.
kicad_check_padstack_presence_on_layers(item_ids, layers) and kicad_get_pad_shapes_as_polygons(pad_ids, layer, limit=200) provide pad-geometry helpers for manufacturing and clearance workflows.
- kicad_check_padstack_presence_on_layers verifies whether padstack-bearing items have copper on specific layers.
- kicad_get_pad_shapes_as_polygons polygonizes pad outlines on one requested layer so downstream tooling can reason about the effective copper shape.
High-level PCB workflow and metadata tools
kicad_set_project_text_variables(variables, merge_mode="merge", dry_run=False) updates project-scoped text variables used by titles, templates, and other project-driven strings.
- variables is required and must be a non-empty string map.
- merge_mode supports merge-style updates or full replacement of the variable set.
- Dry-run responses preview both the previous and resulting variable maps.
kicad_move_footprint(x_mm, y_mm, reference=None, footprint_id=None, dry_run=False, commit_message=None) moves a footprint to an absolute board coordinate.
- Requires either reference or footprint_id.
- Returns the previous serialized footprint, the updated footprint preview or result, and the requested position.
kicad_rotate_footprint(orientation_degrees, reference=None, footprint_id=None, dry_run=False, commit_message=None) sets footprint orientation in degrees.
- Supports dry runs and the same targeting rules as kicad_move_footprint.
- Returns both previous and resulting footprint state.
kicad_flip_footprint(reference=None, footprint_id=None, target_layer=None, dry_run=False, commit_message=None) flips a footprint to the opposite copper side.
- Supports the same targeting rules as kicad_move_footprint and kicad_rotate_footprint.
- target_layer is optional; omit it to flip to the other side automatically, or set it explicitly to F.Cu or B.Cu.
- Returns the previous serialized footprint, the resulting footprint preview or result, plus previous_layer, target_layer, and mirrored.
- This tool is intentionally higher level than the raw KiCad IPC surface: KiPilot implements the visible mirrored flip behavior itself by updating the footprint side, mirroring supported child geometry around the footprint anchor, and swapping paired side-specific layers such as silkscreen.
kicad_update_footprint_pad_net(net_name, reference=None, footprint_id=None, pad_number=None, pad_id=None, expected_current_net_name=None, dry_run=False, commit_message=None) reassigns one footprint pad to a different board net.
- net_name is required and must resolve on the active board.
- Target the parent footprint with reference or footprint_id, then choose the pad with pad_number or pad_id.
- expected_current_net_name is an optional stale-data guard that makes the request fail if the pad no longer belongs to the expected source net.
- Dry-run responses include both previous_pad and pad together with the parent footprint state before and after the preview.
- This is a high-level KiPilot tool rather than a raw one-shot IPC call: KiPilot resolves the child pad inside the footprint, clones the footprint safely, updates the selected pad net, and writes the whole footprint back through the guarded board update path.
- This changes PCB net attachment on the active board only. Keep schematic or upstream net-intent sources in sync separately so later forward-annotation does not overwrite the board-side change.
kicad_set_title_block(title=None, revision=None, date=None, company=None, comments=None, dry_run=False, commit_message=None) merges partial title block updates.
- At least one field or comment change must be provided.
- comments is a mapping keyed by title block comment slot numbers.
- Dry-run responses include both the previous title block and the merged post-change title block.
kicad_update_board_text(text_id, new_text, expected_current_text=None, dry_run=False, commit_message=None) updates one standalone board text or board text box by item ID.
- text_id and new_text are required.
- Use expected_current_text as a stale-data guard when the text must still match an exact known value before the write is applied.
- Dry-run responses include both the previous text item and the post-change preview so an agent can verify the exact silkscreen label before writing.
PCB editor-state and selection tools
kicad_get_selection(limit=200), kicad_add_to_selection(item_ids, dry_run=False), kicad_remove_from_selection(item_ids, dry_run=False), and kicad_clear_selection(dry_run=False) expose the live board-editor selection set.
- Use kicad_get_selection to inspect current editor context before deciding whether selection-sensitive flows are safe.
- The mutation tools preview or apply the resulting selection set but do not modify board-file content.
kicad_get_board_layer_by_name(layer_name) resolves a board layer id from its canonical KiCad name.
- Handy for converting human-friendly names such as F.Cu or B.Silkscreen into the numeric ids many other tools accept.
kicad_flip_board_items(item_ids, direction="left_right", dry_run=False, commit_message=None) flips one or more board items to the opposite side by their unique IDs.
- item_ids is required and must reference existing flippable board items.
- direction is left_right (mirror around the Y axis) or top_bottom (mirror around the X axis).
- This uses the native KiCad flip IPC call and returns the flipped items; unlike kicad_flip_footprint, it works on any flippable item type.
kicad_get_board_plot_settings() and kicad_set_board_plot_settings(plot_settings, dry_run=False, commit_message=None) read and update the board plot settings stored in the current PCB.
- Plot settings control export behavior such as layers, color theme, mirroring, drill marks, and per-layer plot flags.
- String layer names in plot_settings.layers are resolved through the board before writing.
kicad_get_graphics_defaults() and kicad_get_editor_appearance_settings() expose current editor rendering preferences.
- Graphics defaults describe per-layer-class default styles.
- Appearance settings expose fields such as inactive-layer display, net-color display, board flip, and ratsnest display.
kicad_set_editor_appearance_settings(inactive_layer_display=None, net_color_display=None, board_flip=None, ratsnest_display=None, dry_run=False) updates editor rendering preferences without changing board-file geometry.
- Provide one or more settings to change; omitted fields stay unchanged.
- Dry-run mode previews the resulting appearance-state payload before applying it live.
kicad_set_visible_layers(layers, dry_run=False, commit_message=None) updates the visible layer set.
- layers is required and accepts layer names or numeric IDs.
- Returns previous visible layers, resolved target layers, and the resulting visible layer set.
- When mutations are enabled, the operation is committed under the configured commit prefix unless an explicit commit_message is provided.
kicad_set_active_layer(layer, dry_run=False, commit_message=None) updates the current active layer in the board editor.
- layer is required and accepts a numeric layer ID or canonical name such as F.SilkS.
- Returns both the previous and resulting active layer as serialized layer objects.
kicad_set_enabled_layers(non_copper_layers, dry_run=False, commit_message=None, force=False) updates enabled non-copper layers while preserving the current copper layer count.
- The tool intentionally does not expose arbitrary copper-layer-count edits.
- Dry-run mode previews the resulting enabled layer set without requiring live write access.
- Live mode requires force=true because disabling layers can delete content already placed on those layers.
kicad_set_board_origin(origin_type, x_mm, y_mm, dry_run=False, commit_message=None) updates the grid or drill/place origin.
- origin_type accepts grid, drill, 1, or 2.
- Returns previous and requested origin coordinates with a normalized origin type object.
Low-level PCB editing tools
kicad_create_track_segments(points, layer, width_mm, net_name=None, locked=False, dry_run=False, commit_message=None) creates straight track segments from a polyline.
- points is an ordered list of board-space points in millimeters.
- The tool creates one segment between each consecutive point pair.
- Returns the resulting track list, layer, net, and count.
kicad_create_via(x_mm, y_mm, diameter_mm, drill_diameter_mm, net_name=None, via_type=1, locked=False, dry_run=False, commit_message=None) creates a via at an absolute position.
- The default via_type is 1, which maps to through.
- Returns position, diameter, drill diameter, via type, net, and the serialized via result.
kicad_update_track_geometry(track_id, start_x_mm=None, start_y_mm=None, end_x_mm=None, end_y_mm=None, width_mm=None, layer=None, net_name=None, locked=None, dry_run=False, commit_message=None) updates one straight track.
- track_id is required.
- At least one geometry or metadata field must change.
- Supports endpoint edits, width changes, layer reassignment, net reassignment, and lock-state updates.
kicad_update_zone_outline(zone_id, outline_points, dry_run=False, commit_message=None) replaces the outer polygon of a zone.
- zone_id and outline_points are required.
- The outline must contain at least three points.
- The tool focuses on the primary zone outline rather than exposing a generic full-zone editor.
kicad_update_items(updates, dry_run=False, commit_message=None) is the controlled batch updater.
- updates must be a non-empty array of objects.
- Each target item may only appear once per request.
- Only footprint, track, and zone kinds are allowed.
- Footprint updates can change absolute position with x_mm/y_mm, orientation with orientation_degrees, and front/back copper side with layer.
- Unsupported fields are rejected explicitly instead of being ignored silently.
# Whitelisted update shapes
{
"kind": "footprint",
"reference": "R1",
"footprint_id": "optional-id",
"x_mm": 10.0,
"y_mm": 12.0,
"orientation_degrees": 90.0,
"layer": "B.Cu"
}
{
"kind": "track",
"track_id": "track-id",
"start_x_mm": 1.0,
"start_y_mm": 2.0,
"end_x_mm": 6.0,
"end_y_mm": 2.0,
"width_mm": 0.25,
"layer": "F.Cu",
"net_name": "+3V3",
"locked": false
}
{
"kind": "zone",
"zone_id": "zone-id",
"outline_points": [
{"x_mm": 0.0, "y_mm": 0.0},
{"x_mm": 10.0, "y_mm": 0.0},
{"x_mm": 10.0, "y_mm": 8.0},
{"x_mm": 0.0, "y_mm": 8.0}
]
}
kicad_delete_items(item_ids, dry_run=False, commit_message=None, force=False) removes board items by KiCad item ID.
- Requires a non-empty list of item IDs.
- Requires force=true because it is destructive.
- Dry-run responses include the fully serialized target items.
kicad_refill_zones(zone_ids=None, dry_run=False, commit_message=None) refills all zones or a selected subset.
- When zone_ids is omitted, the server can refill all zones on the board.
- On large boards this can be slow, so the server includes targeted retry behavior for transient busy states.
PCB persistence and guarded operations
kicad_revert_board(dry_run=False, force=False) reverts unsaved board changes back to the last saved state.
- This tool is destructive and requires force=true.
- It supports dry-run preview and marks the response with dangerous: true.
- Unlike grouped commit mutations, the live operation calls the board revert directly.
- The implementation includes targeted retry behavior for transient timeout or busy conditions.
kicad_save_board(dry_run=False) persists the currently open board file.
- Dry-run mode reports the target filename without writing.
- Live mode calls the board save operation directly.
kicad_save_board_as(filename, overwrite=False, include_project=True, dry_run=False) writes the active board to a new file path.
- filename is required.
- overwrite controls whether an existing target may be replaced.
- include_project lets the save-as flow carry project context when the underlying KiCad API supports it.
Board manufacturing exports (0.3.0)
These tools run the KiCad-side IPC export jobs, so the produced files match what the GUI plot dialogs and kicad-cli generate. Directory-output jobs write one file per layer into a directory; file-output jobs write exactly one file.
- kicad_export_board_svg(output_dir, fit_page_to_board=False, precision=4, plot_settings=None) plots the board to SVG.
- kicad_export_board_dxf(output_dir, plot_graphic_items_using_contours=False, polygon_mode=False, units=None, plot_settings=None) plots the board to DXF.
- kicad_export_board_pdf(output_file, include_metadata=True, single_document=True, background_color="", front_footprint_property_popups=False, back_footprint_property_popups=False, plot_settings=None) plots the board to one PDF file.
- kicad_export_board_ps(output_dir, force_a4=False, use_global_settings=False, plot_settings=None) plots the board to PostScript.
- kicad_export_gerbers(output_dir, create_gerber_job_file=False, use_x2_format=True, include_netlist_attributes=True, use_protel_file_extensions=True, disable_aperture_macros=False, precision=None, plot_settings=None) writes the Gerber set plus optional job file.
- kicad_export_drill(output_dir, drill_format=None, origin=None, map_format=None, report_filename="", route_oval_holes=False, mirror_y=False, generate_tenting=False) writes Excellon or Gerber NC drill files. Short enum names such as excellon, gerber, or pdf are accepted next to the full proto names.
- kicad_export_position(output_file, settings=None) writes the pick-and-place position file.
- kicad_export_gencad(output_file, flip_bottom_pads=False, use_individual_shapes=False, store_origin_coords=False, use_drill_origin=False, use_unique_pins=False) writes GenCAD.
- kicad_export_ipc2581(output_file, settings=None) writes IPC-2581.
- kicad_export_ipc_d356(output_file) writes the IPC-D-356 netlist.
- kicad_export_odb(output_dir, drawing_sheet="", variant="", units=None, precision=6, compression=None) writes ODB++.
- kicad_export_stats(output_file, output_format=None, units=None, exclude_footprints_without_pads=False, subtract_holes_from_board_area=False, subtract_holes_from_copper_areas=False) writes the board statistics report.
- kicad_export_3d(output_file, settings=None) writes a STEP/STEPZ 3D model.
- kicad_export_render(output_file, settings=None) writes a raytraced 3D render.
plot_settings accepts the same object shape as kicad_set_board_plot_settings, so a plot preset can be read once with kicad_get_board_plot_settings, adjusted, and reused across several export formats. Settings mappings for 3D, render, position, and IPC-2581 exports use snake_case proto field names; unknown fields are rejected with a descriptive error instead of being silently ignored.
Board design rules and embedded files (0.3.0)
Design rule payloads round-trip: whatever kicad_get_design_rules returns can be edited and sent back to kicad_set_design_rules, because both directions use the same proto field names.
- kicad_get_design_rules() returns minimum constraints, predefined sizes, solder mask and paste defaults, teardrops, via protection, DRC severities, exclusions, and the custom-rule status. Requires a KiCad 11 build.
- kicad_set_design_rules(rules, dry_run=False) merges the supplied fields into the current rules. Repeated fields such as severities or exclusions are replaced, not appended.
- kicad_get_custom_design_rules() returns the parsed .kicad_dru rules plus parse status and error text.
- kicad_set_custom_design_rules(rules, dry_run=False) replaces the custom rule set; an empty list clears the rules file.
- kicad_get_embedded_files(include_data=False) lists embedded fonts, 3D models, and datasheets with name, type, hash, and compressed size. Set include_data=true to include base64 payloads.
- kicad_add_embedded_files(paths, dry_run=False) embeds local files while keeping the existing embedded set.
- kicad_set_embedded_files(paths, dry_run=False, force=False) replaces every embedded file. Because that can drop data from the board file, it also requires force=true.
Forward annotation, geometry and workspace tools (0.3.0)
- kicad_import_netlist(netlist_path, match_mode="uuid", delete_extra_footprints=True, update_footprints=True, transfer_groups=True, override_locks=False, dry_run=False) forward-annotates a schematic netlist into the board. match_mode accepts uuid or reference. The response reports the KiCad netlist report text plus the error, warning, and new-footprint counts.
- kicad_get_bounding_box(item_ids, include_text=False) returns KiCad-computed bounding boxes for board items plus a merged box, which is useful for layout reasoning and export framing.
- kicad_set_project_net_classes(net_classes, merge_mode="merge", dry_run=False) creates or updates net classes with clearance, track width, diff-pair, and via values. merge_mode accepts merge or replace.
- kicad_get_paths() returns well-known KiCad filesystem paths such as the library, template, and plugin roots.
- kicad_get_kicad_binary_path(binary_name="kicad-cli") resolves the absolute path of a KiCad binary and reports whether it exists.
- kicad_get_plugin_settings_path(identifier) returns a writable per-plugin settings directory for add-ons.
- kicad_run_action(action, dry_run=False) runs a KiCad TOOL_ACTION by name, for example pcbnew.EditorControl.zoneFillAll. Action names are not a stable public API, so expect capability or invalid-action errors on unusual builds.
- kicad_open_document(path, document_type="pcb", dry_run=False), kicad_create_document(...), and kicad_close_document(...) manage documents in a headless KiCad API server session. They report a clear capability error when the connected endpoint is a GUI session.
kicad_get_items now also accepts the read-only board item kinds table, grid_item, constraint, and reference_point.
Schematic lifecycle and extended item reads (0.3.0)
- kicad_sch_save_as(filename, overwrite=False, include_project=True, dry_run=False) writes a copy of the schematic without opening it. Without overwrite=true an existing target is refused.
- kicad_sch_revert(dry_run=False, force=False) discards unsaved schematic changes and reloads the last saved state. It is destructive, therefore force-gated, and reports was_modified so the agent can tell whether anything was pending.
- kicad_sch_get_items(kinds=...) now also reads sheets, sheet pins, images, shapes, bus entries, rule areas, tables, groups, text boxes, directive labels, fields, and pins next to the existing creation kinds. Only the original creation kinds can be created or updated.
Use a read, preview, apply, then save flow for the safest agent-driven work.
KiPilot works best when an agent first discovers the exact target objects, previews the intended change, and only then applies the mutation. The examples below show the expected rhythm. The first seven cover PCB work; the last four cover the schematic surface, which additionally needs a KiCad 11 (master/nightly) build.
Recommended first prompts
- Run ping_kicad and tell me if KiCad is reachable.
- Run get_kicad_version and show the KiCad and IPC API version.
- Summarize the current board, then list the first ten footprints and nets.
- List the schematic sheets, then list the symbols and labels on the root sheet.
- List the design variants and tell me which one is active.
Safe edit pattern
- Resolve the target with kicad_find_footprints, kicad_get_board_text, kicad_get_pads, kicad_get_tracks, or kicad_get_zones.
- On the schematic side, resolve targets with kicad_sch_get_items, kicad_sch_get_symbols, or kicad_sch_get_labels.
- Preview the change with the matching write tool and dry_run=true.
- Apply the same change with mutations enabled.
- Use kicad_save_board or kicad_sch_save when you want the file written to disk.
Example: move a footprint safely
1. kicad_find_footprints(reference="R1")
2. kicad_move_footprint(reference="R1", x_mm=42.0, y_mm=18.5, dry_run=true)
3. kicad_move_footprint(reference="R1", x_mm=42.0, y_mm=18.5, dry_run=false)
4. kicad_save_board(dry_run=false)
Example: flip a logo footprint to the opposite side
1. kicad_find_footprints(reference="LOGO")
2. kicad_flip_footprint(reference="LOGO", dry_run=true)
3. kicad_flip_footprint(reference="LOGO", target_layer="B.Cu", dry_run=false)
4. kicad_save_board(dry_run=false)
Example: reassign one connector pad from GND to 12V
1. kicad_get_pads(reference="CON301")
2. kicad_update_footprint_pad_net(
reference="CON301",
pad_number="2",
net_name="12V",
expected_current_net_name="GND",
dry_run=true
)
3. kicad_update_footprint_pad_net(
reference="CON301",
pad_number="2",
net_name="12V",
expected_current_net_name="GND",
dry_run=false
)
4. kicad_save_board(dry_run=false)
If the pad reassignment is part of a real power-output redesign, follow it with the necessary track, via, and zone-refill operations. The pad-net tool only changes which board net the selected footprint pad belongs to.
Example: update a silkscreen board label safely
1. kicad_get_board_text(text_query="Mainboard v1.1", layer="F.SilkS", exact=true)
2. kicad_update_board_text(
text_id="board-text-id",
new_text="Mainboard v1.2",
expected_current_text="Mainboard v1.1",
dry_run=true
)
3. kicad_update_board_text(
text_id="board-text-id",
new_text="Mainboard v1.2",
expected_current_text="Mainboard v1.1",
dry_run=false
)
4. kicad_save_board(dry_run=false)
Example: batch update with a whitelist
kicad_update_items(
updates=[
{
"kind": "footprint",
"footprint_id": "footprint-id",
"orientation_degrees": 45.0,
"layer": "B.Cu"
},
{
"kind": "track",
"track_id": "track-id",
"width_mm": 0.3,
"locked": true
},
{
"kind": "zone",
"zone_id": "zone-id",
"outline_points": [
{"x_mm": 0.0, "y_mm": 0.0},
{"x_mm": 12.0, "y_mm": 0.0},
{"x_mm": 12.0, "y_mm": 6.0},
{"x_mm": 0.0, "y_mm": 6.0}
]
}
],
dry_run=true
)
Example: trace a power network by design-rule class
1. kicad_get_project_net_classes()
2. kicad_get_items_by_netclass("Power", layer="F.Cu")
3. kicad_get_connected_items(item_id="track-id")
4. kicad_get_netclass_for_nets(net_names=["+3V3", "GND"])
Example: preview a board-state change before a live layer update
1. kicad_get_stackup()
2. kicad_set_active_layer(layer="F.SilkS", dry_run=true)
3. kicad_set_enabled_layers(non_copper_layers=["F.SilkS", "Edge.Cuts"], dry_run=true)
4. kicad_set_enabled_layers(non_copper_layers=["F.SilkS", "Edge.Cuts"], dry_run=false, force=true)
Example: draw a schematic net from scratch
1. kicad_sch_get_items(limit=200, kinds=["wire", "label"])
2. kicad_sch_create_items(
items=[
{
"kind": "wire",
"points": [
{"x_mm": 50.8, "y_mm": 50.8},
{"x_mm": 63.5, "y_mm": 50.8},
{"x_mm": 63.5, "y_mm": 63.5}
]
},
{
"kind": "global_label",
"text": "VCC",
"x_mm": 63.5,
"y_mm": 63.5,
"spin_style": "right",
"shape": "input"
},
{ "kind": "junction", "x_mm": 63.5, "y_mm": 50.8 }
],
dry_run=true
)
3. Repeat the same call with dry_run=false.
4. kicad_sch_is_document_modified()
5. kicad_sch_save()
A three-vertex polyline becomes two wire segments. Always run the dry run first: it returns the exact item previews, so you can confirm the geometry before anything touches the document.
Example: relabel and move existing schematic items
1. kicad_sch_get_labels(limit=200)
2. kicad_sch_update_items(
updates=[
{ "item_id": "label-item-id", "text": "GND", "x_mm": 71.12, "y_mm": 50.8 }
],
dry_run=true
)
3. kicad_sch_update_items(updates=[ ... ], dry_run=false)
4. kicad_sch_save()
Each update echoes back the fields it actually changed. Moving an item needs x_mm and y_mm together; a move without text is valid, but a payload with no supported field at all is rejected.
Example: swap a design variant before a BOM export
1. kicad_sch_get_variants()
2. kicad_sch_copy_variant(old_name="default", new_name="lite", new_description="Reduced BOM", dry_run=true)
3. kicad_sch_copy_variant(old_name="default", new_name="lite", new_description="Reduced BOM", dry_run=false)
4. kicad_sch_set_current_variant(name="lite", dry_run=false)
5. kicad_sch_export_bom(output_file="C:/out/demo-lite.csv", variant_name="lite")
6. kicad_sch_set_current_variant(name="", dry_run=false) # empty name goes back to the default variant
Example: delete schematic items with a confirmation step
1. kicad_sch_get_selection(limit=200)
2. kicad_sch_remove_items(item_ids=["item-id"], dry_run=true)
3. kicad_sch_remove_items(item_ids=["item-id"], dry_run=false, force=true)
4. kicad_sch_save()
Deletion is force-gated even when mutations are enabled, and a dry run still reports exactly which items would disappear.
Logging, retries, timeout sizing, and mutation guardrails are part of the runtime contract.
KiPilot is meant for real board sessions, so operational behavior matters as much as the raw tool catalog. The current implementation includes deliberate choices around logs, retries, and write safety.
Logging
- Logs go to stderr by default.
- Set KIPILOT_LOG_FILE to persist the same records to disk.
- Server startup, tool start, tool finish, duration, warnings, and exceptions are logged.
Timeouts
- The default IPC timeout is 60000 ms.
- Large zone refills may still require more time on heavier boards.
- If you observe timeouts in practice, increase the timeout in the MCP host environment instead of repeatedly retrying manually.
Targeted retries
- kicad_revert_board retries transient timeout-like failures.
- kicad_refill_zones retries selected busy or timeout conditions.
- The retry policy is intentionally narrow and not applied to arbitrary geometry creation or mutation calls.
Write safety
- Mutations are disabled unless KIPILOT_ENABLE_MUTATIONS=1.
- Dry-run previews remain available when writes are disabled.
- Destructive and high-risk board-state tools still require force=true even after enabling mutations.
Most failures come from endpoint selection, host config drift, or deliberate safety gates.
The fastest way to debug a problem is to verify the basic connection path first, then inspect the server log output, then confirm that the board and tool inputs actually match the current KiCad session.
ping_kicad fails
- Make sure KiCad is already running.
- Verify that the API is enabled in KiCad when your installation requires it.
- If the host is not using the correct endpoint, pass KICAD_API_SOCKET and KICAD_API_TOKEN explicitly.
Health checks pass but board tools fail
- Open the PCB Editor, not only the project window.
- Reconnect to the PCB Editor endpoint if the current endpoint only exposes project-level APIs.
- Use one KiCad instance while stabilizing the setup.
Schematic tools report a capability error
- This is expected on stable KiCad 10.0.x. Upstream registers only GetOpenDocuments on the schematic API handler, so the schematic tools need a KiCad 11 (master/nightly) build.
- Install a nightly build, then open the Schematic Editor so the schematic endpoint is available.
- The PCB tools keep working on the stable 10.x install at the same time; only the schematic tools need the newer build.
- Use get_kicad_version to confirm which build you are actually talking to.
Health checks pass, but a version_warning appears
- The connected KiCad is newer than the bundled kicad-python binding was built against. This is normal when running a KiCad nightly build.
- ping_kicad and get_kicad_version still report ok: true; the warning is informational, not a connection failure.
- Tools that exist only in the newer KiCad can still fail with a capability error, because the older binding does not know about them.
Mutation tools refuse to run
- Set KIPILOT_ENABLE_MUTATIONS=1 for live writes.
- Use dry_run=true if you only want a preview.
- For kicad_revert_board, kicad_delete_items, kicad_sch_remove_items, and live kicad_set_enabled_layers calls, also pass force=true.
Zone refill or revert times out
- Increase KIPILOT_KICAD_TIMEOUT_MS.
- Check the log for tool duration and failure messages.
- Expect long refill operations on large copper pours.
kicad_update_items rejects a payload
- Confirm that the kind is one of footprint, track, or zone.
- For footprint updates, only reference/footprint_id, x_mm/y_mm, orientation_degrees, and layer are accepted.
- Remove unsupported keys instead of assuming they will be ignored.
- Do not target the same item more than once in a single request.
No useful logs available
- Set KIPILOT_LOG_LEVEL=INFO or DEBUG.
- Set KIPILOT_LOG_FILE to a writable path.
- Remember that the server intentionally does not log to stdout.
Python or install problems on Windows
- Use a stable Python release such as 3.13, 3.12, or 3.11.
- Avoid preview or alpha interpreters for this dependency stack.
- Recreate the virtual environment if the interpreter path changed underneath it.