fix: implement export_netlist handler and rewrite generate_netlist to use kicad-cli
export_netlist was returning "Unknown command" because no Python handler
existed. generate_netlist was timing out (30s) due to an O(nets × components
× pins) wire-graph algorithm with a new PinLocator instantiated per net.
Both handlers now delegate to `kicad-cli sch export netlist`:
- export_netlist: new handler; writes KiCad XML / Spice / Cadstar / OrcadPCB2
to the caller-supplied outputPath. Added schematicPath parameter to the TS
tool definition (was absent, making file export impossible).
- generate_netlist: replaces the slow wire-graph with kicad-cli + XML parse;
returns the same {components, nets} JSON the TS handler already expected.
Also adds _find_kicad_cli_static() so both handlers share CLI discovery
without depending on ExportCommands (which requires a loaded pcbnew board).
Cleaned up generate_netlist schema in tool_schemas.py (removed outputPath and
format fields the handler never used), updated MCP tool descriptions and
SCHEMATIC_TOOLS_REFERENCE.md to clearly distinguish the two tools.
26 unit tests added covering parameter validation, subprocess mocking,
format mapping, XML→JSON parsing, and error/timeout propagation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -222,16 +222,19 @@ export function registerExportTools(server: McpServer, callKicadScript: CommandF
|
||||
// ------------------------------------------------------
|
||||
server.tool(
|
||||
"export_netlist",
|
||||
"Export the schematic netlist to a file using kicad-cli. Supports KiCad XML (default), Spice (for simulation), Cadstar, and OrcadPCB2 formats. Use this when you need to write a netlist file to disk — for example to produce a SPICE file for simulation or to diff against a reference. To get net/component data inline without writing a file, use generate_netlist instead.",
|
||||
{
|
||||
outputPath: z.string().describe("Path to save the netlist file"),
|
||||
schematicPath: z.string().describe("Absolute path to the .kicad_sch schematic file"),
|
||||
outputPath: z.string().describe("Absolute path for the output file (e.g. /tmp/design.spice)"),
|
||||
format: z
|
||||
.enum(["KiCad", "Spice", "Cadstar", "OrcadPCB2"])
|
||||
.optional()
|
||||
.describe("Netlist format (default: KiCad)"),
|
||||
},
|
||||
async ({ outputPath, format }) => {
|
||||
async ({ schematicPath, outputPath, format }) => {
|
||||
logger.debug(`Exporting netlist to: ${outputPath}`);
|
||||
const result = await callKicadScript("export_netlist", {
|
||||
schematicPath,
|
||||
outputPath,
|
||||
format,
|
||||
});
|
||||
|
||||
@@ -1152,9 +1152,9 @@ Note: operates on .kicad_sch files only. To modify a PCB footprint use edit_comp
|
||||
// Generate netlist
|
||||
server.tool(
|
||||
"generate_netlist",
|
||||
"Generate a netlist from the schematic",
|
||||
"Return a structured JSON netlist from the schematic — component list (reference, value, footprint) and net list (net name with all connected component/pin pairs). Use this to inspect or verify connectivity within the conversation. Does not write any file. To export a netlist file in Spice, KiCad XML, Cadstar, or OrcadPCB2 format, use export_netlist instead.",
|
||||
{
|
||||
schematicPath: z.string().describe("Path to the schematic file"),
|
||||
schematicPath: z.string().describe("Absolute path to the .kicad_sch schematic file"),
|
||||
},
|
||||
async (args: { schematicPath: string }) => {
|
||||
const result = await callKicadScript("generate_netlist", args);
|
||||
|
||||
Reference in New Issue
Block a user