Phase 1: Schematic Workflow Fix (Issue #26) - Fixed broken schematic workflow using template-based symbol cloning - Updated create_project to generate both PCB and schematic files - Rewrote add_schematic_component to use kicad-skip clone() API - Added template schematics with cloneable R, C, LED symbols - All schematic tests now passing Phase 2: JLCPCB Integration Complete - Integrated JLCSearch public API (no authentication required) - Access to ~100k JLCPCB parts with real-time stock and pricing - Implemented parametric search for resistors, capacitors, components - Added package-to-footprint mapping for KiCad integration - Cost optimization with Basic vs Extended library classification - Alternative part suggestions with price comparison New Components: - python/commands/jlcsearch.py - JLCSearch API client - python/templates/ - Template schematics for symbol cloning - docs/JLCPCB_INTEGRATION.md - Comprehensive API documentation - docs/SCHEMATIC_WORKFLOW_FIX.md - Phase 1 technical details - CHANGELOG.md - Consolidated unified changelog - PHASE_2_COMPLETE.md - Phase 2 implementation summary MCP Tools Available: - download_jlcpcb_database - Download full parts catalog - search_jlcpcb_parts - Parametric search with filters - get_jlcpcb_part - Part details + footprint suggestions - get_jlcpcb_database_stats - Database statistics - suggest_jlcpcb_alternatives - Find similar/cheaper parts Technical Improvements: - SQLite database with FTS5 full-text search - HMAC-SHA256 authentication support (official JLCPCB API) - Improved .gitignore to exclude credentials and databases - Template-based schematic creation workflow Testing: - All integration tests passing - Database operations validated - Live API connectivity confirmed - Schematic workflow end-to-end verified Credits: - JLCSearch API: @tscircuit - Local JLCPCB search: @l3wi Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
10 KiB
JLCPCB Parts Integration - Complete Guide
Overview
The KiCAD MCP Server integrates with JLCPCB's parts library to provide intelligent component selection, cost optimization, and automated part sourcing for PCB assembly.
Current Implementation: Uses the JLCSearch public API (by tscircuit) for free, unauthenticated access to JLCPCB's ~100k parts catalog.
Features
✅ Parametric Search - Find components by specifications (resistance, capacitance, package, etc.) ✅ Price Comparison - Compare Basic vs Extended library pricing ✅ Alternative Suggestions - Find cheaper or higher-stock alternatives ✅ Footprint Mapping - Automatic JLCPCB package to KiCad footprint mapping ✅ Stock Availability - Real-time stock levels from JLCPCB ✅ No Authentication Required - Public API, no API keys needed
Quick Start
1. Search for Components
from commands.jlcsearch import JLCSearchClient
client = JLCSearchClient()
# Search for resistors
resistors = client.search_resistors(
resistance=10000, # 10kΩ
package="0603",
limit=20
)
# Search for capacitors
capacitors = client.search_capacitors(
capacitance=1e-7, # 100nF
package="0603",
limit=20
)
# General component search
components = client.search_components(
"components",
package="0603",
limit=100
)
2. Get Part Details
# Get specific part by LCSC number
part = client.get_part_by_lcsc(25804) # C25804
print(f"Part: {part['mfr']}")
print(f"Stock: {part['stock']}")
print(f"Price: ${part['price1']}")
print(f"Basic Library: {part['is_basic']}")
3. Database Integration
from commands.jlcpcb_parts import JLCPCBPartsManager
# Initialize database
db = JLCPCBPartsManager() # Uses data/jlcpcb_parts.db
# Download and import parts (one-time setup)
client = JLCSearchClient()
parts = client.download_all_components()
db.import_jlcsearch_parts(parts)
# Search imported database
results = db.search_parts(
query="resistor",
package="0603",
library_type="Basic",
in_stock=True,
limit=20
)
4. Footprint Mapping
# Map JLCPCB package to KiCad footprints
footprints = db.map_package_to_footprint("0603")
# Returns:
# [
# "Resistor_SMD:R_0603_1608Metric",
# "Capacitor_SMD:C_0603_1608Metric",
# "LED_SMD:LED_0603_1608Metric"
# ]
API Reference
JLCSearchClient
search_resistors(resistance, package, limit)
Search for resistors by value and package.
Parameters:
resistance(int, optional): Resistance in ohmspackage(str, optional): Package size ("0402", "0603", "0805", etc.)limit(int): Maximum results (default: 100)
Returns: List of resistor dicts with fields:
lcsc: LCSC number (integer)mfr: Manufacturer part numberpackage: Package sizeis_basic: True if Basic library part (no assembly fee)resistance: Resistance in ohmstolerance_fraction: Tolerance (0.01 = 1%)power_watts: Power rating in mWstock: Available stockprice1: Unit price in USD
search_capacitors(capacitance, package, limit)
Search for capacitors by value and package.
Parameters:
capacitance(float, optional): Capacitance in farads (e.g., 1e-7 for 100nF)package(str, optional): Package sizelimit(int): Maximum results
Returns: List of capacitor dicts
search_components(category, limit, offset, **filters)
General component search.
Parameters:
category(str): "resistors", "capacitors", "components", etc.limit(int): Maximum resultsoffset(int): Pagination offset**filters: Additional filters (package="0603", lcsc=25804, etc.)
Returns: List of component dicts
download_all_components(callback, batch_size)
Download entire JLCPCB parts catalog.
Parameters:
callback(callable, optional): Progress callback(parts_count, status_msg)batch_size(int): Parts per batch (default: 1000)
Returns: List of all parts (~100k components)
Note: This may take 5-10 minutes to complete.
JLCPCBPartsManager
import_jlcsearch_parts(parts, progress_callback)
Import parts from JLCSearch into local SQLite database.
Parameters:
parts(list): List of part dicts from JLCSearchClientprogress_callback(callable, optional): Progress updates
search_parts(query, category, package, library_type, manufacturer, in_stock, limit)
Search local database with filters.
Parameters:
query(str, optional): Free-text searchcategory(str, optional): Category filterpackage(str, optional): Package filterlibrary_type(str, optional): "Basic", "Extended", or "Preferred"manufacturer(str, optional): Manufacturer filterin_stock(bool): Only in-stock parts (default: True)limit(int): Maximum results
Returns: List of matching parts
get_part_info(lcsc_number)
Get detailed part information.
Parameters:
lcsc_number(str): LCSC part number (e.g., "C25804")
Returns: Part dict or None
get_database_stats()
Get database statistics.
Returns: Dict with:
total_parts: Total parts countbasic_parts: Basic library countextended_parts: Extended library countin_stock: Parts with stock > 0db_path: Database file path
map_package_to_footprint(package)
Map JLCPCB package to KiCad footprints.
Parameters:
package(str): JLCPCB package name
Returns: List of KiCad footprint library references
Data Format
JLCSearch Part Object
{
"lcsc": 25804,
"mfr": "0603WAF1002T5E",
"package": "0603",
"is_basic": true,
"is_preferred": false,
"resistance": 10000,
"tolerance_fraction": 0.01,
"power_watts": 100,
"stock": 37165617,
"price1": 0.000842857
}
Database Schema
CREATE TABLE components (
lcsc TEXT PRIMARY KEY, -- "C25804"
category TEXT, -- "Resistors"
subcategory TEXT, -- "Chip Resistor"
mfr_part TEXT, -- "0603WAF1002T5E"
package TEXT, -- "0603"
solder_joints INTEGER,
manufacturer TEXT,
library_type TEXT, -- "Basic" or "Extended"
description TEXT, -- "10kΩ ±1% 100mW"
datasheet TEXT,
stock INTEGER,
price_json TEXT, -- JSON array of price breaks
last_updated INTEGER -- Unix timestamp
);
Package to Footprint Mappings
| JLCPCB Package | KiCad Footprints |
|---|---|
| 0402 | Resistor_SMD:R_0402_1005Metric Capacitor_SMD:C_0402_1005Metric LED_SMD:LED_0402_1005Metric |
| 0603 | Resistor_SMD:R_0603_1608Metric Capacitor_SMD:C_0603_1608Metric LED_SMD:LED_0603_1608Metric |
| 0805 | Resistor_SMD:R_0805_2012Metric Capacitor_SMD:C_0805_2012Metric |
| 1206 | Resistor_SMD:R_1206_3216Metric Capacitor_SMD:C_1206_3216Metric |
| SOT-23 | Package_TO_SOT_SMD:SOT-23 Package_TO_SOT_SMD:SOT-23-3 |
| SOT-23-5 | Package_TO_SOT_SMD:SOT-23-5 |
| SOT-23-6 | Package_TO_SOT_SMD:SOT-23-6 |
| SOT-223 | Package_TO_SOT_SMD:SOT-223 |
| SOIC-8 | Package_SO:SOIC-8_3.9x4.9mm_P1.27mm |
| QFN-20 | Package_DFN_QFN:QFN-20-1EP_4x4mm_P0.5mm_EP2.5x2.5mm |
Best Practices
1. Always Use Basic Library Parts First
Basic library parts have no assembly fee ($0/part), while Extended parts cost $3/part.
# Filter for Basic parts only
basic_parts = [p for p in results if p['is_basic']]
2. Check Stock Availability
Ensure sufficient stock before committing to a design.
# Only use parts with >1000 stock
high_stock = [p for p in results if p['stock'] > 1000]
3. Compare Prices
Even within Basic library, prices vary significantly.
# Find cheapest option
cheapest = min(results, key=lambda x: x.get('price1', 999))
4. Use Standardized Packages
Stick to common packages (0402, 0603, 0805) for better availability and pricing.
5. Cache Database Locally
Download the full parts database once and search locally for faster results.
# Initial download (one-time, ~5-10 minutes)
if not os.path.exists("data/jlcpcb_parts.db"):
parts = client.download_all_components()
db.import_jlcsearch_parts(parts)
# Subsequent searches use local database (instant)
results = db.search_parts(...)
Troubleshooting
API Rate Limiting
JLCSearch is a community service. If you hit rate limits:
- Add delays between requests (
time.sleep(0.1)) - Use the local database instead of repeated API calls
- Download the full database once and work offline
Missing Data
JLCSearch may not have all fields that official JLCPCB API provides:
- No datasheets (use manufacturer website)
- Limited category information
- No solder joint count
Stock Discrepancies
Stock levels are updated periodically but may lag real-time JLCPCB data by a few hours.
Official JLCPCB API (Alternative)
The project also includes an implementation of the official JLCPCB API with HMAC-SHA256 authentication. However, this requires:
- API approval from JLCPCB (not all applications are approved)
- APP_ID, ACCESS_KEY, and SECRET_KEY credentials
- Previous order history with JLCPCB
To use the official API instead of JLCSearch:
from commands.jlcpcb import JLCPCBClient
# Set credentials in .env file:
# JLCPCB_APP_ID=<your_app_id>
# JLCPCB_API_KEY=<your_access_key>
# JLCPCB_API_SECRET=<your_secret_key>
client = JLCPCBClient(app_id, access_key, secret_key)
data = client.fetch_parts_page()
Note: Most users should use JLCSearch public API instead, as it's freely available and requires no authentication.
Credits
- JLCSearch API: https://jlcsearch.tscircuit.com/ (by @tscircuit)
- JLCParts Database: https://github.com/yaqwsx/jlcparts (by @yaqwsx)
- JLCPCB: https://jlcpcb.com/ (official parts library provider)
License
This integration uses publicly available JLCPCB parts data via the JLCSearch community service. Users must comply with JLCPCB's terms of service when using this data for production PCB orders.