Files
kicad-mcp-server/docs/JLCPCB_INTEGRATION.md
KiCAD MCP Bot 994965e041 feat: Complete Phase 1 & 2 - Schematic workflow fix and JLCPCB integration
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>
2026-01-10 09:04:56 -05:00

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 ohms
  • package (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 number
  • package: Package size
  • is_basic: True if Basic library part (no assembly fee)
  • resistance: Resistance in ohms
  • tolerance_fraction: Tolerance (0.01 = 1%)
  • power_watts: Power rating in mW
  • stock: Available stock
  • price1: 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 size
  • limit (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 results
  • offset (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 JLCSearchClient
  • progress_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 search
  • category (str, optional): Category filter
  • package (str, optional): Package filter
  • library_type (str, optional): "Basic", "Extended", or "Preferred"
  • manufacturer (str, optional): Manufacturer filter
  • in_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 count
  • basic_parts: Basic library count
  • extended_parts: Extended library count
  • in_stock: Parts with stock > 0
  • db_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:

  1. API approval from JLCPCB (not all applications are approved)
  2. APP_ID, ACCESS_KEY, and SECRET_KEY credentials
  3. 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

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.