set_variable
Create or update a variable in a Figma design system by specifying its name, type (color, float, string, boolean), and value. Optionally create a new variable collection if provided collection name doesn't exist.
Instructions
Create or update a variable in a Figma variable collection. Creates the collection if collectionName is provided and it doesn't exist.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| collectionId | No | ID of an existing variable collection | |
| collectionName | No | Name for a new collection (used if collectionId not provided) | |
| name | Yes | Variable name | |
| resolvedType | Yes | Variable type | |
| value | No | Variable value. COLOR: {r,g,b,a} (0-1). FLOAT: number. STRING: string. BOOLEAN: boolean. | |
| modeId | No | Mode ID to set the value for (uses default mode if omitted) |
Implementation Reference
- The handler for the 'set_variable' tool. Registers the tool on the MCP server with Zod schema for inputs (collectionId, collectionName, name, resolvedType, value, modeId) and sends the command via WebSocket to Figma.
// Set Variable Tool server.tool( "set_variable", "Create or update a variable in a Figma variable collection. Creates the collection if collectionName is provided and it doesn't exist.", { collectionId: z.string().optional().describe("ID of an existing variable collection"), collectionName: z.string().optional().describe("Name for a new collection (used if collectionId not provided)"), name: z.string().describe("Variable name"), resolvedType: z.enum(["COLOR", "FLOAT", "STRING", "BOOLEAN"]).describe("Variable type"), value: z.any().describe("Variable value. COLOR: {r,g,b,a} (0-1). FLOAT: number. STRING: string. BOOLEAN: boolean."), modeId: z.string().optional().describe("Mode ID to set the value for (uses default mode if omitted)"), }, async ({ collectionId, collectionName, name, resolvedType, value, modeId }) => { try { const result = await sendCommandToFigma("set_variable", { collectionId, collectionName, name, resolvedType, value, modeId, }); const typedResult = result as { variableId: string; variableName: string; collectionName: string }; return { content: [ { type: "text", text: `Set variable "${typedResult.variableName}" in collection "${typedResult.collectionName}" (ID: ${typedResult.variableId})`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error setting variable: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } ); - Zod schema definition for the 'set_variable' tool inputs: collectionId (optional), collectionName (optional), name (required), resolvedType (enum: COLOR/FLOAT/STRING/BOOLEAN), value (any), modeId (optional).
{ collectionId: z.string().optional().describe("ID of an existing variable collection"), collectionName: z.string().optional().describe("Name for a new collection (used if collectionId not provided)"), name: z.string().describe("Variable name"), resolvedType: z.enum(["COLOR", "FLOAT", "STRING", "BOOLEAN"]).describe("Variable type"), value: z.any().describe("Variable value. COLOR: {r,g,b,a} (0-1). FLOAT: number. STRING: string. BOOLEAN: boolean."), modeId: z.string().optional().describe("Mode ID to set the value for (uses default mode if omitted)"), - src/talk_to_figma_mcp/tools/variable-tools.ts:41-83 (registration)Registration of the 'set_variable' tool via server.tool() inside registerVariableTools(server), which is called from registerTools(server) in server.ts.
// Set Variable Tool server.tool( "set_variable", "Create or update a variable in a Figma variable collection. Creates the collection if collectionName is provided and it doesn't exist.", { collectionId: z.string().optional().describe("ID of an existing variable collection"), collectionName: z.string().optional().describe("Name for a new collection (used if collectionId not provided)"), name: z.string().describe("Variable name"), resolvedType: z.enum(["COLOR", "FLOAT", "STRING", "BOOLEAN"]).describe("Variable type"), value: z.any().describe("Variable value. COLOR: {r,g,b,a} (0-1). FLOAT: number. STRING: string. BOOLEAN: boolean."), modeId: z.string().optional().describe("Mode ID to set the value for (uses default mode if omitted)"), }, async ({ collectionId, collectionName, name, resolvedType, value, modeId }) => { try { const result = await sendCommandToFigma("set_variable", { collectionId, collectionName, name, resolvedType, value, modeId, }); const typedResult = result as { variableId: string; variableName: string; collectionName: string }; return { content: [ { type: "text", text: `Set variable "${typedResult.variableName}" in collection "${typedResult.collectionName}" (ID: ${typedResult.variableId})`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error setting variable: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } ); - Type definition: 'set_variable' is included as a valid value in the FigmaCommand union type, ensuring type safety for commands sent via WebSocket.
| "set_variable" - The sendCommandToFigma helper function used by the set_variable handler to send the command string 'set_variable' via WebSocket to the Figma plugin server.
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)); }); }