MCP Server Usage Examplesο
This guide provides examples of using the kicad-sch-api MCP server for programmatic circuit generation.
Table of Contentsο
Setupο
Prerequisitesο
# Install kicad-sch-api
cd /path/to/kicad-sch-api
uv pip install -e .
# Verify MCP server works
uv run kicad-sch-mcp
# Press Ctrl+C to stop
Claude Code Integrationο
The .mcp.json file in the project root automatically loads the MCP server:
{
"mcpServers": {
"kicad-sch-api": {
"type": "stdio",
"command": "uv",
"args": ["run", "kicad-sch-mcp"]
}
}
}
Start Claude Code normally (NOT with --dangerously-skip-permissions):
cd /path/to/kicad-sch-api
claude
Approve the MCP server when prompted, then verify:
"What MCP tools do you have available?"
You should see 15 tools across 4 categories.
Basic Component Operationsο
Example 1: Create Schematic and Add Componentο
Request:
Create a new schematic called "BasicTest" and add a 10k resistor at position (100, 100)
MCP Tools Called:
create_schematic(name="BasicTest")add_component(lib_id="Device:R", value="10k", reference="R1", position=(100.0, 100.0))
Result:
New schematic created
Resistor R1 added at specified position
Component has auto-generated UUID
Ready to add more components or save
Example 2: List and Filter Componentsο
Request:
Show me all components in the schematic, then find all resistors
MCP Tools Called:
list_components()- Returns all components with metadatafilter_components(lib_id="Device:R")- Returns only resistors
Output includes:
Reference (R1, R2, etc.)
Value (10k, 100k, etc.)
Position (x, y coordinates)
Rotation (0, 90, 180, 270)
Library ID (Device:R)
Footprint (if specified)
Example 3: Update Component Propertiesο
Request:
Change R1's value to 20k, rotate it 90 degrees, and set footprint to R_0603_1608Metric
MCP Tools Called:
update_component(
reference="R1",
value="20k",
rotation=90.0,
footprint="Resistor_SMD:R_0603_1608Metric"
)
Result:
R1 value updated: 10k β 20k
R1 rotation updated: 0Β° β 90Β°
R1 footprint assigned
Component ready for PCB layout
Example 4: Remove Componentο
Request:
Remove resistor R1 from the schematic
MCP Tools Called:
remove_component(reference="R1")
Result:
R1 removed from schematic
UUID freed for reuse
Schematic modified flag set
Building Complete Circuitsο
Example 5: Voltage Divider (Verified β )ο
Request:
Create a voltage divider with R1=10k and R2=20k, fully connected with VCC and GND labels
Complete MCP Tool Sequence:
# 1. Create schematic
create_schematic(name="Voltage Divider")
# 2. Add components
add_component(
lib_id="Device:R",
reference="R1",
value="10k",
position=(127.0, 76.2),
rotation=0
)
add_component(
lib_id="Device:R",
reference="R2",
value="20k",
position=(127.0, 95.25),
rotation=0
)
# 3. Get pin positions
get_component_pins("R1")
# Returns:
# {
# "pin_count": 2,
# "pins": [
# {"number": "1", "position": {"x": 127.0, "y": 72.39}, "type": "passive"},
# {"number": "2", "position": {"x": 127.0, "y": 80.01}, "type": "passive"}
# ]
# }
get_component_pins("R2")
# Returns:
# {
# "pin_count": 2,
# "pins": [
# {"number": "1", "position": {"x": 127.0, "y": 91.44}, "type": "passive"},
# {"number": "2", "position": {"x": 127.0, "y": 99.06}, "type": "passive"}
# ]
# }
# 4. Add wires
add_wire(start=(127.0, 72.39), end=(127.0, 66.04)) # VCC to R1 pin 1
add_wire(start=(127.0, 80.01), end=(127.0, 91.44)) # R1 pin 2 to R2 pin 1
add_wire(start=(127.0, 99.06), end=(127.0, 105.41)) # R2 pin 2 to GND
# 5. Add labels (offset from wire for visibility)
add_label(text="VCC", position=(129.54, 66.04), rotation=0.0)
add_label(text="VOUT", position=(129.54, 85.725), rotation=0.0)
add_label(text="GND", position=(129.54, 105.41), rotation=0.0)
# 6. Add junction at voltage divider tap point
add_junction(position=(127.0, 85.725), diameter=0.0)
# 7. Save schematic
save_schematic(file_path="voltage_divider.kicad_sch")
Circuit Details:
Input: VCC at top
Output: VOUT = VCC Γ (R2 / (R1 + R2)) = VCC Γ (20k / 30k) = 0.667 Γ VCC
Ground: GND at bottom
Junction: At R1-R2 connection point (VOUT tap)
Result: β VERIFIED WORKING - Opens perfectly in KiCAD with proper connectivity!
Example 6: LED Circuit with Current Limiting Resistorο
Request:
Create an LED circuit with a 220Ξ© current limiting resistor, wired to VCC and GND
Complete MCP Tool Sequence:
# 1. Create schematic
create_schematic(name="LED Circuit")
# 2. Add LED
add_component(
lib_id="Device:LED",
reference="D1",
value="LED",
position=(127.0, 88.9),
rotation=0
)
# 3. Add current limiting resistor
add_component(
lib_id="Device:R",
reference="R1",
value="220",
position=(127.0, 69.85),
rotation=0
)
# 4. Get pin positions
r1_pins = get_component_pins("R1")
# Pin 1 at (127.0, 66.04), Pin 2 at (127.0, 73.66)
d1_pins = get_component_pins("D1")
# Anode (pin 1) at (127.0, 85.09), Cathode (pin 2) at (127.0, 92.71)
# 5. Wire VCC β R1 β LED β GND
add_wire(start=(127.0, 66.04), end=(127.0, 59.69)) # VCC to R1
add_wire(start=(127.0, 73.66), end=(127.0, 85.09)) # R1 to LED anode
add_wire(start=(127.0, 92.71), end=(127.0, 99.06)) # LED cathode to GND
# 6. Add labels
add_label(text="VCC", position=(129.54, 59.69), rotation=0.0)
add_label(text="GND", position=(129.54, 99.06), rotation=0.0)
# 7. Save
save_schematic(file_path="led_circuit.kicad_sch")
Circuit Details:
Current Limiting: I = (VCC - V_LED) / R1 = (5V - 2V) / 220Ξ© β 13.6mA (safe for standard LED)
Polarity: Anode to VCC (through resistor), cathode to GND
Components: Standard red/green LED, 1/4W resistor
Result: Complete LED driver circuit ready for use!
Example 7: RC Low-Pass Filterο
Request:
Create an RC low-pass filter with R=10k, C=100nF for audio applications
Complete MCP Tool Sequence:
# 1. Create schematic
create_schematic(name="RC Low-Pass Filter")
# 2. Add resistor
add_component(
lib_id="Device:R",
reference="R1",
value="10k",
position=(101.6, 88.9),
rotation=90 # Horizontal orientation
)
# 3. Add capacitor
add_component(
lib_id="Device:C",
reference="C1",
value="100nF",
position=(127.0, 95.25),
rotation=0 # Vertical orientation
)
# 4. Get pin positions
r1_pins = get_component_pins("R1")
# Pin 1 (left) at (97.79, 88.9), Pin 2 (right) at (105.41, 88.9)
c1_pins = get_component_pins("C1")
# Pin 1 (top) at (127.0, 91.44), Pin 2 (bottom) at (127.0, 99.06)
# 5. Wire input β R1 β C1 β output
add_wire(start=(97.79, 88.9), end=(88.9, 88.9)) # Input to R1
add_wire(start=(105.41, 88.9), end=(127.0, 88.9)) # R1 to horizontal bus
add_wire(start=(127.0, 88.9), end=(127.0, 91.44)) # Bus to C1 top
add_wire(start=(127.0, 88.9), end=(135.89, 88.9)) # Bus to output
add_wire(start=(127.0, 99.06), end=(127.0, 105.41)) # C1 bottom to GND
# 6. Add labels
add_label(text="INPUT", position=(86.36, 88.9), rotation=0.0)
add_label(text="OUTPUT", position=(138.43, 88.9), rotation=0.0)
add_label(text="GND", position=(129.54, 105.41), rotation=0.0)
# 7. Add junction at output tap (where R1, C1, and output meet)
add_junction(position=(127.0, 88.9), diameter=0.0)
# 8. Save
save_schematic(file_path="rc_filter.kicad_sch")
Circuit Details:
Cutoff Frequency: f_c = 1 / (2Ο Γ R Γ C) = 1 / (2Ο Γ 10kΞ© Γ 100nF) β 159 Hz
Application: Audio low-pass filter, removes high-frequency noise
Attenuation: -20dB/decade above cutoff
Input Impedance: 10kΞ©
Output Impedance: ~10kΞ© at DC, decreases with frequency
Result: Professional audio filter circuit with proper grounding!
Advanced Examplesο
Example 8: Multi-Component Circuit Analysisο
Request:
Load my schematic and analyze it:
1. List all components
2. Find all resistors
3. Find all capacitors with value 100nF
4. Show pin details for U1
MCP Tool Sequence:
# 1. Load existing schematic
load_schematic(file_path="/path/to/my_circuit.kicad_sch")
# 2. List all components
all_components = list_components()
# Returns: {"success": true, "count": 15, "components": [...]}
# 3. Find all resistors
resistors = filter_components(lib_id="Device:R")
# Returns: {"success": true, "count": 5, "components": [R1, R2, R3, R4, R5]}
# 4. Find specific capacitors
caps_100nf = filter_components(lib_id="Device:C", value="100nF")
# Returns: {"success": true, "count": 2, "components": [C2, C7]}
# 5. Get detailed pin information for IC
u1_pins = get_component_pins("U1")
# Returns all 64 pins with positions, names, and types
Use Cases:
BOM generation
Design review
Component inventory
Circuit analysis
Example 9: Pin Discovery for Complex ICsο
Request:
For component U1 (STM32 microcontroller):
1. Show all pins
2. Find all clock pins
3. Find all power input pins
4. Find UART TX pin
MCP Tool Sequence:
# 1. Get all pins (comprehensive view)
all_pins = get_component_pins("U1")
# Returns: 144 pins with complete metadata
# 2. Find clock pins by name pattern
clk_pins = find_pins_by_name("U1", "CLK*", case_sensitive=False)
# Returns: ["PA8", "PB0", "PC9"] - all pins with "CLK" in name
# 3. Find power pins by electrical type
power_pins = find_pins_by_type("U1", "power_in")
# Returns: ["VDD", "VDDA", "VREF+", ...] - all power input pins
# 4. Find specific UART pin
uart_tx = find_pins_by_name("U1", "*TX*", case_sensitive=False)
# Returns: ["PA9", "PB6", "PC10"] - UART TX pins
Use Cases:
Complex IC routing
Power distribution design
Signal integrity analysis
Automatic wire routing
Example 10: Batch Component Updatesο
Request:
Update all resistors to 1% tolerance footprint and rotate them 90 degrees
MCP Tool Sequence:
# 1. Find all resistors
resistors = filter_components(lib_id="Device:R")
# 2. Update each resistor
for resistor in resistors["components"]:
ref = resistor["reference"]
update_component(
reference=ref,
rotation=90.0,
footprint="Resistor_SMD:R_0603_1608Metric"
)
# Result: All resistors now have:
# - 90Β° rotation (horizontal orientation)
# - 0603 footprint for tight PCB layout
Use Cases:
Design standardization
Footprint assignment
Layout optimization
Design rules compliance
Common Patternsο
Pattern 1: Component Placement with Grid Alignmentο
Always use grid-aligned coordinates (1.27mm increments):
# Good - on grid
add_component("Device:R", "R1", "10k", position=(127.0, 76.2))
add_component("Device:C", "C1", "100nF", position=(101.6, 88.9))
# Bad - off grid (causes connectivity issues!)
add_component("Device:R", "R2", "10k", position=(125.5, 75.3))
Grid calculation helper:
# Convert mm to grid units (1.27mm grid)
def to_grid(mm):
return round(mm / 1.27) * 1.27
# Examples
to_grid(100.0) β 101.6 # (80 Γ 1.27)
to_grid(125.0) β 124.46 # (98 Γ 1.27)
Pattern 2: Vertical Component Stackingο
Stack components vertically with consistent spacing:
SPACING = 19.05 # 15 Γ 1.27mm grid units
base_x = 127.0
base_y = 76.2
# Add components with vertical stacking
add_component("Device:R", "R1", "10k", position=(base_x, base_y))
add_component("Device:R", "R2", "20k", position=(base_x, base_y + SPACING))
add_component("Device:R", "R3", "30k", position=(base_x, base_y + 2*SPACING))
# Result: Three resistors perfectly aligned vertically
Pattern 3: Pin-to-Pin Wiringο
Connect components using pin positions:
# 1. Get pin positions
r1_pins = get_component_pins("R1")
r2_pins = get_component_pins("R2")
# Extract specific pins
r1_pin2 = next(p for p in r1_pins["pins"] if p["number"] == "2")
r2_pin1 = next(p for p in r2_pins["pins"] if p["number"] == "1")
# 2. Create wire
add_wire(
start=(r1_pin2["position"]["x"], r1_pin2["position"]["y"]),
end=(r2_pin1["position"]["x"], r2_pin1["position"]["y"])
)
# Result: Direct connection between R1 pin 2 and R2 pin 1
Pattern 4: Label Placement Near Wiresο
Place labels offset from wires for visibility:
# Wire coordinates
wire_x = 127.0
wire_y = 66.04
# Add wire
add_wire(start=(wire_x, wire_y), end=(wire_x, wire_y - 10.0))
# Add label offset to the right (+2.54mm)
add_label(
text="VCC",
position=(wire_x + 2.54, wire_y),
rotation=0.0
)
# Result: Label appears to the right of the wire, clearly visible
Note: See issue #104 for planned improvements to automatic label placement on wires.
Pattern 5: Junction Placementο
Add junctions where 3+ wires meet:
# Connection point coordinates
tap_x = 127.0
tap_y = 85.725
# Add three wires meeting at this point
add_wire(start=(tap_x, 80.01), end=(tap_x, tap_y)) # From above
add_wire(start=(tap_x, tap_y), end=(tap_x, 91.44)) # To below
add_wire(start=(tap_x, tap_y), end=(tap_x + 10, tap_y)) # To right
# Add junction to indicate proper connection
add_junction(position=(tap_x, tap_y), diameter=0.0)
# Result: Clear T-connection with visual junction indicator
Troubleshootingο
Issue 1: Components Not Connectingο
Problem: Wires donβt connect to component pins.
Solution: Verify pin positions and grid alignment:
# Check pin positions
pins = get_component_pins("R1")
print(pins) # Verify exact coordinates
# Ensure wire endpoints match pin positions exactly
add_wire(
start=(127.0, 72.39), # Must match pin position EXACTLY
end=(127.0, 66.04)
)
Issue 2: Labels Not On Wiresο
Problem: Labels appear disconnected from wires.
Current Workaround: Manually calculate label offset:
# Wire position
wire_pos = (127.0, 66.04)
# Place label offset to the right
label_pos = (wire_pos[0] + 2.54, wire_pos[1])
add_label(text="VCC", position=label_pos)
Future: See issue #104 for planned add_label_on_wire() helper method.
Issue 3: Component Rotationο
Problem: Component oriented incorrectly after placement.
Solution: Use correct rotation values:
# Resistor/Capacitor orientations
rotation=0 # Vertical (default) - pins at top and bottom
rotation=90 # Horizontal - pins on left and right
rotation=180 # Vertical inverted
rotation=270 # Horizontal inverted
# Update rotation if needed
update_component(reference="R1", rotation=90.0)
Issue 4: Schematic Not Savingο
Problem: save_schematic() fails or produces empty file.
Solution: Check schematic state and file path:
# Verify schematic info
info = get_schematic_info()
print(info) # Should show component count, project name
# Save with absolute path
save_schematic(file_path="/Users/me/Desktop/my_circuit.kicad_sch")
Issue 5: Component Not Foundο
Problem: get_component_pins("R1") returns error βComponent not foundβ.
Solution: Verify component exists and use correct reference:
# List all components
components = list_components()
print([c["reference"] for c in components["components"]])
# Use exact reference
pins = get_component_pins("R1") # Case-sensitive!
Best Practicesο
Always use grid-aligned coordinates (1.27mm increments)
Get pin positions before wiring - donβt guess coordinates
Add junctions at T-connections - ensures proper connectivity
Place labels offset from wires - improves readability
Use consistent spacing - improves readability and maintainability
Verify component references - use exact case-sensitive names
Save frequently - preserve work incrementally
Test in KiCAD - verify generated schematics open correctly
Additional Resourcesο
MCP Setup Guide - Installation and configuration
README - Main project documentation
API Reference - Complete Python API documentation
Issue #104 - Label placement improvements
Questions or Issues?
Report problems at: https://github.com/circuit-synth/kicad-sch-api/issues