set_annotation
Add or edit annotations on Figma design elements to document specifications, feedback, or instructions within Cursor AI workflows.
Instructions
Create or update an annotation
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the node to annotate | |
| annotationId | No | The ID of the annotation to update (if updating existing annotation) | |
| labelMarkdown | Yes | The annotation text in markdown format | |
| categoryId | No | The ID of the annotation category | |
| properties | No | Additional properties for the annotation |
Implementation Reference
- src/cursor_mcp_plugin/code.js:2206-2302 (handler)Core handler function that implements set_annotation tool logic in Figma plugin: validates params, retrieves node, constructs Figma annotation object, sets node.annotations array overwriting existing, returns success with updated info.async function setAnnotation(params) { try { console.log("=== setAnnotation Debug Start ==="); console.log("Input params:", JSON.stringify(params, null, 2)); const { nodeId, annotationId, labelMarkdown, categoryId, properties } = params; // Validate required parameters if (!nodeId) { console.error("Validation failed: Missing nodeId"); return { success: false, error: "Missing nodeId" }; } if (!labelMarkdown) { console.error("Validation failed: Missing labelMarkdown"); return { success: false, error: "Missing labelMarkdown" }; } console.log("Attempting to get node:", nodeId); // Get and validate node const node = await figma.getNodeByIdAsync(nodeId); console.log("Node lookup result:", { id: nodeId, found: !!node, type: node ? node.type : undefined, name: node ? node.name : undefined, hasAnnotations: node ? "annotations" in node : false, }); if (!node) { console.error("Node lookup failed:", nodeId); return { success: false, error: `Node not found: ${nodeId}` }; } // Validate node supports annotations if (!("annotations" in node)) { console.error("Node annotation support check failed:", { nodeType: node.type, nodeId: node.id, }); return { success: false, error: `Node type ${node.type} does not support annotations`, }; } // Create the annotation object const newAnnotation = { labelMarkdown, }; // Validate and add categoryId if provided if (categoryId) { console.log("Adding categoryId to annotation:", categoryId); newAnnotation.categoryId = categoryId; } // Validate and add properties if provided if (properties && Array.isArray(properties) && properties.length > 0) { console.log( "Adding properties to annotation:", JSON.stringify(properties, null, 2) ); newAnnotation.properties = properties; } // Log current annotations before update console.log("Current node annotations:", node.annotations); // Overwrite annotations console.log( "Setting new annotation:", JSON.stringify(newAnnotation, null, 2) ); node.annotations = [newAnnotation]; // Verify the update console.log("Updated node annotations:", node.annotations); console.log("=== setAnnotation Debug End ==="); return { success: true, nodeId: node.id, name: node.name, annotations: node.annotations, }; } catch (error) { console.error("=== setAnnotation Error ==="); console.error("Error details:", { message: error.message, stack: error.stack, params: JSON.stringify(params, null, 2), }); return { success: false, error: error.message }; } }
- src/talk_to_figma_mcp/server.ts:1007-1047 (registration)MCP server.tool registration for 'set_annotation': defines input schema with Zod validation, provides proxy handler that sends command to Figma plugin via websocket, handles response/error formatting.server.tool( "set_annotation", "Create or update an annotation", { nodeId: z.string().describe("The ID of the node to annotate"), annotationId: z.string().optional().describe("The ID of the annotation to update (if updating existing annotation)"), labelMarkdown: z.string().describe("The annotation text in markdown format"), categoryId: z.string().optional().describe("The ID of the annotation category"), properties: z.array(z.object({ type: z.string() })).optional().describe("Additional properties for the annotation") }, async ({ nodeId, annotationId, labelMarkdown, categoryId, properties }) => { try { const result = await sendCommandToFigma("set_annotation", { nodeId, annotationId, labelMarkdown, categoryId, properties }); return { content: [ { type: "text", text: JSON.stringify(result) } ] }; } catch (error) { return { content: [ { type: "text", text: `Error setting annotation: ${error instanceof Error ? error.message : String(error)}` } ] }; } } );
- Input schema for set_annotation tool using Zod: requires nodeId and labelMarkdown, optional annotationId, categoryId, and properties array.nodeId: z.string().describe("The ID of the node to annotate"), annotationId: z.string().optional().describe("The ID of the annotation to update (if updating existing annotation)"), labelMarkdown: z.string().describe("The annotation text in markdown format"), categoryId: z.string().optional().describe("The ID of the annotation category"), properties: z.array(z.object({ type: z.string() })).optional().describe("Additional properties for the annotation") },
- src/cursor_mcp_plugin/code.js:163-166 (registration)Dispatch registration in Figma plugin's handleCommand switch statement: routes 'set_annotation' command to setAnnotation handler function.case "set_annotation": return await setAnnotation(params); case "scan_nodes_by_types": return await scanNodesByTypes(params);