fix: Register schematic and library tools in MCP server

- Added missing schematic tools registration (fixes #12)
- Created library tools TypeScript implementation
- Added 4 library management tools (list_libraries, search_footprints, list_library_footprints, get_footprint_info)
- Now properly exports and registers all 10 tool categories
- Total of 54 TypeScript tools now properly registered

This resolves the issue where schematic and library tools were defined in Python but not visible to MCP clients.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
KiCAD MCP Bot
2025-11-29 10:17:55 -05:00
parent 8a1fb3d5c3
commit 34ccdb8822
3 changed files with 165 additions and 0 deletions

View File

@@ -17,6 +17,8 @@ import { registerComponentTools } from './tools/component.js';
import { registerRoutingTools } from './tools/routing.js'; import { registerRoutingTools } from './tools/routing.js';
import { registerDesignRuleTools } from './tools/design-rules.js'; import { registerDesignRuleTools } from './tools/design-rules.js';
import { registerExportTools } from './tools/export.js'; import { registerExportTools } from './tools/export.js';
import { registerSchematicTools } from './tools/schematic.js';
import { registerLibraryTools } from './tools/library.js';
import { registerUITools } from './tools/ui.js'; import { registerUITools } from './tools/ui.js';
// Import resource registration functions // Import resource registration functions
@@ -127,6 +129,8 @@ export class KiCADMcpServer {
registerRoutingTools(this.server, this.callKicadScript.bind(this)); registerRoutingTools(this.server, this.callKicadScript.bind(this));
registerDesignRuleTools(this.server, this.callKicadScript.bind(this)); registerDesignRuleTools(this.server, this.callKicadScript.bind(this));
registerExportTools(this.server, this.callKicadScript.bind(this)); registerExportTools(this.server, this.callKicadScript.bind(this));
registerSchematicTools(this.server, this.callKicadScript.bind(this));
registerLibraryTools(this.server, this.callKicadScript.bind(this));
registerUITools(this.server, this.callKicadScript.bind(this)); registerUITools(this.server, this.callKicadScript.bind(this));
// Register all resources // Register all resources

View File

@@ -11,3 +11,5 @@ export { registerRoutingTools } from './routing.js';
export { registerDesignRuleTools } from './design-rules.js'; export { registerDesignRuleTools } from './design-rules.js';
export { registerExportTools } from './export.js'; export { registerExportTools } from './export.js';
export { registerSchematicTools } from './schematic.js'; export { registerSchematicTools } from './schematic.js';
export { registerLibraryTools } from './library.js';
export { registerUITools } from './ui.js';

159
src/tools/library.ts Normal file
View File

@@ -0,0 +1,159 @@
/**
* Library tools for KiCAD MCP server
* Provides access to KiCAD footprint libraries and symbols
*/
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
export function registerLibraryTools(server: McpServer, callKicadScript: Function) {
// List available footprint libraries
server.tool(
"list_libraries",
"List all available KiCAD footprint libraries",
{
search_paths: z.array(z.string()).optional()
.describe("Optional additional search paths for libraries")
},
async (args: { search_paths?: string[] }) => {
const result = await callKicadScript("list_libraries", args);
if (result.success && result.libraries) {
return {
content: [
{
type: "text",
text: `Found ${result.libraries.length} footprint libraries:\n${result.libraries.join('\n')}`
}
]
};
}
return {
content: [
{
type: "text",
text: `Failed to list libraries: ${result.message || 'Unknown error'}`
}
]
};
}
);
// Search for footprints across all libraries
server.tool(
"search_footprints",
"Search for footprints matching a pattern across all libraries",
{
search_term: z.string()
.describe("Search term or pattern to match footprint names"),
library: z.string().optional()
.describe("Optional specific library to search in"),
limit: z.number().optional().default(50)
.describe("Maximum number of results to return")
},
async (args: { search_term: string; library?: string; limit?: number }) => {
const result = await callKicadScript("search_footprints", args);
if (result.success && result.footprints) {
const footprintList = result.footprints.map((fp: any) =>
`${fp.library}:${fp.name}${fp.description ? ' - ' + fp.description : ''}`
).join('\n');
return {
content: [
{
type: "text",
text: `Found ${result.footprints.length} matching footprints:\n${footprintList}`
}
]
};
}
return {
content: [
{
type: "text",
text: `Failed to search footprints: ${result.message || 'Unknown error'}`
}
]
};
}
);
// List footprints in a specific library
server.tool(
"list_library_footprints",
"List all footprints in a specific KiCAD library",
{
library_name: z.string()
.describe("Name of the library to list footprints from"),
filter: z.string().optional()
.describe("Optional filter pattern for footprint names"),
limit: z.number().optional().default(100)
.describe("Maximum number of footprints to list")
},
async (args: { library_name: string; filter?: string; limit?: number }) => {
const result = await callKicadScript("list_library_footprints", args);
if (result.success && result.footprints) {
const footprintList = result.footprints.map((fp: string) => ` - ${fp}`).join('\n');
return {
content: [
{
type: "text",
text: `Library ${args.library_name} contains ${result.footprints.length} footprints:\n${footprintList}`
}
]
};
}
return {
content: [
{
type: "text",
text: `Failed to list footprints in library ${args.library_name}: ${result.message || 'Unknown error'}`
}
]
};
}
);
// Get detailed information about a specific footprint
server.tool(
"get_footprint_info",
"Get detailed information about a specific footprint",
{
library_name: z.string()
.describe("Name of the library containing the footprint"),
footprint_name: z.string()
.describe("Name of the footprint to get information about")
},
async (args: { library_name: string; footprint_name: string }) => {
const result = await callKicadScript("get_footprint_info", args);
if (result.success && result.info) {
const info = result.info;
const details = [
`Footprint: ${info.name}`,
`Library: ${info.library}`,
info.description ? `Description: ${info.description}` : '',
info.keywords ? `Keywords: ${info.keywords}` : '',
info.pads ? `Number of pads: ${info.pads}` : '',
info.layers ? `Layers used: ${info.layers.join(', ')}` : '',
info.courtyard ? `Courtyard size: ${info.courtyard.width}mm x ${info.courtyard.height}mm` : '',
info.attributes ? `Attributes: ${JSON.stringify(info.attributes)}` : ''
].filter(line => line).join('\n');
return {
content: [
{
type: "text",
text: details
}
]
};
}
return {
content: [
{
type: "text",
text: `Failed to get footprint info: ${result.message || 'Unknown error'}`
}
]
};
}
);
}