duplicate_page
Create a complete copy of any Figma page by providing its page ID. Optionally rename the duplicated page to keep your workspace organized.
Instructions
Duplicate an existing page in the Figma document, creating a complete copy of all its contents
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| pageId | Yes | ID of the page to duplicate | |
| name | No | Optional name for the duplicated page (defaults to 'Original Name (Copy)') |
Implementation Reference
- src/talk_to_figma_mcp/tools/document-tools.ts:555-585 (registration)Registration of the 'duplicate_page' tool in the MCP server via server.tool(), with the handler that sends the command via WebSocket.
server.tool( "duplicate_page", "Duplicate an existing page in the Figma document, creating a complete copy of all its contents", { pageId: z.string().describe("ID of the page to duplicate"), name: z.string().optional().describe("Optional name for the duplicated page (defaults to 'Original Name (Copy)')"), }, async ({ pageId, name }) => { try { const result = await sendCommandToFigma("duplicate_page", { pageId, name }); const typedResult = result as { id: string; name: string; originalName: string }; return { content: [ { type: "text", text: `Duplicated page "${typedResult.originalName}" → "${typedResult.name}" with ID: ${typedResult.id}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error duplicating page: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } ); - Type definition for FigmaCommand includes 'duplicate_page' as a valid command literal.
export type FigmaCommand = | "get_document_info" | "get_selection" | "get_node_info" | "create_rectangle" | "create_frame" | "create_text" | "create_ellipse" | "create_polygon" | "create_star" | "create_vector" | "create_line" | "set_fill_color" | "set_stroke_color" | "move_node" | "resize_node" | "delete_node" | "get_styles" | "get_local_components" | "get_team_components" | "create_component_instance" | "export_node_as_image" | "join" | "ping" | "set_corner_radius" | "clone_node" | "set_text_content" | "scan_text_nodes" | "set_multiple_text_contents" | "set_auto_layout" | "set_font_name" | "set_font_size" | "set_font_weight" | "set_letter_spacing" | "set_line_height" | "set_paragraph_spacing" | "set_text_case" | "set_text_decoration" | "get_styled_text_segments" | "load_font_async" | "get_remote_components" | "set_effects" | "set_effect_style_id" | "set_text_style_id" | "group_nodes" | "ungroup_nodes" | "flatten_node" | "insert_child" | "create_component_from_node" | "create_component_set" | "set_instance_variant" | "create_page" | "delete_page" | "rename_page" | "get_pages" | "set_current_page" | "rename_node" | "set_selection_colors" | "set_image_fill" | "get_image_from_node" | "replace_image_fill" // | "get_image_bytes" // COMMENTED OUT: Issues pending investigation | "apply_image_transform" | "set_image_filters" | "rotate_node" | "set_node_properties" | "reorder_node" | "duplicate_page" | "convert_to_frame" | "set_gradient" | "boolean_operation" | "set_svg" | "get_svg" | "set_image" | "set_grid" | "get_grid" | "set_guide" | "get_guide" | "set_annotation" | "get_annotation" | "get_variables" | "set_variable" | "apply_variable_to_node" | "switch_variable_mode" | "get_figjam_elements" | "create_sticky" | "set_sticky_text" | "create_shape_with_text" | "create_connector" | "create_section"; - Generic handler that sends any Figma command (including 'duplicate_page') via WebSocket and returns the response as a promise.
export function sendCommandToFigma( command: FigmaCommand, params: unknown = {}, timeoutMs: number = 300000 ): Promise<unknown> { return new Promise((resolve, reject) => { // If not connected, try to connect first if (!ws || ws.readyState !== WebSocket.OPEN) { connectToFigma(); reject(new Error("Not connected to Figma. Attempting to connect...")); return; } // Check if we need a channel for this command const requiresChannel = command !== "join"; if (requiresChannel && !currentChannel) { reject(new Error("Must join a channel before sending commands")); return; } const id = uuidv4(); const request = { id, type: command === "join" ? "join" : "message", ...(command === "join" ? { channel: (params as any).channel, sessionId: SESSION_ID } : { channel: currentChannel }), message: { id, command, params: { ...(params as any), commandId: id, // Include the command ID in params }, }, }; // Set timeout for request const timeout = setTimeout(() => { if (pendingRequests.has(id)) { pendingRequests.delete(id); logger.error(`Request ${id} to Figma timed out after ${timeoutMs / 1000} seconds`); reject(new Error('Request to Figma timed out')); } }, timeoutMs); // Store the promise callbacks to resolve/reject later pendingRequests.set(id, { resolve, reject, timeout, lastActivity: Date.now() }); // Send the request logger.info(`Sending command to Figma: ${command}`); logger.debug(`Request details: ${JSON.stringify(request)}`); ws.send(JSON.stringify(request)); }); }