Skip to main content
Glama


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 setup

It 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

~/.figma-local-mcp/plugin/manifest.json

%USERPROFILE%\.figma-local-mcp\plugin\manifest.json

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 frame

Keep 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 differences

Projects 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 it

The 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

~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project)

Claude Desktop (macOS)

~/Library/Application Support/Claude/claude_desktop_config.json

Claude Desktop (Windows)

%APPDATA%\Claude\claude_desktop_config.json

Step-by-step for each client, on macOS and Windows: figmcp.web.app/docs/configuration.

Tools

Tool

What it does

get_design_context

Reference code (Flutter or React + Tailwind), assets, a screenshot and variables for a node. The main tool.

get_metadata

Layer tree as XML: ids, types, names, positions and sizes.

get_screenshot

PNG of a node or the selection.

get_variable_defs

Variables and styles used by a node, resolved for its mode.

download_assets

Exported renders, original image fills and vector SVGs.

verify_code

Render Flutter code with flutter test, or React or HTML + Tailwind in headless Chrome, and compare it with Figma's render: errors, layout mismatches, differing pixels and a diff image.

use_figma

Run Figma plugin API scripts to create and edit designs.

search_design_system

Components (with properties and variants), styles and variables of the open file, to reuse while designing.

place_image

Put a local PNG, JPG, GIF or SVG into the open file, as a new layer or a layer's fill.

get_code_connect_map

Which instances map to which code components.

add_code_connect_map

Map a design component to a code component.

remove_code_connect_map

Remove a component mapping.

whoami

Connection status, pairing code, open file, selection and snapshots.

save_design_export

Write a full design export of a node to JSON.

import_design_export

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

FIGMA_LOCAL_MCP_DIR

~/.figma-local-mcp

Data folder: plugin, pairing code, snapshots and assets.

FIGMA_LOCAL_MCP_FRAMEWORK

Force flutter, react or html when the client doesn't say.

FIGMA_LOCAL_MCP_CODE_CONNECT

.figma-local/code-connect.json

Path of the Code Connect mappings file.

FIGMA_LOCAL_MCP_ALLOW_ORIGINS

Comma separated extra origins the server accepts for the plugin.

Update

npx -y @irshad.io/figma-local-mcp@latest setup

Then 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_figma can'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 test

Path

What

bin/, src/

The MCP server, plugin bridge and code generators

plugin/

The Figma development plugin

tools/

Visual and Flutter checks for generated code

test/

Tests (node --test)

web/

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

MIT

Figma is a trademark of Figma, Inc. This project is not affiliated with Figma, Inc.

Available Tools

15 tools
add_code_connect_mapAdd Code Connect MappingA
Idempotent

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.

NameRequiredDescriptionDefault
labelNoFramework, e.g. Flutter or React.
nodeIdYesThe 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.
sourceYesPath of the code component in the project.
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.
componentNameYesCode component name, e.g. AppPrimaryButton.

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 AssetsA
Read-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).

NameRequiredDescriptionDefault
nodeIdNoThe 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.
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.
defaultScaleNo
defaultFormatNo

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 MappingA
Read-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).

NameRequiredDescriptionDefault
nodeIdNoThe 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.
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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 ContextA
Read-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.

NameRequiredDescriptionDefault
pageNoReact 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).
nodeIdNoThe 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.
screenNoDraw the node as a phone screen that fills the screen and scrolls when tall (default: portrait frames 300-480 wide).
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.
assetsDirNoFolder 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.
forceCodeNoAlways return code, even for very large nodes.
frameworkNoCode 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.
screenUtilNoFlutter: 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).
skillNamesNoAccepted for compatibility (logging only).
clientLanguagesNoComma separated languages of the client, e.g. "dart" (picks the framework).
clientFrameworksNoComma separated frameworks of the client, e.g. "flutter" (picks the framework).
excludeScreenshotNoLeave the screenshot out of the response.
disableCodeConnectNoDraw mapped components from their layers instead of naming the code component.

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 MetadataA
Read-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.

NameRequiredDescriptionDefault
nodeIdNoThe 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.
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 ScreenshotA
Read-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.

NameRequiredDescriptionDefault
nodeIdNoThe 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.
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.
contentsOnlyNoRender the node in isolation, without overlapping content.
maxDimensionNoLongest edge of the PNG in pixels (default 1024).
enableBase64ResponseNoAlso include the PNG inline as base64.

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 DefinitionsA
Read-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.

NameRequiredDescriptionDefault
nodeIdNoThe 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.
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 ExportA
Idempotent

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.

NameRequiredDescriptionDefault
pathYesAbsolute path of the export JSON file.

TDQS

A4.4/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

