Commit Graph

115 Commits

Author SHA1 Message Date
Tom
b43c63edca feat: add snapshot_project tool for step checkpoints (resume from Step2 without full redo) 2026-03-06 20:42:42 +01:00
Tom
ae66001886 fix: reload board into pcbnew after SVG logo import (prevents logo loss on next Save) 2026-03-06 20:38:16 +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
ec39905702 feat: add sync_schematic_to_board + fix refill_zones subprocess isolation 2026-03-06 20:05:30 +01:00
Tom
e74653d59d fix: add connect_passthrough + schematic tools to directToolNames so AI always sees them 2026-03-06 19:28:30 +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
bed65a6da2 fix: true -> True in tool_schemas.py (Python NameError) 2026-03-06 17:32:21 +01:00
Tom
dcecde8d2b fix: remove duplicate comma in tool_schemas.py (SyntaxError) 2026-03-06 17:22:09 +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
23946a211a feat: add run_erc tool for schematic electrical rules checking 2026-03-06 12:32:35 +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
4c12096886 fix: redirect Python logging from stderr to stdout (prevents false [ERROR] labels in MCP log) 2026-03-06 11:49:31 +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
68fd4509b9 chore: update changelog and schematic template 2026-03-06 09:59:54 +01:00
mixelpixx
d34c1a6f7e Merge pull request #55 from Kletternaut/fix/mit-license
fix: replace placeholder LICENSE with standard MIT text - fixes my lazyness
2026-03-05 20:14:43 -05:00
Tom
d8fe139917 fix: replace placeholder LICENSE with standard MIT text 2026-03-05 15:15:16 +01:00
mixelpixx
385711b3b0 Merge pull request #53 from Kletternaut/fix/inline-extends-symbols-in-lib-symbols-v2
fix(dynamic-loader): inline extends symbols for lib_symbols compatibility
2026-03-04 18:45:34 -05: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
mixelpixx
d8568fff12 Merge pull request #50 from pasrom/fix/mcp-server-bugs
Fix 6 bugs discovered during end-to-end MCP workflow testing
2026-03-02 08:09:57 -05:00
mixelpixx
688bebdf0c Merge pull request #51 from Kletternaut/fix/remove-invalid-comments-in-templates
fix: remove invalid ;; comments from template (KiCAD parse error, regression from b98c94b)
2026-03-02 08:09:31 -05:00
Tom
53014b9733 fix: remove invalid ;; comments from template_with_symbols_expanded.kicad_sch
PROBLEM
-------
Upstream commit b98c94b added 7 comment lines (;; PASSIVES, ;; SEMICONDUCTORS,
;; INTEGRATED CIRCUITS, ;; CONNECTORS, ;; POWER/REGULATORS, ;; MISC,
;; TEMPLATE INSTANCES) to template_with_symbols_expanded.kicad_sch.

KiCAD's S-expression parser does NOT support any comment syntax.
It expects every non-empty line to begin with '('. These comments caused
KiCAD 9 to refuse opening any schematic generated from this template:

  Expecting '(' in <file>.kicad_sch, line 8, offset 5

AFFECTED USERS
--------------
Any project whose .kicad_sch was generated by the MCP server after upstream
commit b98c94b and before this fix contains the same invalid lines. Those
files must be repaired manually: open the .kicad_sch in a text editor and
delete every line beginning with ';;'.

FIX
---
Remove all 7 ;; lines from the template. No functional change — the comments
provided no information that is not already evident from the symbol names.

ALSO
----
CHANGELOG: add critical bug-fix entry for this regression under v2.2.2-alpha
2026-03-01 21:12:51 +01:00
Roman PASSLER
2dd9de6a52 style: apply black formatting to changed files 2026-03-01 19:15:32 +01:00
Roman PASSLER
61356d42cb fix(schematic): rewrite component lookup to handle single-line files
The previous line-based parser (split("\n") + line-by-line regex)
failed when the MCP server itself generates .kicad_sch files as a
single line. The new implementation works directly on the raw content
string using parenthesis-depth matching to find symbol blocks,
making it independent of formatting/whitespace.
2026-03-01 18:43:20 +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
820097a570 docs: update CHANGELOG for v2.2.2-alpha (PR #49) 2026-03-01 17:40:40 +01:00
mixelpixx
e348ed1811 Merge pull request #49 from Kletternaut/feat/footprint-symbol-tools
fix: project-local library resolution + copy_routing_pattern geometric fallback + TypeScript tool
2026-03-01 10:47:15 -05:00
Tom
16f795c214 chore: update .gitignore - add KiCAD backup file patterns 2026-03-01 15:36:17 +01:00
Tom
d9c296f586 fix: restore KiCAD 9 format version in templates (regression from upstream 2b38796)
Upstream commit 2b38796 downgraded template_with_symbols.kicad_sch and
template_with_symbols_expanded.kicad_sch from version 20250114 to 20240101.

KiCAD 9 requires version 20250114 - files with older versions cause parse
errors or are rejected. This was originally fixed in ce78fb4.
2026-03-01 15:05:36 +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
KiCAD MCP Bot
b98c94be42 docs: Update macOS installation, JLCPCB database size, and part counts (#45, #43)
- Add macOS venv setup using KiCAD's bundled Python (fixes #45)
- Update JLCPCB database size from 1-2 GB to 3-5 GB (accurate for 2.5M+ parts)
- Update all "100k+" references to "2.5M+" for consistency
- Update jlcpcb-api.ts tool description (JLCSearch API, no auth required)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-01 07:57:37 -05:00
mixelpixx
00e72f49b1 Update print statement from 'Hello' to 'Goodbye' 2026-03-01 07:43:38 -05:00
mixelpixx
7a7f8524ec Update print statement from 'Hello' to 'Goodbye' 2026-03-01 07:42:53 -05:00
mixelpixx
b9af05e125 Merge pull request #48 from Kletternaut/feat/footprint-symbol-tools
feat: footprint + symbol creator tools (create_footprint, create_symbol + 6 more)
2026-02-28 20:27:07 -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
66066005d0 Merge pull request #1 from Kletternaut/fix/template-kicad9-format
Bug fixes + new tool, discovered via live testing on a real JLCPCB/KiCAD 9 project.

### Changes

1. **Format version bump**: KiCAD 7 → KiCAD 9 (`20230121` → `20250114`)
   MCP server targets KiCAD 9 exclusively. Every newly created schematic showed spurious "older version" warning.

2. **Remove corrupt `_TEMPLATE_*` placed-symbol blocks** (`lib_id -100` crash)
   13 blocks with `(lib_id -100)` caused KiCAD null-pointer crash on box-select.
   Same sexpdata serializer root cause as PR #40.

3. **Fix footprint param silently ignored** in `add_schematic_component`
   The `footprint` field was never passed through the call chain to the f-string in `DynamicSymbolLoader`.

4. **Fix `delete_schematic_component` only deleting first duplicate**
   `break` after first match replaced with full scan + back-to-front deletion. Response now includes `deleted_count`.

5. **New tool: `edit_schematic_component`**
   Update `footprint`, `value`, and/or `reference` in-place on an existing placed symbol.
2026-02-28 15:32:41 +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
mixelpixx
9dbabeb0a5 Merge pull request #44 from Kletternaut/feat/routing-component-tools-and-bugfixes
feat: Add missing routing/component tools and fix SWIG/UUID bugs
2026-02-28 07:58:05 -05: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