Skip to main content

Professional KiCAD schematic manipulation library with exact format preservation

Project description

KiCAD Schematic API

Documentation Status PyPI version Python 3.10+ License: MIT

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:

  1. Symbol Space (library definitions): Normal Y-axis (+Y is UP, like math)
  2. 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:

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/position
  • list_components - List all components with metadata
  • update_component - Update properties (value, position, rotation, footprint)
  • remove_component - Remove components
  • filter_components - Advanced filtering by lib_id, value, footprint

Connectivity (3 tools):

  • add_wire - Create wire connections between points
  • add_label - Add net labels for logical connections
  • add_junction - Add wire junctions for T-connections

Pin Discovery (3 tools):

  • get_component_pins - Complete pin information with positions
  • find_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 schematics
  • load_schematic - Load existing .kicad_sch files
  • save_schematic - Save schematics to disk
  • get_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:

  1. create_schematic(name="Voltage Divider") - Create new schematic
  2. add_component(lib_id="Device:R", reference="R1", value="10k", position=(127.0, 76.2)) - Add R1
  3. add_component(lib_id="Device:R", reference="R2", value="20k", position=(127.0, 95.25)) - Add R2
  4. get_component_pins("R1") - Get R1 pin positions
  5. get_component_pins("R2") - Get R2 pin positions
  6. add_wire(start=(127.0, 72.39), end=(127.0, 66.04)) - VCC to R1
  7. add_wire(start=(127.0, 80.01), end=(127.0, 91.44)) - R1 to R2
  8. add_wire(start=(127.0, 99.06), end=(127.0, 105.41)) - R2 to GND
  9. add_label(text="VCC", position=(129.54, 66.04)) - Add VCC label
  10. add_label(text="VOUT", position=(129.54, 85.725)) - Add output label
  11. add_label(text="GND", position=(129.54, 105.41)) - Add GND label
  12. add_junction(position=(127.0, 85.725)) - Add junction at tap point
  13. save_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:

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

API Documentation

Project Information

🤝 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


Made with ❤️ for the open hardware community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kicad_sch_api-0.5.6.tar.gz (391.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kicad_sch_api-0.5.6-py3-none-any.whl (329.1 kB view details)

Uploaded Python 3

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

Hashes for kicad_sch_api-0.5.6.tar.gz
Algorithm Hash digest
SHA256 f001faffdf1745d7a52e90636be2bc4ae3463909491fff9f9d40fe1f7842d36e
MD5 8c1deb069f3c59f68bcda61c55af0ffc
BLAKE2b-256 8038cc778c53ad8b15da1e5b49146c640c0e0eb6a86b0d8270459d59cf042d23

See more details on using hashes here.

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

Hashes for kicad_sch_api-0.5.6-py3-none-any.whl
Algorithm Hash digest
SHA256 70935184dca35eed17bffa8958e93f7fe02512fd0c44d6be9f22ddc54e39d164
MD5 9aaf31ba3121ce3047b23ba686ce200a
BLAKE2b-256 e8f5f042a3f61aa919c6ad2ecdb0e7ec6d9c3b184388363a5a1c46f127513ca3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page