Files
kicad-mcp-server/src/resources/library.ts
Eugene Mikhantyev 7d50fa1d4c style: apply Prettier formatting to TS/JS/JSON/MD files
Add Prettier as a dev dependency with .prettierrc.json config and
.prettierignore. Hook added via mirrors-prettier in pre-commit config.
All TypeScript, JSON, Markdown, and YAML files auto-formatted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 13:05:50 +01:00

324 lines
9.1 KiB
TypeScript

/**
* Library resources for KiCAD MCP server
*
* These resources provide information about KiCAD component libraries
* to the LLM, enabling better context-aware assistance.
*/
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { logger } from "../logger.js";
// Command function type for KiCAD script calls
type CommandFunction = (command: string, params: Record<string, unknown>) => Promise<any>;
/**
* Register library resources with the MCP server
*
* @param server MCP server instance
* @param callKicadScript Function to call KiCAD script commands
*/
export function registerLibraryResources(
server: McpServer,
callKicadScript: CommandFunction,
): void {
logger.info("Registering library resources");
// ------------------------------------------------------
// Component Library Resource
// ------------------------------------------------------
server.resource(
"component_library",
new ResourceTemplate("kicad://components/{filter?}/{library?}", {
list: async () => ({
resources: [{ uri: "kicad://components", name: "All Components" }],
}),
}),
async (uri, params) => {
const filter = params.filter || "";
const library = params.library || "";
const limit = Number(params.limit) || undefined;
logger.debug(
`Retrieving component library${filter ? ` with filter: ${filter}` : ""}${library ? ` from library: ${library}` : ""}`,
);
const result = await callKicadScript("get_component_library", {
filter,
library,
limit,
});
if (!result.success) {
logger.error(`Failed to retrieve component library: ${result.errorDetails}`);
return {
contents: [
{
uri: uri.href,
text: JSON.stringify({
error: "Failed to retrieve component library",
details: result.errorDetails,
}),
mimeType: "application/json",
},
],
};
}
logger.debug(
`Successfully retrieved ${result.components?.length || 0} components from library`,
);
return {
contents: [
{
uri: uri.href,
text: JSON.stringify(result),
mimeType: "application/json",
},
],
};
},
);
// ------------------------------------------------------
// Library List Resource
// ------------------------------------------------------
server.resource("library_list", "kicad://libraries", async (uri) => {
logger.debug("Retrieving library list");
const result = await callKicadScript("get_library_list", {});
if (!result.success) {
logger.error(`Failed to retrieve library list: ${result.errorDetails}`);
return {
contents: [
{
uri: uri.href,
text: JSON.stringify({
error: "Failed to retrieve library list",
details: result.errorDetails,
}),
mimeType: "application/json",
},
],
};
}
logger.debug(`Successfully retrieved ${result.libraries?.length || 0} libraries`);
return {
contents: [
{
uri: uri.href,
text: JSON.stringify(result),
mimeType: "application/json",
},
],
};
});
// ------------------------------------------------------
// Library Component Details Resource
// ------------------------------------------------------
server.resource(
"library_component_details",
new ResourceTemplate("kicad://library/component/{componentId}/{library?}", {
list: undefined,
}),
async (uri, params) => {
const { componentId, library } = params;
logger.debug(
`Retrieving details for component: ${componentId}${library ? ` from library: ${library}` : ""}`,
);
const result = await callKicadScript("get_component_details", {
componentId,
library,
});
if (!result.success) {
logger.error(`Failed to retrieve component details: ${result.errorDetails}`);
return {
contents: [
{
uri: uri.href,
text: JSON.stringify({
error: `Failed to retrieve details for component ${componentId}`,
details: result.errorDetails,
}),
mimeType: "application/json",
},
],
};
}
logger.debug(`Successfully retrieved details for component: ${componentId}`);
return {
contents: [
{
uri: uri.href,
text: JSON.stringify(result),
mimeType: "application/json",
},
],
};
},
);
// ------------------------------------------------------
// Component Footprint Resource
// ------------------------------------------------------
server.resource(
"component_footprint",
new ResourceTemplate("kicad://footprint/{componentId}/{footprint?}", {
list: undefined,
}),
async (uri, params) => {
const { componentId, footprint } = params;
logger.debug(
`Retrieving footprint for component: ${componentId}${footprint ? ` (${footprint})` : ""}`,
);
const result = await callKicadScript("get_component_footprint", {
componentId,
footprint,
});
if (!result.success) {
logger.error(`Failed to retrieve component footprint: ${result.errorDetails}`);
return {
contents: [
{
uri: uri.href,
text: JSON.stringify({
error: `Failed to retrieve footprint for component ${componentId}`,
details: result.errorDetails,
}),
mimeType: "application/json",
},
],
};
}
logger.debug(`Successfully retrieved footprint for component: ${componentId}`);
return {
contents: [
{
uri: uri.href,
text: JSON.stringify(result),
mimeType: "application/json",
},
],
};
},
);
// ------------------------------------------------------
// Component Symbol Resource
// ------------------------------------------------------
server.resource(
"component_symbol",
new ResourceTemplate("kicad://symbol/{componentId}", {
list: undefined,
}),
async (uri, params) => {
const { componentId } = params;
logger.debug(`Retrieving symbol for component: ${componentId}`);
const result = await callKicadScript("get_component_symbol", {
componentId,
});
if (!result.success) {
logger.error(`Failed to retrieve component symbol: ${result.errorDetails}`);
return {
contents: [
{
uri: uri.href,
text: JSON.stringify({
error: `Failed to retrieve symbol for component ${componentId}`,
details: result.errorDetails,
}),
mimeType: "application/json",
},
],
};
}
logger.debug(`Successfully retrieved symbol for component: ${componentId}`);
// If the result includes SVG data, return it as SVG
if (result.svgData) {
return {
contents: [
{
uri: uri.href,
text: result.svgData,
mimeType: "image/svg+xml",
},
],
};
}
// Otherwise return the JSON result
return {
contents: [
{
uri: uri.href,
text: JSON.stringify(result),
mimeType: "application/json",
},
],
};
},
);
// ------------------------------------------------------
// Component 3D Model Resource
// ------------------------------------------------------
server.resource(
"component_3d_model",
new ResourceTemplate("kicad://3d-model/{componentId}/{footprint?}", {
list: undefined,
}),
async (uri, params) => {
const { componentId, footprint } = params;
logger.debug(
`Retrieving 3D model for component: ${componentId}${footprint ? ` (${footprint})` : ""}`,
);
const result = await callKicadScript("get_component_3d_model", {
componentId,
footprint,
});
if (!result.success) {
logger.error(`Failed to retrieve component 3D model: ${result.errorDetails}`);
return {
contents: [
{
uri: uri.href,
text: JSON.stringify({
error: `Failed to retrieve 3D model for component ${componentId}`,
details: result.errorDetails,
}),
mimeType: "application/json",
},
],
};
}
logger.debug(`Successfully retrieved 3D model for component: ${componentId}`);
return {
contents: [
{
uri: uri.href,
text: JSON.stringify(result),
mimeType: "application/json",
},
],
};
},
);
logger.info("Library resources registered");
}