# 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 ```python 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 ```python # 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 ```python 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 ```python # 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 ```json { "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 ```sql 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**. ```python # 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. ```python # 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. ```python # 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. ```python # 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: ```python from commands.jlcpcb import JLCPCBClient # Set credentials in .env file: # JLCPCB_APP_ID= # JLCPCB_API_KEY= # JLCPCB_API_SECRET= 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](https://github.com/tscircuit/jlcsearch)) - **JLCParts Database**: https://github.com/yaqwsx/jlcparts (by [@yaqwsx](https://github.com/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.