16 Commits

Author SHA1 Message Date
Gavin Colonese
12523c7575 feat: add set_footprint_type tool for placement attribute control
Adds a `set_footprint_type` MCP tool to set a placed footprint's
placement type (through_hole / smd / unspecified) plus the optional
exclude_from_pos_files / exclude_from_bom / not_in_schematic flags.
These attributes gate inclusion in pick-and-place (.pos) exports and
were previously unreachable: edit_component only handled
reference/value/footprint and get_component_properties did not report
the placement type at all.

- python/commands/component.py: SWIG (pcbnew) handler via
  Set/GetAttributes + the dedicated exclusion setters; extends
  get_component_properties to report a human-readable `type` plus the
  three exclusion flags.
- python/kicad_interface.py: IPC (kipy) handler setting
  attributes.mounting_style and the exclusion fields over the proto
  API with begin_commit/update_items/push_commit so changes are live in
  the KiCAD UI; registered in the command map, the IPC handler map, and
  the realtime/IPC whitelist; SWIG fallback on proto error.
- src/tools/component.ts: tool registration with zod schema.
- tests/test_set_footprint_type.py: 26 unit tests over both backends
  plus the extended get_component_properties response.
- pyproject.toml: add `fitz` (PyMuPDF) to mypy ignore_missing_imports
  overrides; pre-existing gap that fails mypy on any edit to files
  importing it (board/view.py, kicad_interface.py).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 11:07:45 -04:00
Gavin Colonese
fa6cdcc0cd feat: add mil unit support across position/coordinate commands (#162)
* feat(units): add mil unit support across all position/coordinate commands

KiCad natively supports mils, so the MCP server should too. Added "mil"
as a valid unit option in tool schemas and updated all unit-to-nanometer
scale conversions across component, routing, outline, view, and IPC
handler code paths. 1 mil = 25400 nm (0.0254 mm).

Also fixes a pre-existing mypy overload error in pin_locator.py (str cast
on dict.get key) that was blocking pre-commit on any Python file change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(units): add mil to TypeScript tool schemas

The Python-side mil support was added but the actual input validation
happens in the TypeScript/Zod schemas. Updated all z.enum(["mm", "inch"])
to include "mil" across board, component, routing, design-rules, and
export tool definitions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tools): replace CP-1252 mojibake with correct Unicode in board.ts

Replace U+00C3 U+00D7 (×) with U+00D7 (×) in add_logo size output string.
Character was mangled when file was saved as CP-1252 instead of UTF-8.

* fix: restore em-dash and fix pre-commit mypy in component/routing

