import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { sendCommandToFigma } from "../utils/websocket";
/**
* Register component-related tools to the MCP server
* This module contains tools for working with components in Figma
* @param server - The MCP server instance
*/
export function registerComponentTools(server: McpServer): void {
// Create Component Instance Tool
server.tool(
"create_component_instance",
"Create an instance of a component in Figma",
{
componentKey: z.string().describe("Key of the component to instantiate"),
x: z.number().describe("X position"),
y: z.number().describe("Y position"),
},
async ({ componentKey, x, y }) => {
try {
const result = await sendCommandToFigma("create_component_instance", {
componentKey,
x,
y,
});
const typedResult = result as any;
return {
content: [
{
type: "text",
text: JSON.stringify(typedResult),
}
]
}
} catch (error) {
return {
content: [
{
type: "text",
text: `Error creating component instance: ${error instanceof Error ? error.message : String(error)}`,
},
],
};
}
}
);
// Create Component from Node Tool
server.tool(
"create_component_from_node",
"Convert an existing node (frame, group, etc.) into a reusable component in Figma",
{
nodeId: z.string().describe("The ID of the node to convert into a component"),
name: z.string().optional().describe("Optional new name for the component"),
},
async ({ nodeId, name }) => {
try {
const result = await sendCommandToFigma("create_component_from_node", {
nodeId,
name,
});
const typedResult = result as { id: string; name: string; key: string };
return {
content: [
{
type: "text",
text: `Created component "${typedResult.name}" with ID: ${typedResult.id} and key: ${typedResult.key}. You can now create instances of this component using the key.`,
}
]
}
} catch (error) {
return {
content: [
{
type: "text",
text: `Error creating component from node: ${error instanceof Error ? error.message : String(error)}`,
},
],
};
}
}
);
// Create Component Set from Components Tool
server.tool(
"create_component_set",
"Create a component set (variants) from multiple component nodes in Figma",
{
componentIds: z.array(z.string()).describe("Array of component node IDs to combine into a component set"),
name: z.string().optional().describe("Optional name for the component set"),
},
async ({ componentIds, name }) => {
try {
const result = await sendCommandToFigma("create_component_set", {
componentIds,
name,
});
const typedResult = result as { id: string; name: string; key: string; variantCount: number };
return {
content: [
{
type: "text",
text: `Created component set "${typedResult.name}" with ID: ${typedResult.id}, key: ${typedResult.key}, containing ${typedResult.variantCount} variants.`,
}
]
}
} catch (error) {
return {
content: [
{
type: "text",
text: `Error creating component set: ${error instanceof Error ? error.message : String(error)}`,
},
],
};
}
}
);
}