kicad-jlcpcb
Automates PCB design from idea to fabrication: sources JLCPCB parts, fetches pin maps from EasyEDA, places and wires footprints in KiCad, and hands off to EasyEDA for auto-routing and ordering — all via Claude Code.
README
kicad-jlcpcb
From "I want a board that does X" to a wired
.kicad_pcbEasyEDA 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's SQLite-cached jlcparts mirror answers in milliseconds 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. - 13 MCP tools covering setup, sourcing, schematic, PCB generation, EasyEDA handoff, and session resume.
- Session persistence — each project writes a
.kicad_jlcpcb_session.jsonso/pcb-newcan 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:
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_searchper spec (first run populates the 17 MB jlcparts cache)- 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 per unique IC, first run only), places footprints, wires nets, saves.kicad_pcbeasyeda_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_pcbgets 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". libandfpare 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.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.