component.py: replace CP-1252 mojibake (â€") with correct Unicode
em-dash (—) in the 'Add to board first' comment. Addresses
maintainer review on PR #162.

routing.py: annotate ex/ey as float at first assignment site in
_point_to_segment_distance_nm so mypy pre-commit hook passes
cleanly on this branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 17:29:34 -04:00
Gavin Colonese
f03a74a93f Feat: add bounding box and courtyard info to component queries (#163)
Components now include boundingBox (min/max X/Y, width, height) in
get_component_list and get_component_properties responses. The SWIG
get_component_properties also includes courtyard dimensions when the
footprint defines a courtyard layer.

SWIG backend uses GetBoundingBox() and GetCourtyard(). IPC backend
tries get_item_bounding_box(), then pad-extent fallback, then falls
back to SWIG backend data when available. This ensures bounding box
data is present regardless of which backend handles the query.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-19 09:36:33 -04:00
NiNjA-CodE
983ffc3793 feat(component): add check_courtyard_overlaps MCP tool (#189)
Detects courtyard overlaps between footprints and flags courtyards that
extend past the board outline. Returns overlap pairs with intersection
extents (mm), per-component boundary violations, and a placement summary.

The killer feature for AI-driven workflows is the `positions` parameter,
which accepts hypothetical placements `{ref: [x, y]}` or
`{ref: [x, y, rotation_degrees]}`. The tool evaluates the proposed
placement WITHOUT writing to the board file — so an AI agent can validate
a move_component / place_component before committing it, instead of the
current loop of write -> run DRC -> parse violations -> revert.

## Implementation

- Uses the real courtyard polygons from pcbnew (`fp.GetCourtyard(F_CrtYd)`
  or B_CrtYd) for accurate AABBs even on custom and rotated footprints.
- Falls back to `fp.GetBoundingBox()` when no F/B.Courtyard polygon is
  present.
- For virtual rotation, rotates the four AABB corners and re-axis-aligns.
  Conservative: the rotated-AABB is always >= the rotated-polygon, so
  overlap reports are never false-negatives (may be marginally
  over-cautious on diagonal rectangles, which is the right error bias
  for a placement validator).
- Optional `margin` parameter expands every courtyard by N mm — useful
  for enforcing a manufacturing keepout wider than the symbol's
  declared courtyard.

## Attribution

The approach is ported from morningfire-pcb-automation
(https://github.com/NiNjA-CodE/morningfire-pcb-automation), specifically
`scripts/placement/check_overlaps.py`. The upstream uses a static
per-footprint-type courtyard lookup table; this implementation reads
the real polygons from pcbnew so it works on any footprint without
maintaining a table. Attribution is in the function docstring, the
TypeScript wrapper, the tool's description (visible to MCP clients),
and the CHANGELOG entry.

## Tests

12 pytest cases in tests/test_check_courtyard_overlaps.py, all passing:

  - No overlaps when spaced; overlap detected on intersect
  - Margin pushes borderline pairs into overlap
  - `refs` filter restricts the check
  - Boundary violations are flagged; `include_boundary=false` suppresses
  - Virtual position does not mutate the footprint (asserts
    `SetPosition` is never called)
  - Virtual rotation swaps a tall-narrow courtyard's x/y extents
  - No-board-loaded returns clean error payload
  - Bad position spec (wrong arity) returns clean error payload
  - GetCourtyard() OutlineCount=0 -> fallback to GetBoundingBox()
  - `board_outline` override replaces the Edge.Cuts bbox

Tests use mocked pcbnew objects so they run under both the conftest stub
and a real pcbnew install. Real-board smoke test on a 44-footprint
production board succeeds: 1 known overlap detected (SW1<->SW2), 0
boundary violations, virtual placement test reports 6 expected overlaps.

## Files touched

- python/commands/component.py            (impl + helpers)
- python/kicad_interface.py               (tool registration)
- python/schemas/tool_schemas.py          (MCP schema entry)
- src/tools/component.ts                  (TypeScript surface, builds clean)
- tests/test_check_courtyard_overlaps.py  (12 cases)
- CHANGELOG.md                            (Unreleased -> New MCP Tools)
2026-05-18 23:03:34 -04:00
Eugene Mikhantyev
bfc25639c2 chore: normalize all tracked files to LF line endings
Mechanical application of the `.gitattributes` rules from the prior commit.
All 50 files differ only in line endings — verified by
`git diff --cached --ignore-all-space` being empty.

Before: main had 42 CRLF + 27 LF Python files plus mixed-ending in YAML,
templates, and shell scripts. After: every text file is LF (except the
Windows-native *.ps1, *.bat scripts which remain CRLF per gitattributes).

This eliminates the noisy-diff failure mode seen in PR #102, where a
small logic change produced a 918-line diff due to whole-file CRLF→LF
conversion.
2026-04-18 15:23:00 +01:00
Eugene Mikhantyev
c44bd9205d style: sort Python imports with isort
Add isort configuration (profile=black, line_length=100) to pyproject.toml,
add isort pre-commit hook, and auto-sort imports across all Python source files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 13:02:24 +01:00
Eugene Mikhantyev
75cead0860 style: apply Black formatting to all Python files
Add [tool.black] config to pyproject.toml and Black hook to
.pre-commit-config.yaml (rev 26.3.1), then auto-format all Python
source and test files with line-length=100, target-version=py310.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 13:01:08 +01:00
Eugene Mikhantyev
eee5bfb9ed chore: set up pre-commit framework with general hooks
Add .pre-commit-config.yaml with pre-commit-hooks v5.0.0 (trailing
whitespace, end-of-file fixer, yaml/json checks, large file guard,
merge conflict detection). Add minimal pyproject.toml. Auto-fix
trailing whitespace and missing end-of-file newlines across the
codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 12:58:36 +01:00
Mattia Fiumara
dd388470be Add layer option to move_component to support flipping components
Adds an optional `layer` parameter (e.g., 'F.Cu', 'B.Cu') to the
move_component tool. When specified, the component is flipped to
the target layer if it's not already on it. The response now also
includes the component's layer after the move.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 18:09:24 +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
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
ByteBard
8c04038371 various fixes for kicad 9 2025-11-14 16:38:16 -05:00
KiCAD MCP Bot
5717a91a59 Add comprehensive Windows support and documentation
Windows Support Package:
- PowerShell automated setup script (setup-windows.ps1)
  - Auto-detects KiCAD installation and version
  - Validates all prerequisites (Node.js, Python, pcbnew)
  - Installs dependencies automatically
  - Generates MCP configuration with platform-specific paths
  - Runs comprehensive diagnostic tests
- Windows troubleshooting guide (docs/WINDOWS_TROUBLESHOOTING.md)
- Platform comparison guide (docs/PLATFORM_GUIDE.md)

Code Enhancements:
- Enhanced Windows error diagnostics in Python interface
- Startup validation in TypeScript server
- Platform-specific error messages with troubleshooting hints
- Component library integration (153 KiCAD footprint libraries)
- Routing operations KiCAD 9.0 API compatibility fixes

Documentation Updates:
- Updated README with Windows automated setup
- Real-time collaboration workflow guide
- Library integration documentation
- JLCPCB integration planning
- Updated status to reflect Windows support
- Changelogs for Nov 1 and Nov 5 updates

Infrastructure:
- Added venv/ to .gitignore to prevent virtual env commits

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 09:10:45 -05:00
KiCAD MCP Bot
e4c7119c51 feat: Week 1 complete - Linux support + IPC API prep
🎉 Major v2.0 rebuild kickoff - Week 1 accomplished!

## Highlights

### Cross-Platform Support 🌍
-  Linux primary platform (Ubuntu/Debian tested)
-  Windows fully supported
-  macOS experimental support
-  Platform-agnostic path handling (XDG spec)
-  Auto-detection of KiCAD installation

### Infrastructure 🏗️
-  GitHub Actions CI/CD pipeline
-  Pytest framework with 20+ tests
-  Pre-commit hooks (Black, MyPy, ESLint)
-  Automated Linux installation script
-  Enhanced npm scripts

### IPC API Migration Prep 🚀
-  Comprehensive migration plan (30 pages)
-  Backend abstraction layer (800+ lines)
-  Factory pattern with auto-detection
-  SWIG backward compatibility wrapper
-  IPC backend skeleton ready

### Documentation 📚
-  Updated README (Linux installation)
-  CONTRIBUTING.md guide
-  Linux compatibility audit
-  IPC API migration plan
-  Session summaries
-  Platform-specific config templates

## Files Changed

- 27 files created
- ~3,000 lines of code/docs
- 8 comprehensive documentation pages
- 20+ unit tests
- 5 abstraction layer modules

## Next Steps

- Week 2: IPC API migration (project.py → component.py → routing.py)
- Migrate from deprecated SWIG to official IPC API
- JLCPCB/Digikey integration prep

🤖 Generated with Claude Code
https://claude.com/claude-code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-25 20:48:00 -04:00