Commit Graph

117 Commits

Author SHA1 Message Date
Jeff Laflamme
7f1b072d00 Add Docker/Podman support for Freerouting autorouter
Auto-detects runtime: Java 21+ direct or Docker/Podman fallback.
Discovers docker/podman via PATH instead of hardcoding.
README includes one-time setup with JAR download + Docker pull.
31 tests covering both execution modes.
2026-03-20 12:01:19 +07:00
Jeff Laflamme
53a8b3ff3e Add Freerouting autoroute integration
4 new MCP tools: autoroute (full DSN→Freerouting→SES pipeline),
export_dsn, import_ses, check_freerouting. Requires Java 11+ and
freerouting.jar. Includes 21 test cases and README usage examples.
2026-03-20 11:33:37 +07:00
Eugene Mikhantyev
f562035f79 test: add schematic tools tests and apply black formatting
- Add python/tests/conftest.py with MagicMock stubs for pcbnew/skip
- Add python/tests/test_schematic_tools.py with 29 tests covering
  WireManager.delete_wire, WireManager.delete_label (unit + integration),
  and parameter validation for all 11 new _handle_* methods
- Apply black formatting to component_schematic.py, wire_manager.py,
  and kicad_interface.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 22:48:24 +00:00
Eugene Mikhantyev
4dc351660c fix: apply sexpdata round-trip write to delete_schematic_net_label
delete_schematic_net_label was using kicad-skip's write() which silently
discards in-memory _elements mutations. Replaced with WireManager.delete_label()
that uses the same sexpdata round-trip approach already used by delete_schematic_wire.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 01:08:49 +00:00
Eugene Mikhantyev
9d9234abd0 fix: replace kicad-skip mutation with sexpdata in delete_schematic_wire
kicad-skip's write() serializes from original parsed data, silently
discarding in-memory _elements mutations. Switch to the same sexpdata
approach used by add_wire: parse, find matching wire, delete the entry,
write back. Also adds WireManager.delete_wire() static method.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 00:39:23 +00:00
Eugene Mikhantyev
2956b4fa9d fix: use _elements.remove() for kicad-skip collections lacking remove method
ElementCollection in kicad-skip doesn't implement remove(), causing
'WireCollection object has no attribute remove' errors. Access the
underlying _elements list directly for wire, label, and symbol deletion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:27:17 +00:00
Tom
3d9497ebe5 fix: snapshot saves logs+prompt to logs/ subdir; routing via_x under start pad; router disabled 2026-03-11 11:20:05 +01:00
Tom
3e329cbf6b fix: route_pad_to_pad auto-inserts via when pads are on different copper layers
- Detects F.Cu<->B.Cu layer mismatch in route_pad_to_pad
- Splits route into: trace on start layer + via at midpoint + trace on end layer
- route_trace description warns: use route_pad_to_pad for cross-layer routing
- route_pad_to_pad description highlights automatic via insertion
2026-03-07 15:46:54 +01:00
Tom
2e36f96c55 fix: board outline position and rounded corners (3 bugs)
Bug 1 — Rounded corners missing (src/tools/board.ts schema)
  Symptom: Claude sends shape='rectangle' + radius=2.5, but the Zod schema
  only listed 'rectangle', 'circle', 'polygon' as valid shapes. The JS
  handler never passed cornerRadius through the IPC path, and Python only
  generated arcs for shape='rounded_rectangle'. Result: 4 straight lines,
  no arcs.
  Fix: Added 'rounded_rectangle' and 'cornerRadius' to the Zod schema in
  src/tools/board.ts so Claude can send the correct shape directly.
  Also added a Python-side auto-upgrade: if shape='rectangle' and
  cornerRadius>0, silently promote to 'rounded_rectangle' so legacy
  callers still work (python/commands/board/outline.py).

Bug 2 — Board outline placed at (-w/2, -h/2) instead of (0, 0)
  Symptom: A 30x30 mm board outline was placed centred at the origin
  (start -15 -15) ... (end 15 15) instead of the expected top-left at
  (0,0) → (30,30).
  Root cause: src/tools/board.ts extracted x/y from params and renamed
  them to centerX/centerY before forwarding to Python:
      const { x, y, ...otherParams } = params;
      callKicadScript('add_board_outline', { centerX: x, centerY: y, ...otherParams })
  Python received centerX=0, centerY=0 and used that as the board centre,
  placing the outline at (-15,-15)→(+15,+15).
  Fix: Pass x/y directly as top-left corner coordinates. Python already
  contains the correct logic: center = x + width/2, y + height/2. Removed
  the incorrect rename in board.ts:
      callKicadScript('add_board_outline', { shape, ...params })

