set_text_content
Modify text content in Figma designs by updating existing text nodes with new text values through programmatic control.
Instructions
Set the text content of an existing text node in Figma
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the text node to modify | |
| text | Yes | New text content |
Implementation Reference
- src/cursor_mcp_plugin/code.js:1116-1150 (handler)Handler function for 'set_text_content' command. Validates input, retrieves text node, loads font, calls setCharacters helper to update text content, and returns updated node info.async function setTextContent(params) { const { nodeId, text } = params || {}; if (!nodeId) { throw new Error("Missing nodeId parameter"); } if (text === undefined) { throw new Error("Missing text parameter"); } const node = await figma.getNodeByIdAsync(nodeId); if (!node) { throw new Error(`Node not found with ID: ${nodeId}`); } if (node.type !== "TEXT") { throw new Error(`Node is not a text node: ${nodeId}`); } try { await figma.loadFontAsync(node.fontName); await setCharacters(node, text); return { id: node.id, name: node.name, characters: node.characters, fontName: node.fontName, }; } catch (error) { throw new Error(`Error setting text content: ${error.message}`); } }
- src/talk_to_figma_mcp/server.ts:875-909 (registration)MCP tool registration for 'set_text_content' including input schema (nodeId, text) and handler that forwards to Figma plugin via sendCommandToFigma.server.tool( "set_text_content", "Set the text content of an existing text node in Figma", { nodeId: z.string().describe("The ID of the text node to modify"), text: z.string().describe("New text content"), }, async ({ nodeId, text }) => { try { const result = await sendCommandToFigma("set_text_content", { nodeId, text, }); const typedResult = result as { name: string }; return { content: [ { type: "text", text: `Updated text content of node "${typedResult.name}" to "${text}"`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error setting text content: ${error instanceof Error ? error.message : String(error) }`, }, ], }; } } );
- Core helper function setCharacters used by setTextContent to handle font loading (with mixed font strategies) and setting node.characters safely.export const setCharacters = async (node, characters, options) => { const fallbackFont = options?.fallbackFont || { family: "Roboto", style: "Regular", }; try { if (node.fontName === figma.mixed) { if (options?.smartStrategy === "prevail") { const fontHashTree = {}; for (let i = 1; i < node.characters.length; i++) { const charFont = node.getRangeFontName(i - 1, i); const key = `${charFont.family}::${charFont.style}`; fontHashTree[key] = fontHashTree[key] ? fontHashTree[key] + 1 : 1; } const prevailedTreeItem = Object.entries(fontHashTree).sort( (a, b) => b[1] - a[1] )[0]; const [family, style] = prevailedTreeItem[0].split("::"); const prevailedFont = { family, style, }; await figma.loadFontAsync(prevailedFont); node.fontName = prevailedFont; } else if (options?.smartStrategy === "strict") { return setCharactersWithStrictMatchFont(node, characters, fallbackFont); } else if (options?.smartStrategy === "experimental") { return setCharactersWithSmartMatchFont(node, characters, fallbackFont); } else { const firstCharFont = node.getRangeFontName(0, 1); await figma.loadFontAsync(firstCharFont); node.fontName = firstCharFont; } } else { await figma.loadFontAsync({ family: node.fontName.family, style: node.fontName.style, }); } } catch (err) { console.warn( `Failed to load "${node.fontName["family"]} ${node.fontName["style"]}" font and replaced with fallback "${fallbackFont.family} ${fallbackFont.style}"`, err ); await figma.loadFontAsync(fallbackFont); node.fontName = fallbackFont; } try { node.characters = characters; return true; } catch (err) { console.warn(`Failed to set characters. Skipped.`, err); return false; } };