Figma Write Bridge MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| FIGMA_TOKEN | No | Figma personal access token. Required for the REST API tools: get_figma_data, download_figma_images, comments, export_frames_to_disk, search_components. | |
| FIGMA_BRIDGE_HOST | No | Host to bind the bridge server to. | 127.0.0.1 |
| FIGMA_BRIDGE_PORT | No | Port for the bridge server WebSocket. | 8787 |
| FIGMA_BRIDGE_CHANNEL | No | Channel name for the server. Pin this to run multiple MCP servers, each on its own port. | default |
| FIGMA_BRIDGE_TIMEOUT_MS | No | Timeout in milliseconds. | 180000 |
| FIGMA_BRIDGE_MAX_RESULT_BYTES | No | Cap on a single tool result before it is truncated, to stop one big read from filling the agent's context. | 50000 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| figma_bridge_statusA | Returns whether the local Figma plugin is connected, the active channel, and every connected channel with the Figma file it belongs to. The channel defaults to "default" and is tied to this server's FIGMA_BRIDGE_CHANNEL; the plugin UI joins that channel (one plugin = one channel/server). |
| join_channelA | Selects which connected Figma plugin channel to target for subsequent commands. Channels default to "default" and are configured per MCP server via FIGMA_BRIDGE_CHANNEL; the plugin UI joins that channel. Use figma_bridge_status to see which channel maps to which file. |
| get_figma_dataA | Get Figma file data via the REST API. Pass nodeId to fetch only that node (avoids pulling the whole file). depth limits recursion on file/nodes. Returns file (or nodes), plus styles/components/component_sets when no nodeId is given. |
| download_figma_imagesC | Download SVG/PNG/GIF images used in a Figma file via the Figma REST API. |
| rename_nodeC | Renames a node by nodeId. |
| set_target_frameB | Sets the target frame(s) that the agent is allowed to modify. |
| get_target_framesA | Returns the current target frameIds the agent is allowed to modify. |
| clear_target_framesB | Clears the active target frameIds. |
| get_document_infoC | Get information about the current Figma document. |
| get_all_pagesA | Compact map of every page in the open file: id/name/childCount. Pass includeTopLevel: true to also list each page's top-level frames (id/name/type/childCount). Use this once to get a full-file overview before targeted reads. |
| get_document_treeA | Compact structural tree of the whole document (or a subtree). Returns a flattened columnar table: fields lists the column names, rows holds one array per node in pre-order, and the depth column gives nesting level (depth 0 is the root, each +1 is a child of the nearest preceding row with depth-1). Every node is {id, name, type}; no extra fields unless requested. Default maxDepth is 3. Hidden layers are omitted unless includeHidden is true. Pass fields to pull extra per-node values (characters, fills, fillHex, fillCount, strokes, x, y, width, height, absoluteBoundingBox, strokeWeight, cornerRadius, fillStyleId, strokeStyleId, textStyleId, layoutMode, layoutWrap, layoutSizingHorizontal, layoutSizingVertical, layoutPositioning, primaryAxisAlignItems, counterAxisAlignItems, layoutGrow, itemSpacing, padding, visible, opacity). Use rootNodeId to scope to a frame/page and excludeTypes (e.g. ["VECTOR"]) to drop icon noise. verbose returns the nested tree instead. |
| get_selectionB | Get information about the current selection. |
| create_rectangleA | Create a rectangle. Pass parentNodeId to insert into a frame, auto-layout stack, or slot. Inside auto layout, omit x/y and use index + layoutSizing; x/y only apply to freeform frames or ignoreAutoLayout overlays. |
| create_frameA | Create a new frame. Defaults to NO fill (transparent) — Figma's native white fill is cleared so layout containers stay invisible. Pass fillHex only when the frame is a visible surface (card, screen bg, chip). Nested into auto layout: omit x/y and omit width/height (do not ship at 320×200); pass parentNodeId + index + layoutSizing. Optional layoutMode (HORIZONTAL|VERTICAL|GRID). |
| create_textA | Create a text node. Defaults to auto-width hug (textAutoResize WIDTH_AND_HEIGHT + HUG sizing). Pass parentNodeId to insert into a frame/stack/slot — inside auto layout omit x/y and use index. Pass textAlignHorizontal (LEFT|CENTER|RIGHT|JUSTIFIED), textAlignVertical (TOP|CENTER|BOTTOM), textAutoResize (WIDTH_AND_HEIGHT|HEIGHT|NONE|TRUNCATE), and layoutSizingHorizontal/Vertical (FIXED|HUG|FILL). For variable fonts, pass variationSettings (e.g. {wght:550}) and optionally omit fontStyle. |
| set_fill_colorB | Set or clear a node's solid fill. Prefer applying styles/variables when available. Pass clear:true (or fills:[]) to remove fills from layout containers that should be transparent. Also accepts fillHex. |
| read_my_designA | Compact layout-aware summary of the current selection. Default fields cover size, auto-layout (mode, hug/fill, padding, gap, alignment), fillHex/fillCount, and truncated text. VECTOR children are omitted unless you pass excludeTypes: []. Pass verbose for the raw REST dump. Use instead of chaining get_selection when you only need structure. |
| get_node_infoA | Compact layout-aware summary of a node: size, auto-layout (mode, hug/fill, positioning, padding, gap, alignment), fillHex/fillCount, truncated text, and childCount. VECTOR children are omitted unless excludeTypes is []. Default maxDepth is 0 (the node itself). Pass fields to request a subset, or verbose for the raw REST dump. |
| get_nodes_infoA | Compact layout-aware summaries for several nodes. Same defaults as get_node_info. Prefer this over looping get_node_info. |
| get_selection_contextA | One-call bundle for the current selection: compact layout-aware node info plus (for instances) main component id, property definitions/values, and slots. Use instead of chaining get_selection→get_node_info→get_component_property_definitions. |
| get_changes_sinceB | Return nodes this bridge mutated since a cursor (re-read only what changed, not the whole doc). Pass prior currentSeq as sinceSeq to page. Cursor resets when the MCP server restarts. |
| get_instance_sourceB | Get main component/component-set keys and properties for an instance (to verify design system provenance). |
| scan_instances_with_sourcesC | Scan instances under a root node and return their main component/component-set keys. |
| import_component_by_keyC | Import a library component into the current file using its componentKey. Optionally rename the imported main component. |
| import_component_set_by_keyA | Import a library component set into the current file using its componentSetKey. Optionally rename the imported main component set. |
| create_instance_from_component_keyB | Create an instance from a library component key inside the target frame/parent. Pass parentNodeId + index for auto-layout stacks; omit x/y unless the parent is freeform. |
| create_instance_from_set_keyA | Create an instance from a library component set key (default variant) inside the target frame/parent. Pass parentNodeId + index for auto-layout stacks; omit x/y unless the parent is freeform. |
| get_instance_propertiesC | Get componentProperties for an instance. |
| set_instance_propertiesC | Set component properties/variants on an instance. |
| swap_instance_componentC | Swap an instance to a different library component key. |
| send_to_backA | Send a layer to the back of its parent (z-order). In Figma, children[0] is back-most. |
| bring_to_frontA | Bring a layer to the front of its parent (z-order). In Figma, children[last] is front-most. |
| set_focusA | Select a single node and scroll the viewport to it. Switches to the node's page first, so this works with ids returned by a cross-page find_nodes. Use this to show the user what you just built or found. |
| set_selectionsA | Set selection to multiple nodes and scroll viewport to show them. Switches to the first node's page; Figma scopes selection to one page, so nodes on other pages are reported in skippedOnOtherPages. |
| create_instance_from_instanceA | Create a new instance of whatever main component an existing instance points at. Pass parentNodeId (or parentId) to drop it into a frame, stack, or slot. Inside auto layout omit x/y and use index. |
| set_stroke_colorB | Set or clear a node's stroke. Color via hex/strokeHex or r/g/b (0..1 or 0..255), optional strokeWeight, strokeAlign (CENTER|INSIDE|OUTSIDE), dashPattern (e.g. [4,4]), strokeCap (NONE|ROUND|SQUARE), strokeJoin (MITER|BEVEL|ROUND), or styleId to apply a paint style. Pass clear:true to remove strokes. |
| reparent_nodeB | Move (cut) an existing node into a new parent container (frame, section, group, auto-layout, slot, or page). Inside auto layout the node joins the flow (omit x/y, pass index). Pass ignoreAutoLayout + x/y only for overlays. |
| get_parent_chainC | Walk up the parent chain of a node, returning id/name/type at each level. |
| insert_childA | Insert an existing child node at an index inside a parent container. Omit index to append at the end. Inside auto layout this keeps the child in the flow (layoutPositioning AUTO) unless ignoreAutoLayout is true. |
| move_nodeA | Move a node on the canvas. Pass absolute x/y, or relative dx/dy to nudge. Inside auto layout this is rejected unless ignoreAutoLayout is true (Ignore auto layout / overlay). Reorder stacks with insert_child; align with set_axis_align. |
| resize_nodeA | Resize a node. Width and/or height may be passed. For TEXT: WIDTH_AND_HEIGHT (hug) refuses resize — pass textAutoResize HEIGHT (width only) or NONE (fixed). Setting only width on hug auto-promotes to HEIGHT. Prefer set_layout_sizing for HUG/FILL. |
| resize_to_fitA | Fit a layer. Two modes: (1) pass targetNodeId to scale nodeId to fit inside that layer, preserving aspect ratio and centering it (fit: 'contain' letterboxes, 'cover' fills and crops); (2) omit targetNodeId to shrink-wrap nodeId to tightly fit its own children (Figma's 'Resize to Fit'). |
| clone_nodeC | Create a copy of an existing node with optional position offset and name. |
| clone_node_into_parentA | Clone a node and append it into a specified parent container (frame, section, group, auto-layout, slot, or page). In auto-layout parents the copy joins the flow unless dx/dy are non-zero (then it is set to absolute positioning). |
| delete_nodeA | Delete a node by nodeId (only within the allowed target frame). Deleting a page or a top-level frame requires confirmFrameOrPageDeletion: true. |
| delete_multiple_nodesA | Delete multiple nodes by nodeIds (only within the allowed target frame). When any nodeId is a page or top-level frame, confirmFrameOrPageDeletion: true is required for that node. |
| run_batchA | Execute multiple bridge actions in one round trip instead of one WebSocket call per action. Runs sequentially inside the plugin; by default stops at the first error (partial results are still returned in order). This is NOT a transaction: steps that already succeeded are not rolled back if a later step fails. Use create_checkpoint first if you need a rollback path for the nodes you're about to batch-edit. |
| create_checkpointA | Snapshot a handful of common mutable properties (position, size, rotation, opacity, visibility, fills, strokes, corner radius, text characters) on the given nodes so they can be restored later with restore_checkpoint. NOT true undo: it cannot restore a deleted node or undo structural changes (reparenting, new/removed children), and state is lost if the Figma plugin UI reloads. |
| restore_checkpointC | Reapply a snapshot captured by create_checkpoint to whichever of its nodes still exist. See create_checkpoint for what is and isn't covered. |
| list_checkpointsB | List checkpoints captured so far in this plugin session. |
| move_node_to_pageB | Move (cut) a top-level node to another page, or copy it there (duplicate into page, keeping the original). Set copy: true to keep the original. |
| move_component_to_fileA | Import a component or component-set from this file into another connected channel's file, then optionally delete the source (move). Requires the target file to be open with the plugin connected to this server on a different channel (see figma_bridge_status / list_channels). Use mode: 'copy' to keep the source. Accepts componentId, componentKey, or componentName to identify the source. |
| set_corner_radiusC | Set the corner radius of a node with optional per-corner control. |
| set_text_contentC | Set the text content of a single text node. |
| scan_text_nodesC | Scan text nodes with basic chunking support. Matches are returned as a columnar table: fields lists the column names and rows holds one array per node in the same order. |
| find_and_replace_textA | Search TEXT node characters for a literal string or regex and replace matches, optionally across every page in the file (not just the current one). Pass dryRun: true first to preview matches before committing. |
| set_multiple_text_contentsC | Batch update multiple text nodes efficiently. |
| get_stylesA | Get information about local styles. Paged per style type: pass limit/offset to bound each response (default 500); |
| create_paint_styleC | Create or update a local paint style. |
| create_text_styleB | Create or update a local text style. For variable fonts, pass variationSettings (OpenType axis map) and optionally omit fontStyle so Figma picks the matching named instance. |
| create_effect_styleC | Create or update a local effect style. |
| create_grid_styleC | Create or update a local grid style. |
| import_style_by_keyC | Import a published library style into the file by key. |
| apply_fill_styleC | Apply a paint style to a node's fills. |
| apply_stroke_styleA | Apply a paint style to a node's strokes (design-system preferred). For raw color/weight/align/dash without a style, use set_stroke_color instead. |
| apply_text_styleC | Apply a text style to a TEXT node. |
| apply_effect_styleC | Apply an effect style to a node's effects. |
| apply_grid_styleC | Apply a grid style to a frame's layout grids. |
| set_layout_gridsA | Set layout grids (layout guides) on a frame. Each grid is either {pattern:'ROWS'|'COLUMNS', alignment:'MIN'|'MAX'|'CENTER'|'STRETCH', gutterSize, count, sectionSize?, offset?} or {pattern:'GRID', sectionSize}, plus optional visible and color. Figma rejects sectionSize when alignment is STRETCH and offset when alignment is CENTER; the bridge drops those rather than failing, and strips any key the pattern does not declare. |
| get_local_componentsA | Get information about local components across all pages: id, name, type, description, publish key, and a property count, returned as { components, total, offset, limit, pageCount } so you can page every component (default limit 500). Pass includeProperties: true to also get simplified component property definitions (for building library catalogs). Pass verbose to skip compacting; the columnar format is used otherwise. |
| create_componentA | Create a new empty component. Pass parentNodeId to insert into a frame, auto-layout stack, or slot. Inside auto layout omit x/y and use index. Nested into auto layout, omit width/height unless you want a fixed size. |
| create_component_from_nodeC | Convert an existing node into a main component. |
| combine_as_variantsC | Combine existing component nodes into a component set and lay them out to avoid overlap. |
| set_variant_propertiesC | Rename a component using Figma's variant naming format (Property=Value, ...). |
| get_component_property_definitionsC | Inspect component or component-set property definitions for authoring and verification. |
| add_component_propertyC | Add a BOOLEAN, TEXT, INSTANCE_SWAP, or VARIANT property to a component or component set. |
| edit_component_propertyC | Rename or update the default value/preferred values of an existing component property. |
| delete_component_propertyB | Delete an existing component property from a component or component set. |
| bind_component_propertyC | Bind a BOOLEAN/TEXT/INSTANCE_SWAP property to a node field using componentPropertyReferences. |
| create_component_slotC | Create a slot inside a component variant. This also creates the corresponding SLOT property. |
| edit_component_slotB | Rename, resize, or reposition an existing SLOT node inside a component. Figma keeps the SLOT property's name in sync with the slot node's name. |
| delete_component_slotA | Remove a SLOT node from a component and delete its corresponding SLOT property. Any content placed in instances of that slot is discarded. |
| create_component_instanceA | Create an instance of a local component. Pass parentNodeId to insert into a frame, auto-layout stack, or slot. Inside auto layout omit x/y and use index. |
| export_node_as_imageA | Export a node as an image (PNG, JPG, SVG, or PDF) or as video (MP4, GIF, WEBM) for a top-level frame with Motion. Prefer localPath so bytes are written to disk inside the figma-write-bridge repo instead of returning base64. If the payload would exceed the MCP result cap, the server auto-saves under exports/ and returns the path. Video export is only available in Figma Desktop for animated top-level frames. |
| find_nodesA | Query the document for nodes matching a set of predicates, evaluated inside Figma so only matching rows come back (use this instead of reading a whole subtree and filtering). All predicates are optional and are ANDed together. Returns a columnar table: fields names the columns, rows holds one array per match, plus scanned/total/truncated counts. Examples: {types:["INSTANCE"], mainComponentName:"Button", fillHex:"#ff0000"} finds red button instances; {missingFillStyle:true} finds hardcoded fills with no style or variable bound (design-system drift); {types:["INSTANCE"], hasOverrides:true} finds overridden instances. |
| scan_nodes_by_typesA | List nodes of given types in a subtree. Prefer find_nodes for anything more selective than a type filter. Defaults to the current page, or the single target frame if one is set. Pass rootNodeId to scope. Paged (default limit 200). Returns a columnar table plus total/offset/limit/truncated. |
| get_annotationsA | Get annotations on a node or in a subtree. Page-wide scans are paged (default limit 100). Pass nodeId for one node, or rootNodeId to scope. includeCategories defaults to false (pass true to expand category labels). |
| set_annotationC | Create or update an annotation with markdown support. |
| set_multiple_annotationsC | Batch create/update multiple annotations efficiently. |
| get_reactionsC | Get all prototype reactions from nodes. |
| set_reactionsA | Set prototype reactions on a node (replaces existing reactions). Supports every action type including NODE navigation (NAVIGATE/SWAP/OVERLAY/SCROLL_TO/CHANGE_TO), BACK, CLOSE, URL, SET_VARIABLE, SET_VARIABLE_MODE, CONDITIONAL, and UPDATE_MEDIA_RUNTIME. Reactions are validated against a strict schema: transitions of type DISSOLVE/SMART_ANIMATE/SCROLL_ANIMATE must NOT carry direction or matchLayers (only MOVE_IN/MOVE_OUT/PUSH/SLIDE_IN/SLIDE_OUT may), and a NODE destination must be a valid target for its navigation type — NAVIGATE/SWAP need a top-level frame, OVERLAY an overlay-configured frame, SCROLL_TO a node inside a scrollable ancestor, CHANGE_TO a sibling variant in the same component set. |
| clear_reactionsC | Remove all prototype reactions from a node. |
| upsert_reactionC | Replace the first matching reaction (by trigger/action/destination) or append if none match. Supports all action types including NODE navigation. Existing reactions on the node are re-normalized before being written back, so round-tripping does not trip the strict setter schema. |
| get_animation_presetsA | List curated motion presets plus the official Figma transition and easing values supported by this bridge. Use these values with set_reactions, upsert_reaction, set_transition_reaction, and set_smart_animate_reaction. |
| set_transition_reactionA | Create or replace a node-to-node prototype reaction with a typed transition/easing payload. Pass |
| set_smart_animate_reactionC | Create or replace a node-to-node prototype reaction using Smart Animate, with optional easing/preset overrides. Smart Animate interpolates matching layers between source and destination automatically; there is no per-property keyframe API. |
| get_overlay_settingsA | Read a frame/component's overlay prototype settings (position type, background, click-outside behavior). These control HOW an overlay appears; the interaction that opens it is a NODE reaction with navigation OVERLAY, set via set_reactions or set_transition_reaction. |
| set_overlay_settingsB | Configure how a frame/component behaves when it is shown as an OVERLAY: where it's anchored, its scrim background, and whether clicking outside closes it. |
| get_prototype_settingsB | Get the current page's prototype start node and Flows starting points. |
| set_prototype_start_nodeA | Set (or clear, by omitting nodeId) the current page's default prototype start frame — the entry point used by Present. |
| set_flow_starting_pointsB | Replace the current page's Flows list (named prototype entry points), each pointing at a top-level FRAME. |
| set_overflow_directionC | Set frame overflow direction for scrolling in prototype (NONE, HORIZONTAL, VERTICAL, BOTH). |
| set_fixed_childrenC | Mark direct children of a frame as fixed in a scrolling prototype (fix position when scrolling). |
| set_grid_layoutA | Turn a frame into a GRID auto-layout container and configure it. GRID is a third layoutMode alongside HORIZONTAL/VERTICAL: children occupy cells rather than a single flow. Set rowCount/columnCount and the gaps, and optionally size individual tracks via rowSizes/columnSizes — each entry is a number (a FIXED px size) or {type:'FLEX'|'FIXED'|'HUG', value}. FLEX tracks share leftover space by their value as a weight. Position children afterwards with set_grid_child_position. |
| get_grid_layoutA | Read a GRID frame's track counts, gaps, per-track sizes, and every child's cell, span, and alignment. Returns isGrid:false for a frame that is not in GRID layout. Call this before repositioning children so you know the grid's bounds. |
| set_grid_child_positionA | Place a child in its GRID parent: row/column are 0-based anchor indices, rowSpan/columnSpan are how many tracks it covers, and the aligns control it inside its cell ('AUTO' stretches). Spans must fit inside the grid — anchor + span cannot exceed the track count, and the tool reports the actual bound if it does. A span also cannot cross a cell another child already occupies (Figma reports it as a span blocked by existing children in adjacent columns), so place and widen a spanning child BEFORE adding the children beside it. Children keep their own size by default; use align 'AUTO' on an axis to stretch into the cell. |
| reorder_grid_tracksB | Move whole rows or columns of a GRID frame, taking their children with them. fromIndices lists the 0-based tracks to move and insertionIndex is where they land. |
| get_motionA | Read Motion state — timelines (with durations in seconds), the current playheadPosition in seconds (undefined when no timeline is active), manual keyframe tracks, applied animation styles, and resolved animations — for the given nodes, or the current selection when none are given. Motion is distinct from prototype reactions: reactions link frames on click, Motion animates properties over a timeline inside one top-level frame. Returns motionEnabled:false when the account lacks the Motion feature flag. |
| set_keyframe_trackA | Add or replace one manual keyframe track on a node. |
| remove_keyframe_trackA | Remove one manual keyframe track from a node by field (same field naming as set_keyframe_track), or pass all:true to clear every manual track on the node. |
| list_animation_stylesA | List Figma's first-party animation styles, each with its styleId and the props it accepts. Call this before apply_animation_style to get a real styleId. Note |
| apply_animation_styleA | Apply a reusable animation style to a node. Identify it by styleId from list_animation_styles, or by styleName for a substring match. duration and timelineOffset are seconds and are top-level, not props. Returns the applied instance id needed by remove_animation_style. Verify the result against animationStyles in the response — applying a style does not materialize tracks into |
| remove_animation_styleA | Remove one applied animation style from a node by its appliedId (read it from get_motion's animationStyles), or pass all:true to remove every applied style. |
| set_timeline_durationA | Set the duration, in seconds, of the timeline owned by the node's containing top-level frame. Omit timelineId to use the node's first timeline. Lengthen to make room for an animation; do not shorten unless the user asked, since it truncates existing motion. |
| list_shadersA | List shader effects and fills available to this file (in-file, subscribed libraries, and owned shaders), with ids, type (effect|fill), and imported. Property definitions are omitted unless includeProperties is true — import_shader_by_id already returns them. Shaders with imported:false must be imported before apply_shader. |
| import_shader_by_idA | Import a shader into the current file so it can be applied. Pass shaderId (from list_shaders) or name. Idempotent if the shader is already imported; returns the shader with imported:true and populated propertyDefinitions. |
| apply_shaderA | Import (if needed) and apply a shader to a node. Effect shaders go on effects; fill shaders go on fills or strokes. properties may be keyed by property-definition id or by the author-defined name from propertyDefinitions. Prefer this over set_effects when applying a SHADER. Pass replace:false to append an effect shader alongside existing effects. |
| get_font_variation_axesA | Return the OpenType variation axes a font family exposes (e.g. wght, slnt, opsz), or null/variable:false for a static family. Use this before setting variationSettings on create_text / set_text_style / create_text_style. Requires Figma Desktop with Plugin API Update 138 (variable fonts). |
| list_variable_collectionsB | List local variable collections in the current file. |
| list_variablesA | List local variables in the current file (optionally filtered by resolvedType). Pass includeScopes: true to also return each variable's scopes, or includeValues: true to also return each variable's value in EVERY mode (valuesByMode by modeId, valuesByModeName by mode name, defaultValue from the collection's first mode, and the mode list) — use this to read theme/dark-mode values, not just the default mode. Results are paged: default limit 500 per call with |
| get_variableA | Read one variable's values in EVERY mode. Find it by variableId, by publish key, or by name (if the name is not unique, pass collectionId/collectionName to disambiguate). Returns valuesByMode / valuesByModeName (raw values, aliases as {type:"VARIABLE_ALIAS",id}) plus resolvedValuesByMode / resolvedValuesByModeName that follow aliases to a concrete value (colors as hex) with cycle/unresolved markers if needed. |
| create_variable_collectionC | Create a local variable collection, optionally naming modes. |
| create_variableB | Create a local variable in a collection and set values by mode. resolvedType: COLOR, FLOAT, STRING, BOOLEAN, EASING, or TIMING — EASING and TIMING hold motion easing curves and durations, letting a design system tokenize animation alongside color and spacing. |
| set_variable_valuesC | Update a variable's values by mode. |
| rename_variableC | Rename an existing variable by variableId. |
| delete_variableB | Delete an existing variable by variableId. Requires confirmDelete=true. |
| import_variable_by_keyC | Import a published library variable into the file by key. |
| bind_color_variable_to_fillC | Bind a COLOR variable to a node's fill paint. |
| bind_color_variable_to_strokeC | Bind a COLOR variable to a node's stroke paint. |
| bind_variable_to_propertyB | Bind a FLOAT/STRING/BOOLEAN/EASING/TIMING variable to a node property via setBoundVariable(property, variable). Use property "opacity" to token-bind layer opacity (pair a FLOAT variable with a color rather than detaching the fill). Also used for padding, radius, spacing, and fontSize. |
| set_node_explicit_variable_modeC | Set an explicit variable mode for a node for a given collection. |
| get_instance_slotsB | List SLOT nodes inside an instance (for inserting content into slots). |
| append_to_slotB | Reparent existing nodes into a SLOT. Children join the slot's layout flow (AUTO + FILL when the slot is auto layout) at 0,0 when it is freeform. Do not move_node afterwards. Optionally pass index and layoutSizing. |
| set_auto_layoutB | Set multiple auto-layout properties in one call. sizing may include primaryAxisSizingMode/counterAxisSizingMode and/or layoutSizingHorizontal|width + layoutSizingVertical|height (FIXED|HUG|FILL). Empty frames keep Figma's default white fill stripped unless you pass clearFill:false. |
| set_layout_modeA | Set the layout mode and wrap behavior of a frame: NONE, HORIZONTAL, VERTICAL, or GRID. GRID is a full cell-based layout — configure its tracks with set_grid_layout and place children with set_grid_child_position. layoutWrap (NO_WRAP | WRAP) applies to HORIZONTAL only. Empty wrappers strip leftover default white fill unless clearFill is false. |
| set_paddingC | Set padding values for an auto-layout frame (top, right, bottom, left). |
| set_axis_alignA | Set primary and counter axis alignment for auto-layout frames. primaryAxisAlignItems: MIN, CENTER, MAX, SPACE_BETWEEN, SPACE_AROUND, or SPACE_EVENLY (SPACE_AROUND and SPACE_EVENLY distribute children with equal space around or between them, padding included). counterAxisAlignItems: MIN, CENTER, MAX, or BASELINE. |
| set_layout_sizingB | Set hug/fill/fixed sizing. Prefer layoutSizingHorizontal/Vertical or width/height aliases with FIXED | HUG | FILL. For TEXT nodes you can also pass textAutoResize (WIDTH_AND_HEIGHT | HEIGHT | NONE | TRUNCATE) so wrap mode stays aligned with sizing. |
| set_item_spacingC | Set distance between children in an auto-layout frame. |
| figma_set_textB | Sets characters on a TEXT node (by nodeId or current selection). |
| figma_set_solid_fillC | Sets a SOLID fill on a node by nodeId. |
| set_image_fillA | Set an IMAGE fill on a node from a URL (createImageAsync), raw base64 imageBytes, or a local image file via localPath (read as base64 server-side). scaleMode: FILL, FIT, CROP, TILE. |
| undoA | Reverses the most recent auto-captured mutating action (snapshot-based, best-effort). Cannot restore deleted nodes or structural changes. Only works within the current plugin session while target-frame mutating actions were executed through this bridge. |
| redoA | Re-applies the most recently undone action (snapshot-based, best-effort). |
| get_style_guideA | Extract a usage style guide from the current page (or rootNodeId subtree): counts of distinct solid colors (hex), color variable bindings, font family/style combos, font sizes, line heights, spacing/gap/padding values, corner radii, stroke weights, and opacities. |
| get_font_listA | List the distinct fonts (family + style, plus variationSettings when the text uses a variable font) used in the current page or a rootNodeId subtree, with usage counts. Pair with get_font_variation_axes to inspect a family's OpenType axes. |
| distribute_nodesA | Space or align a set of nodes along an axis. axis: horizontal|vertical. mode: gap (fixed gap), spaceBetween/evenly (fill bounds), center (center the cluster). crossAlign: none|start|center|end. Bounds default to the common parent; pass bounds {x1,y1,x2,y2} to override (horizontal coordinates) or {y1,x1,y2,x2} semantics for vertical. |
| arrange_childrenC | Distribute the direct children of a frame/node along the main axis (horizontal or vertical). Accepts the same mode/gap/crossAlign options as distribute_nodes. Bounds default to the parent. |
| import_tokensA | Import a W3C-style Design Tokens JSON object into Figma variables (and optionally paint styles). Accepts nested {group:{name:{$type,$value}}} or plain nested values (types inferred from values). Creates/updates a variable collection (default 'Design Tokens') and a Default mode, then sets values. color -> COLOR variable + paint style, number/dimension -> FLOAT, string -> STRING, boolean -> BOOLEAN. |
| export_tokensA | Export local Figma variables as a W3C-style Design Tokens object (nested by collection/variable name), plus a flat variables list. Colors are emitted as hex. With includeModes (default true) every mode's values are returned under tokensByMode like "Color/Dark"; the response also includes |
| create_typography_scaleB | Create a text-style scale (caption/body/h3/h2/h1/display by default, or custom steps) from a baseSize and ratio: fontSize = base * ratio^offset. Can also create sample text nodes in a frame (createSampleFrame) spanning the steps. For variable fonts, pass variationSettings and optionally omit fontStyle. |
| generate_paletteB | Generate a tonal 50..900 palette (default 10 steps) from a seed hex color. Light steps mix toward white, dark steps toward black. Optionally creates paint styles (createStyles=true), COLOR variables in a ' Tokens' collection (createVariables=true), and a swatch frame with labeled rectangles (createFrame=true). |
| extract_component_setB | Convert multiple existing frames (or components) into a variant component set: each frame becomes a COMPONENT, then they are combined into a COMPONENT_SET via combine_as_variants. Set propertyName to attempt adding a VARIANT property (best-effort). |
| set_gradient_fillB | Set a gradient fill (LINEAR, RADIAL, ANGULAR, DIAMOND) on a node. stops: [{position 0..1, color {r,g,b[,a]}}]. Optional from/to transform points (normalized), opacity, paintIndex. |
| set_effectsA | Set effects on a node. Pass effectStyleId to apply an existing style, or effects as a raw array. Supported types: DROP_SHADOW and INNER_SHADOW ({color, offset:{x,y}, radius, spread}; DROP_SHADOW also takes showShadowBehindNode), LAYER_BLUR and BACKGROUND_BLUR ({radius, blurType:'NORMAL'} or blurType:'PROGRESSIVE' with startRadius/startOffset/endOffset), NOISE ({color, noiseSize, density, noiseType:'MONOTONE'|'DUOTONE'|'MULTITONE'}), TEXTURE ({noiseSize, radius, clipToShape}), GLASS ({lightIntensity, lightAngle, refraction, depth, dispersion, radius}), and SHADER ({id, properties}) after the shader has been imported. Prefer apply_shader for shaders. Figma requires visible and blendMode on shadows and visible plus blurType on blurs; the bridge fills those in and strips any key the effect variant does not declare, so pass only the fields you care about and never echo back an effect read off another node. boundVariables.color can bind a variable to the shadow color. |
| create_vectorC | Create a VECTOR node from SVG path data. vectorPaths: [{data, windingRule?}]. Supports fills, strokes, strokeWeight, parentNodeId, x, y. |
| set_vector_pathsC | Replace the SVG path data on an existing VECTOR node. |
| boolean_groupC | Combine 2+ vector nodes into a boolean group (UNION, SUBTRACT, INTERSECT, EXCLUDE). |
| group_nodesC | Wrap existing nodes in a GROUP. |
| ungroup_nodeB | Ungroup a GROUP node, moving its children up to the group's parent. |
| create_sectionC | Create a SECTION node. Optional fillColor {r,g,b,a}, sectionProperties (e.g. {sectionType}), and parentNodeId. |
| set_section_propertiesC | Edit properties of an existing SECTION node, e.g. sectionType (SECTION | VIEWPORT) or the raw sectionProperties object. |
| set_text_styleB | Apply a text style and/or fine-grained typography to a TEXT node. Pass textStyleId to apply an existing style; also supports fontFamily/fontStyle, variationSettings (variable-font axes, e.g. {wght:550}), fontSize, lineHeight (number|'AUTO'|{unit,value}), letterSpacing (number|{unit,value}), textCase, textDecoration, textAlignHorizontal (LEFT|CENTER|RIGHT|JUSTIFIED), textAlignVertical (TOP|CENTER|BOTTOM), textAutoResize (WIDTH_AND_HEIGHT|HEIGHT|NONE|TRUNCATE), layoutSizingHorizontal/Vertical or width/height (FIXED|HUG|FILL), paragraphIndent/Spacing, fillsHex/fills/fillStyleId, boundVariables, textWrapStyle (AUTO|BALANCE|PRETTY), textTruncation (DISABLED|ENDING) and maxLines. |
| create_pageC | Create a new page in the document. Pass activate: true to also switch to it. |
| rename_pageC | Rename a page by pageId. |
| delete_pageA | Delete a page by pageId. Requires confirmDelete=true. |
| duplicate_pageA | Duplicate a page (including all contents) by pageId. Auto-suffixes the name (Page 2, Page 3...) unless a name is given. Pass activate: true to switch to the duplicate. |
| set_current_pageC | Set the current/active page by pageId. |
| reorder_pageB | Move a page to a new index in the page tab bar (0-based). |
| generate_gridA | Generate a grid of items inside a parent. Clones itemNodeId if given, otherwise creates rectangles of itemWidth x itemHeight. Use {i} in name for the running index. |
| bulk_renameB | Find-and-replace text in node names across a subtree (defaults to current page). Supports regex and dryRun. Returns a before/after diff. |
| bulk_updateB | Apply one property across many nodes. Supported properties: fillColor, cornerRadius, opacity, visible, name, fillStyle, textStyle, cornerRadii. Target by nodeIds, by nodeTypes under rootNodeId, or the whole current page. |
| replace_all_instancesA | Swap every instance whose main component key matches sourceComponentKey to targetComponentKey. Supports dryRun and a rootNodeId scope. |
| set_variable_modeA | Theme switch: set the variable mode for one or many nodes. modeId can be a mode id or exact mode name. Scope via nodeIds, rootNodeId (recurse defaults true, pass recurse:false for the root only), or the whole current page. |
| create_variable_modeC | Add a new mode to a variable collection. |
| rename_variable_modeC | Rename a mode within a variable collection. |
| delete_variable_modeC | Remove a mode from a variable collection. Requires confirmDelete=true. |
| rename_variable_collectionC | Rename a variable collection by collectionId. |
| delete_variable_collectionA | Delete an entire variable collection (and all its variables/modes). Requires confirmDelete=true. |
| subscribe_eventsA | Start pushing Figma events (selectionchange, documentchange) to the bridge. They land in the event log read via get_events. |
| unsubscribe_eventsC | Stop pushing selected Figma events to the bridge. |
| get_eventsA | Read pushed Figma events (selectionchange/documentchange) since a sequence cursor. Pass the previous call's currentSeq as sinceSeq to page forward. Cursor state lives in the MCP server process and resets on restart. |
| list_channelsA | Channel dashboard: lists every connected Figma plugin channel with its fileKey/fileName and connection time. |
| list_commentsC | List comments on a Figma file via the REST API (requires FIGMA_TOKEN). |
| post_commentA | Create a comment on a Figma file via the REST API (requires FIGMA_TOKEN). Optional nodeId anchors it to a node; clientMeta {x,y[,nodeId]} positions it on the canvas. |
| delete_commentB | Delete a comment from a Figma file via the REST API (requires FIGMA_TOKEN). |
| search_componentsA | Search for components/component-sets via the Figma REST API (requires FIGMA_TOKEN). Provide teamId to use /v1/team/{teamId}/components, or omit it to use /v1/me/components. Optional fileKey and pageSize filter the results. |
| export_frames_to_diskA | Bulk-export frames from a Figma file to local disk via the REST API (requires FIGMA_TOKEN). Pass nodeIds, or pass pageId to export all top-level frames on a page. Renders PNG/JPG/SVG/PDF into a folder inside the figma-write-bridge repo. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 188 tools
With 188 tools there are many overlapping purposes: figma_set_solid_fill vs set_fill_color both set solid fills, and text-setting is split across figma_set_text, set_text_content, set_multiple_text_contents, and create_text. Reaction tools (set_reactions, upsert_reaction, set_transition_reaction, set_smart_animate_reaction) and instance-creation tools (create_instance_from_component_key, create_instance_from_set_key, create_instance_from_instance, create_component_instance) also have fuzzy boundaries. Descriptions help, but an agent will frequently misselect.
The vast majority follow a predictable snake_case verb_noun pattern (create_frame, set_padding, get_node_info, delete_variable). Minor deviations exist: a handful of tools carry a figma_ prefix (figma_set_solid_fill, figma_bridge_status) and a few are not strictly verb_noun (boolean_group, combine_as_variants), but overall it is readable and consistent.
188 tools is an extreme mismatch for any single server surface, far beyond the 50+ threshold that indicates an unwieldy set. Even for a rich domain like Figma, this volume forces the agent to navigate a huge catalog and increases the chance of picking the wrong tool.
The surface covers an enormous breadth: node CRUD, fills/strokes/effects, text, auto-layout and grid, variables/tokens, components and slots, prototyping reactions and motion, styles, comments, exports, and events. Nearly every design workflow has a corresponding operation, with no obvious dead ends.