🔧 Tool Enhancements: - Update all MCP tools to use FastMCP instead of legacy Context - Improve IPC client with proper kicad-python integration - Streamline function signatures for better performance - Remove unnecessary Context dependencies from pattern recognition ⚡ Performance Improvements: - Simplified function calls for faster execution - Better error handling and logging - Enhanced IPC connection management with socket path support - Optimized pattern recognition without blocking operations 🛠️ Technical Updates: - BOM tools: Remove Context dependency for cleaner API - DRC tools: Streamline CLI integration - Export tools: Update thumbnail generation with FastMCP - Netlist tools: Enhance extraction performance - Pattern tools: Non-blocking circuit pattern recognition - IPC client: Add proper kicad-python socket connection These improvements make the MCP tools more reliable and performant for real-time KiCad automation workflows. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
181 lines
6.5 KiB
Python
181 lines
6.5 KiB
Python
"""
|
|
Circuit pattern recognition tools for KiCad schematics.
|
|
"""
|
|
|
|
import os
|
|
from typing import Any
|
|
|
|
from fastmcp import FastMCP
|
|
|
|
from kicad_mcp.utils.file_utils import get_project_files
|
|
from kicad_mcp.utils.netlist_parser import analyze_netlist, extract_netlist
|
|
from kicad_mcp.utils.pattern_recognition import (
|
|
identify_amplifiers,
|
|
identify_digital_interfaces,
|
|
identify_filters,
|
|
identify_microcontrollers,
|
|
identify_oscillators,
|
|
identify_power_supplies,
|
|
identify_sensor_interfaces,
|
|
)
|
|
|
|
|
|
def register_pattern_tools(mcp: FastMCP) -> None:
|
|
"""Register circuit pattern recognition tools with the MCP server.
|
|
|
|
Args:
|
|
mcp: The FastMCP server instance
|
|
"""
|
|
|
|
@mcp.tool()
|
|
def identify_circuit_patterns(schematic_path: str) -> dict[str, Any]:
|
|
"""Identify common circuit patterns in a KiCad schematic.
|
|
|
|
This tool analyzes a schematic to recognize common circuit blocks such as:
|
|
- Power supply circuits (linear regulators, switching converters)
|
|
- Amplifier circuits (op-amps, transistor amplifiers)
|
|
- Filter circuits (RC, LC, active filters)
|
|
- Digital interfaces (I2C, SPI, UART)
|
|
- Microcontroller circuits
|
|
- And more
|
|
|
|
Args:
|
|
schematic_path: Path to the KiCad schematic file (.kicad_sch)
|
|
|
|
Returns:
|
|
Dictionary with identified circuit patterns
|
|
"""
|
|
if not os.path.exists(schematic_path):
|
|
return {"success": False, "error": f"Schematic file not found: {schematic_path}"}
|
|
|
|
# Report progress
|
|
|
|
try:
|
|
# Extract netlist information
|
|
|
|
netlist_data = extract_netlist(schematic_path)
|
|
|
|
if "error" in netlist_data:
|
|
return {"success": False, "error": netlist_data["error"]}
|
|
|
|
# Analyze components and nets
|
|
|
|
components = netlist_data.get("components", {})
|
|
nets = netlist_data.get("nets", {})
|
|
|
|
# Start pattern recognition
|
|
|
|
identified_patterns = {
|
|
"power_supply_circuits": [],
|
|
"amplifier_circuits": [],
|
|
"filter_circuits": [],
|
|
"oscillator_circuits": [],
|
|
"digital_interface_circuits": [],
|
|
"microcontroller_circuits": [],
|
|
"sensor_interface_circuits": [],
|
|
"other_patterns": [],
|
|
}
|
|
|
|
# Identify power supply circuits
|
|
identified_patterns["power_supply_circuits"] = identify_power_supplies(components, nets)
|
|
|
|
# Identify amplifier circuits
|
|
identified_patterns["amplifier_circuits"] = identify_amplifiers(components, nets)
|
|
|
|
# Identify filter circuits
|
|
identified_patterns["filter_circuits"] = identify_filters(components, nets)
|
|
|
|
# Identify oscillator circuits
|
|
identified_patterns["oscillator_circuits"] = identify_oscillators(components, nets)
|
|
|
|
# Identify digital interface circuits
|
|
identified_patterns["digital_interface_circuits"] = identify_digital_interfaces(
|
|
components, nets
|
|
)
|
|
|
|
# Identify microcontroller circuits
|
|
identified_patterns["microcontroller_circuits"] = identify_microcontrollers(components)
|
|
|
|
# Identify sensor interface circuits
|
|
identified_patterns["sensor_interface_circuits"] = identify_sensor_interfaces(
|
|
components, nets
|
|
)
|
|
|
|
# Build result
|
|
result = {
|
|
"success": True,
|
|
"schematic_path": schematic_path,
|
|
"component_count": netlist_data["component_count"],
|
|
"identified_patterns": identified_patterns,
|
|
}
|
|
|
|
# Count total patterns
|
|
total_patterns = sum(len(patterns) for patterns in identified_patterns.values())
|
|
result["total_patterns_found"] = total_patterns
|
|
|
|
# Complete progress
|
|
|
|
return result
|
|
|
|
except Exception as e:
|
|
return {"success": False, "error": str(e)}
|
|
|
|
@mcp.tool()
|
|
def analyze_project_circuit_patterns(project_path: str) -> dict[str, Any]:
|
|
"""Identify circuit patterns in a KiCad project's schematic.
|
|
|
|
Args:
|
|
project_path: Path to the KiCad project file (.kicad_pro)
|
|
|
|
Returns:
|
|
Dictionary with identified circuit patterns
|
|
"""
|
|
if not os.path.exists(project_path):
|
|
return {"success": False, "error": f"Project not found: {project_path}"}
|
|
|
|
# Get the schematic file
|
|
try:
|
|
files = get_project_files(project_path)
|
|
|
|
if "schematic" not in files:
|
|
return {"success": False, "error": "Schematic file not found in project"}
|
|
|
|
schematic_path = files["schematic"]
|
|
|
|
# Identify patterns in the schematic - call synchronous version
|
|
if not os.path.exists(schematic_path):
|
|
return {"success": False, "error": f"Schematic file not found: {schematic_path}"}
|
|
|
|
# Extract netlist data
|
|
netlist_data = extract_netlist(schematic_path)
|
|
if not netlist_data:
|
|
return {"success": False, "error": "Failed to extract netlist from schematic"}
|
|
|
|
components, nets = analyze_netlist(netlist_data)
|
|
|
|
# Identify patterns
|
|
identified_patterns = {}
|
|
identified_patterns["power_supply_circuits"] = identify_power_supplies(components, nets)
|
|
identified_patterns["amplifier_circuits"] = identify_amplifiers(components, nets)
|
|
identified_patterns["filter_circuits"] = identify_filters(components, nets)
|
|
identified_patterns["oscillator_circuits"] = identify_oscillators(components, nets)
|
|
identified_patterns["digital_interface_circuits"] = identify_digital_interfaces(components, nets)
|
|
identified_patterns["microcontroller_circuits"] = identify_microcontrollers(components)
|
|
identified_patterns["sensor_interface_circuits"] = identify_sensor_interfaces(components, nets)
|
|
|
|
result = {
|
|
"success": True,
|
|
"schematic_path": schematic_path,
|
|
"patterns": identified_patterns,
|
|
"total_patterns_found": sum(len(patterns) for patterns in identified_patterns.values())
|
|
}
|
|
|
|
# Add project path to result
|
|
if "success" in result and result["success"]:
|
|
result["project_path"] = project_path
|
|
|
|
return result
|
|
|
|
except Exception as e:
|
|
return {"success": False, "error": str(e)}
|