get_node_info
Retrieve detailed information about a specific Figma design node, including its properties and child elements. Specify a node ID and optional depth to control how many levels of nested children return full details.
Instructions
Get detailed information about a specific node in Figma
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the node to get information about | |
| depth | No | How many child levels to include in full detail. Deeper levels return only id/name/type stubs. |
Implementation Reference
- The handler function for the 'get_node_info' tool. Registers the tool on the MCP server, accepts nodeId (string) and optional depth (number) parameters, calls sendCommandToFigma with the command, filters the result via filterFigmaNode, and returns JSON-stringified node info.
// Node Info Tool server.tool( "get_node_info", "Get detailed information about a specific node in Figma", { nodeId: z.string().describe("The ID of the node to get information about"), depth: z.number().int().min(0).optional().describe("How many child levels to include in full detail. Deeper levels return only id/name/type stubs."), }, async ({ nodeId, depth }) => { try { const result = await sendCommandToFigma("get_node_info", { nodeId }); const filtered = filterFigmaNode(result, depth ?? 1); const coordinateNote = filtered.absoluteBoundingBox && filtered.localPosition ? "absoluteBoundingBox contains global coordinates (relative to canvas). localPosition contains local coordinates (relative to parent, use these for move_node)." : undefined; const payload = coordinateNote ? { ...filtered, _note: coordinateNote } : filtered; return { content: [ { type: "text", text: JSON.stringify(payload) } ] }; } catch (error) { return { content: [ { type: "text", text: `Error getting node info: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } ); - The FigmaCommand type definition that includes 'get_node_info' as a valid command string for type-safe commands to Figma.
export type FigmaCommand = | "get_document_info" | "get_selection" | "get_node_info" | "create_rectangle" | "create_frame" | "create_text" | "create_ellipse" | "create_polygon" | "create_star" | "create_vector" | "create_line" | "set_fill_color" | "set_stroke_color" | "move_node" | "resize_node" | "delete_node" | "get_styles" | "get_local_components" | "get_team_components" | "create_component_instance" | "export_node_as_image" | "join" | "ping" | "set_corner_radius" | "clone_node" | "set_text_content" | "scan_text_nodes" | "set_multiple_text_contents" | "set_auto_layout" | "set_font_name" | "set_font_size" | "set_font_weight" | "set_letter_spacing" | "set_line_height" | "set_paragraph_spacing" | "set_text_case" | "set_text_decoration" | "get_styled_text_segments" | "load_font_async" | "get_remote_components" | "set_effects" | "set_effect_style_id" | "set_text_style_id" | "group_nodes" | "ungroup_nodes" | "flatten_node" | "insert_child" | "create_component_from_node" | "create_component_set" | "set_instance_variant" | "create_page" | "delete_page" | "rename_page" | "get_pages" | "set_current_page" | "rename_node" | "set_selection_colors" | "set_image_fill" | "get_image_from_node" | "replace_image_fill" // | "get_image_bytes" // COMMENTED OUT: Issues pending investigation | "apply_image_transform" | "set_image_filters" | "rotate_node" | "set_node_properties" | "reorder_node" | "duplicate_page" | "convert_to_frame" | "set_gradient" | "boolean_operation" | "set_svg" | "get_svg" | "set_image" | "set_grid" | "get_grid" | "set_guide" | "get_guide" | "set_annotation" | "get_annotation" | "get_variables" | "set_variable" | "apply_variable_to_node" | "switch_variable_mode" | "get_figjam_elements" | "create_sticky" | "set_sticky_text" | "create_shape_with_text" | "create_connector" | "create_section"; - src/talk_to_figma_mcp/tools/index.ts:17-19 (registration)The registration entry point: registerTools() calls registerDocumentTools(server) which registers all document tools including get_node_info.
export function registerTools(server: McpServer): void { // Register all tool categories registerDocumentTools(server); - The filterFigmaNode helper function used by the handler to recursively filter/reduce the Figma node response, converting colors to hex and limiting child depth based on the maxDepth parameter.
export function filterFigmaNode(node: any, maxDepth: number = Infinity, currentDepth: number = 0) { // Skip VECTOR type nodes if (node.type === "VECTOR") { return null; } const filtered: any = { id: node.id, name: node.name, type: node.type, }; if (node.fills && node.fills.length > 0) { filtered.fills = node.fills.map((fill: any) => { const processedFill = { ...fill }; // Remove boundVariables and imageRef delete processedFill.boundVariables; delete processedFill.imageRef; // Process gradientStops if present if (processedFill.gradientStops) { processedFill.gradientStops = processedFill.gradientStops.map((stop: any) => { const processedStop = { ...stop }; // Convert color to hex if present if (processedStop.color) { processedStop.color = rgbaToHex(processedStop.color); } // Remove boundVariables delete processedStop.boundVariables; return processedStop; }); } // Convert solid fill colors to hex if (processedFill.color) { processedFill.color = rgbaToHex(processedFill.color); } return processedFill; }); } if (node.strokes && node.strokes.length > 0) { filtered.strokes = node.strokes.map((stroke: any) => { const processedStroke = { ...stroke }; // Remove boundVariables delete processedStroke.boundVariables; // Convert color to hex if present if (processedStroke.color) { processedStroke.color = rgbaToHex(processedStroke.color); } return processedStroke; }); } if (node.cornerRadius !== undefined) { filtered.cornerRadius = node.cornerRadius; } if (node.absoluteBoundingBox) { filtered.absoluteBoundingBox = node.absoluteBoundingBox; } if (node.localPosition) { filtered.localPosition = node.localPosition; } if (node.characters) { filtered.characters = node.characters; } if (node.style) { filtered.style = { fontFamily: node.style.fontFamily, fontStyle: node.style.fontStyle, fontWeight: node.style.fontWeight, fontSize: node.style.fontSize, textAlignHorizontal: node.style.textAlignHorizontal, letterSpacing: node.style.letterSpacing, lineHeightPx: node.style.lineHeightPx }; } if (node.children) { if (currentDepth >= maxDepth) { // Beyond depth: return only minimal child stubs so the model can request deeper info on demand filtered.children = node.children .filter((child: any) => child.type !== "VECTOR") .map((child: any) => ({ id: child.id, name: child.name, type: child.type })); if (filtered.children.length > 0) { filtered._childrenTruncated = true; } } else { filtered.children = node.children .map((child: any) => filterFigmaNode(child, maxDepth, currentDepth + 1)) .filter((child: any) => child !== null); // Remove null children (VECTOR nodes) } } return filtered; } - src/talk_to_figma_mcp/tools/document-tools.ts:11-11 (registration)The registerDocumentTools function that registers all document-related tools including get_node_info on the MCP server.
export function registerDocumentTools(server: McpServer): void {