Bug 3 — print() on stdout corrupted JSON-RPC protocol → Timeout
  Symptom: Claude Desktop reported 'Timeout' for add_board_outline even
  though Python completed the command in <5 ms. KiCAD was falsely launched.
  Root cause: Debug print() statements written to stdout (the same channel
  used for JSON-RPC responses) injected non-JSON lines into the protocol.
  Node.js could not parse the response → timeout → Claude Desktop invented
  a 'KiCAD UI required' workaround.
  Fix: Removed all print() calls from outline.py. Logger.info/debug writes
  to the log file (~/.kicad-mcp/logs/kicad_interface.log) and is safe.

Files changed:
  src/tools/board.ts               — Zod schema + removed centerX/centerY rename
  python/commands/board/outline.py — auto-upgrade rectangle+radius, remove print()
2026-03-07 14:52:45 +01:00
Tom
91fe6a379c feat: dev mode — auto-copy MCP session log to project dir on export_gerber (KICAD_MCP_DEV=1) 2026-03-07 12:45:52 +01:00
Tom
8e4e3176c2 fix: register sync_schematic_to_board + snapshot_project as MCP tools; auto-save board after SWIG mutations; boardPath reload in place_component; add_schematic_connection warns about connect_passthrough; via.GetWidth(F_Cu) for KiCAD 9.0 2026-03-07 11:27:41 +01:00
Tom
0f1bfa3eff fix: search_tools now includes direct tools (snapshot_project etc.)
- searchTools() previously only searched routed tool categories, so
  direct tools like snapshot_project, save_project, create_project
  returned 0 results when Claude called search_tools('snapshot')
- Direct tools are now searched first, with a hint that they must be
  called directly (not via execute_tool)

Also includes routing.py zone-inset fix for rounded board corners
(already staged from previous session)
2026-03-07 09:56:08 +01:00
Tom
44c5e7f388 fix: unwrap nested params in add_board_outline (SWIG + IPC paths)
Claude sends {shape:'rectangle', params:{x,y,width,height,...}} but handlers
were reading params.get('width') on the outer dict → None → wrong board size.

outline.py: extract inner = params.get('params', params) at method start,
read all dimensions from inner dict.

kicad_interface.py (_ipc_add_board_outline): delegate 'rectangle' to SWIG
path (same as 'rounded_rectangle') so Claude's shape+dims call is handled
correctly. For polygon IPC path: also unwrap inner params for points/width.
2026-03-07 01:43:43 +01:00
Tom
f4d516f5c3 fix: Flip() after board.Add() to avoid 30s hang in KiCAD 9
FootprintLoad+Flip() on standalone footprint (not yet in board) causes
a 30-second block in KiCAD 9 pcbnew. Solution: add footprint to board
first, then call Flip() with board context available.

Fixes B.Cu placement timeout that killed the Python process.
2026-03-07 00:59:32 +01:00
Tom
f3078b7a02 fix: B.Cu footprint Flip() in SWIG path + J2-on-B.Cu prompt note + pin-1-at-top schema hint 2026-03-06 20:51:52 +01:00
Tom
8e92e144b3 fix: board outline 3 bugs (cornerRadius fallback, top-left origin default, IPC rounded_rect arc delegation) 2026-03-06 20:33:25 +01:00
Tom
373ab35a10 fix: svg_import tokenizer preserves command/number order (fixes V-command crash) 2026-03-06 18:34:27 +01:00
Tom
0688626781 fix: inject_symbol_into_lib_symbols handles sexpdata single-line compaction 2026-03-06 18:10:20 +01:00
Tom
93ae23dacc fix: prevent header corruption when sexpdata compacts schematic to single line
create_component_instance used line-based insertion which placed new
symbols BEFORE (kicad_sch ...) header when the file was written as
a single line by sexpdata.dumps(). Switch to rfind()-based string
insertion which is format-independent.

