{"version":3,"sources":["../src/talk_to_figma_mcp/server.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport WebSocket from \"ws\";\nimport { v4 as uuidv4 } from \"uuid\";\n\n// Define TypeScript interfaces for Figma responses\ninterface FigmaResponse {\n  id: string;\n  result?: any;\n  error?: string;\n}\n\n// Define interface for command progress updates\ninterface CommandProgressUpdate {\n  type: 'command_progress';\n  commandId: string;\n  commandType: string;\n  status: 'started' | 'in_progress' | 'completed' | 'error';\n  progress: number;\n  totalItems: number;\n  processedItems: number;\n  currentChunk?: number;\n  totalChunks?: number;\n  chunkSize?: number;\n  message: string;\n  payload?: any;\n  timestamp: number;\n}\n\n// Update the getInstanceOverridesResult interface to match the plugin implementation\ninterface getInstanceOverridesResult {\n  success: boolean;\n  message: string;\n  sourceInstanceId: string;\n  mainComponentId: string;\n  overridesCount: number;\n}\n\ninterface setInstanceOverridesResult {\n  success: boolean;\n  message: string;\n  totalCount?: number;\n  results?: Array<{\n    success: boolean;\n    instanceId: string;\n    instanceName: string;\n    appliedCount?: number;\n    message?: string;\n  }>;\n}\n\n// Custom logging functions that write to stderr instead of stdout to avoid being captured\nconst logger = {\n  info: (message: string) => process.stderr.write(`[INFO] ${message}\\n`),\n  debug: (message: string) => process.stderr.write(`[DEBUG] ${message}\\n`),\n  warn: (message: string) => process.stderr.write(`[WARN] ${message}\\n`),\n  error: (message: string) => process.stderr.write(`[ERROR] ${message}\\n`),\n  log: (message: string) => process.stderr.write(`[LOG] ${message}\\n`)\n};\n\n// WebSocket connection and request tracking\nlet ws: WebSocket | null = null;\nconst pendingRequests = new Map<string, {\n  resolve: (value: unknown) => void;\n  reject: (reason: unknown) => void;\n  timeout: ReturnType<typeof setTimeout>;\n  lastActivity: number; // Add timestamp for last activity\n}>();\n\n// Track which channel each client is in\nlet currentChannel: string | null = null;\n\n// Create MCP server\nconst server = new McpServer({\n  name: \"TalkToFigmaMCP\",\n  version: \"1.0.0\",\n});\n\n// Add command line argument parsing\nconst args = process.argv.slice(2);\nconst serverArg = args.find(arg => arg.startsWith('--server='));\nconst serverUrl = serverArg ? serverArg.split('=')[1] : 'localhost';\nconst WS_URL = serverUrl === 'localhost' ? `ws://${serverUrl}` : `wss://${serverUrl}`;\n\n// Document Info Tool\nserver.tool(\n  \"get_document_info\",\n  \"Get detailed information about the current Figma document\",\n  {},\n  async () => {\n    try {\n      const result = await sendCommandToFigma(\"get_document_info\");\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(result)\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error getting document info: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Selection Tool\nserver.tool(\n  \"get_selection\",\n  \"Get information about the current selection in Figma\",\n  {},\n  async () => {\n    try {\n      const result = await sendCommandToFigma(\"get_selection\");\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(result)\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error getting selection: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Read My Design Tool\nserver.tool(\n  \"read_my_design\",\n  \"Get detailed information about the current selection in Figma, including all node details\",\n  {},\n  async () => {\n    try {\n      const result = await sendCommandToFigma(\"read_my_design\", {});\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(result)\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error getting node info: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Node Info Tool\nserver.tool(\n  \"get_node_info\",\n  \"Get detailed information about a specific node in Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the node to get information about\"),\n  },\n  async ({ nodeId }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"get_node_info\", { nodeId });\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(filterFigmaNode(result))\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error getting node info: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\nfunction rgbaToHex(color: any): string {\n  // skip if color is already hex\n  if (color.startsWith('#')) {\n    return color;\n  }\n\n  const r = Math.round(color.r * 255);\n  const g = Math.round(color.g * 255);\n  const b = Math.round(color.b * 255);\n  const a = Math.round(color.a * 255);\n\n  return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}${a === 255 ? '' : a.toString(16).padStart(2, '0')}`;\n}\n\nfunction filterFigmaNode(node: any) {\n  // Skip VECTOR type nodes\n  if (node.type === \"VECTOR\") {\n    return null;\n  }\n\n  const filtered: any = {\n    id: node.id,\n    name: node.name,\n    type: node.type,\n  };\n\n  if (node.fills && node.fills.length > 0) {\n    filtered.fills = node.fills.map((fill: any) => {\n      const processedFill = { ...fill };\n\n      // Remove boundVariables and imageRef\n      delete processedFill.boundVariables;\n      delete processedFill.imageRef;\n\n      // Process gradientStops if present\n      if (processedFill.gradientStops) {\n        processedFill.gradientStops = processedFill.gradientStops.map((stop: any) => {\n          const processedStop = { ...stop };\n          // Convert color to hex if present\n          if (processedStop.color) {\n            processedStop.color = rgbaToHex(processedStop.color);\n          }\n          // Remove boundVariables\n          delete processedStop.boundVariables;\n          return processedStop;\n        });\n      }\n\n      // Convert solid fill colors to hex\n      if (processedFill.color) {\n        processedFill.color = rgbaToHex(processedFill.color);\n      }\n\n      return processedFill;\n    });\n  }\n\n  if (node.strokes && node.strokes.length > 0) {\n    filtered.strokes = node.strokes.map((stroke: any) => {\n      const processedStroke = { ...stroke };\n      // Remove boundVariables\n      delete processedStroke.boundVariables;\n      // Convert color to hex if present\n      if (processedStroke.color) {\n        processedStroke.color = rgbaToHex(processedStroke.color);\n      }\n      return processedStroke;\n    });\n  }\n\n  if (node.cornerRadius !== undefined) {\n    filtered.cornerRadius = node.cornerRadius;\n  }\n\n  if (node.absoluteBoundingBox) {\n    filtered.absoluteBoundingBox = node.absoluteBoundingBox;\n  }\n\n  if (node.characters) {\n    filtered.characters = node.characters;\n  }\n\n  if (node.style) {\n    filtered.style = {\n      fontFamily: node.style.fontFamily,\n      fontStyle: node.style.fontStyle,\n      fontWeight: node.style.fontWeight,\n      fontSize: node.style.fontSize,\n      textAlignHorizontal: node.style.textAlignHorizontal,\n      letterSpacing: node.style.letterSpacing,\n      lineHeightPx: node.style.lineHeightPx\n    };\n  }\n\n  if (node.children) {\n    filtered.children = node.children\n      .map((child: any) => filterFigmaNode(child))\n      .filter((child: any) => child !== null); // Remove null children (VECTOR nodes)\n  }\n\n  return filtered;\n}\n\n// Nodes Info Tool\nserver.tool(\n  \"get_nodes_info\",\n  \"Get detailed information about multiple nodes in Figma\",\n  {\n    nodeIds: z.array(z.string()).describe(\"Array of node IDs to get information about\")\n  },\n  async ({ nodeIds }: any) => {\n    try {\n      const results = await Promise.all(\n        nodeIds.map(async (nodeId: any) => {\n          const result = await sendCommandToFigma('get_node_info', { nodeId });\n          return { nodeId, info: result };\n        })\n      );\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(results.map((result) => filterFigmaNode(result.info)))\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error getting nodes info: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n\n// Create Rectangle Tool\nserver.tool(\n  \"create_rectangle\",\n  \"Create a new rectangle in Figma\",\n  {\n    x: z.number().describe(\"X position\"),\n    y: z.number().describe(\"Y position\"),\n    width: z.number().describe(\"Width of the rectangle\"),\n    height: z.number().describe(\"Height of the rectangle\"),\n    name: z.string().optional().describe(\"Optional name for the rectangle\"),\n    parentId: z\n      .string()\n      .optional()\n      .describe(\"Optional parent node ID to append the rectangle to\"),\n  },\n  async ({ x, y, width, height, name, parentId }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"create_rectangle\", {\n        x,\n        y,\n        width,\n        height,\n        name: name || \"Rectangle\",\n        parentId,\n      });\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Created rectangle \"${JSON.stringify(result)}\"`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error creating rectangle: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Create Frame Tool\nserver.tool(\n  \"create_frame\",\n  \"Create a new frame in Figma\",\n  {\n    x: z.number().describe(\"X position\"),\n    y: z.number().describe(\"Y position\"),\n    width: z.number().describe(\"Width of the frame\"),\n    height: z.number().describe(\"Height of the frame\"),\n    name: z.string().optional().describe(\"Optional name for the frame\"),\n    parentId: z\n      .string()\n      .optional()\n      .describe(\"Optional parent node ID to append the frame to\"),\n    fillColor: z\n      .object({\n        r: z.number().min(0).max(1).describe(\"Red component (0-1)\"),\n        g: z.number().min(0).max(1).describe(\"Green component (0-1)\"),\n        b: z.number().min(0).max(1).describe(\"Blue component (0-1)\"),\n        a: z\n          .number()\n          .min(0)\n          .max(1)\n          .optional()\n          .describe(\"Alpha component (0-1)\"),\n      })\n      .optional()\n      .describe(\"Fill color in RGBA format\"),\n    strokeColor: z\n      .object({\n        r: z.number().min(0).max(1).describe(\"Red component (0-1)\"),\n        g: z.number().min(0).max(1).describe(\"Green component (0-1)\"),\n        b: z.number().min(0).max(1).describe(\"Blue component (0-1)\"),\n        a: z\n          .number()\n          .min(0)\n          .max(1)\n          .optional()\n          .describe(\"Alpha component (0-1)\"),\n      })\n      .optional()\n      .describe(\"Stroke color in RGBA format\"),\n    strokeWeight: z.number().positive().optional().describe(\"Stroke weight\"),\n    layoutMode: z.enum([\"NONE\", \"HORIZONTAL\", \"VERTICAL\"]).optional().describe(\"Auto-layout mode for the frame\"),\n    layoutWrap: z.enum([\"NO_WRAP\", \"WRAP\"]).optional().describe(\"Whether the auto-layout frame wraps its children\"),\n    paddingTop: z.number().optional().describe(\"Top padding for auto-layout frame\"),\n    paddingRight: z.number().optional().describe(\"Right padding for auto-layout frame\"),\n    paddingBottom: z.number().optional().describe(\"Bottom padding for auto-layout frame\"),\n    paddingLeft: z.number().optional().describe(\"Left padding for auto-layout frame\"),\n    primaryAxisAlignItems: z\n      .enum([\"MIN\", \"MAX\", \"CENTER\", \"SPACE_BETWEEN\"])\n      .optional()\n      .describe(\"Primary axis alignment for auto-layout frame. Note: When set to SPACE_BETWEEN, itemSpacing will be ignored as children will be evenly spaced.\"),\n    counterAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"BASELINE\"]).optional().describe(\"Counter axis alignment for auto-layout frame\"),\n    layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional().describe(\"Horizontal sizing mode for auto-layout frame\"),\n    layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional().describe(\"Vertical sizing mode for auto-layout frame\"),\n    itemSpacing: z\n      .number()\n      .optional()\n      .describe(\"Distance between children in auto-layout frame. Note: This value will be ignored if primaryAxisAlignItems is set to SPACE_BETWEEN.\")\n  },\n  async ({\n    x,\n    y,\n    width,\n    height,\n    name,\n    parentId,\n    fillColor,\n    strokeColor,\n    strokeWeight,\n    layoutMode,\n    layoutWrap,\n    paddingTop,\n    paddingRight,\n    paddingBottom,\n    paddingLeft,\n    primaryAxisAlignItems,\n    counterAxisAlignItems,\n    layoutSizingHorizontal,\n    layoutSizingVertical,\n    itemSpacing\n  }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"create_frame\", {\n        x,\n        y,\n        width,\n        height,\n        name: name || \"Frame\",\n        parentId,\n        fillColor: fillColor || { r: 1, g: 1, b: 1, a: 1 },\n        strokeColor: strokeColor,\n        strokeWeight: strokeWeight,\n        layoutMode,\n        layoutWrap,\n        paddingTop,\n        paddingRight,\n        paddingBottom,\n        paddingLeft,\n        primaryAxisAlignItems,\n        counterAxisAlignItems,\n        layoutSizingHorizontal,\n        layoutSizingVertical,\n        itemSpacing\n      });\n      const typedResult = result as { name: string; id: string };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Created frame \"${typedResult.name}\" with ID: ${typedResult.id}. Use the ID as the parentId to appendChild inside this frame.`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error creating frame: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Create Text Tool\nserver.tool(\n  \"create_text\",\n  \"Create a new text element in Figma\",\n  {\n    x: z.number().describe(\"X position\"),\n    y: z.number().describe(\"Y position\"),\n    text: z.string().describe(\"Text content\"),\n    fontSize: z.number().optional().describe(\"Font size (default: 14)\"),\n    fontWeight: z\n      .number()\n      .optional()\n      .describe(\"Font weight (e.g., 400 for Regular, 700 for Bold)\"),\n    fontColor: z\n      .object({\n        r: z.number().min(0).max(1).describe(\"Red component (0-1)\"),\n        g: z.number().min(0).max(1).describe(\"Green component (0-1)\"),\n        b: z.number().min(0).max(1).describe(\"Blue component (0-1)\"),\n        a: z\n          .number()\n          .min(0)\n          .max(1)\n          .optional()\n          .describe(\"Alpha component (0-1)\"),\n      })\n      .optional()\n      .describe(\"Font color in RGBA format\"),\n    name: z\n      .string()\n      .optional()\n      .describe(\"Semantic layer name for the text node\"),\n    parentId: z\n      .string()\n      .optional()\n      .describe(\"Optional parent node ID to append the text to\"),\n  },\n  async ({ x, y, text, fontSize, fontWeight, fontColor, name, parentId }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"create_text\", {\n        x,\n        y,\n        text,\n        fontSize: fontSize || 14,\n        fontWeight: fontWeight || 400,\n        fontColor: fontColor || { r: 0, g: 0, b: 0, a: 1 },\n        name: name || \"Text\",\n        parentId,\n      });\n      const typedResult = result as { name: string; id: string };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Created text \"${typedResult.name}\" with ID: ${typedResult.id}`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error creating text: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Set Fill Color Tool\nserver.tool(\n  \"set_fill_color\",\n  \"Set the fill color of a node in Figma can be TextNode or FrameNode\",\n  {\n    nodeId: z.string().describe(\"The ID of the node to modify\"),\n    r: z.number().min(0).max(1).describe(\"Red component (0-1)\"),\n    g: z.number().min(0).max(1).describe(\"Green component (0-1)\"),\n    b: z.number().min(0).max(1).describe(\"Blue component (0-1)\"),\n    a: z.number().min(0).max(1).optional().describe(\"Alpha component (0-1)\"),\n  },\n  async ({ nodeId, r, g, b, a }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_fill_color\", {\n        nodeId,\n        color: { r, g, b, a: a || 1 },\n      });\n      const typedResult = result as { name: string };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Set fill color of node \"${typedResult.name\n              }\" to RGBA(${r}, ${g}, ${b}, ${a || 1})`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting fill color: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Set Stroke Color Tool\nserver.tool(\n  \"set_stroke_color\",\n  \"Set the stroke color of a node in Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the node to modify\"),\n    r: z.number().min(0).max(1).describe(\"Red component (0-1)\"),\n    g: z.number().min(0).max(1).describe(\"Green component (0-1)\"),\n    b: z.number().min(0).max(1).describe(\"Blue component (0-1)\"),\n    a: z.number().min(0).max(1).optional().describe(\"Alpha component (0-1)\"),\n    weight: z.number().positive().optional().describe(\"Stroke weight\"),\n  },\n  async ({ nodeId, r, g, b, a, weight }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_stroke_color\", {\n        nodeId,\n        color: { r, g, b, a: a || 1 },\n        weight: weight || 1,\n      });\n      const typedResult = result as { name: string };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Set stroke color of node \"${typedResult.name\n              }\" to RGBA(${r}, ${g}, ${b}, ${a || 1}) with weight ${weight || 1}`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting stroke color: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Move Node Tool\nserver.tool(\n  \"move_node\",\n  \"Move a node to a new position in Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the node to move\"),\n    x: z.number().describe(\"New X position\"),\n    y: z.number().describe(\"New Y position\"),\n  },\n  async ({ nodeId, x, y }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"move_node\", { nodeId, x, y });\n      const typedResult = result as { name: string };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Moved node \"${typedResult.name}\" to position (${x}, ${y})`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error moving node: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Clone Node Tool\nserver.tool(\n  \"clone_node\",\n  \"Clone an existing node in Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the node to clone\"),\n    x: z.number().optional().describe(\"New X position for the clone\"),\n    y: z.number().optional().describe(\"New Y position for the clone\")\n  },\n  async ({ nodeId, x, y }: any) => {\n    try {\n      const result = await sendCommandToFigma('clone_node', { nodeId, x, y });\n      const typedResult = result as { name: string, id: string };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Cloned node \"${typedResult.name}\" with new ID: ${typedResult.id}${x !== undefined && y !== undefined ? ` at position (${x}, ${y})` : ''}`\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error cloning node: ${error instanceof Error ? error.message : String(error)}`\n          }\n        ]\n      };\n    }\n  }\n);\n\n// Resize Node Tool\nserver.tool(\n  \"resize_node\",\n  \"Resize a node in Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the node to resize\"),\n    width: z.number().positive().describe(\"New width\"),\n    height: z.number().positive().describe(\"New height\"),\n  },\n  async ({ nodeId, width, height }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"resize_node\", {\n        nodeId,\n        width,\n        height,\n      });\n      const typedResult = result as { name: string };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Resized node \"${typedResult.name}\" to width ${width} and height ${height}`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error resizing node: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Delete Node Tool\nserver.tool(\n  \"delete_node\",\n  \"Delete a node from Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the node to delete\"),\n  },\n  async ({ nodeId }: any) => {\n    try {\n      await sendCommandToFigma(\"delete_node\", { nodeId });\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Deleted node with ID: ${nodeId}`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error deleting node: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Delete Multiple Nodes Tool\nserver.tool(\n  \"delete_multiple_nodes\",\n  \"Delete multiple nodes from Figma at once\",\n  {\n    nodeIds: z.array(z.string()).describe(\"Array of node IDs to delete\"),\n  },\n  async ({ nodeIds }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"delete_multiple_nodes\", { nodeIds });\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(result)\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error deleting multiple nodes: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Export Node as Image Tool\nserver.tool(\n  \"export_node_as_image\",\n  \"Export a node as an image from Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the node to export\"),\n    format: z\n      .enum([\"PNG\", \"JPG\", \"SVG\", \"PDF\"])\n      .optional()\n      .describe(\"Export format\"),\n    scale: z.number().positive().optional().describe(\"Export scale\"),\n  },\n  async ({ nodeId, format, scale }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"export_node_as_image\", {\n        nodeId,\n        format: format || \"PNG\",\n        scale: scale || 1,\n      });\n      const typedResult = result as { imageData: string; mimeType: string };\n\n      return {\n        content: [\n          {\n            type: \"image\",\n            data: typedResult.imageData,\n            mimeType: typedResult.mimeType || \"image/png\",\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error exporting node as image: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Set Text Content Tool\nserver.tool(\n  \"set_text_content\",\n  \"Set the text content of an existing text node in Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the text node to modify\"),\n    text: z.string().describe(\"New text content\"),\n  },\n  async ({ nodeId, text }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_text_content\", {\n        nodeId,\n        text,\n      });\n      const typedResult = result as { name: string };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Updated text content of node \"${typedResult.name}\" to \"${text}\"`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting text content: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Get Styles Tool\nserver.tool(\n  \"get_styles\",\n  \"Get all styles from the current Figma document\",\n  {},\n  async () => {\n    try {\n      const result = await sendCommandToFigma(\"get_styles\");\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(result)\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error getting styles: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Get Local Components Tool\nserver.tool(\n  \"get_local_components\",\n  \"Get all local components from the Figma document\",\n  {},\n  async () => {\n    try {\n      const result = await sendCommandToFigma(\"get_local_components\");\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(result)\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error getting local components: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Get Annotations Tool\nserver.tool(\n  \"get_annotations\",\n  \"Get all annotations in the current document or specific node\",\n  {\n    nodeId: z.string().describe(\"node ID to get annotations for specific node\"),\n    includeCategories: z.boolean().optional().default(true).describe(\"Whether to include category information\")\n  },\n  async ({ nodeId, includeCategories }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"get_annotations\", {\n        nodeId,\n        includeCategories\n      });\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(result)\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error getting annotations: ${error instanceof Error ? error.message : String(error)}`\n          }\n        ]\n      };\n    }\n  }\n);\n\n// Set Annotation Tool\nserver.tool(\n  \"set_annotation\",\n  \"Create or update an annotation\",\n  {\n    nodeId: z.string().describe(\"The ID of the node to annotate\"),\n    annotationId: z.string().optional().describe(\"The ID of the annotation to update (if updating existing annotation)\"),\n    labelMarkdown: z.string().describe(\"The annotation text in markdown format\"),\n    categoryId: z.string().optional().describe(\"The ID of the annotation category\"),\n    properties: z.array(z.object({\n      type: z.string()\n    })).optional().describe(\"Additional properties for the annotation\")\n  },\n  async ({ nodeId, annotationId, labelMarkdown, categoryId, properties }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_annotation\", {\n        nodeId,\n        annotationId,\n        labelMarkdown,\n        categoryId,\n        properties\n      });\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(result)\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting annotation: ${error instanceof Error ? error.message : String(error)}`\n          }\n        ]\n      };\n    }\n  }\n);\n\ninterface SetMultipleAnnotationsParams {\n  nodeId: string;\n  annotations: Array<{\n    nodeId: string;\n    labelMarkdown: string;\n    categoryId?: string;\n    annotationId?: string;\n    properties?: Array<{ type: string }>;\n  }>;\n}\n\n// Set Multiple Annotations Tool\nserver.tool(\n  \"set_multiple_annotations\",\n  \"Set multiple annotations parallelly in a node\",\n  {\n    nodeId: z\n      .string()\n      .describe(\"The ID of the node containing the elements to annotate\"),\n    annotations: z\n      .array(\n        z.object({\n          nodeId: z.string().describe(\"The ID of the node to annotate\"),\n          labelMarkdown: z.string().describe(\"The annotation text in markdown format\"),\n          categoryId: z.string().optional().describe(\"The ID of the annotation category\"),\n          annotationId: z.string().optional().describe(\"The ID of the annotation to update (if updating existing annotation)\"),\n          properties: z.array(z.object({\n            type: z.string()\n          })).optional().describe(\"Additional properties for the annotation\")\n        })\n      )\n      .describe(\"Array of annotations to apply\"),\n  },\n  async ({ nodeId, annotations }: any) => {\n    try {\n      if (!annotations || annotations.length === 0) {\n        return {\n          content: [\n            {\n              type: \"text\",\n              text: \"No annotations provided\",\n            },\n          ],\n        };\n      }\n\n      // Initial response to indicate we're starting the process\n      const initialStatus = {\n        type: \"text\" as const,\n        text: `Starting annotation process for ${annotations.length} nodes. This will be processed in batches of 5...`,\n      };\n\n      // Track overall progress\n      let totalProcessed = 0;\n      const totalToProcess = annotations.length;\n\n      // Use the plugin's set_multiple_annotations function with chunking\n      const result = await sendCommandToFigma(\"set_multiple_annotations\", {\n        nodeId,\n        annotations,\n      });\n\n      // Cast the result to a specific type to work with it safely\n      interface AnnotationResult {\n        success: boolean;\n        nodeId: string;\n        annotationsApplied?: number;\n        annotationsFailed?: number;\n        totalAnnotations?: number;\n        completedInChunks?: number;\n        results?: Array<{\n          success: boolean;\n          nodeId: string;\n          error?: string;\n          annotationId?: string;\n        }>;\n      }\n\n      const typedResult = result as AnnotationResult;\n\n      // Format the results for display\n      const success = typedResult.annotationsApplied && typedResult.annotationsApplied > 0;\n      const progressText = `\n      Annotation process completed:\n      - ${typedResult.annotationsApplied || 0} of ${totalToProcess} successfully applied\n      - ${typedResult.annotationsFailed || 0} failed\n      - Processed in ${typedResult.completedInChunks || 1} batches\n      `;\n\n      // Detailed results\n      const detailedResults = typedResult.results || [];\n      const failedResults = detailedResults.filter(item => !item.success);\n\n      // Create the detailed part of the response\n      let detailedResponse = \"\";\n      if (failedResults.length > 0) {\n        detailedResponse = `\\n\\nNodes that failed:\\n${failedResults.map(item =>\n          `- ${item.nodeId}: ${item.error || \"Unknown error\"}`\n        ).join('\\n')}`;\n      }\n\n      return {\n        content: [\n          initialStatus,\n          {\n            type: \"text\" as const,\n            text: progressText + detailedResponse,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting multiple annotations: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Create Component Instance Tool\nserver.tool(\n  \"create_component_instance\",\n  \"Create an instance of a component in Figma. For LOCAL components (from get_local_components), use componentId with the id field. For published LIBRARY components, use componentKey with the publishedKey field.\",\n  {\n    componentId: z.string().optional().describe(\"ID of a local component (use the id field from get_local_components result). Use this for unpublished/local components.\"),\n    componentKey: z.string().optional().describe(\"Key of a published library component to instantiate (use the publishedKey field from get_local_components result). Only works for published components.\"),\n    x: z.number().describe(\"X position\"),\n    y: z.number().describe(\"Y position\"),\n    parentId: z.string().optional().describe(\"Optional parent node ID to place the instance into\"),\n  },\n  async ({ componentId, componentKey, x, y, parentId }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"create_component_instance\", {\n        componentId,\n        componentKey,\n        x,\n        y,\n        parentId,\n      });\n      const typedResult = result as any;\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(typedResult),\n          }\n        ]\n      }\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error creating component instance: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Copy Instance Overrides Tool\nserver.tool(\n  \"get_instance_overrides\",\n  \"Get all override properties from a selected component instance. These overrides can be applied to other instances, which will swap them to match the source component.\",\n  {\n    nodeId: z.string().optional().describe(\"Optional ID of the component instance to get overrides from. If not provided, currently selected instance will be used.\"),\n  },\n  async ({ nodeId }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"get_instance_overrides\", {\n        instanceNodeId: nodeId || null\n      });\n      const typedResult = result as getInstanceOverridesResult;\n\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: typedResult.success\n              ? `Successfully got instance overrides: ${typedResult.message}`\n              : `Failed to get instance overrides: ${typedResult.message}`\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error copying instance overrides: ${error instanceof Error ? error.message : String(error)}`\n          }\n        ]\n      };\n    }\n  }\n);\n\n// Set Instance Overrides Tool\nserver.tool(\n  \"set_instance_overrides\",\n  \"Apply previously copied overrides to selected component instances. Target instances will be swapped to the source component and all copied override properties will be applied.\",\n  {\n    sourceInstanceId: z.string().describe(\"ID of the source component instance\"),\n    targetNodeIds: z.array(z.string()).describe(\"Array of target instance IDs. Currently selected instances will be used.\")\n  },\n  async ({ sourceInstanceId, targetNodeIds }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_instance_overrides\", {\n        sourceInstanceId: sourceInstanceId,\n        targetNodeIds: targetNodeIds || []\n      });\n      const typedResult = result as setInstanceOverridesResult;\n\n      if (typedResult.success) {\n        const successCount = typedResult.results?.filter(r => r.success).length || 0;\n        return {\n          content: [\n            {\n              type: \"text\",\n              text: `Successfully applied ${typedResult.totalCount || 0} overrides to ${successCount} instances.`\n            }\n          ]\n        };\n      } else {\n        return {\n          content: [\n            {\n              type: \"text\",\n              text: `Failed to set instance overrides: ${typedResult.message}`\n            }\n          ]\n        };\n      }\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting instance overrides: ${error instanceof Error ? error.message : String(error)}`\n          }\n        ]\n      };\n    }\n  }\n);\n\n\n// Set Corner Radius Tool\nserver.tool(\n  \"set_corner_radius\",\n  \"Set the corner radius of a node in Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the node to modify\"),\n    radius: z.number().min(0).describe(\"Corner radius value\"),\n    corners: z\n      .array(z.boolean())\n      .length(4)\n      .optional()\n      .describe(\n        \"Optional array of 4 booleans to specify which corners to round [topLeft, topRight, bottomRight, bottomLeft]\"\n      ),\n  },\n  async ({ nodeId, radius, corners }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_corner_radius\", {\n        nodeId,\n        radius,\n        corners: corners || [true, true, true, true],\n      });\n      const typedResult = result as { name: string };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Set corner radius of node \"${typedResult.name}\" to ${radius}px`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting corner radius: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Define design strategy prompt\nserver.prompt(\n  \"design_strategy\",\n  \"Best practices for working with Figma designs\",\n  (extra) => {\n    return {\n      messages: [\n        {\n          role: \"assistant\",\n          content: {\n            type: \"text\",\n            text: `When working with Figma designs, follow these best practices:\n\n1. Start with Document Structure:\n   - First use get_document_info() to understand the current document\n   - Plan your layout hierarchy before creating elements\n   - Create a main container frame for each screen/section\n\n2. Naming Conventions:\n   - Use descriptive, semantic names for all elements\n   - Follow a consistent naming pattern (e.g., \"Login Screen\", \"Logo Container\", \"Email Input\")\n   - Group related elements with meaningful names\n\n3. Layout Hierarchy:\n   - Create parent frames first, then add child elements\n   - For forms/login screens:\n     * Start with the main screen container frame\n     * Create a logo container at the top\n     * Group input fields in their own containers\n     * Place action buttons (login, submit) after inputs\n     * Add secondary elements (forgot password, signup links) last\n\n4. Input Fields Structure:\n   - Create a container frame for each input field\n   - Include a label text above or inside the input\n   - Group related inputs (e.g., username/password) together\n\n5. Element Creation:\n   - Use create_frame() for containers and input fields\n   - Use create_text() for labels, buttons text, and links\n   - Set appropriate colors and styles:\n     * Use fillColor for backgrounds\n     * Use strokeColor for borders\n     * Set proper fontWeight for different text elements\n\n6. Mofifying existing elements:\n  - use set_text_content() to modify text content.\n\n7. Visual Hierarchy:\n   - Position elements in logical reading order (top to bottom)\n   - Maintain consistent spacing between elements\n   - Use appropriate font sizes for different text types:\n     * Larger for headings/welcome text\n     * Medium for input labels\n     * Standard for button text\n     * Smaller for helper text/links\n\n8. Best Practices:\n   - Verify each creation with get_node_info()\n   - Use parentId to maintain proper hierarchy\n   - Group related elements together in frames\n   - Keep consistent spacing and alignment\n\nExample Login Screen Structure:\n- Login Screen (main frame)\n  - Logo Container (frame)\n    - Logo (image/text)\n  - Welcome Text (text)\n  - Input Container (frame)\n    - Email Input (frame)\n      - Email Label (text)\n      - Email Field (frame)\n    - Password Input (frame)\n      - Password Label (text)\n      - Password Field (frame)\n  - Login Button (frame)\n    - Button Text (text)\n  - Helper Links (frame)\n    - Forgot Password (text)\n    - Don't have account (text)`,\n          },\n        },\n      ],\n      description: \"Best practices for working with Figma designs\",\n    };\n  }\n);\n\nserver.prompt(\n  \"read_design_strategy\",\n  \"Best practices for reading Figma designs\",\n  (extra) => {\n    return {\n      messages: [\n        {\n          role: \"assistant\",\n          content: {\n            type: \"text\",\n            text: `When reading Figma designs, follow these best practices:\n\n1. Start with selection:\n   - First use read_my_design() to understand the current selection\n   - If no selection ask user to select single or multiple nodes\n`,\n          },\n        },\n      ],\n      description: \"Best practices for reading Figma designs\",\n    };\n  }\n);\n\n// Text Node Scanning Tool\nserver.tool(\n  \"scan_text_nodes\",\n  \"Scan all text nodes in the selected Figma node\",\n  {\n    nodeId: z.string().describe(\"ID of the node to scan\"),\n  },\n  async ({ nodeId }: any) => {\n    try {\n      // Initial response to indicate we're starting the process\n      const initialStatus = {\n        type: \"text\" as const,\n        text: \"Starting text node scanning. This may take a moment for large designs...\",\n      };\n\n      // Use the plugin's scan_text_nodes function with chunking flag\n      const result = await sendCommandToFigma(\"scan_text_nodes\", {\n        nodeId,\n        useChunking: true,  // Enable chunking on the plugin side\n        chunkSize: 10       // Process 10 nodes at a time\n      });\n\n      // If the result indicates chunking was used, format the response accordingly\n      if (result && typeof result === 'object' && 'chunks' in result) {\n        const typedResult = result as {\n          success: boolean,\n          totalNodes: number,\n          processedNodes: number,\n          chunks: number,\n          textNodes: Array<any>\n        };\n\n        const summaryText = `\n        Scan completed:\n        - Found ${typedResult.totalNodes} text nodes\n        - Processed in ${typedResult.chunks} chunks\n        `;\n\n        return {\n          content: [\n            initialStatus,\n            {\n              type: \"text\" as const,\n              text: summaryText\n            },\n            {\n              type: \"text\" as const,\n              text: JSON.stringify(typedResult.textNodes, null, 2)\n            }\n          ],\n        };\n      }\n\n      // If chunking wasn't used or wasn't reported in the result format, return the result as is\n      return {\n        content: [\n          initialStatus,\n          {\n            type: \"text\",\n            text: JSON.stringify(result, null, 2),\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error scanning text nodes: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Node Type Scanning Tool\nserver.tool(\n  \"scan_nodes_by_types\",\n  \"Scan for child nodes with specific types in the selected Figma node\",\n  {\n    nodeId: z.string().describe(\"ID of the node to scan\"),\n    types: z.array(z.string()).describe(\"Array of node types to find in the child nodes (e.g. ['COMPONENT', 'FRAME'])\")\n  },\n  async ({ nodeId, types }: any) => {\n    try {\n      // Initial response to indicate we're starting the process\n      const initialStatus = {\n        type: \"text\" as const,\n        text: `Starting node type scanning for types: ${types.join(', ')}...`,\n      };\n\n      // Use the plugin's scan_nodes_by_types function\n      const result = await sendCommandToFigma(\"scan_nodes_by_types\", {\n        nodeId,\n        types\n      });\n\n      // Format the response\n      if (result && typeof result === 'object' && 'matchingNodes' in result) {\n        const typedResult = result as {\n          success: boolean,\n          count: number,\n          matchingNodes: Array<{\n            id: string,\n            name: string,\n            type: string,\n            bbox: {\n              x: number,\n              y: number,\n              width: number,\n              height: number\n            }\n          }>,\n          searchedTypes: Array<string>\n        };\n\n        const summaryText = `Scan completed: Found ${typedResult.count} nodes matching types: ${typedResult.searchedTypes.join(', ')}`;\n\n        return {\n          content: [\n            initialStatus,\n            {\n              type: \"text\" as const,\n              text: summaryText\n            },\n            {\n              type: \"text\" as const,\n              text: JSON.stringify(typedResult.matchingNodes, null, 2)\n            }\n          ],\n        };\n      }\n\n      // If the result is in an unexpected format, return it as is\n      return {\n        content: [\n          initialStatus,\n          {\n            type: \"text\",\n            text: JSON.stringify(result, null, 2),\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error scanning nodes by types: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Text Replacement Strategy Prompt\nserver.prompt(\n  \"text_replacement_strategy\",\n  \"Systematic approach for replacing text in Figma designs\",\n  (extra) => {\n    return {\n      messages: [\n        {\n          role: \"assistant\",\n          content: {\n            type: \"text\",\n            text: `# Intelligent Text Replacement Strategy\n\n## 1. Analyze Design & Identify Structure\n- Scan text nodes to understand the overall structure of the design\n- Use AI pattern recognition to identify logical groupings:\n  * Tables (rows, columns, headers, cells)\n  * Lists (items, headers, nested lists)\n  * Card groups (similar cards with recurring text fields)\n  * Forms (labels, input fields, validation text)\n  * Navigation (menu items, breadcrumbs)\n\\`\\`\\`\nscan_text_nodes(nodeId: \"node-id\")\nget_node_info(nodeId: \"node-id\")  // optional\n\\`\\`\\`\n\n## 2. Strategic Chunking for Complex Designs\n- Divide replacement tasks into logical content chunks based on design structure\n- Use one of these chunking strategies that best fits the design:\n  * **Structural Chunking**: Table rows/columns, list sections, card groups\n  * **Spatial Chunking**: Top-to-bottom, left-to-right in screen areas\n  * **Semantic Chunking**: Content related to the same topic or functionality\n  * **Component-Based Chunking**: Process similar component instances together\n\n## 3. Progressive Replacement with Verification\n- Create a safe copy of the node for text replacement\n- Replace text chunk by chunk with continuous progress updates\n- After each chunk is processed:\n  * Export that section as a small, manageable image\n  * Verify text fits properly and maintain design integrity\n  * Fix issues before proceeding to the next chunk\n\n\\`\\`\\`\n// Clone the node to create a safe copy\nclone_node(nodeId: \"selected-node-id\", x: [new-x], y: [new-y])\n\n// Replace text chunk by chunk\nset_multiple_text_contents(\n  nodeId: \"parent-node-id\", \n  text: [\n    { nodeId: \"node-id-1\", text: \"New text 1\" },\n    // More nodes in this chunk...\n  ]\n)\n\n// Verify chunk with small, targeted image exports\nexport_node_as_image(nodeId: \"chunk-node-id\", format: \"PNG\", scale: 0.5)\n\\`\\`\\`\n\n## 4. Intelligent Handling for Table Data\n- For tabular content:\n  * Process one row or column at a time\n  * Maintain alignment and spacing between cells\n  * Consider conditional formatting based on cell content\n  * Preserve header/data relationships\n\n## 5. Smart Text Adaptation\n- Adaptively handle text based on container constraints:\n  * Auto-detect space constraints and adjust text length\n  * Apply line breaks at appropriate linguistic points\n  * Maintain text hierarchy and emphasis\n  * Consider font scaling for critical content that must fit\n\n## 6. Progressive Feedback Loop\n- Establish a continuous feedback loop during replacement:\n  * Real-time progress updates (0-100%)\n  * Small image exports after each chunk for verification\n  * Issues identified early and resolved incrementally\n  * Quick adjustments applied to subsequent chunks\n\n## 7. Final Verification & Context-Aware QA\n- After all chunks are processed:\n  * Export the entire design at reduced scale for final verification\n  * Check for cross-chunk consistency issues\n  * Verify proper text flow between different sections\n  * Ensure design harmony across the full composition\n\n## 8. Chunk-Specific Export Scale Guidelines\n- Scale exports appropriately based on chunk size:\n  * Small chunks (1-5 elements): scale 1.0\n  * Medium chunks (6-20 elements): scale 0.7\n  * Large chunks (21-50 elements): scale 0.5\n  * Very large chunks (50+ elements): scale 0.3\n  * Full design verification: scale 0.2\n\n## Sample Chunking Strategy for Common Design Types\n\n### Tables\n- Process by logical rows (5-10 rows per chunk)\n- Alternative: Process by column for columnar analysis\n- Tip: Always include header row in first chunk for reference\n\n### Card Lists\n- Group 3-5 similar cards per chunk\n- Process entire cards to maintain internal consistency\n- Verify text-to-image ratio within cards after each chunk\n\n### Forms\n- Group related fields (e.g., \"Personal Information\", \"Payment Details\")\n- Process labels and input fields together\n- Ensure validation messages and hints are updated with their fields\n\n### Navigation & Menus\n- Process hierarchical levels together (main menu, submenu)\n- Respect information architecture relationships\n- Verify menu fit and alignment after replacement\n\n## Best Practices\n- **Preserve Design Intent**: Always prioritize design integrity\n- **Structural Consistency**: Maintain alignment, spacing, and hierarchy\n- **Visual Feedback**: Verify each chunk visually before proceeding\n- **Incremental Improvement**: Learn from each chunk to improve subsequent ones\n- **Balance Automation & Control**: Let AI handle repetitive replacements but maintain oversight\n- **Respect Content Relationships**: Keep related content consistent across chunks\n\nRemember that text is never just text—it's a core design element that must work harmoniously with the overall composition. This chunk-based strategy allows you to methodically transform text while maintaining design integrity.`,\n          },\n        },\n      ],\n      description: \"Systematic approach for replacing text in Figma designs\",\n    };\n  }\n);\n\n// Set Multiple Text Contents Tool\nserver.tool(\n  \"set_multiple_text_contents\",\n  \"Set multiple text contents parallelly in a node\",\n  {\n    nodeId: z\n      .string()\n      .describe(\"The ID of the node containing the text nodes to replace\"),\n    text: z\n      .array(\n        z.object({\n          nodeId: z.string().describe(\"The ID of the text node\"),\n          text: z.string().describe(\"The replacement text\"),\n        })\n      )\n      .describe(\"Array of text node IDs and their replacement texts\"),\n  },\n  async ({ nodeId, text }: any) => {\n    try {\n      if (!text || text.length === 0) {\n        return {\n          content: [\n            {\n              type: \"text\",\n              text: \"No text provided\",\n            },\n          ],\n        };\n      }\n\n      // Initial response to indicate we're starting the process\n      const initialStatus = {\n        type: \"text\" as const,\n        text: `Starting text replacement for ${text.length} nodes. This will be processed in batches of 5...`,\n      };\n\n      // Track overall progress\n      let totalProcessed = 0;\n      const totalToProcess = text.length;\n\n      // Use the plugin's set_multiple_text_contents function with chunking\n      const result = await sendCommandToFigma(\"set_multiple_text_contents\", {\n        nodeId,\n        text,\n      });\n\n      // Cast the result to a specific type to work with it safely\n      interface TextReplaceResult {\n        success: boolean;\n        nodeId: string;\n        replacementsApplied?: number;\n        replacementsFailed?: number;\n        totalReplacements?: number;\n        completedInChunks?: number;\n        results?: Array<{\n          success: boolean;\n          nodeId: string;\n          error?: string;\n          originalText?: string;\n          translatedText?: string;\n        }>;\n      }\n\n      const typedResult = result as TextReplaceResult;\n\n      // Format the results for display\n      const success = typedResult.replacementsApplied && typedResult.replacementsApplied > 0;\n      const progressText = `\n      Text replacement completed:\n      - ${typedResult.replacementsApplied || 0} of ${totalToProcess} successfully updated\n      - ${typedResult.replacementsFailed || 0} failed\n      - Processed in ${typedResult.completedInChunks || 1} batches\n      `;\n\n      // Detailed results\n      const detailedResults = typedResult.results || [];\n      const failedResults = detailedResults.filter(item => !item.success);\n\n      // Create the detailed part of the response\n      let detailedResponse = \"\";\n      if (failedResults.length > 0) {\n        detailedResponse = `\\n\\nNodes that failed:\\n${failedResults.map(item =>\n          `- ${item.nodeId}: ${item.error || \"Unknown error\"}`\n        ).join('\\n')}`;\n      }\n\n      return {\n        content: [\n          initialStatus,\n          {\n            type: \"text\" as const,\n            text: progressText + detailedResponse,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting multiple text contents: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Annotation Conversion Strategy Prompt\nserver.prompt(\n  \"annotation_conversion_strategy\",\n  \"Strategy for converting manual annotations to Figma's native annotations\",\n  (extra) => {\n    return {\n      messages: [\n        {\n          role: \"assistant\",\n          content: {\n            type: \"text\",\n            text: `# Automatic Annotation Conversion\n            \n## Process Overview\n\nThe process of converting manual annotations (numbered/alphabetical indicators with connected descriptions) to Figma's native annotations:\n\n1. Get selected frame/component information\n2. Scan and collect all annotation text nodes\n3. Scan target UI elements (components, instances, frames)\n4. Match annotations to appropriate UI elements\n5. Apply native Figma annotations\n\n## Step 1: Get Selection and Initial Setup\n\nFirst, get the selected frame or component that contains annotations:\n\n\\`\\`\\`typescript\n// Get the selected frame/component\nconst selection = await get_selection();\nconst selectedNodeId = selection[0].id\n\n// Get available annotation categories for later use\nconst annotationData = await get_annotations({\n  nodeId: selectedNodeId,\n  includeCategories: true\n});\nconst categories = annotationData.categories;\n\\`\\`\\`\n\n## Step 2: Scan Annotation Text Nodes\n\nScan all text nodes to identify annotations and their descriptions:\n\n\\`\\`\\`typescript\n// Get all text nodes in the selection\nconst textNodes = await scan_text_nodes({\n  nodeId: selectedNodeId\n});\n\n// Filter and group annotation markers and descriptions\n\n// Markers typically have these characteristics:\n// - Short text content (usually single digit/letter)\n// - Specific font styles (often bold)\n// - Located in a container with \"Marker\" or \"Dot\" in the name\n// - Have a clear naming pattern (e.g., \"1\", \"2\", \"3\" or \"A\", \"B\", \"C\")\n\n\n// Identify description nodes\n// Usually longer text nodes near markers or with matching numbers in path\n  \n\\`\\`\\`\n\n## Step 3: Scan Target UI Elements\n\nGet all potential target elements that annotations might refer to:\n\n\\`\\`\\`typescript\n// Scan for all UI elements that could be annotation targets\nconst targetNodes = await scan_nodes_by_types({\n  nodeId: selectedNodeId,\n  types: [\n    \"COMPONENT\",\n    \"INSTANCE\",\n    \"FRAME\"\n  ]\n});\n\\`\\`\\`\n\n## Step 4: Match Annotations to Targets\n\nMatch each annotation to its target UI element using these strategies in order of priority:\n\n1. **Path-Based Matching**:\n   - Look at the marker's parent container name in the Figma layer hierarchy\n   - Remove any \"Marker:\" or \"Annotation:\" prefixes from the parent name\n   - Find UI elements that share the same parent name or have it in their path\n   - This works well when markers are grouped with their target elements\n\n2. **Name-Based Matching**:\n   - Extract key terms from the annotation description\n   - Look for UI elements whose names contain these key terms\n   - Consider both exact matches and semantic similarities\n   - Particularly effective for form fields, buttons, and labeled components\n\n3. **Proximity-Based Matching** (fallback):\n   - Calculate the center point of the marker\n   - Find the closest UI element by measuring distances to element centers\n   - Consider the marker's position relative to nearby elements\n   - Use this method when other matching strategies fail\n\nAdditional Matching Considerations:\n- Give higher priority to matches found through path-based matching\n- Consider the type of UI element when evaluating matches\n- Take into account the annotation's context and content\n- Use a combination of strategies for more accurate matching\n\n## Step 5: Apply Native Annotations\n\nConvert matched annotations to Figma's native annotations using batch processing:\n\n\\`\\`\\`typescript\n// Prepare annotations array for batch processing\nconst annotationsToApply = Object.values(annotations).map(({ marker, description }) => {\n  // Find target using multiple strategies\n  const target = \n    findTargetByPath(marker, targetNodes) ||\n    findTargetByName(description, targetNodes) ||\n    findTargetByProximity(marker, targetNodes);\n  \n  if (target) {\n    // Determine appropriate category based on content\n    const category = determineCategory(description.characters, categories);\n\n    // Determine appropriate additional annotationProperty based on content\n    const annotationProperty = determineProperties(description.characters, target.type);\n    \n    return {\n      nodeId: target.id,\n      labelMarkdown: description.characters,\n      categoryId: category.id,\n      properties: annotationProperty\n    };\n  }\n  return null;\n}).filter(Boolean); // Remove null entries\n\n// Apply annotations in batches using set_multiple_annotations\nif (annotationsToApply.length > 0) {\n  await set_multiple_annotations({\n    nodeId: selectedNodeId,\n    annotations: annotationsToApply\n  });\n}\n\\`\\`\\`\n\n\nThis strategy focuses on practical implementation based on real-world usage patterns, emphasizing the importance of handling various UI elements as annotation targets, not just text nodes.`\n          },\n        },\n      ],\n      description: \"Strategy for converting manual annotations to Figma's native annotations\",\n    };\n  }\n);\n\n// Instance Slot Filling Strategy Prompt\nserver.prompt(\n  \"swap_overrides_instances\",\n  \"Guide to swap instance overrides between instances\",\n  (extra) => {\n    return {\n      messages: [\n        {\n          role: \"assistant\",\n          content: {\n            type: \"text\",\n            text: `# Swap Component Instance and Override Strategy\n\n## Overview\nThis strategy enables transferring content and property overrides from a source instance to one or more target instances in Figma, maintaining design consistency while reducing manual work.\n\n## Step-by-Step Process\n\n### 1. Selection Analysis\n- Use \\`get_selection()\\` to identify the parent component or selected instances\n- For parent components, scan for instances with \\`scan_nodes_by_types({ nodeId: \"parent-id\", types: [\"INSTANCE\"] })\\`\n- Identify custom slots by name patterns (e.g. \"Custom Slot*\" or \"Instance Slot\") or by examining text content\n- Determine which is the source instance (with content to copy) and which are targets (where to apply content)\n\n### 2. Extract Source Overrides\n- Use \\`get_instance_overrides()\\` to extract customizations from the source instance\n- This captures text content, property values, and style overrides\n- Command syntax: \\`get_instance_overrides({ nodeId: \"source-instance-id\" })\\`\n- Look for successful response like \"Got component information from [instance name]\"\n\n### 3. Apply Overrides to Targets\n- Apply captured overrides using \\`set_instance_overrides()\\`\n- Command syntax:\n  \\`\\`\\`\n  set_instance_overrides({\n    sourceInstanceId: \"source-instance-id\", \n    targetNodeIds: [\"target-id-1\", \"target-id-2\", ...]\n  })\n  \\`\\`\\`\n\n### 4. Verification\n- Verify results with \\`get_node_info()\\` or \\`read_my_design()\\`\n- Confirm text content and style overrides have transferred successfully\n\n## Key Tips\n- Always join the appropriate channel first with \\`join_channel()\\`\n- When working with multiple targets, check the full selection with \\`get_selection()\\`\n- Preserve component relationships by using instance overrides rather than direct text manipulation`,\n          },\n        },\n      ],\n      description: \"Strategy for transferring overrides between component instances in Figma\",\n    };\n  }\n);\n\n// Set Layout Mode Tool\nserver.tool(\n  \"set_layout_mode\",\n  \"Set the layout mode and wrap behavior of a frame in Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the frame to modify\"),\n    layoutMode: z.enum([\"NONE\", \"HORIZONTAL\", \"VERTICAL\"]).describe(\"Layout mode for the frame\"),\n    layoutWrap: z.enum([\"NO_WRAP\", \"WRAP\"]).optional().describe(\"Whether the auto-layout frame wraps its children\")\n  },\n  async ({ nodeId, layoutMode, layoutWrap }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_layout_mode\", {\n        nodeId,\n        layoutMode,\n        layoutWrap: layoutWrap || \"NO_WRAP\"\n      });\n      const typedResult = result as { name: string };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Set layout mode of frame \"${typedResult.name}\" to ${layoutMode}${layoutWrap ? ` with ${layoutWrap}` : ''}`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting layout mode: ${error instanceof Error ? error.message : String(error)}`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Set Padding Tool\nserver.tool(\n  \"set_padding\",\n  \"Set padding values for an auto-layout frame in Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the frame to modify\"),\n    paddingTop: z.number().optional().describe(\"Top padding value\"),\n    paddingRight: z.number().optional().describe(\"Right padding value\"),\n    paddingBottom: z.number().optional().describe(\"Bottom padding value\"),\n    paddingLeft: z.number().optional().describe(\"Left padding value\"),\n  },\n  async ({ nodeId, paddingTop, paddingRight, paddingBottom, paddingLeft }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_padding\", {\n        nodeId,\n        paddingTop,\n        paddingRight,\n        paddingBottom,\n        paddingLeft,\n      });\n      const typedResult = result as { name: string };\n\n      // Create a message about which padding values were set\n      const paddingMessages = [];\n      if (paddingTop !== undefined) paddingMessages.push(`top: ${paddingTop}`);\n      if (paddingRight !== undefined) paddingMessages.push(`right: ${paddingRight}`);\n      if (paddingBottom !== undefined) paddingMessages.push(`bottom: ${paddingBottom}`);\n      if (paddingLeft !== undefined) paddingMessages.push(`left: ${paddingLeft}`);\n\n      const paddingText = paddingMessages.length > 0\n        ? `padding (${paddingMessages.join(', ')})`\n        : \"padding\";\n\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Set ${paddingText} for frame \"${typedResult.name}\"`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting padding: ${error instanceof Error ? error.message : String(error)}`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Set Axis Align Tool\nserver.tool(\n  \"set_axis_align\",\n  \"Set primary and counter axis alignment for an auto-layout frame in Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the frame to modify\"),\n    primaryAxisAlignItems: z\n      .enum([\"MIN\", \"MAX\", \"CENTER\", \"SPACE_BETWEEN\"])\n      .optional()\n      .describe(\"Primary axis alignment (MIN/MAX = left/right in horizontal, top/bottom in vertical). Note: When set to SPACE_BETWEEN, itemSpacing will be ignored as children will be evenly spaced.\"),\n    counterAxisAlignItems: z\n      .enum([\"MIN\", \"MAX\", \"CENTER\", \"BASELINE\"])\n      .optional()\n      .describe(\"Counter axis alignment (MIN/MAX = top/bottom in horizontal, left/right in vertical)\")\n  },\n  async ({ nodeId, primaryAxisAlignItems, counterAxisAlignItems }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_axis_align\", {\n        nodeId,\n        primaryAxisAlignItems,\n        counterAxisAlignItems\n      });\n      const typedResult = result as { name: string };\n\n      // Create a message about which alignments were set\n      const alignMessages = [];\n      if (primaryAxisAlignItems !== undefined) alignMessages.push(`primary: ${primaryAxisAlignItems}`);\n      if (counterAxisAlignItems !== undefined) alignMessages.push(`counter: ${counterAxisAlignItems}`);\n\n      const alignText = alignMessages.length > 0\n        ? `axis alignment (${alignMessages.join(', ')})`\n        : \"axis alignment\";\n\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Set ${alignText} for frame \"${typedResult.name}\"`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting axis alignment: ${error instanceof Error ? error.message : String(error)}`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Set Layout Sizing Tool\nserver.tool(\n  \"set_layout_sizing\",\n  \"Set horizontal and vertical sizing modes for an auto-layout frame in Figma\",\n  {\n    nodeId: z.string().describe(\"The ID of the frame to modify\"),\n    layoutSizingHorizontal: z\n      .enum([\"FIXED\", \"HUG\", \"FILL\"])\n      .optional()\n      .describe(\"Horizontal sizing mode (HUG for frames/text only, FILL for auto-layout children only)\"),\n    layoutSizingVertical: z\n      .enum([\"FIXED\", \"HUG\", \"FILL\"])\n      .optional()\n      .describe(\"Vertical sizing mode (HUG for frames/text only, FILL for auto-layout children only)\")\n  },\n  async ({ nodeId, layoutSizingHorizontal, layoutSizingVertical }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_layout_sizing\", {\n        nodeId,\n        layoutSizingHorizontal,\n        layoutSizingVertical\n      });\n      const typedResult = result as { name: string };\n\n      // Create a message about which sizing modes were set\n      const sizingMessages = [];\n      if (layoutSizingHorizontal !== undefined) sizingMessages.push(`horizontal: ${layoutSizingHorizontal}`);\n      if (layoutSizingVertical !== undefined) sizingMessages.push(`vertical: ${layoutSizingVertical}`);\n\n      const sizingText = sizingMessages.length > 0\n        ? `layout sizing (${sizingMessages.join(', ')})`\n        : \"layout sizing\";\n\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Set ${sizingText} for frame \"${typedResult.name}\"`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting layout sizing: ${error instanceof Error ? error.message : String(error)}`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Set Item Spacing Tool\nserver.tool(\n  \"set_item_spacing\",\n  \"Set distance between children in an auto-layout frame\",\n  {\n    nodeId: z.string().describe(\"The ID of the frame to modify\"),\n    itemSpacing: z.number().optional().describe(\"Distance between children. Note: This value will be ignored if primaryAxisAlignItems is set to SPACE_BETWEEN.\"),\n    counterAxisSpacing: z.number().optional().describe(\"Distance between wrapped rows/columns. Only works when layoutWrap is set to WRAP.\")\n  },\n  async ({ nodeId, itemSpacing, counterAxisSpacing}: any) => {\n    try {\n      const params: any = { nodeId };\n      if (itemSpacing !== undefined) params.itemSpacing = itemSpacing;\n      if (counterAxisSpacing !== undefined) params.counterAxisSpacing = counterAxisSpacing;\n      \n      const result = await sendCommandToFigma(\"set_item_spacing\", params);\n      const typedResult = result as { name: string, itemSpacing?: number, counterAxisSpacing?: number };\n\n      let message = `Updated spacing for frame \"${typedResult.name}\":`;\n      if (itemSpacing !== undefined) message += ` itemSpacing=${itemSpacing}`;\n      if (counterAxisSpacing !== undefined) message += ` counterAxisSpacing=${counterAxisSpacing}`;\n\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: message,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting spacing: ${error instanceof Error ? error.message : String(error)}`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// A tool to get Figma Prototyping Reactions from multiple nodes\nserver.tool(\n  \"get_reactions\",\n  \"Get Figma Prototyping Reactions from multiple nodes. CRITICAL: The output MUST be processed using the 'reaction_to_connector_strategy' prompt IMMEDIATELY to generate parameters for connector lines via the 'create_connections' tool.\",\n  {\n    nodeIds: z.array(z.string()).describe(\"Array of node IDs to get reactions from\"),\n  },\n  async ({ nodeIds }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"get_reactions\", { nodeIds });\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: JSON.stringify(result)\n          },\n          {\n            type: \"text\",\n            text: \"IMPORTANT: You MUST now use the reaction data above and follow the `reaction_to_connector_strategy` prompt to prepare the parameters for the `create_connections` tool call. This is a required next step.\"\n          }\n        ],\n        followUp: {\n          type: \"prompt\",\n          prompt: \"reaction_to_connector_strategy\",\n        },\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error getting reactions: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Create Connectors Tool\nserver.tool(\n  \"set_default_connector\",\n  \"Set a copied connector node as the default connector\",\n  {\n    connectorId: z.string().optional().describe(\"The ID of the connector node to set as default\")\n  },\n  async ({ connectorId }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_default_connector\", {\n        connectorId\n      });\n\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Default connector set: ${JSON.stringify(result)}`\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting default connector: ${error instanceof Error ? error.message : String(error)}`\n          }\n        ]\n      };\n    }\n  }\n);\n\n// Connect Nodes Tool\nserver.tool(\n  \"create_connections\",\n  \"Create connections between nodes using the default connector style\",\n  {\n    connections: z.array(z.object({\n      startNodeId: z.string().describe(\"ID of the starting node\"),\n      endNodeId: z.string().describe(\"ID of the ending node\"),\n      text: z.string().optional().describe(\"Optional text to display on the connector\")\n    })).describe(\"Array of node connections to create\")\n  },\n  async ({ connections }: any) => {\n    try {\n      if (!connections || connections.length === 0) {\n        return {\n          content: [\n            {\n              type: \"text\",\n              text: \"No connections provided\"\n            }\n          ]\n        };\n      }\n\n      const result = await sendCommandToFigma(\"create_connections\", {\n        connections\n      });\n\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Created ${connections.length} connections: ${JSON.stringify(result)}`\n          }\n        ]\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error creating connections: ${error instanceof Error ? error.message : String(error)}`\n          }\n        ]\n      };\n    }\n  }\n);\n\n// Set Focus Tool\nserver.tool(\n  \"set_focus\",\n  \"Set focus on a specific node in Figma by selecting it and scrolling viewport to it\",\n  {\n    nodeId: z.string().describe(\"The ID of the node to focus on\"),\n  },\n  async ({ nodeId }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_focus\", { nodeId });\n      const typedResult = result as { name: string; id: string };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Focused on node \"${typedResult.name}\" (ID: ${typedResult.id})`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting focus: ${error instanceof Error ? error.message : String(error)}`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Set Selections Tool\nserver.tool(\n  \"set_selections\",\n  \"Set selection to multiple nodes in Figma and scroll viewport to show them\",\n  {\n    nodeIds: z.array(z.string()).describe(\"Array of node IDs to select\"),\n  },\n  async ({ nodeIds }: any) => {\n    try {\n      const result = await sendCommandToFigma(\"set_selections\", { nodeIds });\n      const typedResult = result as { selectedNodes: Array<{ name: string; id: string }>; count: number };\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Selected ${typedResult.count} nodes: ${typedResult.selectedNodes.map(node => `\"${node.name}\" (${node.id})`).join(', ')}`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error setting selections: ${error instanceof Error ? error.message : String(error)}`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Strategy for converting Figma prototype reactions to connector lines\nserver.prompt(\n  \"reaction_to_connector_strategy\",\n  \"Strategy for converting Figma prototype reactions to connector lines using the output of 'get_reactions'\",\n  (extra) => {\n    return {\n      messages: [\n        {\n          role: \"assistant\",\n          content: {\n            type: \"text\",\n            text: `# Strategy: Convert Figma Prototype Reactions to Connector Lines\n\n## Goal\nProcess the JSON output from the \\`get_reactions\\` tool to generate an array of connection objects suitable for the \\`create_connections\\` tool. This visually represents prototype flows as connector lines on the Figma canvas.\n\n## Input Data\nYou will receive JSON data from the \\`get_reactions\\` tool. This data contains an array of nodes, each with potential reactions. A typical reaction object looks like this:\n\\`\\`\\`json\n{\n  \"trigger\": { \"type\": \"ON_CLICK\" },\n  \"action\": {\n    \"type\": \"NAVIGATE\",\n    \"destinationId\": \"destination-node-id\",\n    \"navigationTransition\": { ... },\n    \"preserveScrollPosition\": false\n  }\n}\n\\`\\`\\`\n\n## Step-by-Step Process\n\n### 1. Preparation & Context Gathering\n   - **Action:** Call \\`read_my_design\\` on the relevant node(s) to get context about the nodes involved (names, types, etc.). This helps in generating meaningful connector labels later.\n   - **Action:** Call \\`set_default_connector\\` **without** the \\`connectorId\\` parameter.\n   - **Check Result:** Analyze the response from \\`set_default_connector\\`.\n     - If it confirms a default connector is already set (e.g., \"Default connector is already set\"), proceed to Step 2.\n     - If it indicates no default connector is set (e.g., \"No default connector set...\"), you **cannot** proceed with \\`create_connections\\` yet. Inform the user they need to manually copy a connector from FigJam, paste it onto the current page, select it, and then you can run \\`set_default_connector({ connectorId: \"SELECTED_NODE_ID\" })\\` before attempting \\`create_connections\\`. **Do not proceed to Step 2 until a default connector is confirmed.**\n\n### 2. Filter and Transform Reactions from \\`get_reactions\\` Output\n   - **Iterate:** Go through the JSON array provided by \\`get_reactions\\`. For each node in the array:\n     - Iterate through its \\`reactions\\` array.\n   - **Filter:** Keep only reactions where the \\`action\\` meets these criteria:\n     - Has a \\`type\\` that implies a connection (e.g., \\`NAVIGATE\\`, \\`OPEN_OVERLAY\\`, \\`SWAP_OVERLAY\\`). **Ignore** types like \\`CHANGE_TO\\`, \\`CLOSE_OVERLAY\\`, etc.\n     - Has a valid \\`destinationId\\` property.\n   - **Extract:** For each valid reaction, extract the following information:\n     - \\`sourceNodeId\\`: The ID of the node the reaction belongs to (from the outer loop).\n     - \\`destinationNodeId\\`: The value of \\`action.destinationId\\`.\n     - \\`actionType\\`: The value of \\`action.type\\`.\n     - \\`triggerType\\`: The value of \\`trigger.type\\`.\n\n### 3. Generate Connector Text Labels\n   - **For each extracted connection:** Create a concise, descriptive text label string.\n   - **Combine Information:** Use the \\`actionType\\`, \\`triggerType\\`, and potentially the names of the source/destination nodes (obtained from Step 1's \\`read_my_design\\` or by calling \\`get_node_info\\` if necessary) to generate the label.\n   - **Example Labels:**\n     - If \\`triggerType\\` is \"ON\\_CLICK\" and \\`actionType\\` is \"NAVIGATE\": \"On click, navigate to [Destination Node Name]\"\n     - If \\`triggerType\\` is \"ON\\_DRAG\" and \\`actionType\\` is \"OPEN\\_OVERLAY\": \"On drag, open [Destination Node Name] overlay\"\n   - **Keep it brief and informative.** Let this generated string be \\`generatedText\\`.\n\n### 4. Prepare the \\`connections\\` Array for \\`create_connections\\`\n   - **Structure:** Create a JSON array where each element is an object representing a connection.\n   - **Format:** Each object in the array must have the following structure:\n     \\`\\`\\`json\n     {\n       \"startNodeId\": \"sourceNodeId_from_step_2\",\n       \"endNodeId\": \"destinationNodeId_from_step_2\",\n       \"text\": \"generatedText_from_step_3\"\n     }\n     \\`\\`\\`\n   - **Result:** This final array is the value you will pass to the \\`connections\\` parameter when calling the \\`create_connections\\` tool.\n\n### 5. Execute Connection Creation\n   - **Action:** Call the \\`create_connections\\` tool, passing the array generated in Step 4 as the \\`connections\\` argument.\n   - **Verify:** Check the response from \\`create_connections\\` to confirm success or failure.\n\nThis detailed process ensures you correctly interpret the reaction data, prepare the necessary information, and use the appropriate tools to create the connector lines.`\n          },\n        },\n      ],\n      description: \"Strategy for converting Figma prototype reactions to connector lines using the output of 'get_reactions'\",\n    };\n  }\n);\n\n\n// Define command types and parameters\ntype FigmaCommand =\n  | \"get_document_info\"\n  | \"get_selection\"\n  | \"get_node_info\"\n  | \"get_nodes_info\"\n  | \"read_my_design\"\n  | \"create_rectangle\"\n  | \"create_frame\"\n  | \"create_text\"\n  | \"set_fill_color\"\n  | \"set_stroke_color\"\n  | \"move_node\"\n  | \"resize_node\"\n  | \"delete_node\"\n  | \"delete_multiple_nodes\"\n  | \"get_styles\"\n  | \"get_local_components\"\n  | \"create_component_instance\"\n  | \"get_instance_overrides\"\n  | \"set_instance_overrides\"\n  | \"export_node_as_image\"\n  | \"join\"\n  | \"set_corner_radius\"\n  | \"clone_node\"\n  | \"set_text_content\"\n  | \"scan_text_nodes\"\n  | \"set_multiple_text_contents\"\n  | \"get_annotations\"\n  | \"set_annotation\"\n  | \"set_multiple_annotations\"\n  | \"scan_nodes_by_types\"\n  | \"set_layout_mode\"\n  | \"set_padding\"\n  | \"set_axis_align\"\n  | \"set_layout_sizing\"\n  | \"set_item_spacing\"\n  | \"get_reactions\"\n  | \"set_default_connector\"\n  | \"create_connections\"\n  | \"set_focus\"\n  | \"set_selections\";\n\ntype CommandParams = {\n  get_document_info: Record<string, never>;\n  get_selection: Record<string, never>;\n  get_node_info: { nodeId: string };\n  get_nodes_info: { nodeIds: string[] };\n  create_rectangle: {\n    x: number;\n    y: number;\n    width: number;\n    height: number;\n    name?: string;\n    parentId?: string;\n  };\n  create_frame: {\n    x: number;\n    y: number;\n    width: number;\n    height: number;\n    name?: string;\n    parentId?: string;\n    fillColor?: { r: number; g: number; b: number; a?: number };\n    strokeColor?: { r: number; g: number; b: number; a?: number };\n    strokeWeight?: number;\n  };\n  create_text: {\n    x: number;\n    y: number;\n    text: string;\n    fontSize?: number;\n    fontWeight?: number;\n    fontColor?: { r: number; g: number; b: number; a?: number };\n    name?: string;\n    parentId?: string;\n  };\n  set_fill_color: {\n    nodeId: string;\n    r: number;\n    g: number;\n    b: number;\n    a?: number;\n  };\n  set_stroke_color: {\n    nodeId: string;\n    r: number;\n    g: number;\n    b: number;\n    a?: number;\n    weight?: number;\n  };\n  move_node: {\n    nodeId: string;\n    x: number;\n    y: number;\n  };\n  resize_node: {\n    nodeId: string;\n    width: number;\n    height: number;\n  };\n  delete_node: {\n    nodeId: string;\n  };\n  delete_multiple_nodes: {\n    nodeIds: string[];\n  };\n  get_styles: Record<string, never>;\n  get_local_components: Record<string, never>;\n  get_team_components: Record<string, never>;\n  create_component_instance: {\n    componentKey: string;\n    x: number;\n    y: number;\n  };\n  get_instance_overrides: {\n    instanceNodeId: string | null;\n  };\n  set_instance_overrides: {\n    targetNodeIds: string[];\n    sourceInstanceId: string;\n  };\n  export_node_as_image: {\n    nodeId: string;\n    format?: \"PNG\" | \"JPG\" | \"SVG\" | \"PDF\";\n    scale?: number;\n  };\n  execute_code: {\n    code: string;\n  };\n  join: {\n    channel: string;\n  };\n  set_corner_radius: {\n    nodeId: string;\n    radius: number;\n    corners?: boolean[];\n  };\n  clone_node: {\n    nodeId: string;\n    x?: number;\n    y?: number;\n  };\n  set_text_content: {\n    nodeId: string;\n    text: string;\n  };\n  scan_text_nodes: {\n    nodeId: string;\n    useChunking: boolean;\n    chunkSize: number;\n  };\n  set_multiple_text_contents: {\n    nodeId: string;\n    text: Array<{ nodeId: string; text: string }>;\n  };\n  get_annotations: {\n    nodeId?: string;\n    includeCategories?: boolean;\n  };\n  set_annotation: {\n    nodeId: string;\n    annotationId?: string;\n    labelMarkdown: string;\n    categoryId?: string;\n    properties?: Array<{ type: string }>;\n  };\n  set_multiple_annotations: SetMultipleAnnotationsParams;\n  scan_nodes_by_types: {\n    nodeId: string;\n    types: Array<string>;\n  };\n  get_reactions: { nodeIds: string[] };\n  set_default_connector: {\n    connectorId?: string | undefined;\n  };\n  create_connections: {\n    connections: Array<{\n      startNodeId: string;\n      endNodeId: string;\n      text?: string;\n    }>;\n  };\n  set_focus: {\n    nodeId: string;\n  };\n  set_selections: {\n    nodeIds: string[];\n  };\n\n};\n\n\n// Helper function to process Figma node responses\nfunction processFigmaNodeResponse(result: unknown): any {\n  if (!result || typeof result !== \"object\") {\n    return result;\n  }\n\n  // Check if this looks like a node response\n  const resultObj = result as Record<string, unknown>;\n  if (\"id\" in resultObj && typeof resultObj.id === \"string\") {\n    // It appears to be a node response, log the details\n    console.info(\n      `Processed Figma node: ${resultObj.name || \"Unknown\"} (ID: ${resultObj.id\n      })`\n    );\n\n    if (\"x\" in resultObj && \"y\" in resultObj) {\n      console.debug(`Node position: (${resultObj.x}, ${resultObj.y})`);\n    }\n\n    if (\"width\" in resultObj && \"height\" in resultObj) {\n      console.debug(`Node dimensions: ${resultObj.width}×${resultObj.height}`);\n    }\n  }\n\n  return result;\n}\n\n// Update the connectToFigma function\nfunction connectToFigma(port: number = 3055) {\n  // If already connected, do nothing\n  if (ws && ws.readyState === WebSocket.OPEN) {\n    logger.info('Already connected to Figma');\n    return;\n  }\n\n  const wsUrl = serverUrl === 'localhost' ? `${WS_URL}:${port}` : WS_URL;\n  logger.info(`Connecting to Figma socket server at ${wsUrl}...`);\n  ws = new WebSocket(wsUrl);\n\n  ws.on('open', () => {\n    logger.info('Connected to Figma socket server');\n    // Reset channel on new connection\n    currentChannel = null;\n  });\n\n  ws.on(\"message\", (data: any) => {\n    try {\n      // Define a more specific type with an index signature to allow any property access\n      interface ProgressMessage {\n        message: FigmaResponse | any;\n        type?: string;\n        id?: string;\n        [key: string]: any; // Allow any other properties\n      }\n\n      const json = JSON.parse(data) as ProgressMessage;\n\n      // Handle progress updates\n      if (json.type === 'progress_update') {\n        const progressData = json.message.data as CommandProgressUpdate;\n        const requestId = json.id || '';\n\n        if (requestId && pendingRequests.has(requestId)) {\n          const request = pendingRequests.get(requestId)!;\n\n          // Update last activity timestamp\n          request.lastActivity = Date.now();\n\n          // Reset the timeout to prevent timeouts during long-running operations\n          clearTimeout(request.timeout);\n\n          // Create a new timeout\n          request.timeout = setTimeout(() => {\n            if (pendingRequests.has(requestId)) {\n              logger.error(`Request ${requestId} timed out after extended period of inactivity`);\n              pendingRequests.delete(requestId);\n              request.reject(new Error('Request to Figma timed out'));\n            }\n          }, 60000); // 60 second timeout for inactivity\n\n          // Log progress\n          logger.info(`Progress update for ${progressData.commandType}: ${progressData.progress}% - ${progressData.message}`);\n\n          // For completed updates, we could resolve the request early if desired\n          if (progressData.status === 'completed' && progressData.progress === 100) {\n            // Optionally resolve early with partial data\n            // request.resolve(progressData.payload);\n            // pendingRequests.delete(requestId);\n\n            // Instead, just log the completion, wait for final result from Figma\n            logger.info(`Operation ${progressData.commandType} completed, waiting for final result`);\n          }\n        }\n        return;\n      }\n\n      // Handle regular responses\n      const myResponse = json.message;\n      logger.debug(`Received message: ${JSON.stringify(myResponse)}`);\n      logger.log('myResponse' + JSON.stringify(myResponse));\n\n      // Handle response to a request\n      if (\n        myResponse.id &&\n        pendingRequests.has(myResponse.id) &&\n        myResponse.result\n      ) {\n        const request = pendingRequests.get(myResponse.id)!;\n        clearTimeout(request.timeout);\n\n        if (myResponse.error) {\n          logger.error(`Error from Figma: ${myResponse.error}`);\n          request.reject(new Error(myResponse.error));\n        } else {\n          if (myResponse.result) {\n            request.resolve(myResponse.result);\n          }\n        }\n\n        pendingRequests.delete(myResponse.id);\n      } else {\n        // Handle broadcast messages or events\n        logger.info(`Received broadcast message: ${JSON.stringify(myResponse)}`);\n      }\n    } catch (error) {\n      logger.error(`Error parsing message: ${error instanceof Error ? error.message : String(error)}`);\n    }\n  });\n\n  ws.on('error', (error) => {\n    logger.error(`Socket error: ${error}`);\n  });\n\n  ws.on('close', () => {\n    logger.info('Disconnected from Figma socket server');\n    ws = null;\n\n    // Reject all pending requests\n    for (const [id, request] of pendingRequests.entries()) {\n      clearTimeout(request.timeout);\n      request.reject(new Error(\"Connection closed\"));\n      pendingRequests.delete(id);\n    }\n\n    // Attempt to reconnect\n    logger.info('Attempting to reconnect in 2 seconds...');\n    setTimeout(() => connectToFigma(port), 2000);\n  });\n}\n\n// Function to join a channel\nasync function joinChannel(channelName: string): Promise<void> {\n  if (!ws || ws.readyState !== WebSocket.OPEN) {\n    throw new Error(\"Not connected to Figma\");\n  }\n\n  try {\n    await sendCommandToFigma(\"join\", { channel: channelName });\n    currentChannel = channelName;\n    logger.info(`Joined channel: ${channelName}`);\n  } catch (error) {\n    logger.error(`Failed to join channel: ${error instanceof Error ? error.message : String(error)}`);\n    throw error;\n  }\n}\n\n// Function to send commands to Figma\nfunction sendCommandToFigma(\n  command: FigmaCommand,\n  params: unknown = {},\n  timeoutMs: number = 30000\n): Promise<unknown> {\n  return new Promise((resolve, reject) => {\n    // If not connected, try to connect first\n    if (!ws || ws.readyState !== WebSocket.OPEN) {\n      connectToFigma();\n      reject(new Error(\"Not connected to Figma. Attempting to connect...\"));\n      return;\n    }\n\n    // Check if we need a channel for this command\n    const requiresChannel = command !== \"join\";\n    if (requiresChannel && !currentChannel) {\n      reject(new Error(\"Must join a channel before sending commands\"));\n      return;\n    }\n\n    const id = uuidv4();\n    const request = {\n      id,\n      type: command === \"join\" ? \"join\" : \"message\",\n      ...(command === \"join\"\n        ? { channel: (params as any).channel }\n        : { channel: currentChannel }),\n      message: {\n        id,\n        command,\n        params: {\n          ...(params as any),\n          commandId: id, // Include the command ID in params\n        },\n      },\n    };\n\n    // Set timeout for request\n    const timeout = setTimeout(() => {\n      if (pendingRequests.has(id)) {\n        pendingRequests.delete(id);\n        logger.error(`Request ${id} to Figma timed out after ${timeoutMs / 1000} seconds`);\n        reject(new Error('Request to Figma timed out'));\n      }\n    }, timeoutMs);\n\n    // Store the promise callbacks to resolve/reject later\n    pendingRequests.set(id, {\n      resolve,\n      reject,\n      timeout,\n      lastActivity: Date.now()\n    });\n\n    // Send the request\n    logger.info(`Sending command to Figma: ${command}`);\n    logger.debug(`Request details: ${JSON.stringify(request)}`);\n    ws.send(JSON.stringify(request));\n  });\n}\n\n// Update the join_channel tool\nserver.tool(\n  \"join_channel\",\n  \"Join a specific channel to communicate with Figma\",\n  {\n    channel: z.string().describe(\"The name of the channel to join\").default(\"\"),\n  },\n  async ({ channel }: any) => {\n    try {\n      if (!channel) {\n        // If no channel provided, ask the user for input\n        return {\n          content: [\n            {\n              type: \"text\",\n              text: \"Please provide a channel name to join:\",\n            },\n          ],\n          followUp: {\n            tool: \"join_channel\",\n            description: \"Join the specified channel\",\n          },\n        };\n      }\n\n      await joinChannel(channel);\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Successfully joined channel: ${channel}`,\n          },\n        ],\n      };\n    } catch (error) {\n      return {\n        content: [\n          {\n            type: \"text\",\n            text: `Error joining channel: ${error instanceof Error ? error.message : String(error)\n              }`,\n          },\n        ],\n      };\n    }\n  }\n);\n\n// Start the server\nasync function main() {\n  try {\n    // Try to connect to Figma socket server\n    connectToFigma();\n  } catch (error) {\n    logger.warn(`Could not connect to Figma initially: ${error instanceof Error ? error.message : String(error)}`);\n    logger.warn('Will try to connect when the first command is sent');\n  }\n\n  // Start the MCP server with stdio transport\n  const transport = new StdioServerTransport();\n  await server.connect(transport);\n  logger.info('FigmaMCP server running on stdio');\n}\n\n// Run the server\nmain().catch(error => {\n  logger.error(`Error starting FigmaMCP server: ${error instanceof Error ? error.message : String(error)}`);\n  process.exit(1);\n});\n\n\n\n"],"mappings":"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","names":["WebSocket","uuidv4"]}