feat(schematic): hierarchical sheet insertion and subsheet scaffolding
Adds add_hierarchical_sheet (insert a sheet symbol referencing a child .kicad_sch, with sheet_instances + fixed component instance paths) and create_hierarchical_subsheet (create the child file + wire it into the parent in one call). Upstream has add_sheet_pin / add_schematic_hierarchical_label but no way to create a sheet or stand up a child sheet, so hierarchical designs can't be built through the MCP server today. - python/commands/schematic_hierarchy.py: SchematicHierarchyCommands - src/tools/schematic-hierarchy.ts + registry 'schematic_hierarchy' category - python/kicad_interface.py: import + instantiate + dispatch routes - tests/test_schematic_hierarchy.py: 5 unit/integration tests on real .kicad_sch Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import { registerExportTools } from "./tools/export.js";
|
||||
import { registerSchematicTools } from "./tools/schematic.js";
|
||||
import { registerLibraryTools } from "./tools/library.js";
|
||||
import { registerSymbolLibraryTools } from "./tools/library-symbol.js";
|
||||
import { registerSchematicHierarchyTools } from "./tools/schematic-hierarchy.js";
|
||||
import { registerJLCPCBApiTools } from "./tools/jlcpcb-api.js";
|
||||
import { registerDatasheetTools } from "./tools/datasheet.js";
|
||||
import { registerFootprintTools } from "./tools/footprint.js";
|
||||
@@ -296,6 +297,7 @@ export class KiCADMcpServer {
|
||||
registerSchematicTools(this.server, this.callKicadScript.bind(this));
|
||||
registerLibraryTools(this.server, this.callKicadScript.bind(this));
|
||||
registerSymbolLibraryTools(this.server, this.callKicadScript.bind(this));
|
||||
registerSchematicHierarchyTools(this.server, this.callKicadScript.bind(this));
|
||||
registerJLCPCBApiTools(this.server, this.callKicadScript.bind(this));
|
||||
registerDatasheetTools(this.server, this.callKicadScript.bind(this));
|
||||
registerFootprintTools(this.server, this.callKicadScript.bind(this));
|
||||
|
||||
@@ -123,6 +123,11 @@ export const toolCategories: ToolCategory[] = [
|
||||
description: "Read a symbol's pins straight from the library (no schematic needed)",
|
||||
tools: ["list_symbol_pins", "batch_list_symbol_pins"],
|
||||
},
|
||||
{
|
||||
name: "schematic_hierarchy",
|
||||
description: "Hierarchical schematic sheets: insert a sheet, scaffold a sub-sheet",
|
||||
tools: ["add_hierarchical_sheet", "create_hierarchical_subsheet"],
|
||||
},
|
||||
{
|
||||
name: "routing",
|
||||
description: "Advanced routing operations: vias, copper pours",
|
||||
|
||||
64
src/tools/schematic-hierarchy.ts
Normal file
64
src/tools/schematic-hierarchy.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Schematic hierarchy tools: insert a hierarchical sheet, scaffold a sub-sheet.
|
||||
*/
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { z } from "zod";
|
||||
|
||||
export function registerSchematicHierarchyTools(server: McpServer, callKicadScript: Function) {
|
||||
// Link an existing sub-sheet into a parent
|
||||
server.tool(
|
||||
"add_hierarchical_sheet",
|
||||
"Insert a hierarchical-sheet reference block into a parent schematic, pointing at an existing sub-sheet file. Adds the sheet box, name/file fields, a sheet_instances path entry on the next page number, and fixes sub-sheet component instance paths so ERC resolves references.",
|
||||
{
|
||||
schematicPath: z.string().describe("Path to the parent .kicad_sch"),
|
||||
subsheetPath: z.string().describe("Path to the existing sub-sheet .kicad_sch to reference"),
|
||||
sheetName: z.string().optional().default("Sheet").describe("Display name for the sheet"),
|
||||
position: z
|
||||
.object({ x: z.number(), y: z.number() })
|
||||
.optional()
|
||||
.describe("Top-left of the sheet box in mm (default 50,50)"),
|
||||
size: z
|
||||
.object({ width: z.number(), height: z.number() })
|
||||
.optional()
|
||||
.describe("Sheet box size in mm (default 80x50)"),
|
||||
},
|
||||
async (args: any) => {
|
||||
const r = await callKicadScript("add_hierarchical_sheet", args);
|
||||
if (!r.success)
|
||||
return { content: [{ type: "text", text: `Failed: ${r.message || "Unknown error"}` }] };
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `Added sheet '${r.sheet_name}' -> ${r.subsheet_path} (page ${r.page})`,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
// Create a sub-sheet file AND link it in one call
|
||||
server.tool(
|
||||
"create_hierarchical_subsheet",
|
||||
"Create a new sub-sheet .kicad_sch file and link it into a parent schematic in a single call (create_schematic + add_hierarchical_sheet). The fastest way to grow a hierarchical design.",
|
||||
{
|
||||
parentSchematicPath: z.string().describe("Path to the parent .kicad_sch"),
|
||||
subsheetPath: z.string().describe("Path for the new sub-sheet .kicad_sch to create"),
|
||||
sheetName: z.string().optional().default("Sheet").describe("Display name for the sheet"),
|
||||
position: z.object({ x: z.number(), y: z.number() }).optional(),
|
||||
size: z.object({ width: z.number(), height: z.number() }).optional(),
|
||||
metadata: z
|
||||
.record(z.string(), z.any())
|
||||
.optional()
|
||||
.describe("Optional metadata for the new sub-sheet (title, etc.)"),
|
||||
},
|
||||
async (args: any) => {
|
||||
const r = await callKicadScript("create_hierarchical_subsheet", args);
|
||||
return {
|
||||
content: [
|
||||
{ type: "text", text: r.success ? r.message : `Failed: ${r.message || "Unknown error"}` },
|
||||
],
|
||||
};
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user