Also remove StreamHandler(sys.stdout) from logging — Python logs now
go only to file (~/.kicad-mcp/logs/kicad_interface.log) to avoid
polluting MCP stderr with INFO/DEBUG entries shown as [error].
2026-03-06 13:17:25 +01:00
Tom
e7a8234ec4 fix: list_library_footprints accepts library_name as alias for library param 2026-03-06 12:45:54 +01:00
Tom
410d02ad8b feat: add import_svg_logo tool — converts SVG to PCB silkscreen polygons 2026-03-06 12:41:11 +01:00
Tom
11d7e49e74 feat: add connect_passthrough tool for FFC/ribbon cable pin-to-pin wiring 2026-03-06 12:25:25 +01:00
Tom
fec537950f fix: PinLocator resolves pin names (e.g. VCC1, SDA) in addition to pin numbers 2026-03-06 11:38:54 +01:00
Tom
1d390f4fed fix: schematic pin connection reliability
- add_schematic_net_label: warn in description that coords must be exact pin endpoints; recommend connect_to_net instead
- connect_to_net: stub wire direction now follows pin angle (was hardcoded +X)
- pin_locator.py: add get_pin_angle() and _get_lib_id() helpers
- new tool: get_schematic_pin_locations(schematicPath, reference) → returns exact x/y of every pin endpoint, so Claude can place labels correctly
2026-03-06 11:29:52 +01:00
Tom
2340afe9a4 fix(dynamic-loader): inline extends symbols for lib_symbols compatibility
KiCad 9 refuses to load any schematic whose lib_symbols section contains
an (extends ...) clause, because the extends mechanism is only valid
inside .kicad_sym library files - not inside schematics.

The previous implementation kept the (extends ...) clause and prepended
the parent symbol block with a qualified name, but left the child's
extends referring to the unqualified parent name, causing:
  'Error loading schematic: No parent for extended symbol Q_NMOS_GSD'

Fix: add _iter_top_level_items() and _inline_extends_symbol() helpers.
When a library symbol uses extends, the parent's content (pins, graphics,
sub-symbols) is now merged directly into the child definition:
- Parent properties are overridden by child property values
- Sub-symbol names are renamed from ParentName_X_Y to ChildName_X_Y
- The (extends ...) clause is removed entirely
- Only the fully-resolved child symbol is injected into lib_symbols

Affected symbols include Transistor_FET:2N7002, Transistor_BJT:*,
Regulator_Linear:*, Regulator_Switching:* and many others (~30% of the
KiCad standard library uses extends).

Fixes #52
2026-03-04 15:27:59 +01:00
Roman PASSLER
2dd9de6a52 style: apply black formatting to changed files 2026-03-01 19:15:32 +01:00
Roman PASSLER
a018575bbc fix(mounting-hole): generate unique references MH1, MH2, etc.
All mounting holes were assigned the same reference "MH", violating
PCB conventions and causing conflicts. Now queries existing footprints
to find the next available MH number.
2026-03-01 18:41:39 +01:00
Roman PASSLER
4e70342eae fix(drc): extract violation coordinates from kicad-cli JSON items
kicad-cli DRC JSON output stores coordinates in items[].pos.x/y,
not at the violation top level. The code was reading violation.x/y
which don't exist, falling back to (0, 0) for every violation.
Now correctly reads the position from the first item in each
violation entry.
2026-03-01 18:40:45 +01:00
Roman PASSLER
ec1939bef4 fix(copper-pour): add outline parameter and fallback to board outline
Two issues fixed:
1. TypeScript schema was missing the outline parameter entirely,
   so MCP clients couldn't send pour boundary points.
2. Python code read "points" key but schema defined "outline" key.

Now accepts "outline" (with "points" as fallback for backwards
compatibility). When no outline is provided, automatically uses
the board edge bounding box as the pour boundary.
2026-03-01 18:40:24 +01:00
Roman PASSLER
246050001a fix(nets): use GetNetClassName() instead of GetClassName() on NETINFO_ITEM
NETINFO_ITEM objects don't have a GetClassName() method, causing
an AttributeError crash when listing nets. The correct method is
GetNetClassName() which returns the net class name string.
2026-03-01 18:37:55 +01:00
Roman PASSLER
c7d6d0126f fix(bom): use GetUniStringLibId() instead of str() for footprint in BOM export
str(module.GetFPID()) returns the Swig proxy representation like
"<pcbnew.LIB_ID; proxy of ...>" instead of the actual footprint name.
GetUniStringLibId() returns the proper "Library:Footprint" string.
2026-03-01 18:37:35 +01:00
Tom
f0d738fff1 feat: add route_pad_to_pad tool
Convenience wrapper around route_trace that eliminates the need for
separate get_pad_position calls before routing.

