/**
* Component Extraction Tools
* MCP tools for extracting and analyzing Figma components
*/
export function registerComponentExtractionTools(protocol, figmaClient) {
// List components
protocol.registerTool("list_components", {
description: "List all components available in a Figma file",
inputSchema: {
type: "object",
properties: {
fileKey: {
type: "string",
description: "Figma file key",
},
},
required: ["fileKey"],
},
handler: async (args) => {
const { fileKey } = args;
const fileData = await figmaClient.getFile(fileKey);
const components = fileData.components || {};
const componentSets = fileData.componentSets || {};
return {
fileKey,
components: Object.values(components).map((comp) => ({
key: comp.key,
name: comp.name,
description: comp.description || "",
componentSetId: comp.componentSetId,
})),
componentSets: Object.values(componentSets).map((set) => ({
key: set.key,
name: set.name,
description: set.description || "",
})),
};
},
});
// Get component details
protocol.registerTool("get_component_details", {
description:
"Get detailed information about a specific component including properties and variants",
inputSchema: {
type: "object",
properties: {
fileKey: {
type: "string",
description: "Figma file key",
},
componentKey: {
type: "string",
description: "Component key (ID)",
},
},
required: ["fileKey", "componentKey"],
},
handler: async (args) => {
const { fileKey, componentKey } = args;
const fileData = await figmaClient.getFile(fileKey);
const components = fileData.components || {};
const component = components[componentKey];
if (!component) {
throw new Error(`Component ${componentKey} not found in file`);
}
// Find the node in the document tree
const findNode = (node, targetId) => {
if (node.id === targetId) {
return node;
}
if (node.children) {
for (const child of node.children) {
const found = findNode(child, targetId);
if (found) return found;
}
}
return null;
};
const componentNode = findNode(fileData.document, componentKey);
return {
fileKey,
component: {
key: component.key,
name: component.name,
description: component.description || "",
componentSetId: component.componentSetId,
documentationLinks: component.documentationLinks || [],
node: componentNode
? {
id: componentNode.id,
name: componentNode.name,
type: componentNode.type,
visible: componentNode.visible,
locked: componentNode.locked,
}
: null,
},
};
},
});
// Find component usage
protocol.registerTool("find_component_usage", {
description: "Find all instances where a component is used in a Figma file",
inputSchema: {
type: "object",
properties: {
fileKey: {
type: "string",
description: "Figma file key",
},
componentKey: {
type: "string",
description: "Component key to search for",
},
},
required: ["fileKey", "componentKey"],
},
handler: async (args) => {
const { fileKey, componentKey } = args;
const fileData = await figmaClient.getFile(fileKey);
const findInstances = (node, instances = []) => {
if (node.type === "INSTANCE" && node.componentId === componentKey) {
instances.push({
id: node.id,
name: node.name,
page: node.parent?.name || "Unknown",
});
}
if (node.children) {
node.children.forEach((child) => findInstances(child, instances));
}
return instances;
};
const instances = findInstances(fileData.document);
return {
fileKey,
componentKey,
instances,
count: instances.length,
};
},
});
}