Skip to content

BeckhamLabsLLC/kicad-jlcpcb

kicad-jlcpcb

License: MIT Python 3.10+ KiCad 8+ Tests MCP

From "I want a board that does X" to a wired .kicad_pcb EasyEDA can auto-route and JLCPCB can build — in a single Claude Code conversation.

kicad-jlcpcb is a Claude Code plugin + MCP server that automates the tedious half of going from idea to fab. It sources LCSC parts with a hard preference for JLCPCB basic-library stock, auto-fetches pin maps from EasyEDA, places KiCad-stdlib footprints, wires every net by pin name (not pad number), and hands off a .kicad_pcb that EasyEDA can route and order in two clicks.

┌─ you ──────────────────────────────────┐
│  /pcb-new An ESP32-C3 soil-moisture    │
│          sensor, USB-C, 3.3V LDO...    │
└────────────────┬───────────────────────┘
                 │
   ┌─────────────▼─────────────┐
   │  kicad-jlcpcb MCP server  │
   │  • source parts (LCSC)    │
   │  • fetch pin maps         │
   │  • place + wire footprints│
   │  • save .kicad_pcb        │
   └─────────────┬─────────────┘
                 │
       drag into easyeda.com
                 │
             Auto Route
                 │
          Order via JLCPCB

Why this plugin

Three recurring friction points in small-batch PCB work, automated:

  1. "Is this part basic or extended on JLCPCB?" — You stop needing to cross-reference LCSC's UI. The plugin's SQLite-cached jlcparts mirror answers in milliseconds and always prefers basic-tier (no $3/part assembly setup fee).
  2. "What's the right pad number for this IC's GPIO10?" — You stop reading datasheets to build netlists. The plugin queries EasyEDA by LCSC C-number, caches the pin-name → pad-number map, and lets you reference pins by their functional names.
  3. "Why is my auto-router failing?" — You stop fighting Freerouting on RF boards. The plugin stops at "wired .kicad_pcb" and hands off to EasyEDA's cloud auto-router, which works on real designs.

Quick tour

  • Two slash commands: /pcb-new (from a description) and /pcb-from-bom (from a CSV).
  • One agent: part-sourcer — finds the best JLCPCB-stocked part for a generic spec.
  • One skill: kicad-jlcpcb-workflow — the full reference the LLM consults while driving the workflow.
  • 13 MCP tools covering setup, sourcing, schematic, PCB generation, EasyEDA handoff, and session resume.
  • Session persistence — each project writes a .kicad_jlcpcb_session.json so /pcb-new can resume mid-flow after a Claude Code restart.

Requirements

Component Version Notes
Python 3.10 – 3.13 Tested on all four
KiCad 8.0+ kicad-cli on PATH, pcbnew Python bindings for pcb_generate
EasyEDA account free Only needed for the final routing + ordering step

Install KiCad:

  • Fedora 40+: sudo dnf install kicad
  • Ubuntu 22.04+: sudo add-apt-repository ppa:kicad/kicad-9.0-releases && sudo apt install kicad
  • Arch: sudo pacman -Syu kicad
  • macOS: kicad.org/download

Install

Distributed via GitHub only — no PyPI, no marketplace. Clone and install locally.

1. Clone + install (virtualenv recommended)

git clone https://github.com/BeckhamLabsLLC/kicad-jlcpcb.git
cd kicad-jlcpcb
python -m venv .venv
source .venv/bin/activate     # Windows: .\.venv\Scripts\activate
pip install -e ".[dev]"

The editable install puts a kicad-jlcpcb entry-point script in the venv's bin/. .mcp.json calls that script directly; if the venv isn't active when Claude Code launches, point .mcp.json at the absolute path:

{
  "mcpServers": {
    "kicad-jlcpcb": {
      "command": "/abs/path/to/kicad-jlcpcb/.venv/bin/kicad-jlcpcb",
      "args": []
    }
  }
}

