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
patternoffileKeyandnodeId, 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
patternofplanKey, so thatud::localpasses (Figma’s is^(team|organization)::\d+$); fileKeydropped fromrequiredwhenud mcp --fileis set (section 8). Without--fileit 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:
{
"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
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:
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.
<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:
{
"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.