- Accepts fromRef/fromPad/toRef/toPad instead of raw coordinates
- Automatically looks up pad positions from board footprints
- Auto-detects net from pad assignment (overridable via net param)
- Returns fromPad/toPad position info in response
- Saves ~2 tool calls (64+ calls for a full TMC2209 board) vs 3-step flow

Registered in: routing.py, kicad_interface.py (dispatch), routing.ts (MCP)
2026-03-01 15:03:52 +01:00
Tom
b33d6e22fd fix: project-local library resolution + copy_routing_pattern geometric fallback + TypeScript tool
- fix: DynamicSymbolLoader reads project sym-lib-table before global dirs
  add_schematic_component now finds symbols from project-local .kicad_sym files
  project_path derived automatically from schematic file path

- fix: place_component reloads FootprintLibraryManager with project_path
  new boardPath parameter passed to place_component tool (TypeScript + Python)
  _handle_place_component wrapper recreates LibraryManager per project

- fix: copy_routing_pattern geometric fallback when pads have no nets
  primary filter: net-based (when pads are assigned to nets)
  fallback: bounding box of source footprint pads +5mm tolerance
  filterMethod field in response indicates which mode was used

- feat: register copy_routing_pattern as MCP tool in routing.ts
  sourceRefs, targetRefs, includeVias, traceWidth parameters

Live tested: ESP32 + 2x TMC2209 in Test3 project
  13 traces U2 routed, copy_routing_pattern copied all 13 to U3
  offset Y+30mm correct, 26 total traces verified