If you'd rather install into your user Python without a venv, substitute pip install -e . after cd kicad-jlcpcb and skip the venv lines. The entry-point lands in ~/.local/bin instead.

2. Register with Claude Code

/plugin marketplace add /abs/path/to/kicad-jlcpcb
/plugin install kicad-jlcpcb@local

Restart Claude Code so the MCP server registers.

3. Sanity check

kicad-jlcpcb --help     # should print nothing (MCP servers speak JSON-RPC on stdio), exit 0

Five-minute quick-start

Pick a small idea — an ESP32-C3 board with one sensor, a USB-C port, and an LDO works well. Run:

/pcb-new An ESP32-C3 soil-moisture sensor with two capacitive probes,
         USB-C 5V in, a 3.3V LDO, status LED, and JST-PH battery header.
         Place it on an 80x60 mm board.

Claude walks you through:

  1. detect_kicad — verify the toolchain (< 1 s)
  2. create_project — scaffold .kicad_pro + .kicad_sch + session file
  3. Decomposes the description into ~12 generic part specs
  4. lcsc_search per spec (first run populates the 17 MB jlcparts cache)
  5. BOM checkpoint — shows every resolved part, flags extended-tier ones with cost warnings, and waits for your confirmation
  6. pcb_generate — fetches EasyEDA pin maps (~12 s per unique IC, first run only), places footprints, wires nets, saves .kicad_pcb
  7. easyeda_handoff — prints the import instructions

The full trace with real timings and tool outputs: examples/soilnode-esp32/walkthrough.md.

First run: ~90 s. Subsequent runs on similar designs: under 10 s.


What the plugin does not do

Set expectations honestly before you start:

  • Auto-route traces. That's why the .kicad_pcb gets handed to EasyEDA. Freerouting 2.1.0's CLI is buggy and can't handle RF matching networks; nothing else works headlessly well enough to ship.
  • Beautiful placement. The three-band grid (connectors on top, ICs in the middle, passives below) is functional, not pretty. You rearrange in EasyEDA before routing.
  • Design review. There's no DRC integration (yet — see Roadmap). The plugin trusts your spec and relies on KiCad / EasyEDA to catch rule violations.
  • PyPI distribution. Install from the clone. No pip install kicad-jlcpcb.

MCP tool surface

Stage Tool Purpose
Setup detect_kicad Probe kicad-cli version, return install hint if missing
Setup create_project Scaffold .kicad_pro + subdirs + session file
Setup load_project Validate existing .kicad_pro; surfaces resumable session state
Resume session_resume Report where a prior workflow left off for a project dir
Sourcing lcsc_search Free-text part search, basic-only by default
Sourcing lcsc_resolve_bom Batch BOM resolution with cost-impact warnings
Sourcing fetch_part_library Placeholder symbol/footprint fetch into project libs/
Pin maps part_pin_map Fetch pin-name → pad-number map from EasyEDA
Schematic sch_generate Emit .kicad_sch from a netlist spec
Schematic sch_run_erc Run kicad-cli sch erc and parse the report
PCB pcb_generate Main tool. Auto-fetches pin maps, places footprints, wires every net, saves .kicad_pcb
Terminal easyeda_handoff Recommended terminal tool. Produces EasyEDA import instructions
Legacy package_for_jlcpcb For users routing in KiCad: export Gerbers + package a JLCPCB upload zip

Full input-schema definitions are in src/kicad_jlcpcb_mcp/server.py under _tool_definitions().


PCB spec format

pcb_generate consumes a JSON-serializable dict:

{
  "name": "demo",
  "board": {"width_mm": 80, "height_mm": 60, "layer_count": 2},
  "components": [
    {
      "ref": "U1",
      "value": "ESP32-C3-WROOM-02",
      "lcsc": "C2934560",
      "lib": "RF_Module",
      "fp": "ESP32-C3-WROOM-02"
    }
  ],
  "nets": {
    "3V3":     [["U1", "3V3"], ["C1", "1"]],
    "GND":     [["U1", "GND"], ["C1", "2"]],
    "SPI_SCK": [["U1", "GPIO10"], ["U2", "SCK"]]
  }
}

