import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { sendCommandToFigma } from "../communication";
import { logger } from "../logger";
/**
* Register component-related MCP tools
*/
export function registerComponentTools(server: McpServer): void {
// Get Local Components
server.tool(
"get_local_components",
"Get all local components from the Figma document",
{},
async () => {
try {
const result = await sendCommandToFigma("get_local_components", {});
return {
content: [
{
type: "text",
text: JSON.stringify(result),
},
],
};
} catch (error) {
logger.error("Error getting local components", error);
return {
content: [
{
type: "text",
text: `Error getting local components: ${
error instanceof Error ? error.message : String(error)
}`,
},
],
};
}
},
);
// Get Styles
server.tool(
"get_styles",
"Get all styles from the current Figma document",
{},
async () => {
try {
const result = await sendCommandToFigma("get_styles", {});
return {
content: [
{
type: "text",
text: JSON.stringify(result),
},
],
};
} catch (error) {
logger.error("Error getting styles", error);
return {
content: [
{
type: "text",
text: `Error getting styles: ${
error instanceof Error ? error.message : String(error)
}`,
},
],
};
}
},
);
// Create Component Instance
server.tool(
"create_component_instance",
"Create an instance of a component in Figma",
{
componentKey: z
.string()
.describe("The key of the component to instantiate"),
x: z.number().describe("X position for the instance"),
y: z.number().describe("Y position for the instance"),
},
async ({ componentKey, x, y }) => {
try {
const result = await sendCommandToFigma<{ name: string; id: string }>(
"create_component_instance",
{ componentKey, x, y },
);
return {
content: [
{
type: "text",
text: `Created component instance "${result.name}" with ID: ${result.id}`,
},
],
};
} catch (error) {
logger.error("Error creating component instance", error);
return {
content: [
{
type: "text",
text: `Error creating component instance: ${
error instanceof Error ? error.message : String(error)
}`,
},
],
};
}
},
);
// Get Instance Overrides
server.tool(
"get_instance_overrides",
"Get overrides applied to a component instance",
{
instanceNodeId: z
.string()
.optional()
.nullable()
.describe(
"The ID of the instance node (uses selection if not provided)",
),
},
async ({ instanceNodeId }) => {
try {
const result = await sendCommandToFigma("get_instance_overrides", {
instanceNodeId,
});
return {
content: [
{
type: "text",
text: JSON.stringify(result),
},
],
};
} catch (error) {
logger.error("Error getting instance overrides", error);
return {
content: [
{
type: "text",
text: `Error getting instance overrides: ${
error instanceof Error ? error.message : String(error)
}`,
},
],
};
}
},
);
// Set Instance Overrides
server.tool(
"set_instance_overrides",
"Apply overrides from one instance to other instances of the same component",
{
sourceInstanceId: z
.string()
.describe("The ID of the source instance to copy overrides from"),
targetNodeIds: z
.array(z.string())
.describe("Array of target node IDs to apply overrides to"),
},
async ({ sourceInstanceId, targetNodeIds }) => {
try {
const result = await sendCommandToFigma<{
success: boolean;
message: string;
totalCount?: number;
}>("set_instance_overrides", { sourceInstanceId, targetNodeIds });
return {
content: [
{
type: "text",
text: result.message,
},
],
};
} catch (error) {
logger.error("Error setting instance overrides", error);
return {
content: [
{
type: "text",
text: `Error setting instance overrides: ${
error instanceof Error ? error.message : String(error)
}`,
},
],
};
}
},
);
}