Professional KiCAD schematic manipulation library with exact format preservation
Project description
KiCAD Schematic API
Python library for reading and writing KiCAD schematic files
Generates valid .kicad_sch files that open in KiCAD 7/8. Focus on exact format preservation and simple API design.
Overview
Read and write KiCAD schematic files programmatically. This library parses and generates .kicad_sch files with exact format preservation - output matches KiCAD's native formatting byte-for-byte.
Core Features
- Exact format preservation - Output matches KiCAD's native formatting byte-for-byte
- Standalone library - No KiCAD installation required
- Simple API - Object-oriented interface for components, wires, labels, and symbols
- Tested compatibility - 70+ tests verify format preservation against KiCAD reference files
- KiCAD library access - Read actual KiCAD symbol libraries for component validation
- Connectivity analysis - Trace electrical connections through wires, labels, and hierarchy
- Hierarchical design - Complete support for multi-sheet schematic projects
- Component bounding boxes - Calculate precise component boundaries for layout algorithms
- Wire routing - Manhattan-style orthogonal routing with basic obstacle avoidance
- BOM property management - Audit, update, and transform component properties for manufacturing
- MCP server - 15 tools for programmatic schematic manipulation via Model Context Protocol
Quick Start
Installation
# Install from PyPI
pip install kicad-sch-api
# Or install from source
git clone https://github.com/circuit-synth/kicad-sch-api.git
cd kicad-sch-api
uv pip install -e .
Basic Usage
import kicad_sch_api as ksa
# Create a new schematic
sch = ksa.create_schematic("My Circuit")
# Add components with proper validation
resistor = sch.components.add(
lib_id="Device:R",
reference="R1",
value="10k",
position=(100.0, 100.0),
footprint="Resistor_SMD:R_0603_1608Metric"
)
# Add wires for connectivity
sch.wires.add(start=(100, 110), end=(150, 110))
# Pin-to-pin wiring
wire_uuid = sch.add_wire_between_pins("R1", "2", "C1", "1")
# Add labels for nets
sch.add_label("VCC", position=(125, 110))
# Save with exact format preservation
sch.save("my_circuit.kicad_sch")
⚠️ Critical: KiCAD Coordinate System
Understanding this is CRITICAL for working with this library.
The Two Coordinate Systems
KiCAD uses two different Y-axis conventions:
- Symbol Space (library definitions): Normal Y-axis (+Y is UP, like math)
- Schematic Space (placed components): Inverted Y-axis (+Y is DOWN, like graphics)
The Transformation
When placing a symbol on a schematic, Y coordinates are negated:
# Symbol library (normal Y, +Y up):
Pin 1: (0, +3.81) # 3.81mm UPWARD in symbol
Pin 2: (0, -3.81) # 3.81mm DOWNWARD in symbol
# Component placed at (100, 100) in schematic (inverted Y, +Y down):
# Y is NEGATED during transformation:
Pin 1: (100, 100 + (-3.81)) = (100, 96.52) # LOWER Y = visually HIGHER
Pin 2: (100, 100 + (+3.81)) = (100, 103.81) # HIGHER Y = visually LOWER
Visual Interpretation
In schematic space (inverted Y-axis):
- Lower Y values = visually HIGHER on screen (top)
- Higher Y values = visually LOWER on screen (bottom)
- X-axis is normal (increases to the right)
Grid Alignment
ALL positions MUST be grid-aligned:
- Default grid: 1.27mm (50 mil)
- Component positions, wire endpoints, pin positions, labels must all align to grid
- Common values: 0.00, 1.27, 2.54, 3.81, 5.08, 6.35, 7.62, 8.89, 10.16...
# Good - on grid
sch.components.add('Device:R', 'R1', '10k', position=(100.33, 101.60))
# Bad - off grid (will cause connectivity issues)
sch.components.add('Device:R', 'R2', '10k', position=(100.5, 101.3))
This coordinate system is critical for:
- Pin position calculations
- Wire routing and connectivity
- Component placement
- Hierarchical connections
- Electrical connectivity detection
🔧 Core Features
Component Management
# Add and manage components
resistor = sch.components.add("Device:R", "R1", "10k", (100, 100))
# Search and filter
resistors = sch.components.find(lib_id_pattern='Device:R*')
# Bulk updates
sch.components.bulk_update(
criteria={'lib_id': 'Device:R'},
updates={'properties': {'Tolerance': '1%'}}
)
# Remove components
sch.components.remove("R1")
📖 See API Reference for complete component API
Text Effects & Styling
# Read text effects from component properties
r1 = sch.components.get("R1")
effects = r1.get_property_effects("Reference")
# Returns: {'font_face': 'Arial', 'font_size': (2.0, 2.0), 'bold': True, ...}
# Modify text effects (partial updates - preserves other effects)
r1.set_property_effects("Reference", {
"color": (0, 255, 0, 1.0), # Green
"bold": True,
"font_size": (2.0, 2.0)
})
# Create components with custom styling
r2 = sch.components.add("Device:R", "R2", "10k", position=(100, 100))
r2.set_property_effects("Value", {
"rotation": 90.0, # Sideways
"justify_h": "left", # Left justified
"color": (160, 32, 240, 1.0), # Purple
"italic": True
})
# Supported effects: position, rotation, font_face, font_size, font_thickness,
# bold, italic, color (RGBA), justify_h, justify_v, visible
📖 See API Reference for text effects details
Connectivity Analysis
# Check if pins are electrically connected
if sch.are_pins_connected("R1", "2", "R2", "1"):
print("Connected!")
# Get net information
net = sch.get_net_for_pin("R1", "2")
print(f"Net: {net.name}, Pins: {len(net.pins)}")
# Get all connected pins
connected = sch.get_connected_pins("R1", "2")
Connectivity analysis includes:
- Direct wire connections
- Connections through junctions
- Local and global labels
- Hierarchical labels (cross-sheet)
- Power symbols (VCC, GND)
- Sheet pins (parent/child)
📖 See API Reference for complete connectivity API
Hierarchy Management
# Build hierarchy tree
tree = sch.hierarchy.build_hierarchy_tree(sch, schematic_path)
# Find reused sheets
reused = sch.hierarchy.find_reused_sheets()
for filename, instances in reused.items():
print(f"{filename} used {len(instances)} times")
# Validate sheet connections
connections = sch.hierarchy.validate_sheet_pins()
errors = sch.hierarchy.get_validation_errors()
# Trace signals through hierarchy
paths = sch.hierarchy.trace_signal_path("VCC")
# Flatten design
flattened = sch.hierarchy.flatten_hierarchy(prefix_references=True)
# Visualize hierarchy
print(sch.hierarchy.visualize_hierarchy(include_stats=True))
📖 See Hierarchy Features Guide for complete hierarchy documentation
Wire Routing & Pin Connections
# Direct pin-to-pin wiring
sch.add_wire_between_pins("R1", "2", "R2", "1")
# Manhattan routing with obstacle avoidance
wires = sch.auto_route_pins(
"R1", "2", "R2", "1",
routing_mode="manhattan",
avoid_components=True
)
# Get pin positions
pos = sch.get_component_pin_position("R1", "1")
📖 See Recipes for routing patterns and examples
Component Bounding Boxes
from kicad_sch_api.core.component_bounds import get_component_bounding_box
# Get bounding box
bbox = get_component_bounding_box(resistor, include_properties=False)
print(f"Size: {bbox.width:.2f}×{bbox.height:.2f}mm")
# Visualize with rectangles
sch.draw_bounding_box(bbox, stroke_color="blue")
sch.draw_component_bounding_boxes(include_properties=True)
📖 See API Reference for bounding box details
Configuration & Customization
import kicad_sch_api as ksa
# Customize property positioning
ksa.config.properties.reference_y = -2.0
ksa.config.properties.value_y = 2.0
# Tolerances
ksa.config.tolerance.position_tolerance = 0.05
# Grid settings
ksa.config.grid.component_spacing = 5.0
📖 See API Reference for all configuration options
Library Path Configuration
The library automatically discovers KiCAD symbol libraries from:
- Environment variables (
KICAD_SYMBOL_DIR,KICAD8_SYMBOL_DIR,KICAD7_SYMBOL_DIR) - Standard KiCAD installations (version-flexible detection)
- User document directories
Set environment variable (Unix/macOS):
# Single path
export KICAD_SYMBOL_DIR=/path/to/kicad/symbols
# Multiple paths (colon-separated)
export KICAD_SYMBOL_DIR=/path/to/symbols:/path/to/custom/symbols
Set environment variable (Windows):
# Single path
set KICAD_SYMBOL_DIR=C:\KiCad\symbols
# Multiple paths (semicolon-separated)
set KICAD_SYMBOL_DIR=C:\KiCad\symbols;D:\Custom\symbols
Add library paths programmatically:
import kicad_sch_api as ksa
# Get cache
cache = ksa.library.get_symbol_cache()
# Add specific library file
cache.add_library_path("/path/to/Device.kicad_sym")
# Discover all libraries in directory
cache.discover_libraries(["/path/to/custom/symbols"])
📖 See Library Configuration Guide for complete documentation
📝 Examples
Learn by example with our polished reference circuits in the examples/ directory:
Basic Circuits
- voltage_divider.py - Simple 10k/10k voltage divider with grid-based parametric design
- rc_filter.py - RC low-pass filter demonstrating wire routing and junctions
- power_supply.py - AMS1117-3.3 voltage regulator (5V → 3.3V) with power symbols
Microcontroller Examples
- stm32_simple.py - STM32G030K8Tx with reset circuit, LED, and SWD debug interface
Run All Examples
- COMBINED.py - Master script that generates all example schematics at once
Getting Started
Start with WALKTHROUGH.md - a complete tutorial from basics to advanced parametric circuits.
All examples use:
- Grid-based positioning with intuitive grid units (1.27mm)
- Parametric
p(x, y)helper for clean, readable coordinates - Individual
add_wire()calls with descriptive comments - Proper wire junctions at all T-connection points
- Comprehensive inline documentation
# Run any example
uv run python examples/voltage_divider.py
uv run python examples/rc_filter.py
uv run python examples/power_supply.py
uv run python examples/stm32_simple.py
# Or run all examples at once
uv run python examples/COMBINED.py
📚 Advanced Features
For comprehensive documentation on all features:
- API Reference - Complete API documentation with examples
- Hierarchy Features - Multi-sheet design guide
- Recipes - Common patterns and examples
- Getting Started - Detailed tutorial
- Architecture - Library design and internals
MCP Server
Includes an MCP (Model Context Protocol) server with 15 tools for programmatic schematic manipulation:
# Start the MCP server
uv run kicad-sch-mcp
# Or install and run directly
pip install kicad-sch-api
kicad-sch-mcp
MCP Tool Suite (15 Tools)
Component Management (5 tools):
add_component- Add components with auto-reference/positionlist_components- List all components with metadataupdate_component- Update properties (value, position, rotation, footprint)remove_component- Remove componentsfilter_components- Advanced filtering by lib_id, value, footprint
Connectivity (3 tools):
add_wire- Create wire connections between pointsadd_label- Add net labels for logical connectionsadd_junction- Add wire junctions for T-connections
Pin Discovery (3 tools):
get_component_pins- Complete pin information with positionsfind_pins_by_name- Semantic lookup with wildcards (, CLK, IN)find_pins_by_type- Filter by electrical type (passive, input, output, power_in)
Schematic Management (4 tools):
create_schematic- Create new KiCAD schematicsload_schematic- Load existing .kicad_sch filessave_schematic- Save schematics to diskget_schematic_info- Query schematic metadata
MCP Server Capabilities
The MCP server provides tools for:
- Adding components, creating connections, and labeling nets
- Creating, loading, saving, and modifying schematic files
- Listing components, filtering by criteria, and discovering pin information
- Building circuits like voltage dividers, filters, LED drivers, and power supplies
Example: Building Complete Circuits via MCP
Voltage Divider (Verified Working ✅)
Natural Language Request:
"Create a voltage divider with R1=10k and R2=20k, fully wired with VCC and GND labels"
The AI agent executes:
create_schematic(name="Voltage Divider")- Create new schematicadd_component(lib_id="Device:R", reference="R1", value="10k", position=(127.0, 76.2))- Add R1add_component(lib_id="Device:R", reference="R2", value="20k", position=(127.0, 95.25))- Add R2get_component_pins("R1")- Get R1 pin positionsget_component_pins("R2")- Get R2 pin positionsadd_wire(start=(127.0, 72.39), end=(127.0, 66.04))- VCC to R1add_wire(start=(127.0, 80.01), end=(127.0, 91.44))- R1 to R2add_wire(start=(127.0, 99.06), end=(127.0, 105.41))- R2 to GNDadd_label(text="VCC", position=(129.54, 66.04))- Add VCC labeladd_label(text="VOUT", position=(129.54, 85.725))- Add output labeladd_label(text="GND", position=(129.54, 105.41))- Add GND labeladd_junction(position=(127.0, 85.725))- Add junction at tap pointsave_schematic(file_path="voltage_divider.kicad_sch")- Save to disk
Result: ✅ Fully functional KiCAD schematic verified to open perfectly in KiCAD!
LED Circuit with Current Limiting
Natural Language Request:
"Create an LED circuit with 220Ω current limiting resistor"
The AI agent will:
- Add LED and 220Ω resistor components
- Wire VCC → resistor → LED → GND
- Add appropriate net labels
- Save the complete circuit
Result: Ready-to-use LED driver circuit schematic!
RC Low-Pass Filter
Natural Language Request:
"Create an RC low-pass filter with R=10k, C=100nF"
The AI agent will:
- Add resistor (10k) and capacitor (100nF)
- Wire input → R → C → output
- Add GND connection to capacitor
- Label INPUT, OUTPUT, and GND nets
- Add junction at output tap
- Save filter schematic
Result: Complete filter circuit with proper connectivity!
Claude Desktop Integration
Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"kicad-sch-api": {
"command": "uv",
"args": ["run", "kicad-sch-mcp"],
"env": {}
}
}
}
MCP tools enable programmatic creation, modification, and analysis of KiCAD schematics.
📖 Complete Documentation:
- MCP Setup Guide - Installation, configuration, and troubleshooting
- MCP Examples - Comprehensive usage examples and patterns
- API Reference - Complete API documentation
Architecture
Design Principles
- Building Block First: Designed to be the foundation for other tools
- Exact Format Preservation: Guaranteed byte-perfect KiCAD output
- Comprehensive Validation: Error handling and input validation
- MCP Integration: Includes MCP server for programmatic schematic manipulation
- Performance Optimized: Fast operations on large schematics
📖 See Architecture Guide for detailed design documentation
Testing & Quality
# Run all tests (29 tests covering all functionality)
uv run pytest tests/ -v
# Format preservation tests (critical - exact KiCAD output matching)
uv run pytest tests/reference_tests/ -v
# Code quality checks
uv run black kicad_sch_api/ tests/
uv run mypy kicad_sch_api/
Test Categories
- Format Preservation: Byte-for-byte compatibility with KiCAD native files
- Component Management: Creation, modification, and removal
- Connectivity: Wire tracing, net analysis, hierarchical connections
- Hierarchy: Multi-sheet designs, sheet reuse, signal tracing
- Integration: Real KiCAD library compatibility
Why This Library?
vs. Direct KiCAD File Editing
- High-level API: Object-oriented interface vs low-level S-expression manipulation
- Format Preservation: Byte-perfect output vs manual formatting
- Validation: Real KiCAD library integration and component validation
vs. Other Python KiCAD Libraries
- Format Preservation: Exact KiCAD compatibility vs approximate output
- Object-Oriented Design: Modern collection classes vs legacy patterns
- MCP Integration: Included MCP server vs no programmatic interface
📖 See Why Use This Library for detailed comparison
Known Limitations
Connectivity Analysis
- Global Labels: Explicit global label connections not yet fully implemented (power symbols like VCC/GND work correctly)
ERC (Electrical Rule Check)
- Partial Implementation: ERC validators have incomplete features
- Net tracing, pin type checking, and power net detection are in development
- Core functionality works, advanced validation features coming soon
Performance
- Large schematics (>1000 components) may experience slower connectivity analysis
- Symbol cache helps, but first analysis can take time
- Optimization ongoing
Report issues: https://github.com/circuit-synth/kicad-sch-api/issues
Documentation
Full documentation is available:
Learning Resources
- Examples Walkthrough - Start here! Complete tutorial from basics to advanced
- Example Circuits - Polished reference circuits (voltage divider, RC filter, power supply, STM32)
- Getting Started Guide - Complete beginner's tutorial
API Documentation
- API Reference - Complete API documentation
- Hierarchy Features - Multi-sheet design guide
- Recipes & Patterns - Practical examples
Project Information
- Why Use This Library - Value proposition
- Architecture - Internal design details
🤝 Contributing
We welcome contributions! Key areas:
- KiCAD library integration and component validation
- Performance optimizations for large schematics
- MCP server tools and AI agent capabilities
- Test coverage and format preservation validation
See CONTRIBUTING.md for guidelines.
📄 License
MIT License - see LICENSE for details.
🔗 Related Projects
- circuit-synth - High-level circuit design automation
- Claude Code - AI development environment with MCP support
- KiCAD - Open source electronics design automation
- Model Context Protocol - Standard for AI agent tool integration
Made with ❤️ for the open hardware community
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kicad_sch_api-0.5.6.tar.gz.
File metadata
- Download URL: kicad_sch_api-0.5.6.tar.gz
- Upload date:
- Size: 391.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f001faffdf1745d7a52e90636be2bc4ae3463909491fff9f9d40fe1f7842d36e
|
|
| MD5 |
8c1deb069f3c59f68bcda61c55af0ffc
|
|
| BLAKE2b-256 |
8038cc778c53ad8b15da1e5b49146c640c0e0eb6a86b0d8270459d59cf042d23
|
File details
Details for the file kicad_sch_api-0.5.6-py3-none-any.whl.
File metadata
- Download URL: kicad_sch_api-0.5.6-py3-none-any.whl
- Upload date:
- Size: 329.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70935184dca35eed17bffa8958e93f7fe02512fd0c44d6be9f22ddc54e39d164
|
|
| MD5 |
9aaf31ba3121ce3047b23ba686ce200a
|
|
| BLAKE2b-256 |
e8f5f042a3f61aa919c6ad2ecdb0e7ec6d9c3b184388363a5a1c46f127513ca3
|