2026-03-01 15:03:52 +01:00
KiCAD MCP Bot
2b38796409 fix: Update schematic format to KiCAD 9 and fix invalid UUIDs (#37)
- Update schematic version from 20230121 (KiCAD 7) to 20240101 (KiCAD 9)
- Replace invalid all-zeros UUIDs in template files with valid UUIDs
- Add post-copy UUID regeneration to ensure each project gets unique UUID
- Add UTF-8 encoding and Unix line endings for cross-platform compatibility

Fixes the root cause where templates were copied with invalid UUIDs and
outdated version format, causing KiCAD 9.0.x to reject the schematic files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 08:02:52 -05:00
Tom
914c4fa1e3 feat: add footprint + symbol creator tools
Footprint tools:
- create_footprint: generates .kicad_mod via f-string (SMD/THT, courtyard, silkscreen, fab)
- edit_footprint_pad: updates size/position/drill/shape in-place
- list_footprint_libraries: scans .pretty directories
- register_footprint_library: adds entry to fp-lib-table

Symbol tools:
- create_symbol: generates .kicad_sym with pins, rectangles, polylines
- delete_symbol: removes symbol from library
- list_symbols_in_library: lists all symbols in a .kicad_sym file
- register_symbol_library: adds entry to sym-lib-table

Also:
- Fix footprint format version: 20250114 (schematic) -> 20241229 (footprint)
- Two MCP prompts: create_footprint_guide + footprint_ipc_checklist

Live tested: TMC2209 footprint (19 pads), R_0603_Test, edit_footprint_pad,
TMC2209_Custom symbol with pins all confirmed in KiCAD 9
2026-02-28 22:42:27 +01:00
Tom
b1eb570183 fix: footprint param ignored, delete duplicates, add edit_schematic_component
Bug 1 - add_schematic_component: footprint parameter silently ignored
  The footprint value from MCP params was never passed through to
  DynamicSymbolLoader.add_component() / create_component_instance().
  Every placed symbol had an empty Footprint field regardless of input.
  Fix: added footprint: str='' to both functions, passed through all
  call sites, added footprint to schematic.ts tool schema.

Bug 2 - delete_schematic_component: only deleted first duplicate
  When a reference appeared multiple times (e.g. after a failed
  add attempt), only the first instance was removed due to break
  after first match. Fix: collect all matching blocks first, then
  delete back-to-front to preserve indices. Response now includes
  deleted_count.

New tool - edit_schematic_component
  Update footprint, value or reference of a placed symbol in-place.
  More efficient than delete+re-add: preserves position and UUID.
  Accepts: schematicPath, reference, footprint?, value?, newReference?

All 3 fixes verified by live tests on a real JLCPCB/KiCAD 9 project:
  - R_TEST1: footprint Resistor_SMD:R_0603_1608Metric written correctly
  - J1 duplicate: deleted_count=2 with single call
  - J2 edit: PinSocket footprint assigned in-place, no delete+add needed
  - PCB update (F8) confirmed: only components with footprint imported
2026-02-28 15:21:07 +01:00
Tom
ce78fb4111 fix: update templates to KiCAD 9 format + remove corrupt _TEMPLATE_ blocks
Verified by live test: created a fresh schematic via MCP, result shows
format version 20250114, 0 _TEMPLATE_ hits, 0 (lib_id -100) hits, 24
real components placed cleanly.

--- Format version bump (20230121 KiCAD 7 -> 20250114 KiCAD 9) ---
Files: python/templates/*.kicad_sch, python/commands/project.py,
       python/commands/schematic.py

Root cause: the MCP server targets KiCAD 9 exclusively - pcbnew.pyd is
compiled for KiCAD 9.0 / Python 3.11.5, and server.ts explicitly selects
the KiCAD 9 bundled Python on Windows. Generating new schematics with a
2-year-old format tag caused a spurious 'This file was created with an
older KiCAD version' warning on every newly created schematic.

--- Remove corrupt _TEMPLATE_* placed-symbol blocks ---
File: python/templates/template_with_symbols_expanded.kicad_sch

Root cause: the expanded template was generated by the old sexpdata
serializer (same corruption PR #40 fixed for DynamicSymbolLoader add-path).
The serializer converted the string 'Device:R' to integer -100, producing
(lib_id -100) instead of (lib_id Device:R). KiCAD cannot resolve an
integer as a library reference and crashes with a null-pointer when the
user attempts to select these symbols. They appeared as grey _TEMPLATE_R?,
_TEMPLATE_C?, _TEMPLATE_U_REG? etc. ~5000mm off-sheet - invisible during
normal work but triggering a crash on accidental box-select.

Discovered via live testing on a real JLCPCB/KiCAD 9 project.
2026-02-28 14:40:32 +01:00
Tom
1ba86f7769 feat: datasheet tools + fix missing delete_schematic_component
New tools - datasheet:
- get_datasheet_url: construct LCSC datasheet PDF URL + product page URL
  without any API key (URL schema: https://www.lcsc.com/datasheet/<C#>.pdf)
- enrich_datasheets: scan .kicad_sch, write LCSC datasheet URL into every
  symbol that has an LCSC property but an empty Datasheet field; supports
  dry_run=true for preview; text-based implementation (no skip writes)
  Implementation: python/commands/datasheet_manager.py

New tool - schematic:
- delete_schematic_component: remove a placed symbol from a .kicad_sch file
  by reference designator (e.g. R1, U3)

Bug fix - delete_schematic_component (two separate root causes):
1. No MCP tool named delete_schematic_component was registered at all.
   Any delete-symbol request fell through to the PCB-only delete_component
   tool which searches pcbnew.BOARD and always returned 'Component not found'
   for schematic symbols.
2. component_schematic.py::remove_component() still used skip for writes.
   PR #40 rewrote DynamicSymbolLoader (add path) to avoid skip-induced
   schematic corruption, but the delete path was not touched by that PR.

Fix: _handle_delete_schematic_component in kicad_interface.py uses direct
text manipulation with parenthesis-depth tracking (same technique as PR #40),
bypassing component_schematic.py entirely. Error message explicitly guides
users: 'use delete_component for PCB footprints'.

Files changed:
- python/commands/datasheet_manager.py (new)
- src/tools/datasheet.ts (new)
- python/kicad_interface.py: 3 new handlers + dispatch entries
- src/tools/schematic.ts: delete_schematic_component tool
- src/server.ts: registerDatasheetTools import + call
- src/tools/index.ts: export registerDatasheetTools
- CHANGELOG.md: document all above
2026-02-28 13:48:35 +01:00
Tom
76503b144c fix: generate_netlist schematic_path, PinLocator cache, server.ts Python detection
- connection_schematic.py: generate_netlist() now accepts schematic_path param,
  threaded through to get_net_connections() so PinLocator is actually invoked
  (previously only 1 connection per component was returned due to fallback break)
- kicad_interface.py: pass schematic_path to generate_netlist()
- pin_locator.py: add _schematic_cache to avoid loading Schematic() once per pin
  (was causing timeout: O(nets x components x pins) Schematic() calls)
- server.ts: remove fragile PYTHONPATH?.includes('KiCad') condition,
  always prefer KiCAD bundled Python on Windows when executable exists
- CHANGELOG.md: document fixes under v2.2.0-alpha
2026-02-28 01:23:36 +01:00
Tom
2945b52eae feat: Add missing routing/component tools and fix SWIG/UUID bugs
New MCP tools added (TypeScript layer):
- Routing: delete_trace, query_traces, get_nets_list, modify_trace,
  create_netclass, route_differential_pair, refill_zones (with SWIG warning)
- Component: get_component_pads, get_component_list, get_pad_position,
  place_component_array, align_components, duplicate_component

Bug fixes:
- routing.py: Fix SwigPyObject UUID comparison (str() -> m_Uuid.AsString())
- routing.py: Fix SWIG iterator invalidation after board.Remove()
  by converting board.Tracks() to list() before iteration
- routing.py: Add board.SetModified() and clear Python refs after Remove()
  to prevent dangling SWIG pointers crashing subsequent calls
- routing.py: Wrap each track access in try/except in query_traces()
  to gracefully skip invalid track objects after bulk delete
- routing.py: Add missing return statement (mypy fix)
- library.py: Fix search_footprints param mapping search_term->pattern
- library.py: Fix fp.name -> fp.full_name field access
- library.py: Accept both 'pattern' and 'search_term' parameter names
- library.py: Add library filter support in search_footprints
- library.py: Fix loop variable shadowing Path object (mypy fix)
- design_rules.py: Add type annotation for violation_counts (mypy fix)

Contribution guidelines followed (CONTRIBUTING.md):
- black python/ applied (3 touched files pass without changes)
- mypy python/ passes with 0 errors on all changed files
- npx prettier --write applied to changed TypeScript files
- npm run build passes (tsc --noEmit: 0 errors)
- Commit messages follow feat:/fix: convention

Note on diff size: The large insertion/deletion count in the changed files
is due to black and prettier reformatting previously unformatted code
(missing trailing commas, quote style, line length). The actual logic
changes are limited to the 6 files listed above.

Note: refill_zones has known SWIG segfault risk (see KNOWN_ISSUES.md).
Prefer IPC backend (KiCAD open) or zone fill via KiCAD UI.
2026-02-27 18:15:46 +01:00
FlowSync0
a69d288251 fix: Rewrite DynamicSymbolLoader to prevent schematic file corruption (#40)
Fixes Issue #26 - add_schematic_component corrupts .kicad_sch files

Complete rewrite of DynamicSymbolLoader to use text manipulation instead of sexpdata:
- Preserves KiCAD file formatting perfectly
- Correctly handles KiCAD 9 symbol naming conventions (library prefix for top-level, no prefix for sub-symbols)
- Resolves parent-child symbol dependencies with (extends)
- Adds symbol caching for performance
- Simplifies component addition workflow

Tested on KiCAD 9.0.7 with R, C, LED, ESP32, and transistor components.
Compatible with recent Windows fixes (UUID generation, IPC, JLCPCB).

Co-authored-by: FlowSync0 <249798311+FlowSync0@users.noreply.github.com>
2026-02-26 11:02:10 -05:00
KiCAD MCP Bot
e4fa774eda fix: Phase 2 - DRC API fix and JLCPCB documentation restructure (#33, #34, #43)
Phase 2 medium-priority fixes addressing three issues:

Issue #33 - DRC violations API broken in KiCAD 9.0:
- Reimplemented get_drc_violations() to use run_drc() internally
- run_drc uses kicad-cli which is stable across KiCAD versions
- Maintains backward compatibility while fixing GetDRCMarkers() issue
- Added documentation to KNOWN_ISSUES.md
- Returns violations in original format by parsing kicad-cli JSON output

Issue #34 - JLCPCB API documentation misleading:
- Restructured README and JLCPCB_USAGE_GUIDE.md
- Now leads with JLCSearch public API (no authentication required)
- Moved official JLCPCB API to "Advanced" section with clear requirements
- Clarified that official API requires enterprise account + order history
- Makes it easier for new users to get started

Issue #43 - JLCPCB part count documentation inaccurate:
- Updated all "100k+" references to "2.5M+" (accurate catalog size)
- Updated download time estimates to 40-60 minutes
- Updated expected database size to 1-2 GB
- Clarified 100-part pagination limit in JLCSearch API

Documentation changes:
- README.md: Updated JLCPCB integration section
- docs/JLCPCB_USAGE_GUIDE.md: Complete restructure with 3 approaches
- docs/KNOWN_ISSUES.md: Added DRC fix documentation

All changes improve user experience and documentation accuracy.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-26 10:11:55 -05:00
KiCAD MCP Bot
b4d114ac74 fix: Address critical Windows compatibility and JLCPCB issues (#36, #37, #35)
Phase 1 critical fixes addressing three high-priority issues:

Issue #36 - Windows IPC backend crash (os.getuid not available):
- Add platform detection to skip Unix-specific socket paths on Windows
- Use hasattr check before calling os.getuid()
- Windows now uses auto-detect fallback (named pipes)
- Maintains full Unix socket support on Linux/macOS

Issue #37 - Windows schematic file creation broken:
- Generate unique UUIDs instead of invalid all-zeros UUID
- Add explicit UTF-8 encoding for cross-platform compatibility
- Force Unix line endings (LF) to prevent Windows CRLF issues
- Update template file with valid placeholder UUID
- Fix hardcoded /tmp/ paths in wire_manager.py and pin_locator.py

Issue #35 - JLCPCB download limited to 100 parts:
- Change batch_size from 1000 to 100 to match tscircuit API limit
- Remove premature loop termination when batch < batch_size
- Add documentation explaining API limitation
- Expected result: Full ~2.5M part catalog download (40-60 minutes)

All changes maintain backward compatibility and include detailed comments.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-26 10:03:20 -05:00
KiCAD MCP Bot
b9bd401b11 feat: Add routing replication commands for Issue #30 Phase 2
Implements advanced trace manipulation and routing pattern copying:
- Enhanced delete_trace with net-based bulk deletion and layer filtering
- Added modify_trace to change width, layer, or net by UUID/position
- Added copy_routing_pattern to replicate routing between component groups

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 19:24:59 -05:00
KiCAD MCP Bot
04db774a2b feat: Address multiple open issues (#32, #30, #26, #19)
Issue #32 - Unknown command errors:
- Register get_board_extents in command_routes (was implemented but not registered)
- Implement find_component command with pattern matching on reference/value/footprint
- Add schemas for both commands

Issue #30 - PCB routing replication (Phase 1):
- Implement get_component_pads: returns all pads with positions, nets, shapes
- Implement get_pad_position: returns specific pad coordinates and properties
- Implement query_traces: query traces by net, layer, or bounding box
- Add schemas for all new commands

Issue #26 - Schematic workflow:
- Add missing schemas for add_schematic_connection, add_schematic_net_label,
  connect_to_net, get_net_connections, and generate_netlist

Issue #19 - macOS Python path detection:
- Add Python 3.13 to version detection
- Add alternative KiCAD installation paths (user Applications, capitalization variants)
- Add Homebrew Python fallback paths for Apple Silicon and Intel Macs
- Expand platform_helper.py with same improvements

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 19:17:35 -05:00
KiCAD MCP Bot
aa18486359 fix: Replace SetFootprintName with SetFPID for KiCAD 9.x compatibility
Fixes issue #28 where place_component fails on KiCAD 9.0.5 with:
'FOOTPRINT' object has no attribute 'SetFootprintName'

KiCAD 9.x API changed from SetFootprintName() to SetFPID(LIB_ID).

Changes:
- place_component: Parse footprint string and use SetFPID with LIB_ID
- update_component: Parse footprint string or preserve existing library
- duplicate_component: Use source.GetFPID() directly

All three methods now use the KiCAD 9.x API while maintaining backward
compatibility with the footprint parameter format.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-10 11:43:54 -05:00
KiCAD MCP Bot
a5a542b1e9 feat: Implement wire graph analysis for net connectivity (Phase 2)
Major Feature: Wire Graph Analysis
- Rewrote get_net_connections() with geometric wire tracing
- Added points_coincide() helper for coordinate matching
- Implemented multi-step connectivity algorithm:
  1. Find all labels with target net name
  2. Trace wires connected to label positions
  3. Find component pins at wire endpoints using PinLocator
  4. Return accurate component/pin connections

Technical Implementation:
- Tolerance-based point matching (0.5mm for grid alignment)
- Wire polyline support (traces multi-segment paths)
- Accurate pin location matching with rotation support
- Fallback proximity matching when schematic_path unavailable

Testing Results:  100% PASSING
- VCC: 2 connections (R1_/1, D1_/1) ✓
- GND: 4 connections (R1_/2, R2_/2, C1_/2, D1_/2) ✓
- +3V3: 1 connection (R2_/1) ✓
- +5V: 1 connection (C1_/1) ✓
- Netlist generation: 4 nets detected ✓
- Comprehensive power circuit test: PASSED ✓

Updates:
- get_net_connections() now accepts optional schematic_path parameter
- generate_netlist() automatically uses improved connectivity analysis
- Full integration with PinLocator for accurate pin matching

Addresses: Phase 2 net connectivity analysis requirements

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-10 10:52:20 -05:00
KiCAD MCP Bot
b77f0081d6 fix: Resolve template mapping bug in dynamic symbol loading
Critical Bug Fixes:
1. Changed get_or_create_template() return type to tuple (template_ref, needs_reload)
2. Added automatic schematic reload after dynamic loading
3. Replaced hasattr() checks with symbol iteration (handles special characters like +)
4. Added template_exists() helper function
5. Fixed template lookup to check multiple potential reference formats

Issues Resolved:
- Multiple components of same type can now be added after dynamic loading
- Power symbols with special characters (+3V3, +5V) work correctly
- Template references with library prefix are properly detected
- Schematic object stays in sync with file after dynamic injections

Testing:
-  Power symbols: 4/4 loaded (VCC, GND, +3V3, +5V)
-  Components: 4/4 placed (R, R, C, LED)
-  Connections: 8/8 created
-  Special character handling (+3V3, +5V) working

Technical Details:
- hasattr() fails with attribute names containing special characters
- Must iterate symbols and check Reference.value directly
- Schematic reload required after S-expression injection
- Template name formats: _TEMPLATE_R, _TEMPLATE_power_VCC, _TEMPLATE_Device_R

Addresses template mapping issues found during Phase 2 power net testing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-10 10:49:08 -05:00
KiCAD MCP Bot
c67f400383 feat: Update connect_to_net to use WireManager (Phase 2)
Updates:
- ConnectionManager.connect_to_net() now uses PinLocator + WireManager
- Accepts Path parameter instead of Schematic object
- Creates wire stub (2.54mm) from pin to label position
- Uses WireManager.add_wire() and WireManager.add_label()
- Updated MCP handler _handle_connect_to_net()

Testing:
-  connect_to_net test: 100% passing
-  R1/1 → VCC wire stub + label
-  D1/2 → GND wire stub + label
-  Verified with kicad-skip: 5 wires, 4 labels

Part of Phase 2: Net Labels & Named Nets (Issue #26)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-10 10:40:56 -05:00
KiCAD MCP Bot
16703e28f9 feat: Integrate WireManager and PinLocator into MCP interface handlers
Updates MCP handlers to use the new wiring infrastructure:

Handler Updates:
- _handle_add_schematic_wire: Uses WireManager.add_wire() with S-expression manipulation
- _handle_add_schematic_connection: Uses ConnectionManager with automatic pin discovery and routing options (direct, orthogonal_h, orthogonal_v)
- _handle_add_schematic_net_label: Uses WireManager.add_label() with support for label types and orientation

Features:
- Automatic pin location discovery with rotation support
- Professional wire routing (direct, orthogonal horizontal-first, orthogonal vertical-first)
- Net label placement with customizable types (label, global_label, hierarchical_label)
- Comprehensive error handling and logging

Testing:
- All MCP handlers tested and verified working
- Integration test: 100% passing (2 wires, 1 label created successfully)
- Verified with kicad-skip that wires and labels are correctly formed

Part of Issue #26 schematic wiring implementation (Phase 1)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-10 10:35:16 -05:00