NameRequiredDescriptionDefault
xNo
yNo
nameNoLayer name (default: the file name).
pathYesPath of the image file (absolute, or relative to the project).
widthNo
heightNo
nodeIdNoSet the image as the fill of this layer instead of making a new one (not for SVG).
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.
parentIdNoFrame or group to put the new layer in.
keepFillsNoWith nodeId: add the image above the existing fills instead of replacing them.
scaleModeNoHow the image fills the layer (default FILL).

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 MappingA
DestructiveIdempotent

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.

NameRequiredDescriptionDefault
nodeIdYesThe 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.
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 ExportA
Idempotent

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.

NameRequiredDescriptionDefault
pathNoAbsolute .json path to write (default: the data folder).
nodeIdNoThe 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.
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 SystemA
Read-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.

NameRequiredDescriptionDefault
kindsNoWhat to search (default: all of components, styles, variables).
limitNoMost results per kind (default 50).
queryNoWords to look for, e.g. "button primary".
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.
allPagesNoSearch components on every page, not just the current one (slower on large files).

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 DesignA
Destructive

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.

NameRequiredDescriptionDefault
codeYesBody of an async function run with `figma` in scope.
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.
timeoutMsNoHow long to wait for the script, in ms (default 60000).

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 CodeA
Idempotent

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.

NameRequiredDescriptionDefault
cssNoReact: a CSS file to load with the component, e.g. its global stylesheet with the design tokens.
fileNoFlutter: the .dart file with the widget, under the project's lib/. React: the .jsx/.tsx component file. Absolute, or relative to the project.
fontsNoFolders with font files (default: the project's assets/fonts and the system fonts).
nodeIdNoThe 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.
widgetNoFlutter: the widget class in `file` (default: its first widget class).
fileKeyNoThe key of the Figma file. Accepted for compatibility; the file open in Figma Desktop is always used.
flutterNoPath of the flutter tool, when it is not on PATH.
tailwindNoReact: the Tailwind major version (default: the project's, else 4).
viewportNoLay 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.
frameworkNoflutter or react (default: from the file, else as get_design_context picks: the client, then the project).
clientLanguagesNoComma separated languages of the client, e.g. "dart" (picks the framework).
clientFrameworksNoComma separated frameworks of the client, e.g. "flutter" (picks the framework).

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 StatusA
Read-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.

NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

  1. 2 tool updates
    • Changedget_design_context5 fields changed
      • changedInput schema / properties / assetsDir / description
        Previous 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."
      • changedInput schema / properties / framework / description
        Previous 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."
      • changedInput schema / properties / framework / enum
        Previous value: -[
        -  "react",
        -  "flutter"
        -]New value: +[
        +  "react",
        +  "html",
        +  "flutter"
        +]
      • addedInput schema / properties / page
        Added 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"
        +}
      • changedInput schema / properties / screen / description
        Previous 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)."
    • Changedverify_code7 fields changed
      • addedInput schema / properties / clientFrameworks
        Added value: +{
        +  "description": "Comma separated frameworks of the client, e.g. \"flutter\" (picks the framework).",
        +  "type": "string"
        +}
      • addedInput schema / properties / clientLanguages
        Added value: +{
        +  "description": "Comma separated languages of the client, e.g. \"dart\" (picks the framework).",
        +  "type": "string"
        +}
      • addedInput schema / properties / css
        Added value: +{
        +  "description": "React: a CSS file to load with the component, e.g. its global stylesheet with the design tokens.",
        +  "type": "string"
        +}
      • changedInput schema / properties / file / description
        Previous 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."
      • addedInput schema / properties / framework
        Added 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"
        +}
      • addedInput schema / properties / tailwind
        Added value: +{
        +  "anyOf": [
        +    {
        +      "const": 3,
        +      "type": "number"
        +    },
        +    {
        +      "const": 4,
        +      "type": "number"
        +    }
        +  ],
        +  "description": "React: the Tailwind major version (default: the project's, else 4)."
        +}
      • changedInput schema / properties / widget / description
        Previous value: -"The widget class in `file` (default: its first widget class)."New value: +"Flutter: the widget class in `file` (default: its first widget class)."
  2. 15 tool updatesv1.5.1
    • First observedadd_code_connect_map
    • First observeddownload_assets
    • First observedget_code_connect_map
    • First observedget_design_context
    • First observedget_metadata
    • First observedget_screenshot
    • First observedget_variable_defs
    • First observedimport_design_export
    • First observedplace_image
    • First observedremove_code_connect_map
    • First observedsave_design_export
    • First observedsearch_design_system
    • First observeduse_figma
    • First observedverify_code
    • First observedwhoami

TDQS

A4.2/5.0

Scored across 15 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Figma 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.
    3
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Local 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