Skip to main content
Glama
lamaalrajih

KiCad MCP Server

by lamaalrajih

extract_schematic_netlist

Extract netlist data from KiCad schematic files to analyze components, connections, and labels for circuit design verification.

Instructions

Extract netlist information from a KiCad schematic.

This tool parses a KiCad schematic file and extracts comprehensive netlist information including components, connections, and labels.

Args: schematic_path: Path to the KiCad schematic file (.kicad_sch) ctx: MCP context for progress reporting

Returns: Dictionary with netlist information

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
schematic_pathYes
ctxYes

Implementation Reference

  • The primary handler for the 'extract_schematic_netlist' tool. Decorated with @mcp.tool(), it handles input validation, progress reporting, calls helper functions extract_netlist and analyze_netlist, and constructs the response dictionary with components, nets, and analysis results.
    @mcp.tool()
    async def extract_schematic_netlist(schematic_path: str, ctx: Context | None) -> Dict[str, Any]:
        """Extract netlist information from a KiCad schematic.
        
        This tool parses a KiCad schematic file and extracts comprehensive
        netlist information including components, connections, and labels.
        
        Args:
            schematic_path: Path to the KiCad schematic file (.kicad_sch)
            ctx: MCP context for progress reporting
            
        Returns:
            Dictionary with netlist information
        """
        print(f"Extracting netlist from schematic: {schematic_path}")
        
        if not os.path.exists(schematic_path):
            print(f"Schematic file not found: {schematic_path}")
            if ctx:
                ctx.info(f"Schematic file not found: {schematic_path}")
            return {"success": False, "error": f"Schematic file not found: {schematic_path}"}
        
        # Report progress
        if ctx:
            await ctx.report_progress(10, 100)
            ctx.info(f"Loading schematic file: {os.path.basename(schematic_path)}")
        
        # Extract netlist information
        try:
            if ctx:
                await ctx.report_progress(20, 100)
                ctx.info("Parsing schematic structure...")
            
            netlist_data = extract_netlist(schematic_path)
            
            if "error" in netlist_data:
                print(f"Error extracting netlist: {netlist_data['error']}")
                if ctx:
                    ctx.info(f"Error extracting netlist: {netlist_data['error']}")
                return {"success": False, "error": netlist_data['error']}
            
            if ctx:
                await ctx.report_progress(60, 100)
                ctx.info(f"Extracted {netlist_data['component_count']} components and {netlist_data['net_count']} nets")
            
            # Analyze the netlist
            if ctx:
                await ctx.report_progress(70, 100)
                ctx.info("Analyzing netlist data...")
            
            analysis_results = analyze_netlist(netlist_data)
            
            if ctx:
                await ctx.report_progress(90, 100)
            
            # Build result
            result = {
                "success": True,
                "schematic_path": schematic_path,
                "component_count": netlist_data["component_count"],
                "net_count": netlist_data["net_count"],
                "components": netlist_data["components"],
                "nets": netlist_data["nets"],
                "analysis": analysis_results
            }
            
            # Complete progress
            if ctx:
                await ctx.report_progress(100, 100)
                ctx.info("Netlist extraction complete")
            
            return result
            
        except Exception as e:
            print(f"Error extracting netlist: {str(e)}")
            if ctx:
                ctx.info(f"Error extracting netlist: {str(e)}")
            return {"success": False, "error": str(e)}
  • Top-level registration call to register_netlist_tools(mcp), which defines and registers the extract_schematic_netlist tool (and others) with the FastMCP server instance.
    register_netlist_tools(mcp)
  • Key helper function extract_netlist that instantiates SchematicParser to parse the .kicad_sch file, extracting components, labels, wires, power symbols, and building basic netlist data.
    def extract_netlist(schematic_path: str) -> Dict[str, Any]:
        """Extract netlist information from a KiCad schematic file.
        
        Args:
            schematic_path: Path to the KiCad schematic file (.kicad_sch)
            
        Returns:
            Dictionary with netlist information
        """
        try:
            parser = SchematicParser(schematic_path)
            return parser.parse()
        except Exception as e:
            print(f"Error extracting netlist: {str(e)}")
            return {
                "error": str(e),
                "components": {},
                "nets": {},
                "component_count": 0,
                "net_count": 0
            }
  • Supporting helper analyze_netlist that processes netlist data to categorize components by type, identify power nets, and compute connection statistics.
    def analyze_netlist(netlist_data: Dict[str, Any]) -> Dict[str, Any]:
        """Analyze netlist data to provide insights.
        
        Args:
            netlist_data: Dictionary with netlist information
            
        Returns:
            Dictionary with analysis results
        """
        results = {
            "component_count": netlist_data.get("component_count", 0),
            "net_count": netlist_data.get("net_count", 0),
            "component_types": defaultdict(int),
            "power_nets": []
        }
        
        # Analyze component types
        for ref, component in netlist_data.get("components", {}).items():
            # Extract component type from reference (e.g., R1 -> R)
            comp_type = re.match(r'^([A-Za-z_]+)', ref)
            if comp_type:
                results["component_types"][comp_type.group(1)] += 1
        
        # Identify power nets
        for net_name in netlist_data.get("nets", {}):
            if any(net_name.startswith(prefix) for prefix in ["VCC", "VDD", "GND", "+5V", "+3V3", "+12V"]):
                results["power_nets"].append(net_name)
        
        # Count pin connections
        total_pins = sum(len(pins) for pins in netlist_data.get("nets", {}).values())
        results["total_pin_connections"] = total_pins
        
        return results

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lamaalrajih/kicad-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server