figmcp
figmcp is a local MCP server that connects a coding agent to the Figma file open in Figma Desktop over localhost (no Figma REST API, tokens, or rate limits), for design-to-code and code-to-design workflows.
Generate code from designs —
get_design_contextturns a selected frame or node into Flutter widgets, React + Tailwind, or HTML + Tailwind, plus assets, a screenshot (unless excluded), variables, and reference code to adapt.Inspect structure and tokens —
get_metadatareturns the layer tree as XML (ids, types, names, positions, sizes);get_variable_defsreturns variables and styles resolved for the node's mode.Capture visuals and assets —
get_screenshotrenders a PNG (local URL/path, optional base64),download_assetsexports renders, original image fills, and vector SVGs.Design inside Figma —
use_figmaruns Figma plugin API scripts to create and edit frames (one undo step per script), andplace_imageinserts local PNG/JPG/GIF/SVG files as layers or fills.Reuse the design system —
search_design_systemfinds local and used library components (with properties/variants), styles, and variables before designing.Map components to code —
add_code_connect_map,get_code_connect_map, andremove_code_connect_maplink design components to code components via.figma-local/code-connect.json.Verify generated code —
verify_coderenders Flutter or React/HTML and diffs it against Figma's render, reporting analyzer/runtime errors, pixel differences, and a diff image.Work offline via snapshots —
save_design_exportwrites a full design export JSON,import_design_exportloads one as a snapshot, and reads fall back to saved snapshots when the plugin is closed.Check connection state —
whoamireports plugin connection, pairing code, open file, page, selection, project, Code Connect file, and snapshots.
Enables reading and writing Figma design files via a local Figma Desktop plugin, including design context extraction, screenshots, asset downloads, design creation/editing, and Code Connect mappings.
figmcp is a local MCP server that gives your coding agent the Figma file you have open in Figma Desktop. A development plugin streams the file to a server on your machine over localhost, so reads never touch the Figma REST API: no access token, no quota, no rate limit.
Design to code. Flutter widgets for Flutter projects, HTML + Tailwind for static sites, React + Tailwind for everything else, with the assets and a screenshot to compare against.
Design in Figma. The agent creates and edits frames in the open file with Figma plugin API scripts, one undo step per script.
Your components. Map design components to code components with Code Connect.
Works offline. Read saved snapshots when the plugin is closed.
Any plan. Works on every Figma plan, including the free Starter plan. No Dev Mode seat needed.
Works with Claude Code, Cursor, Claude Desktop and any MCP client that runs stdio servers.
Quick start
Needs Node.js 18+ and Figma Desktop on macOS or Windows.
1. Run setup
npx -y @irshad.io/figma-local-mcp@latest setupIt registers the server with Claude Code, copies the Figma plugin to your home folder, and prints your pairing code and the config for other MCP clients.
2. Import the plugin (once)
In Figma Desktop, go to Plugins › Development › Import plugin from manifest… and choose:
macOS | Windows |
|
|
On macOS, press ⌘ ⇧ G in the file picker and paste the path. On Windows, paste it into the File name box.
3. Pair and ask
Restart your coding agent. In Figma Desktop, run Plugins › Development › figmcp and enter the pairing code. The dot turns green once it's connected. Then select a frame and ask:
implement the selected Figma frameKeep the plugin window open while you work. Full guide: figmcp.web.app/docs/installation.
Related MCP server: Figma Bridge MCP
Usage
Design to code
Select a frame, or paste a Figma link that has a node-id:
implement this frame as a Flutter screen and match the spacing exactly
build this frame as a React component with Tailwind, using our existing Button
compare your screen with the Figma screenshot and fix the differencesProjects with a pubspec.yaml get Flutter widgets, and SVGs and images are saved into the asset folders the pubspec declares. Static sites get HTML + Tailwind, and everything else gets React + Tailwind. React output uses the real font families, declares the design's variables as CSS (with a Tailwind 4 @theme), writes repeated items as data with .map() and names reused text styles, names assets after their layers with copy commands for public/figma, turns prototype taps, layer names and placeholders into buttons, links, landmarks and inputs, draws phone frames as screens that fill the viewport and desktop frames as pages whose full-width sections stretch. Its classes work in Tailwind 3.4 and 4. The code is a reference that your agent adapts to your project. More →
Design in Figma
Open the file in Figma Desktop, run the plugin and ask:
design a settings screen for a 390x844 phone in Figma
add a dark mode version of the selected frame next to itThe agent builds the design with use_figma and checks each step with a screenshot. Each script is one undo step. More →
Code Connect
map the selected button to AppButton in lib/widgets/app_button.dart
which components in this frame are not mapped yet?Mapped instances come back as your own components. Mappings are saved in .figma-local/code-connect.json in your project. More →
MCP clients
Claude Code is registered by setup. Restart it and check with /mcp.
Cursor, Claude Desktop and other clients: add the config that setup prints. It looks like this, with paths for your machine:
{
"mcpServers": {
"figma-local": {
"command": "/usr/local/bin/node",
"args": ["/Users/you/.figma-local-mcp/app/node_modules/@irshad.io/figma-local-mcp/bin/figma-local-mcp.js"]
}
}
}Client | Config file |
Cursor |
|
Claude Desktop (macOS) |
|
Claude Desktop (Windows) |
|
Step-by-step for each client, on macOS and Windows: figmcp.web.app/docs/configuration.
Tools
Tool | What it does |
| Reference code (Flutter or React + Tailwind), assets, a screenshot and variables for a node. The main tool. |
| Layer tree as XML: ids, types, names, positions and sizes. |
| PNG of a node or the selection. |
| Variables and styles used by a node, resolved for its mode. |
| Exported renders, original image fills and vector SVGs. |
| Render Flutter code with |
| Run Figma plugin API scripts to create and edit designs. |
| Components (with properties and variants), styles and variables of the open file, to reuse while designing. |
| Put a local PNG, JPG, GIF or SVG into the open file, as a new layer or a layer's fill. |
| Which instances map to which code components. |
| Map a design component to a code component. |
| Remove a component mapping. |
| Connection status, pairing code, open file, selection and snapshots. |
| Write a full design export of a node to JSON. |
| Load an export JSON as a snapshot. |
Arguments for each tool: figmcp.web.app/docs/tools.
How it works
Figma Desktop ── WebSocket 127.0.0.1:3947 ──▶ figma-local-mcp ── MCP stdio ──▶ Coding agent
(dev plugin) paired with your code (node server) (Claude Code, Cursor, …)The plugin reads the open file with the Figma plugin API and runs the scripts your agent sends. The server turns that into code, assets, screenshots and metadata. When the plugin is closed, reads fall back to the newest saved snapshot. More →
Configuration
Set these in the env of your MCP client config.
Variable | Default | Description |
|
| Data folder: plugin, pairing code, snapshots and assets. |
| Force | |
|
| Path of the Code Connect mappings file. |
| Comma separated extra origins the server accepts for the plugin. |
Update
npx -y @irshad.io/figma-local-mcp@latest setupThen restart your coding agent and run the plugin again. The plugin updates itself, so there's no need to import it again.
Troubleshooting
The dot stays grey: start your coding agent first, then run the plugin again.
Lost the pairing code: run setup again, or ask your agent to run
whoami.use_figmacan't edit the file: switch the file from Dev Mode back to Design mode.
More fixes: figmcp.web.app/docs/troubleshooting. Still stuck? Open an issue with the output of whoami.
Development
npm install
npm testPath | What |
| The MCP server, plugin bridge and code generators |
| The Figma development plugin |
| Visual and Flutter checks for generated code |
| Tests ( |
| The website and docs (figmcp.web.app), Next.js on Firebase Hosting |
To work on the site: cd web && npm install && npm run dev. To publish it: npm run deploy.
License
Figma is a trademark of Figma, Inc. This project is not affiliated with Figma, Inc.
Available Tools
15 toolsadd_code_connect_mapAdd Code Connect MappingAIdempotent
Map a design component to a code component, so get_design_context names the code component for every instance of it. Pass an instance, component or component set id; a component in a set maps the whole set.
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | Framework, e.g. Flutter or React. | |
| nodeId | Yes | The ID of the node, eg. "123:456" or "123-456" (instance ids like "I1:2;3:4" work too). Omit it to use the current selection in Figma. | |
| source | Yes | Path of the code component in the project. | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. | |
| componentName | Yes | Code component name, e.g. AppPrimaryButton. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotent=true, destructive=false, and closed-world, so the safety profile is covered. The description adds a genuinely non-obvious behavioral trait beyond that: mapping a component inside a set maps the whole set. It doesn't disclose overwrite/conflict behavior, but given annotations carry the safety burden, this addition earns above baseline.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the action and its effect, followed by the ID guidance. No filler; every clause informs invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description needn't explain returns. For a mutation tool it covers the effect and the ID semantics well, leaving only edge behavior (overwriting an existing mapping, conflict handling) unspecified, which is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description nevertheless adds meaning the schema lacks: it clarifies that nodeId accepts instance, component, or component-set IDs and that a component within a set maps the entire set, which is not stated in the schema's nodeId description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (map) with both resources (design component -> code component) and the downstream effect (get_design_context names the code component). It is clearly the 'add' counterpart to the sibling get_code_connect_map/remove_code_connect_map, though it never names them explicitly, so an agent infers the distinction rather than being told it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The clause 'Pass an instance, component or component set id' gives usage context on what to supply, and the effect clause implies why you'd use it. But there is no explicit when-to-use vs the sibling get_code_connect_map or remove_code_connect_map, and no stated preconditions. Usage is implied, not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
download_assetsDownload AssetsARead-only
Download assets for a single node: an exported render (export), the original images used as fills (rawImages, up to 20) and SVGs of the vector layers (svgAssets, up to 20). defaultFormat and defaultScale set the export format (png, jpg, svg, pdf) and scale (default png at 1).
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | No | The ID of the node, eg. "123:456" or "123-456" (instance ids like "I1:2;3:4" work too). Omit it to use the current selection in Figma. | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. | |
| defaultScale | No | ||
| defaultFormat | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint/openWorldHint, so the description usefully adds the payload composition (three asset categories), the per-category cap of 20, and the default format/scale behavior. It still does not say where the downloaded files land or what happens when a node has more than 20 fills, which is the remaining behavioral gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences with the returned asset categories front-loaded and the format/scale controls second. The format list partially duplicates the schema enum, which is the only minor redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-shape burden and does so by naming the three asset groups and their limits. It omits the current-selection fallback for nodeId and any note that fileKey is ignored in practice, but the core call path is covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: nodeId and fileKey are documented in-schema, while defaultFormat and defaultScale are not. The description fills that gap by naming the accepted formats (png, jpg, svg, pdf) and stating the default (png at scale 1), so it compensates for the undocumented parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Download) and resource (assets for a single node) and enumerates exactly what comes back: export, rawImages, svgAssets with caps. It is clear what the tool does, though it never differentiates itself from close siblings like get_screenshot or save_design_export.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'for a single node' implies the scope of use and the cap of 20 per asset type hints at bulk behavior, but there is no explicit when-to-use guidance or comparison to get_screenshot / save_design_export / import_design_export. Usage is inferable but not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_code_connect_mapGet Code Connect MappingARead-only
Get the mapping from the component instances in a node to code components: { nodeId: { codeConnectName, codeConnectSrc, label } }, plus the components that are not mapped yet. Mappings live in the project (.figma-local/code-connect.json under the working directory).
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | No | The ID of the node, eg. "123:456" or "123-456" (instance ids like "I1:2;3:4" work too). Omit it to use the current selection in Figma. | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds useful context beyond them: where mappings are persisted (.figma-local/code-connect.json under the working directory) and the exact return shape. It stops short of describing behavior when no mapping exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the verb and result, then the storage location. The inline object shape is dense but informative; nothing is wasted, though the second sentence could be tighter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by outlining the returned map structure and the 'not mapped yet' list, plus the storage location. It is nearly complete for a read tool; only edge-case behavior (empty results, missing file) is unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (nodeId, fileKey, including the fileKey compatibility caveat) are already fully documented in the schema. The description adds nothing about parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get the mapping from the component instances in a node to code components') and even spells out the returned shape. It is clearly distinguished from its add_code_connect_map/remove_code_connect_map siblings by naming the exact resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: mentioning that it also returns 'the components that are not mapped yet' hints at the discovery use case, but there is no explicit when-to-use or when-not-to-use guidance, nor a pointer to add_code_connect_map for creating mappings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_design_contextGet Design ContextARead-only
Get design context for a Figma node — the primary tool for design-to-code workflows. Returns reference code (Flutter widgets for Flutter projects, HTML + Tailwind for static sites, React + Tailwind otherwise), the assets it uses, a screenshot and the variables in the node. The code must be adapted to the target project. Use the nodeId parameter to specify a node id; from a URL like https://figma.com/design/:fileKey/:fileName?node-id=1-2 the node id is 1:2. With no nodeId the current selection in Figma is used. Large nodes return metadata instead of code unless forceCode is set.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | React and HTML: draw the node as a web page that fills the viewport, never narrower than the design, with full-width sections stretching (default: frames 768 or more wide). | |
| nodeId | No | The ID of the node, eg. "123:456" or "123-456" (instance ids like "I1:2;3:4" work too). Omit it to use the current selection in Figma. | |
| screen | No | Draw the node as a phone screen that fills the screen and scrolls when tall (default: portrait frames 300-480 wide). | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. | |
| assetsDir | No | Folder of the asset files in the code. Flutter default: the svg/png/images folders of the project's pubspec.yaml, else assets/figma. React default: public/figma (static/figma for SvelteKit), loaded by URL (/figma/name.svg). HTML default: assets/figma, relative to the page. | |
| forceCode | No | Always return code, even for very large nodes. | |
| framework | No | Code to generate: react, html or flutter. Default: from clientFrameworks / clientLanguages, else FIGMA_LOCAL_MCP_FRAMEWORK, else flutter when the project has a pubspec.yaml, html for a static site (index.html without package.json), else react. | |
| screenUtil | No | Flutter: write lengths with flutter_screenutil (.w, .h, .r, .sp) so the layout scales from the design size (default: when the project's pubspec.yaml depends on flutter_screenutil). | |
| skillNames | No | Accepted for compatibility (logging only). | |
| clientLanguages | No | Comma separated languages of the client, e.g. "dart" (picks the framework). | |
| clientFrameworks | No | Comma separated frameworks of the client, e.g. "flutter" (picks the framework). | |
| excludeScreenshot | No | Leave the screenshot out of the response. | |
| disableCodeConnect | No | Draw mapped components from their layers instead of naming the code component. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover only readOnlyHint/openWorldHint, yet the description discloses the substantive behaviors an agent needs: output varies by framework, the code is reference-only and 'must be adapted,' large nodes degrade to metadata unless forceCode is set, and the response bundles assets/screenshot/variables. These are non-obvious runtime traits well beyond the annotation layer.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the purpose and return contents, then moves to invocation mechanics (nodeId/selection) and the large-node caveat. Every sentence carries information – no restatement of the title and no filler – despite covering a lot of ground.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 13 parameters, zero required fields and no output schema, the description carries the burden of explaining the response and does so (code flavor by framework, assets, screenshot, variables, metadata fallback). An agent has enough to invoke it correctly without the schema filling gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the 13 parameters are already documented and a baseline of 3 applies. The description adds genuine value on top, notably the URL-to-nodeId mapping convention (node-id=1-2 → 1:2) and the selection-default and forceCode override behaviors, which go beyond the raw schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with a specific verb+resource ('Get design context for a Figma node') and immediately positions it as 'the primary tool for design-to-code workflows,' which distinguishes it from get_metadata, get_screenshot and get_variable_defs. It then enumerates exactly what comes back (reference code, assets, screenshot, variables), so an agent knows its role without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operative conditions: how to derive nodeId from a Figma URL, and that omitting nodeId falls back to the current selection. The 'primary tool for design-to-code workflows' framing tells the agent when to reach for it, but it never names an alternative (e.g. get_screenshot when only an image is needed) or a when-not-to-use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_metadataGet MetadataARead-only
IMPORTANT: Always prefer to use get_design_context. Get metadata for a node or page in XML format: node IDs, layer types, names, positions and sizes, useful for an overview of the structure. nodeId can be a page id (e.g. 0:1). When nodeId is omitted, returns the pages of the document (and saved snapshots) instead. When something is selected in Figma, the response starts with a "Currently selected nodes:" block.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | No | The ID of the node, eg. "123:456" or "123-456" (instance ids like "I1:2;3:4" work too). Omit it to use the current selection in Figma. | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered; the description adds real behavioral detail beyond them — the XML response format, the 'Currently selected nodes:' prefix when a selection exists in Figma, and the different return shape when nodeId is omitted. It stops short of describing size limits or truncation on very large documents.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the most decision-relevant instruction (prefer get_design_context) before any detail, then progressively adds payload contents and edge cases. Every sentence carries distinct information; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the full burden of explaining returns - XML format, field contents, the selection block, and the pages/snapshots fallback - and it does so. Combined with read-only annotations, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline would be 3, but the description adds meaning the schema lacks: nodeId may be a page id (e.g. 0:1), and omitting it returns the document's pages and saved snapshots rather than just a selection. That last point nuances the schema's simpler 'omit it to use the current selection' wording.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (get) and resource (metadata for a node or page) and enumerates the concrete payload: node IDs, layer types, names, positions, sizes, in XML format. It also names the sibling it should not be confused with (get_design_context), so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Opens with an explicit routing directive — 'Always prefer to use get_design_context' — naming the alternative and the condition that selects it (structural overview rather than design context). It also covers the fallback case when nodeId is omitted, so both usage paths are defined.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_screenshotGet ScreenshotARead-only
Generate a screenshot for a given node or the currently selected node in Figma. maxDimension (default 1024) caps the longer edge of the PNG (up to 2x the node size). The response gives a local URL and file path plus width/height and original_width/original_height. Set enableBase64Response to also get the image inline.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | No | The ID of the node, eg. "123:456" or "123-456" (instance ids like "I1:2;3:4" work too). Omit it to use the current selection in Figma. | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. | |
| contentsOnly | No | Render the node in isolation, without overlapping content. | |
| maxDimension | No | Longest edge of the PNG in pixels (default 1024). | |
| enableBase64Response | No | Also include the PNG inline as base64. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, and the description adds real behavior beyond that: maxDimension caps the longer edge and can reach up to 2x the node size, and the return payload contains a local URL, file path, and both rendered and original dimensions. It still doesn't disclose failure modes (e.g. node not found, oversized requests), which keeps it out of the top band.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, all front-loaded: what it does, the sizing control, the response shape, then the opt-in base64 flag. No sentence is redundant and no filler is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly compensates by enumerating the returned URL, file path, width/height, and original dimensions, and it notes that omitting nodeId falls back to the selection. It omits anything about the ignored fileKey or error behavior, but nothing essential to a correct call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters and the baseline is 3. The description adds one genuine detail not in the schema — that maxDimension may go up to 2x the node size — and explains what enableBase64Response produces, but otherwise restates the documented defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb+resource ("Generate a screenshot") and scope (a given node or the current selection in Figma), which is clearly distinct from siblings like get_metadata or get_design_context. It stops short of naming an alternative tool, so an agent still has to infer which read tool to pick.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by "for a given node or the currently selected node," which tells the agent the two invocation modes. There is no explicit when-to-use-this-vs-siblings guidance (e.g. versus download_assets or get_design_context), so routing remains inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_variable_defsGet Variable DefinitionsARead-only
Get variable definitions for a given node id. E.g. {'icon/default/secondary': #949494}. Variables and styles are reusable values applied to colours, fonts, sizes and spacings. Values resolve for the node's own mode. Read-only; with no nodeId it uses the selection. Use it for design tokens, and get_design_context for the layout. Without the plugin, a saved snapshot gives the raw values only, without names.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | No | The ID of the node, eg. "123:456" or "123-456" (instance ids like "I1:2;3:4" work too). Omit it to use the current selection in Figma. | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the description is not the sole source of the safety profile. It goes beyond that by disclosing mode resolution ('Values resolve for the node's own mode') and the plugin-absent fallback ('a saved snapshot gives the raw values only, without names'), which is real behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the verb+resource and the example, then layers behavior and routing. Every sentence contributes; it is a touch long but not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but the inline example gives the return shape and the fallback/snapshot caveat is covered. Adequate for a zero-required-param read tool, though return scale or edge cases are not addressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents nodeId's selection default and fileKey's compatibility note. The description restates 'with no nodeId it uses the selection' rather than adding new meaning, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Get variable definitions for a given node id'), gives a concrete example of the returned shape, and explicitly distinguishes itself from get_design_context ('Use it for design tokens, and get_design_context for the layout'). An agent can select this tool over siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the use case ('for design tokens') and the alternative ('get_design_context for the layout'), plus the default behavior with no nodeId. It provides clear context but no explicit when-not-to-use beyond the single sibling routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_design_exportImport Design ExportAIdempotent
Save a design export JSON (frames with node trees, as the plugin produces) as a snapshot, so its nodes can be read without the plugin. Use it for an export made earlier with save_design_export or the plugin. Copies the file into the local snapshot store, replacing an earlier snapshot of the same frames; the source file and the Figma file are not changed. Fails if the JSON is not a design export.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path of the export JSON file. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing what actually happens: the file is copied into a local snapshot store, an earlier snapshot of the same frames is replaced, the source file and Figma file are untouched, and it fails if the JSON is not a valid design export. This confirms and enriches the idempotentHint and non-destructive profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core purpose, then usage, behavioral effects, and failure mode in four tight sentences. Slightly long but each sentence carries distinct information; nothing is redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, no-output-schema tool with adequate annotations, the description covers purpose, sourcing, side effects, persistence semantics, and the failure condition. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single path parameter is fully documented in the schema. The description references 'the file' and 'the JSON' but adds no format or constraint detail beyond what the schema already provides, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action (save/import a design export JSON as a snapshot) and the resource (frames with node trees as the plugin produces). It clearly distinguishes itself from the sibling save_design_export by framing this as ingesting a previously made export rather than creating one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to use it for an export made earlier with save_design_export or the plugin, naming the relevant sibling and the condition that selects this tool. It stops short of stating when NOT to use it (e.g. point save_design_export at it if you have not exported yet), but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
place_imagePlace ImageA
Put an image file from this computer into the file open in Figma Desktop: a PNG, JPG or GIF becomes a rectangle with the image fill (or the fill of the layer nodeId), and an SVG becomes editable vector layers. Use it for the project's own assets (logos, icons, photos) while designing; use_figma with figma.createImageAsync(url) takes images from the web. The new layer goes into parentId (default: the current page, right of its content), sized by width/height (one keeps the aspect ratio; default: the image's own size). Images larger than 4096 px on a side are scaled down by Figma.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | ||
| y | No | ||
| name | No | Layer name (default: the file name). | |
| path | Yes | Path of the image file (absolute, or relative to the project). | |
| width | No | ||
| height | No | ||
| nodeId | No | Set the image as the fill of this layer instead of making a new one (not for SVG). | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. | |
| parentId | No | Frame or group to put the new layer in. | |
| keepFills | No | With nodeId: add the image above the existing fills instead of replacing them. | |
| scaleMode | No | How the image fills the layer (default FILL). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real behavior beyond the annotations: format-dependent results (PNG/JPG/GIF become an image-filled rectangle, SVG becomes editable vector layers), the 4096 px downscale by Figma, and default sizing/placement rules. It does not mention permission requirements or error conditions, and only implicitly conveys that targeting nodeId replaces existing fills rather than adding to them (fully spelled out only in the schema's keepFills description).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and then layered with usage and behavioral detail; every sentence carries information. The parenthetical clauses make it dense for a single paragraph, but there is little waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter mutation tool with no output schema and no nested objects, the description covers the essential creation/replacement behavior, format handling, defaults, and scaling limits. Remaining gaps (x/y, scaleMode, error behavior) are adequately documented in the schema or are minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 64% and the description compensates meaningfully for the undocumented parameters: it explains that width/height each keep the aspect ratio and default to the image's own size, and that parentId defaults to the current page right of its content. It does not cover x/y or scaleMode, but those gaps are small relative to the added sizing/placement semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb+resource ('Put an image file from this computer into the file open in Figma Desktop') and immediately names the sibling it is not for web-sourced images ('use_figma with figma.createImageAsync(url)'). An agent can distinguish it from use_figma, download_assets, and import_design_export without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly gives the when ('Use it for the project's own assets (logos, icons, photos) while designing') and names the alternative plus its selection condition ('use_figma with figma.createImageAsync(url) takes images from the web'). This is the routing information an agent needs, not an inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_code_connect_mapRemove Code Connect MappingADestructiveIdempotent
Remove the code component mapping saved by add_code_connect_map, so get_design_context stops naming that code component. Pass an instance, component or component set id. Only the local mapping file changes, never the design; returns how many mappings were removed (0 when none existed). Add it again with add_code_connect_map to undo.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the node, eg. "123:456" or "123-456" (instance ids like "I1:2;3:4" work too). Omit it to use the current selection in Figma. | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and idempotentHint=true, but the description adds the blast radius ('Only the local mapping file changes, never the design') and the return contract (count removed, 0 when none existed) – neither is derivable from annotations, and there is no output schema to carry the latter.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the action and its downstream effect before the operative details. Every clause carries unique information (sibling linkage, scope, return value, undo).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return semantics and the 0-when-none case; with annotations covering the safety profile, it adds scope and reversibility. Nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds real value by stating that instance, component, or component set IDs are acceptable, clarifying the semantics of nodeId's pattern. It does not explain fileKey's compatibility-only behavior, which the schema already covers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Remove the code component mapping') and ties it to named siblings: the mapping saved by add_code_connect_map, consumed by get_design_context. An agent can distinguish it from add_code_connect_map and get_code_connect_map without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives the condition that selects this tool (you want get_design_context to stop naming that code component) and the explicit reversal path ('Add it again with add_code_connect_map to undo'). It also states the accepted ID kinds, so the when-and-how is not left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_design_exportSave Design ExportAIdempotent
Write a full design export of a node (default: the selection) to a JSON file: the node tree with every layout, paint, text, variable, style, component and interaction detail, icon SVGs, renders of masked or rotated groups, image fills and a 2x preview. Mapped components carry their code component. Use it to hand a frame to a build script.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Absolute .json path to write (default: the data folder). | |
| nodeId | No | The ID of the node, eg. "123:456" or "123-456" (instance ids like "I1:2;3:4" work too). Omit it to use the current selection in Figma. | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a write (readOnlyHint=false), idempotent and non-destructive; the description goes beyond them by specifying exactly what is serialized (layout, paint, text, variables, styles, components, interactions, SVGs, masked/rotated renders, image fills, 2x preview) and that the default target is the selection. It omits overwrite/error behavior, but idempotentHint covers much of that risk.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, verb front-loaded, with the content enumeration kept as a single clause list rather than separate sentences. Nothing is redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema the description carries the return burden, and it does so by describing the written payload in detail. It does not state whether an existing file is overwritten or whether the directory must pre-exist, but for a 3-param, all-optional, idempotent write tool this is close to sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description restates the two defaults (selection, data folder) that the schema parameters already document, adding no new syntax, path-creation, or fileKey caveats beyond what is already present.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: 'Write a full design export of a node ... to a JSON file', and immediately enumerates the export's contents. It is clearly distinguishable from siblings like import_design_export (the inverse) and get_design_context without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use it to hand a frame to a build script' gives a concrete use context and the implicit default (current selection). It stops short of naming when NOT to use it or pointing to alternatives such as import_design_export or get_design_context, so it is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_design_systemSearch Design SystemARead-only
Search the design system of the file open in Figma Desktop: local components and component sets (with their properties and variant options), library components the file already uses (with an instance to copy), and local paint, text and effect styles and variables (with their default-mode values). Every word of query must appear in the name or description; leave it empty to list everything. Call it before designing with use_figma, and reuse what it finds: figma.getNodeByIdAsync(id) then component.createInstance(), instance.clone() for a library component, figma.getStyleByIdAsync and figma.variables.getVariableByIdAsync. Libraries the file does not use yet are not visible to the plugin; instancesNotScanned means the page was too large to look through all its instances. Needs the plugin and Design mode.
| Name | Required | Description | Default |
|---|---|---|---|
| kinds | No | What to search (default: all of components, styles, variables). | |
| limit | No | Most results per kind (default 50). | |
| query | No | Words to look for, e.g. "button primary". | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. | |
| allPages | No | Search components on every page, not just the current one (slower on large files). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give readOnlyHint=true and openWorldHint=false, but the description adds substantial context: libraries the file doesn't use are invisible to the plugin, instancesNotScanned signals pages too large to scan, and it requires the plugin and Design mode. It even discloses that fileKey is accepted for compatibility only, which is real behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the search scope, then query semantics, then the call-before-use_figma directive, then caveats. Efficient overall, but the embedded reuse instructions (figma.getNodeByIdAsync, component.createInstance, instance.clone, getStyleByIdAsync) are dense implementation detail that could be trimmed without losing selection value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by naming returnable entities, the IDs usable with the Figma API, and the instancesNotScanned signal. Combined with the prerequisites and library-visibility caveats, an agent has enough to call and interpret it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes beyond it: 'Every word of query must appear in the name or description; leave it empty to list everything' explains matching semantics and the empty-query behavior that the schema does not. It says less about kinds/limit/allPages, which the schema already covers adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Search) and resource (the design system of the file open in Figma Desktop) and then enumerates exactly what is covered: local components/component sets with properties and variants, used library components, paint/text/effect styles and variables. This distinguishes it cleanly from siblings like get_variable_defs or get_design_context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: 'Call it before designing with use_figma, and reuse what it finds', naming the sibling and the ordering. It also gives query semantics ('leave it empty to list everything') and constraints on library visibility, so the agent knows when results will and won't be useful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
use_figmaEdit DesignADestructive
Create or edit designs in the file open in Figma Desktop by running JavaScript against the Figma plugin API. code is the body of an async function with figma in scope: use await, and return a value (nodes come back as {id, name, type, x, y, width, height}); console.log output is returned too. The whole run is one undo step. If the script throws, the changes it made before the error stay.
Rules of the plugin API here:
The file uses dynamic page loading: use figma.getNodeByIdAsync, figma.setCurrentPageAsync, await page.loadAsync() before reading another page, getMainComponentAsync, and the *Async style/variable getters.
Load every font before setting text or text properties: await figma.loadFontAsync({ family: "Inter", style: "Regular" }). Check figma.listAvailableFontsAsync() when unsure a font exists.
Colours are 0-1 RGB: fills = [{ type: "SOLID", color: { r: 1, g: 0.4, b: 0 } }]. Paint arrays are immutable: assign a new array.
Prefer auto layout: layoutMode, itemSpacing, padding*, primaryAxisAlignItems, counterAxisAlignItems; set layoutSizingHorizontal/Vertical ("FILL", "HUG", "FIXED") only after the node is appended to an auto-layout parent.
New nodes land on the current page: place top-level frames clear of existing ones, and append children with parent.appendChild(node).
Reuse what the file has: find its components, styles and variables with search_design_system first, and set bound variables with figma.variables.setBoundVariableForPaint.
Images from the web: const img = await figma.createImageAsync(url), then fills = [{ type: "IMAGE", imageHash: img.hash, scaleMode: "FILL" }]. fetch(url) works too (e.g. an SVG for figma.createNodeFromSvg). Local files go in with place_image.
figma.currentPage.selection = [node] and figma.viewport.scrollAndZoomIntoView([node]) show the result.
Build a screen in a few calls (structure, then sections), return the ids, and check each step with get_screenshot.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | Body of an async function run with `figma` in scope. | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. | |
| timeoutMs | No | How long to wait for the script, in ms (default 60000). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and non-idempotent, and the description adds genuinely non-obvious behavior: the whole run is a single undo step, partial changes persist if the script throws, code runs as an async body with return values and console.log surfaced. It also discloses API-level constraints (dynamic page loading requires the *Async APIs, fonts must be loaded before text edits), which an agent could not infer elsewhere.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded: purpose, then return semantics, then a compact bulleted rules block, then a workflow closer. Dense and every bullet carries operational value, but the volume is very large for a tool description and sits close to documentation rather than selection guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, arbitrary-code-execution tool with no output schema, the description covers failure semantics, undo scope, async API requirements, mutation patterns (immutable paint arrays, append before sizing) and verification path. Nothing essential to calling it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantics for `code`: async function body with `figma` in scope, use await, `return` a value, node shape {id, name, type, x, y, width, height}, console.log captured. Only timeoutMs is left to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource+mechanism: 'Create or edit designs in the file open in Figma Desktop by running JavaScript against the Figma plugin API.' This is clearly separable from siblings like search_design_system (read-only lookup) and get_screenshot (verification), and it names its execution environment explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete workflow guidance: reuse the file's components via search_design_system first, use place_image for local files, build in a few calls (structure then sections), and verify each step with get_screenshot. It does not explicitly state when NOT to use this tool (e.g. when a narrower sibling suffices), so it stops short of the top band.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_codeVerify CodeAIdempotent
Check Flutter or React + Tailwind code against the design: renders it at 2x (Flutter with flutter test, React in headless Chrome with Tailwind) and compares the render with Figma's own 2x render of the node. Returns analyzer or runtime errors (overflows, missing assets, broken images), the share of differing pixels and a diff image (the design in grey, differing pixels in red).
React and HTML: without file it checks the code get_design_context generates and compares every layer's box too. With file (a .jsx or .tsx under a folder with package.json, or an .html page) it renders that file's default export or page: it must be self-contained apart from React and image imports; images load from the project's public folder. Pass css for the stylesheet with its tokens. React and Tailwind load from a CDN and the fonts from the system or Google Fonts. Needs Chrome and the puppeteer-core package.
Flutter: With file, it checks that widget inside its own Flutter project: the project's packages and assets, inside a MaterialApp, scaled by flutter_screenutil to the frame size when the project uses it. The widget needs a constructor without arguments. Without file, it checks the reference code get_design_context generates and also compares every layer's box. Use it after implementing a frame, and fix what it reports. Text in fonts it cannot find is drawn in a fallback font, and emoji have no colour font in the test, so text after them shifts. A run takes from 20 seconds to a few minutes.
| Name | Required | Description | Default |
|---|---|---|---|
| css | No | React: a CSS file to load with the component, e.g. its global stylesheet with the design tokens. | |
| file | No | Flutter: the .dart file with the widget, under the project's lib/. React: the .jsx/.tsx component file. Absolute, or relative to the project. | |
| fonts | No | Folders with font files (default: the project's assets/fonts and the system fonts). | |
| nodeId | No | The ID of the node, eg. "123:456" or "123-456" (instance ids like "I1:2;3:4" work too). Omit it to use the current selection in Figma. | |
| widget | No | Flutter: the widget class in `file` (default: its first widget class). | |
| fileKey | No | The key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used. | |
| flutter | No | Path of the flutter tool, when it is not on PATH. | |
| tailwind | No | React: the Tailwind major version (default: the project's, else 4). | |
| viewport | No | Lay the code out on a screen of this size, e.g. "360x780", and report runtime errors (overflows) and layers pushed off screen instead of comparing. | |
| framework | No | flutter or react (default: from the file, else as get_design_context picks: the client, then the project). | |
| clientLanguages | No | Comma separated languages of the client, e.g. "dart" (picks the framework). | |
| clientFrameworks | No | Comma separated frameworks of the client, e.g. "flutter" (picks the framework). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: discloses prerequisites (Chrome, puppeteer-core), runtime cost ('20 seconds to a few minutes'), what a run returns (analyzer/runtime errors, diff share, grey/red diff image), and rendering caveats (fallback fonts, uncoloured emoji shifting text). These are exactly the operational facts an agent needs before committing to the call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence front-loads purpose, mechanism, and return value, and the framework-split paragraphs are a sensible structure for a dual-mode tool. It is dense and repeats the 'compares every layer's box too' clause across both framework paragraphs, which is mildly redundant, but almost every sentence carries actionable content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter, no-output-schema tool this is unusually complete: it covers both framework paths, the with/without-`file` behavior, environment requirements, latency, and known rendering limitations. Nothing an agent needs to invoke it correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: `file` must be self-contained apart from React/image imports with images from the public folder, `css` carries the design tokens, `viewport` switches the tool into layout/overflow reporting instead of comparison, and `fileKey` is accepted for compatibility only. These go beyond the field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Check Flutter or React + Tailwind code against the design') and immediately explains the mechanism (renders at 2x, compares with Figma's own render). This is clearly distinguishable from every sibling, which either produce code, screenshots, or metadata rather than verifying a render.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear trigger: 'Use it after implementing a frame, and fix what it reports,' and ties usage to get_design_context output when `file` is omitted. It does not, however, name an alternative tool or state when not to use it (e.g. when a plain screenshot would suffice), so it stops short of full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoamiConnection StatusARead-only
Status of the local Figma connection: whether the plugin is connected, the pairing code it needs, the open file, page and selection, the project and its Code Connect file, and the saved snapshots. Use it when a read fails.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuine context beyond that by enumerating the state it inspects (including the pairing code, which implies setup/auth troubleshooting) and framing it as a failure-diagnosis tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with what the tool reports and ending on the usage trigger. The enumeration is long but each item conveys a distinct piece of diagnostic state, so little is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description compensates by listing the returned fields (connection, pairing code, file/page/selection, project, Code Connect, snapshots). It stops short of describing format or failure/empty behavior, but is adequate for a simple status probe.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4; schema coverage is trivially 100%. The description correctly adds no parameter discussion, avoiding noise.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a clear noun-phrase purpose — 'Status of the local Figma connection' — and enumerates the exact scope (plugin connection, pairing code, open file/page/selection, project and Code Connect file, snapshots). No sibling does diagnostics/status, so it is easily distinguished, though the verb is implicit rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use it when a read fails' gives an explicit trigger condition for reaching for this tool. It does not name alternatives or say when not to use it, but for a zero-param diagnostic the trigger is the main thing an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
- Changed
get_design_context5 fields changed- changed
Input schema / properties / assetsDir / descriptionPrevious value: -"Flutter: folder of the asset paths in the code (default: the svg/png/images folders of the project's pubspec.yaml, else assets/figma)."New value: +"Folder of the asset files in the code. Flutter default: the svg/png/images folders of the project's pubspec.yaml, else assets/figma. React default: public/figma (static/figma for SvelteKit), loaded by URL (/figma/name.svg). HTML default: assets/figma, relative to the page." - changed
Input schema / properties / framework / descriptionPrevious value: -"Code to generate: flutter or react. Default: from clientFrameworks / clientLanguages, else FIGMA_LOCAL_MCP_FRAMEWORK, else flutter when the project has a pubspec.yaml, else react."New value: +"Code to generate: react, html or flutter. Default: from clientFrameworks / clientLanguages, else FIGMA_LOCAL_MCP_FRAMEWORK, else flutter when the project has a pubspec.yaml, html for a static site (index.html without package.json), else react." - changed
Input schema / properties / framework / enumPrevious value: -[ - "react", - "flutter" -]New value: +[ + "react", + "html", + "flutter" +] - added
Input schema / properties / pageAdded value: +{ + "description": "React and HTML: draw the node as a web page that fills the viewport, never narrower than the design, with full-width sections stretching (default: frames 768 or more wide).", + "type": "boolean" +} - changed
Input schema / properties / screen / descriptionPrevious value: -"Flutter: draw the node as a phone screen that fills the screen and scrolls when tall (default: portrait frames 300-480 wide)."New value: +"Draw the node as a phone screen that fills the screen and scrolls when tall (default: portrait frames 300-480 wide)."
- Changed
verify_code7 fields changed- added
Input schema / properties / clientFrameworksAdded value: +{ + "description": "Comma separated frameworks of the client, e.g. \"flutter\" (picks the framework).", + "type": "string" +} - added
Input schema / properties / clientLanguagesAdded value: +{ + "description": "Comma separated languages of the client, e.g. \"dart\" (picks the framework).", + "type": "string" +} - added
Input schema / properties / cssAdded value: +{ + "description": "React: a CSS file to load with the component, e.g. its global stylesheet with the design tokens.", + "type": "string" +} - changed
Input schema / properties / file / descriptionPrevious value: -"The .dart file with the widget, under the project's lib/ (absolute, or relative to the project)."New value: +"Flutter: the .dart file with the widget, under the project's lib/. React: the .jsx/.tsx component file. Absolute, or relative to the project." - added
Input schema / properties / frameworkAdded value: +{ + "description": "flutter or react (default: from the file, else as get_design_context picks: the client, then the project).", + "enum": [ + "flutter", + "react", + "html" + ], + "type": "string" +} - added
Input schema / properties / tailwindAdded value: +{ + "anyOf": [ + { + "const": 3, + "type": "number" + }, + { + "const": 4, + "type": "number" + } + ], + "description": "React: the Tailwind major version (default: the project's, else 4)." +} - changed
Input schema / properties / widget / descriptionPrevious value: -"The widget class in `file` (default: its first widget class)."New value: +"Flutter: the widget class in `file` (default: its first widget class)."
15 tool updates
v1.5.1- First observed
add_code_connect_map - First observed
download_assets - First observed
get_code_connect_map - First observed
get_design_context - First observed
get_metadata - First observed
get_screenshot - First observed
get_variable_defs - First observed
import_design_export - First observed
place_image - First observed
remove_code_connect_map - First observed
save_design_export - First observed
search_design_system - First observed
use_figma - First observed
verify_code - First observed
whoami
TDQS
Scored across 15 tools
Most tools target a distinct resource or action, and the descriptions actively steer the agent (e.g. get_metadata says 'Always prefer get_design_context', get_variable_defs distinguishes tokens from layout). The main overlaps are get_design_context also returning a screenshot and assets, which get_screenshot/download_assets cover separately, and import_design_export vs save_design_export, which could momentarily confuse direction. These are minor and well documented.
The set mostly follows a snake_case verb_noun convention (get_*, add_*, remove_*, import_*, save_*, download_*, search_*, place_*, verify_*), which is readable and predictable. Outliers are whoami (no verb_noun form) and the vaguely named use_figma, but overall consistency is strong.
15 tools sit right at the upper end of the well-scoped range and each earns its place: read/context, screenshots, assets, variables, design-system search, code-connect CRUD, snapshots, write/edit, and verification. Nothing appears redundant filler or missing from a reasonable budget.
The surface covers a full design-to-code lifecycle: inspect (context, metadata, screenshot, variables, assets), search the design system, manage code-connect mappings (get/add/remove), import/save snapshots, write designs (use_figma, place_image), and verify code. Minor gaps remain, such as no explicit snapshot deletion/listing tool despite snapshots being replaceable, but core workflows are covered.
Maintenance
Related MCP Connectors
The Figma MCP server brings Figma design context directly into your AI workflow.
A coding agent searches the Icons8 library by keyword and style, then adds the selected icon or illustration to the project. Icons8 draws all of it: 420,000+ icons (130+ styles) and 110,000+ illustrations (340+ styles), so one project doesn't end up with mixed looks. The server lives at https://mcp.icons8.com/mcp/ and signs people in through their Icons8 account in the browser. Downloading PNG is free as long as the project links back to Icons8. SVG is on the paid plan, and that plan makes the link optional.
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
Official Fibery MCP server: query and update your workspace from any AI client via OAuth.
Related MCP Servers
- AlicenseAqualityDmaintenanceLocal-first MCP server that connects AI coding agents to the currently open Figma file through a local plugin bridge, requiring no Figma API token.8MIT
- AlicenseBqualityCmaintenanceLocal MCP server connecting AI clients to the Figma desktop app for inspecting and editing Figma documents via the Plugin API.1616 npm1MIT
- AlicenseAqualityDmaintenanceFigma MCP server that lets agents execute arbitrary JavaScript inside a running Figma desktop app via a local development plugin, enabling real-time document inspection and manipulation while avoiding REST API rate limits.3MIT
- AlicenseNot gradedqualityBmaintenanceLocal MCP server exposing Figma REST API tools to AI agents, enabling file reads, comments, variables, and other resource operations. Works with personal access tokens and integrates with Claude, Cursor, Codex, and more.MIT