kicad-jlcpcb

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:
- "Is this part basic or extended on JLCPCB?" — You stop needing to cross-reference LCSC's UI. The plugin queries the JLCPCB catalog directly, caches the answer, and always prefers basic-tier (no $3/part assembly setup fee).
- "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.
- "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.
- 14 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 in CI |
| KiCad | 8.0 – 10.x | kicad-cli on PATH or in a standard install location; pcbnew Python bindings for pcb_generate. Only the 8.0 floor is enforced — KiCad 11 removed the SWIG bindings and will pass detection, then fail at pcb_generate. See TROUBLESHOOTING |
| EasyEDA account | free | Only needed for the final routing + ordering step |
| Network | required | Part data is fetched live — see below |
Data dependencies
Part sourcing depends on two third-party, unofficial services. Neither is
run by JLCPCB, and neither is run by us. Both are overridable, so a fork can
point at a mirror without touching code:
| Service | Used for | Override |
|---|
jlcsearch.tscircuit.com | Catalog search, JLCPCB stock, basic/extended tier | KJLC_JLCSEARCH_BASE |
easyeda.com | Exact C-number lookup, symbols, pin maps | KJLC_EASYEDA_BASE |
Resolved parts are cached in ~/.cache/kicad-jlcpcb/lcsc_parts.sqlite for 24
hours. There is no bulk catalog download.
Why the overrides exist. v0.1.0 hardcoded a single third-party URL. Upstream
retired that data layout, the URL started returning 404, and part sourcing
broke silently for months before anyone noticed
(#1). A weekly CI job
now tests both services directly, and you can repoint either one yourself.
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
/plugin marketplace add BeckhamLabsLLC/claude-plugins
/plugin install kicad-jlcpcb@beckhamlabs-plugins
Restart Claude Code, then run /mcp and look for kicad-jlcpcb.
That is the whole install. You do not need to clone the repo, and you do not
need to install anything with pip — the plugin resolves its own two
dependencies (mcp, httpx) on first launch via uv,
which most Python toolchains already have:
curl -LsSf https://astral.sh/uv/install.sh | sh # if you do not have it
If you would rather not use uv, install the dependencies into whichever Python
python3 resolves to and the plugin will use them directly:
python3 -m pip install mcp httpx
KiCad itself is a separate install — see Requirements.
Installing from a clone instead (contributors)
git clone https://github.com/BeckhamLabsLLC/kicad-jlcpcb.git
cd kicad-jlcpcb
pip install -e ".[dev]"
Then register the clone as a local marketplace, which is what makes Claude Code
expand ${CLAUDE_PLUGIN_ROOT} for the MCP server:
/plugin marketplace add /abs/path/to/kicad-jlcpcb
/plugin install kicad-jlcpcb@beckhamlabs
Note the marketplace name differs from the published one: the repo's own
.claude-plugin/marketplace.json declares beckhamlabs, while the aggregator
repo declares beckhamlabs-plugins.
Do not register the checkout by enabling its .mcp.json as a project
server. ${CLAUDE_PLUGIN_ROOT} is only substituted for plugin-provided MCP
configs; in project scope it stays a literal string and the server cannot be
found. See TROUBLESHOOTING.
Sanity check
/mcp in Claude Code should list kicad-jlcpcb with its 14 tools. If it
reports the server failed, see TROUBLESHOOTING — the
first step there prints the actual reason, which Claude Code does not show you.
From a clone, you can also check the whole path end to end — that the server
starts, registers its handlers, and answers a real tool call:
python3 bin/launch.py --version # prints the version, exits 0
python3 scripts/check_protocol.py # initialize -> tools/list -> tools/call
Run the launcher with no arguments and it will appear to hang — that is
correct. An MCP server speaks JSON-RPC on stdio and is waiting for a client.
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:
detect_kicad — verify the toolchain (< 1 s)
create_project — scaffold .kicad_pro + .kicad_sch + session file
- Decomposes the description into ~12 generic part specs
lcsc_search per spec (live catalog query, cached locally for 24 h)
- BOM checkpoint — shows every resolved part, flags extended-tier ones with cost warnings, and waits for your confirmation
pcb_generate — fetches EasyEDA pin maps (~12 s each, only for parts whose nets reference pins by name, first run only), places footprints, wires nets, saves .kicad_pcb
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 through the Claude Code marketplace. There is 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 |
| Resume | session_confirm_bom | Record the user's BOM approval so a restart doesn't re-ask |
| 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 | Symbol + footprint from EasyEDA's real geometry 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. The plugin finds KiCad's footprint directory automatically on Linux, macOS, Windows and Flatpak; override with KJLC_FOOTPRINT_DIR or pcb_generate's lib_dir.
Full worked spec: examples/soilnode-esp32/spec.json.
Architecture