Key rules:

  • Reference IC pins by their functional name (3V3, GPIO10, SCK). The plugin resolves them via EasyEDA's pinmap.
  • For passives (R, C, L, D), use bare pad numbers: "1", "2".
  • lib and fp are KiCad-stdlib library + footprint names. See /usr/share/kicad/footprints/ for the catalog.

Full worked spec: examples/soilnode-esp32/spec.json.


Architecture

src/kicad_jlcpcb_mcp/
  server.py         ← MCP server + 13 tool definitions
  session.py        ← per-project state (.kicad_jlcpcb_session.json)
  project.py        ← .kicad_pro create / load / validate
  kicad_cli.py      ← async wrapper for kicad-cli (KiCad 8/9)
  lcsc_client.py    ← jlcparts mirror + SQLite cache + basic-tier filter
  part_library.py   ← EasyEDA client (EasyEdaRateLimiter + pin-map cache)
  pcb.py            ← pcbnew-based .kicad_pcb generator
  schematic.py      ← netlist spec → .kicad_sch
  gerber_pack.py    ← KiCad 8/9 Protel extension normalizer + JLCPCB zip
  sexpr.py          ← s-expression reader/writer
  config.py         ← module-level constants

All HTTP goes through lcsc_client and part_library. All KiCad CLI invocations go through kicad_cli. pcbnew is lazy-imported inside pcb.py so the rest of the plugin runs fine when KiCad isn't installed (most tools don't need it).


Testing

PYTHONPATH=src pytest tests/           # 212 tests (6 skipped without KiCad)

With KiCad's pcbnew bindings available:

KICAD_INSTALLED=1 PYTHONPATH=src pytest tests/ -v   # runs integration suite too

Coverage spans subprocess wrapping, HTTP mocking, SQLite cache, s-expression round-trip, schematic emission, Gerber renaming, EasyEDA pin-map parsing, rate-limit / retry, session persistence, MCP tool routing, and real pcbnew board generation.

Lint:

ruff check .
ruff format --check .

Troubleshooting

Full guide: TROUBLESHOOTING.md. Most common issues:

Symptom Fix
kicad-jlcpcb command not found pip install -e . from the clone, restart Claude Code
ImportError: No module named pcbnew Install KiCad; don't try to pip install pcbnew (it ships with KiCad)
First run stalls ~12 s per IC Expected — EasyEDA rate limit. Cached forever after first fetch.
Footprint not found Check /usr/share/kicad/footprints/<lib>.pretty/ for the exact name
/pcb-new offers to resume when you wanted a clean start Delete .kicad_jlcpcb_session.json or pick a new project name

Design rationale (Phase 1.6)

Earlier releases tried to route the board headlessly with Freerouting and produce a JLCPCB Gerber zip directly. That didn't work for real boards — Freerouting 2.1.0 has CLI bugs, can't route RF matching networks, and won't save partial results.

Phase 1.6 takes the pragmatic win: the plugin wires everything up, EasyEDA routes and orders. The tradeoff is opening a browser tab and clicking two buttons; in exchange you get reliability the open-source tooling can't match and a one-click path to a JLCPCB order.


Roadmap

  • Phase 2 — auto-placement that respects functional groupings (power domain, RF block, analog front-end), DRC integration, differential-pair awareness.
  • Phase 3 — vision-based schematic extraction: drop in a photo of a hand-drawn schematic, out comes a wired .kicad_pcb.

Contributing

See CONTRIBUTING.md for dev setup, test running, and PR conventions. All contributors follow the Code of Conduct. Bug reports: open an issue.


License

MIT — see LICENSE.

About

Claude Code plugin that turns a PCB idea into a wired .kicad_pcb ready for EasyEDA auto-routing and one-click JLCPCB ordering — LCSC part sourcing, EasyEDA pin-map auto-fetch, and session-persisted workflows.

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages