3. Figma MCP tools

This section lists every Figma MCP tool and what ud does with it.

This section lists every Figma MCP tool and what ud does with it. Parameters are Figma’s. Where ud adds an optional parameter it is marked ud. The schemas served by ud schema <tool> and by ud mcp are the compatibility contract tested by SRS CMD-8: each is Figma’s schema for the tool, and the test accepts only these differences (review decision D8):

  • extra parameters, all optional, marked ud below;
  • the pattern of fileKey and nodeId, and of every other property that carries a node id, array items included (nodeIds[], mappings[].nodeId, currentPageId, …), so that native ids (section 2.3) pass;
  • the pattern of planKey, so that ud::local passes (Figma’s is ^(team|organization)::\d+$);
  • fileKey dropped from required when ud mcp --file is set (section 8). Without --file it stays required, as in Figma.

Everything else — tool names, descriptions, parameter names, types and the required lists — is Figma’s.

Tool Reads / writes M
use_figma writes 0.1
get_metadata reads 0.1
create_new_file writes 0.1
whoami reads 0.1
get_screenshot reads 0.2
upload_assets writes 0.2
download_assets reads 0.2
get_variable_defs reads 0.4
search_design_system reads 0.4
get_libraries reads 0.4
get_motion_context reads 0.5
get_design_context reads 0.6
Code Connect tools both 0.6
generate_figma_design writes 0.8
Unsupported tools — —

3.1 use_figma#

Runs a script against the document with the figma global (section 4).

Parameter Type Req. Meaning
fileKey string yes¹ The file (section 2.2).
code string ≤ 50 000 chars yes JavaScript. Top-level await is allowed.
description string ≤ 2 000 chars yes What the script does. Becomes the undo label and the event group’s note.
skillNames string no Skills being followed, comma-separated. Logged with the run.
timeoutMs ud integer no Default 30 000, maximum 300 000.
dryRun ud boolean no Run, report, apply nothing.

¹ Required by the schema, as in Figma. On the command line it can be left out when section 2.2 resolves it; under ud mcp --file it becomes optional in the schema too. The same applies to fileKey in every tool below.

The call is atomic (SRS CMD-12): if the script throws or hits a limit, nothing is applied. The result is one text content item with a JSON object:

json
{
  "result": { "frameId": "nd-3f9a0c1e7b2d" },
  "createdNodeIds": ["nd-3f9a0c1e7b2d", "nd-91c0d4e2aa17"],
  "changedNodeIds": [],
  "removedNodeIds": [],
  "logs": ["Built login frame"],
  "events": { "from": 412, "to": 431 },
  "durationMs": 38
}

result is the script’s return value, serialised as JSON. Nodes become { "id", "name", "type" }, and figma.mixed becomes "<mixed>". On error the content has isError: true and the text is

text
Error at line 14, column 9: UnsupportedApiError: figma.createSlice is not supported by UI Designer yet
(planned for 0.2). No changes were applied.

Shell example:

sh
ud use_figma designs/app.design --description "Add a card" --code '
  const card = figma.createFrame();
  card.name = "Card";
  card.layoutMode = "VERTICAL";
  card.itemSpacing = 12;
  card.paddingTop = card.paddingBottom = card.paddingLeft = card.paddingRight = 24;
  card.fills = [{ type: "SOLID", color: { r: 1, g: 1, b: 1 } }];
  figma.currentPage.appendChild(card);
  return { id: card.id };
'

3.2 get_metadata#

Parameter Type Req. Meaning
fileKey string yes
nodeId string no A node or page. Left out: the list of pages.
depth ud integer no Limit the XML depth. Default unlimited.

Returns the same sparse XML as Figma: element per node, named by type, with id, name, x, y, width, height, and hidden="true" when invisible. When the live editor has a selection, the response starts with a Currently selected nodes: block, as Figma’s does.

xml
<frame id="nd-3f9a0c1e7b2d" name="Login" x="0" y="0" width="390" height="844">
  <text id="nd-91c0d4e2aa17" name="Title" x="24" y="96" width="342" height="36" />
  <instance id="nd-c2e8a1f0937b" name="Button" x="24" y="720" width="342" height="48" />
</frame>

Without nodeId: [{ "id": "pg-0b44e1d2a9c3", "name": "Screens" }, …]. An unknown nodeId returns an error that includes this list. The native form with more detail is ud tree (section 5.3).

3.3 create_new_file#

Parameter Type Req. Meaning
fileName string yes File name without extension.
editorType design | figjam | slides yes Only design is supported; the others exit 6.
planKey string yes¹ Accepted and ignored. whoami returns ud::local to pass here; the schema’s pattern allows it (D8).
projectId string no A folder relative to the workspace, where the file is created.
template ud string no blank (default), mobile, web, desktop, design-system (SRS PLT-7).

¹ Required by the schema, as in Figma; any value is accepted.

Result: { "fileKey": "designs/login.design", "url": "ud://designs/login.design", "documentId": "doc-…" }. The file is opened in VS Code when a window is reachable through the bridge, unless --no-open.

3.4 whoami#

No parameters. Result:

json
{
  "handle": "Claude",
  "email": null,
  "plans": [{ "key": "ud::local", "name": "UI Designer Pro", "seat": "edit" }],
  "actor": "Claude",
  "licence": { "plan": "pro", "state": "active", "offlineGraceUntil": "2026-10-13T09:00:00.000Z" }
}

seat is edit with a paid plan or the trial, otherwise view.

3.5 get_screenshot#

Parameter Type Req. Meaning
fileKey string yes
nodeId string yes
maxDimension integer no Longer edge in px, default 1024.
contentsOnly boolean no Render the node in isolation.
enableBase64Response boolean no Also inline the PNG as an image content item.
mode ud string no Variable mode(s) to render with, e.g. Theme=Dark.
out ud path no Write the PNG here (CLI default: a temporary file).

The result has a JSON item { width, height, original_width, original_height, path, url }, and curl instructions like Figma’s. url is a single-use loopback URL (SRS CMD-5) when a server is running to answer it: the extension host when the call goes through the bridge, or ud mcp while it runs (section 3.16). A one-shot headless ud get_screenshot exits before anyone could fetch the URL, so it returns url: null and the file at path; on the command line it prints the path. The native form with more options is ud render (section 5.4).

3.6 upload_assets#

Parameter Type Req. Meaning
fileKey string yes
count integer 1–60 no Number of upload URLs to return. Default 1.
nodeIds string[] no Target node per URL: the image becomes its fill.
nodeId string no Deprecated in Figma; still accepted when count is 1.
scaleMode FILL | FIT | TILE no Default FILL.
currentPageId string no Page for new frames when there is no target.
batchCommit boolean no Commit all uploads once, through the returned commitUrl.
paths ud string[] no Local files or URLs to upload directly, instead of the URL protocol.

As in Figma, the result lists single-use upload URLs: http://127.0.0.1:<port>/u/<token>. A POST of the raw bytes with the right Content-Type stores the image in <name>.design.assets/ and places it. PNG, JPEG, GIF and WebP become image fills (on the target, or on a new frame of the image’s size). SVG becomes editable vectors. The limit is 10 MB per asset. On the command line, ud upload_assets --paths hero.png logo.svg does it in one step.

The URL protocol needs a server that stays up to receive the POST (section 3.16): the extension host when bridged, or ud mcp while it runs. A one-shot headless ud upload_assets has nobody to serve the URLs, so there --paths is required; without it the command exits 2 (usage) with that hint. Under ud mcp --proposal the entries of paths must be local files; URLs are refused (section 8).

3.7 download_assets#

Parameter Type Req. Meaning
fileKey string yes
nodeId string yes
defaultFormat png | jpg | svg | pdf no Overrides the node’s export settings.
defaultScale number 0.01–4 no Overrides the node’s export settings.
out ud path no Folder to write into.

Result, as in Figma: export (render of the node), rawImages (original source images of fills in the subtree, with format, at most 20) and svgAssets (vector layers best shipped as SVG, at most 20). Each entry has a local path and a loopback url; as for get_screenshot, url is null from a one-shot headless command and set only while a server runs (section 3.16).

3.8 get_variable_defs#

Parameter Type Req.
fileKey string yes
nodeId string yes
mode ud string no

Returns the variables and styles used by the node and its subtree, resolved for the node’s mode (or mode), as Figma’s flat map: { "color/surface": "#FFFFFF", "space/4": "16", "Heading/H1": "Font(family: Inter, style: Bold, size: 32, lineHeight: 40)" }. With --json and --detail ud, each entry also has the variable id, collection, all mode values and the code syntax.

3.9 search_design_system#

Parameter Type Req. Meaning
fileKey string yes
queries { entity: "component" | "variable" | "style", query }[] yes One search intent each.
includeLibraryKeys string[] no Restrict to these libraries (keys from get_libraries).
disableCodeConnect boolean no Leave code-map information out of the results.

Searches the file’s own components, variables and styles and those of every library the file can use (SRS VAR-7). Matches are ranked by name, description, aliases and usage count. Results come in the same order as queries. Each match has key (usable with figma.importComponentByKeyAsync and figma.variables.importVariableByKeyAsync), name, description, libraryKey, libraryName, variant properties for component sets, the resolved value for variables, and the code-map entry when there is one.

3.10 get_libraries#

Parameter Type Req.
fileKey string yes
offset integer no

The result keeps Figma’s shape. libraries_added_to_file: libraries the file uses. libraries_available_to_add: other .design files of the workspace that publish a library (SRS VAR-7), plus libraries listed in the ud.libraries setting, 50 per page. When more remain, libraries_available_to_add_next_offset is the offset for the next call. Each library has name, libraryKey (the library document id), description, sourceType (workspace or setting) and path.

3.11 get_motion_context#

Parameter Type Req.
fileKey, nodeId string yes
recursive boolean no
clientFrameworks, clientLanguages string no

Returns smart-animate transitions and prototype animations of the node (SRS PRO-4) as keyframe tracks with easing, CSS @keyframes and motion.dev snippets, and the coordination hints described in Figma’s documentation.

3.12 get_design_context#

Parameter Type Req. Meaning
fileKey, nodeId string yes
clientFrameworks string no e.g. react, vue, html, swiftui, compose, web-components. Chooses the generator.
clientLanguages string no e.g. typescript, css.
excludeScreenshot boolean no
forceCode boolean no Return code even when it is large.
disableCodeConnect boolean no Ignore the code map.
skillNames string no Logged.

Returns reference code for the node, written by the generators of SRS DEV-2. The default is React with Tailwind, as in Figma. Instances that have a code-map entry (SRS DEV-4) are emitted as the mapped component with its props. Variables appear as their code syntax. The result also has a screenshot and the assets the code refers to, each with a local path and a loopback url that is set only while a server runs (section 3.16). When the code would exceed 40 000 characters and forceCode is not set, the result is the get_metadata outline with a note to call the tool on child nodes, as Figma does.

3.13 Code Connect tools#

They read and write the code map of SRS DEV-4. The code map is stored in the file (codeMap of components) and can be overridden by the ud.codeMap setting.

Tool Parameters Effect
get_code_connect_map fileKey, nodeId, codeConnectLabel { [nodeId]: { codeConnectSrc, codeConnectName, snippet?, label } } for instances under the node.
add_code_connect_map fileKey, nodeId, source, componentName, label, template, templateDataJson Adds or replaces a mapping of the component (or the main component of an instance).
get_code_connect_suggestions fileKey, nodeId, excludeMappingPrompt Scans the workspace (TS/JS exports, custom-element registrations, SwiftUI views) and proposes mappings with confidence.
send_code_connect_mappings fileKey, nodeId, mappings[], clientFrameworks, clientLanguages Saves several mappings in one transaction.
get_context_for_code_connect fileKey, nodeId Component properties with types and variant options, and the tree of nested instances and text bound to properties.
list_file_components_for_code_connect fileKey All published components and sets with properties, instance counts and dependencies.

label takes Figma’s values (React, Web Components, Vue, SwiftUI, Compose, …). template is stored and used by get_design_context when it renders a mapped instance.

3.14 generate_figma_design#

Captures a web page into frames, as Figma’s code-to-canvas does, using the HTML import of SRS EXP-6. The parameters are Figma’s. The capture runs locally through the Browser DevTools extension or a local headless Chromium. Figma’s clipboard output mode is not supported: the target is always a file.

3.15 Unsupported tools#

get_figjam, generate_diagram, generate_image, export_video, list_shaders, get_shader, create_shader, update_shader, list_file_shaders, list_generative_plugins, get_generative_plugin, create_generative_plugin, update_generative_plugin, html_to_figma (use generate_figma_design or ud import html) and the weave_* tools are not served by ud mcp. Called through ud, they exit 6 with a hint, for example: generate_diagram is a FigJam tool. UI Designer designs interfaces; for diagrams use Software Board (uml).

3.16 Loopback URLs#

get_screenshot, download_assets, the assets of get_design_context and the upload URLs of upload_assets keep Figma’s URL protocol so that Figma’s skills work unchanged (review decision D7). The URLs are served by a small HTTP server that exists only while something is running to own it:

How ud runs Who serves the URLs url in results
Through the bridge to a live editor The extension host set
ud mcp The ud mcp process, for as long as it runs set
One-shot headless command (no live editor, no ud mcp) Nobody; the process exits before a fetch could arrive null; use path

Every result that carries a url also carries a local path, and the local path is what a headless script should use. upload_assets headless needs --paths (section 3.6).

Hardening, specified in ARC-001 §9.6 and SRS NFR-4: the server binds 127.0.0.1 only; the Host header must match the address it was given out with, otherwise the request is dropped; requests that carry an Origin header are rejected, so a browser page cannot reach it; bodies are capped at 10 MB; each URL holds a random 128-bit token that is valid for one request and for 10 minutes, after which it answers 404.