Figma Edit MCP
The Figma Edit MCP server enables AI assistants to programmatically read, create, and modify Figma designs through the Model Context Protocol (MCP), with built-in safety, validation, and batch efficiency.
Connection
Establish WebSocket communication with the Figma plugin via
join_channel
Reading & Exporting
Retrieve page structure and node details with recursive traversal, field filtering, and depth control
Export nodes as images (PNG, JPG, SVG, PDF)
Node Manipulation
Create shapes: rectangles, ellipses (arc/donut), polygons, stars, frames, text nodes, and SVG-based nodes
Move, resize, rename, clone, delete, group, ungroup, flatten, reparent, and select nodes
Styling & Effects
Set fill colors, stroke colors, and per-side stroke weights
Set uniform or per-corner radius
Apply shadows (drop/inner) and blurs (layer/background)
Link nodes to shared library styles (paint, text, effect, grid)
Auto-Layout
Configure layout mode, padding, spacing, alignment, sizing modes (FIXED/HUG/FILL), and wrapping on frames
Text & Typography
Create text nodes and batch-update content across multiple nodes
Control font family, style, size, line height, letter spacing, alignment, decoration, and casing
Components & Instances
List local and library components
Convert frames to main components; combine into variant/component sets
Create instances by node ID or library key
Add, edit, or delete component property definitions (boolean, text, instance swap)
Read overrides from a source instance and propagate them to multiple targets
Styles
List, create, update, and delete shared styles (Text, Paint, Effect, Grid)
Variables
List, create, update, and delete variables and collections (color, float, string, boolean)
Bind variables to node properties or set explicit variable modes
Safe deletion (rejected if variable is still in use)
Annotations & Prototyping
Read and batch-create/update Dev Mode annotations with markdown
Read and update prototype reactions (click flows, overlays, variable sets)
Draw connector lines between nodes and set default connector styles
Safety & Efficiency
Programmatic checks, name verification, and batch validation prevent errors and hallucinations
Bulk operations (text replacement, override propagation) enhance speed and consistency
Provides tools for reading, creating, and modifying Figma designs, including nodes, styles, components, variables, auto layout, text, and exports.
Integrates with GitHub Copilot in VS Code to enable AI-driven Figma design operations.
Integrates with Google Antigravity to perform programmatic Figma design tasks via AI.
Figma Edit MCP
Connect AI assistants to Figma via Model Context Protocol to read designs, create and modify elements, and manage design systems programmatically.
This plugin empowers your AI assistant to become a Figma assistant, executing design updates Safer, Cleaner, and Faster than a human ever could.
This plugin allows you as a Designer to focus purely on creative decision-making, leaving the error-prone & repetitive manual changes to the automated systems.
π Featured by IDEO: Letting AI edit live Figma files without trusting it to behave
π Documentation: neozhehan.github.io/figma-edit-mcp
What This Does for You
The project has three goals: Safer, Cleaner, and Faster.
π‘οΈ Safer: The plugin checks every action the AI requests before that action runs. If an action would damage the file, the plugin refuses it and tells the AI why. For example, the plugin will not delete a color variable while layers still use it. Figma itself does not warn you when you delete a variable that is in use β the deletion leaves broken references that are very hard to find afterwards.
β¨ Cleaner: Because damaging actions are refused, the file does not accumulate broken references or leftover values. Bulk updates cover every layer that matches your request, not just the layers a person remembers to check.
β‘ Faster: The AI applies one change across hundreds of layers in seconds. For example, it can replace a product name in every text layer on a page, or copy the overrides from one component instance to fifty others.
These goals support each other: when the plugin refuses mistakes, the file stays consistent, and a consistent file is easier for both you and the AI to work with.
Read the full reasoning behind these goals β
Related MCP server: figmind
What the AI Cannot Do to Your File
AI assistants sometimes invent things. An AI can name a layer that does not exist, or misremember which layer it was editing. This plugin does not depend on the AI being right. The plugin checks every edit itself, inside Figma, and refuses any edit that fails a check. The AI cannot skip these checks.
What the plugin enforces:
The AI can only edit the area you chose. When you connect, you choose one page or one frame for the session. The plugin refuses any edit outside that area. If you choose no area, the AI can read the file but cannot edit any layers.
Every edit must name its exact target layer. The plugin compares the layer name the AI supplies with the real layer's name. If the names do not match, the plugin refuses the edit. This stops the AI from editing a layer it invented or misremembered.
A bulk edit with one bad item changes nothing. The plugin validates every item in a bulk edit before it changes the first one. If any item fails validation, the plugin rejects the entire bulk edit.
Protected layers stay protected. The plugin refuses edits to locked layers and to assets from shared libraries. It also refuses to add, delete, or move layers inside a component instance.
The AI cannot delete its own working area. The plugin refuses any action that would delete or replace the page or frame you assigned for the session.
Variables and styles require separate permission. Editing your variables or styles requires its own checkbox in the plugin, and both checkboxes are off by default. You grant that permission; the AI cannot grant it to itself.
One honest limit: the plugin checks where an edit happens and which layer it touches. It cannot check whether the edit is the one you wanted. A wrong edit that follows all the rules will go through. So you review the AI's work the same way you would review a colleague's work.
The exact rules, and the conditions under which each one holds, are written down in SAFETY.md. That document is for developers. (Your AI assistant loads the same rules at runtime via the figma-edit skill or the figma-edit://guide/* resources.)
How the Work Is Divided
You do not need to know every Figma feature to direct this system. The work splits three ways:
You decide what the design should be. You describe the change in plain language, and you judge the result. You do not need to know which Figma menu or panel performs the change.
The AI assistant turns your request into specific Figma operations and carries out the repetitive work across many layers.
The plugin runs inside Figma, checks each operation, and refuses the unsafe ones.
The AI contributes scale. The plugin contributes protection. You contribute the design judgment.
Supported AI Integrations
Cursor
GitHub Copilot (VS Code)
Google Antigravity
Claude Code (VS Code & CLI)
Claude Desktop (Chat, Cowork & Code)
LM Studio
Quick Start
The quickest way to run Figma Edit MCP is directly from the NPM registry. You do not need to clone this repository.
1. Configure your AI assistant
Add the server to your AI assistant's MCP configuration:
{
"mcpServers": {
"FigmaEdit": {
"command": "npx",
"args": ["-y", "figma-edit-mcp"]
}
}
}The config file location depends on your host β see Integration-Specific Setup below. Bun users can substitute bunx for npx; both resolve the same package.
2. Start the WebSocket bridge
In a terminal, start the bridge that connects the MCP server to the Figma plugin. Keep this terminal running:
npx -y --package figma-edit-mcp figma-edit-mcp-socket3. Install the Figma plugin
The Figma plugin ships inside the NPM package. Install the package once to materialize the plugin files on disk:
# In any directory of your choosing (e.g., ~/figma-edit-mcp/)
npm install figma-edit-mcpThen in the Figma desktop app:
Open Plugins β Development β Import plugin from manifestβ¦
Select
node_modules/figma-edit-mcp/figma_plugin/manifest.jsonfrom the directory above.
The plugin is now available under Plugins β Development in any Figma file.
4. (Optional) Install the agent skill
The package also ships a cross-tool skill that teaches your agent the server's safety constraints, error recovery, and tool selection β loaded on demand, so it costs almost nothing until needed. Agents that support the open SKILL.md standard (Claude Code, GitHub Copilot, OpenAI Codex, Cursor, Gemini CLI, Google Antigravity) discover it once it's in their skills directory:
# copy the skill into your agent's skills directory (path varies by host)
cp -R node_modules/figma-edit-mcp/skills/figma-edit ~/.claude/skills/Clients that don't support skills can still reach the same guidance over the MCP connection as resources under figma-edit://guide/* β no install required.
Running from a local clone? See CONTRIBUTING.md for the contributor-only --local development workflow.
Integration-Specific Setup
Paste the JSON snippet from the Quick Start into your host's MCP config file:
Integration | Config File Location | Notes |
Cursor |
| Restart Cursor after editing |
VS Code / GitHub Copilot |
| Requires VS Code 1.102+ with Copilot; enable Agent Mode |
Google Antigravity |
| Restart Antigravity to load |
Claude Desktop |
| β |
Claude Code (CLI / VS Code) | run | No file edit needed |
LM Studio | edit | Or use a deeplink, if provided |
Manual Configuration
If you prefer to edit your host's MCP config directly, paste this snippet into the appropriate config file:
{
"mcpServers": {
"FigmaEdit": {
"command": "npx",
"args": ["-y", "figma-edit-mcp"]
}
}
}Integration | Config File Location |
Cursor |
|
VS Code / Copilot |
|
Antigravity |
|
Claude Desktop |
|
LM Studio | Use the in-app editor (via Developer tab) or edit |
Running from a local clone? See CONTRIBUTING.md for the --local workflow.
Contributing
For local development β building from source, running the bridge from a clone, and the --local integrate workflow β see CONTRIBUTING.md.
Windows + WSL Guide
To allow Figma (running on Windows) to connect to the bridge (running inside WSL), the bridge needs to listen on 0.0.0.0 instead of localhost:
npx -y --package figma-edit-mcp figma-edit-mcp-socket --host 0.0.0.0
# or via environment variable:
FIGMA_EDIT_MCP_SOCKET_HOST=0.0.0.0 npx -y --package figma-edit-mcp figma-edit-mcp-socketThen point the Figma plugin's WebSocket address at your WSL instance's IP.
Usage
Start the WebSocket bridge:
npx -y --package figma-edit-mcp figma-edit-mcp-socketConfigure the MCP server in your AI assistant (see Integration-Specific Setup)
Open Figma and launch the Figma Edit MCP plugin from Plugins β Development
Use the
channel_joinMCP tool to establish communicationUse your AI assistant to interact with Figma via the available MCP tools
MCP Tools
Tools are grouped into a two-level, underscore-separated namespace (group_action). Reads are *_list / *_info; writes use verb leaves. Anything that mutates a node lives under node_*.
page β pages
Tool | Description |
| List the document's pages; with |
node β read, transform, and style any node
Tool | Description |
| Read one or more nodes β recursive traversal with |
| Move and/or resize a node by setting absolute |
| Rename a node |
| Delete one or more nodes in a single validated batch |
| Duplicate a node, optionally at a new position |
| Navigate the editor view to a page or node(s) |
| Wrap nodes in a new group |
| Dissolve a group, promoting its children |
| Flatten a node and its children into a single vector |
| Reparent a node under a new parent at an optional index |
| Configure a frame's auto-layout (mode, padding, spacing, alignment, sizing) |
| Set a node's fill to a color or image, or clear it |
| Set stroke color and weight (uniform or per-side) |
| Set corner radius (uniform or per-corner) |
| Set the effect array (shadows, blurs) |
| Link a node to a shared library style (paint/text/effect/grid) |
| Bind a variable to a node property, or set an explicit variable mode |
| Render a node to an image (PNG / JPG / SVG / PDF) |
create β make new nodes
Tool | Description |
| Create a rectangle, ellipse, polygon, or star ( |
| Create a frame with optional fill/stroke and full auto-layout |
| Create a text node with optional font size/weight/color |
| Create a node from an SVG markup string |
| Convert an existing frame into a main component |
| Instantiate a component at a position |
| Combine components into a component set (variants) |
style β shared styles
Tool | Description |
| List all local styles (paint/text/effect/grid) |
| Create a named style, or update one when |
| Delete a local style by id (detaches consumers, which keep their resolved values) |
text β text content & typography
Tool | Description |
| Batch-set the text of one or more text nodes |
| Set any combination of typography properties on a text node |
component β components & variants
Tool | Description |
| List components, with filtering and scope options |
| Add or edit a component-property definition (BOOLEAN/TEXT/INSTANCE_SWAP) |
| Remove a component-property definition |
instance β component instances
Tool | Description |
| Set one property on an instance (toggle, text, swap, or variant) |
| Read the override properties from a source instance |
| Apply copied overrides to target instances |
variable β variables & collections
Tool | Description |
| List variables/collections, or detail by ID; optionally scan consumers |
| Create collections and variables and set values/aliases |
| Delete variables or a collection (rejected if still in use) |
annotation β Dev Mode annotations
Tool | Description |
| Read annotations on a node; optionally include categories |
| Batch create or update native annotations (markdown) |
reaction β prototype reactions
Tool | Description |
| Read prototype reactions (click flows, overlays) from nodes |
| Replace a node's reactions with a full new array |
channel β connection
Tool | Description |
| Join a WebSocket channel to establish communication with the plugin |
MCP Prompts
Built-in prompts guide complex multi-step design tasks:
Prompt | Description |
| Transfer component instance overrides from a source to multiple targets |
Best Practices
When working with Figma Edit MCP:
Always join a channel first with
channel_joinbefore sending any other commands.
Notes
Automatic Node ID Normalization
Node IDs copied from Figma URLs use dashes (20485-41), but the plugin API expects colons (20485:41). The MCP server automatically converts dash-format IDs before forwarding, so either format works without manual intervention.
Acknowledgements
Built on prior work by sonnylazuardi and the contributors to grab/cursor-talk-to-figma-mcp. Thank you for the foundation this project builds on.
Thanks to @dusskapark for the following contributions:
Bulk text content replacement β Batch-update text across large designs efficiently. Demo video
Instance override propagation β Propagate component instance overrides from a source to multiple targets in a single command, dramatically reducing repetitive design work. Demo video
License
The MIT License (MIT)
Copyright (c) 2025 sonnylazuardi
Copyright (c) 2026 Neo Product LLC
Available Tools
45 toolsannotation_listList AnnotationsARead-only
Read the native annotations on a page or node (and subtree); exactly one of pageId or nodeId is required. The file's annotation categories are returned by default; pass includeCategories: false to omit them. Page loading is bounded; a page-scoped failure returns its structured error directly and successful reads include coverage.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | No | The node ID to get annotations from. Exactly one of pageId or nodeId is required. | |
| pageId | No | The page ID to get annotations from. Exactly one of pageId or nodeId is required. | |
| includeCategories | No | Include the file's global annotation categories in the result. Defaults to true; pass false to omit them. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| coverage | No | Page-scan coverage; partial read data remains usable when complete is false |
| categories | No | List of global annotation categories |
| annotatedNodes | No | Grouped annotations, preserving the owning node in page and node modes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint and openWorldHint, but the description adds meaningful behavioral details: 'Page loading is bounded; a page-scoped failure returns its structured error directly and successful reads include `coverage`.' This goes beyond the annotation and informs the agent about edge cases and return characteristics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each serving a distinct purpose: scope, parameter constraints, and behavioral edge cases. The description is front-loaded with the core action and is free of fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (3 params, output schema exists), the description covers all essential aspects: the resource being read, the parameter exclusivity, optional categories, and potential partial failure behavior. No important gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all three parameters. The description reinforces the mutual exclusivity and default for includeCategories but adds no new semantic details beyond what the schema provides, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Read the native annotations on a page or node (and subtree)', which is a specific verb and resource. It clearly distinguishes this read tool from the sibling write tool annotation_set and other list-style tools like style_list or variable_list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states the core usage rule ('exactly one of pageId or nodeId is required') and mentions the includeCategories toggle. While it doesn't explicitly say when not to use it, the read-only intent and sibling set (annotation_set for writing) imply appropriate usage clearly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
annotation_setSet AnnotationsA
Append native annotations to one or more nodes in a batched call. If the status is 'partial_success', treat it as an incomplete operation and report the failed and skipped items to the user. Appending is NOT idempotent and a 'failed' row may already have appended its annotation (verified counts differ, or outcomeUnknown is true when post-state is unreadable; both carry partialMutation: true) β before retrying any non-success item, call annotation_list and compare the labels already on the node, or you will create a duplicate.
| Name | Required | Description | Default |
|---|---|---|---|
| annotations | Yes | Array of annotations to set |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| status | No | Overall status of the batch operation |
| results | No | Detailed execution results with before/after annotation counts (one row per input, in input order) |
| success | No | Whether all annotations were set successfully |
| failedCount | No | Number of failed annotations |
| skippedCount | No | Number of skipped annotations |
| requestedCount | No | Number of requested annotations |
| succeededCount | No | Number of succeeded annotations |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description richly discloses non-idempotency, partial mutation semantics, possible false failures, and validation steps, going far beyond the openWorldHint annotation. This is exemplary behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences convey the core purpose and critical operational warnings without filler. Every clause adds value, and the warning about non-idempotency is essential to safe use.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's batch, non-idempotent nature and the presence of an output schema, the description covers operational pitfalls, error handling, and verification workflow. It is complete enough without explaining return values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed descriptions for the annotations array, including the properties enum and nodeName requirement. The description itself adds no additional parameter-level meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Append native annotations to one or more nodes in a batched call' β a specific verb and resource. It clearly distinguishes from sibling annotation_list and other node-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides actionable guidance on handling partial_success and explicitly instructs to call annotation_list before retrying non-success items to avoid duplicates. However, it does not broadly state when to use this tool vs alternatives beyond this retry scenario.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
channel_joinJoin ChannelAIdempotent
Join a plugin channel to establish the live connection to the Figma document.
| Name | Required | Description | Default |
|---|---|---|---|
| channel | Yes | The name of the channel to join |
Output Schema
| Name | Required | Description |
|---|---|---|
| node | No | |
| error | No | |
| pages | No | |
| status | No | Connection status |
| channel | No | Channel name |
| errorCode | No | Error code if status is error |
| pageCount | No | Number of pages in the document |
| documentId | No | Figma document ID |
| scopeRootId | No | Editable scope root node ID |
| documentName | No | Figma document name |
| errorDetails | No | Structured error context if status is error and the underlying failure carried any |
| errorMessage | No | Error message if status is error |
| allowEditNode | No | false | 'page' | 'node' |
| pluginVersion | No | Self-reported bound Figma plugin build version (present on every successful join) |
| serverVersion | No | Self-reported MCP server build version (present on every successful join) |
| allowEditStyle | No | Whether style edits are allowed |
| allowEditVariable | No | Whether variable edits are allowed |
| editableScopeType | No | readonly, page, or node |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that joining a channel establishes a live connection, which is a behavioral trait beyond the idempotent and open-world hints already provided in annotations. It adds useful context about the connection side effect without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that places the action first and states the purpose without any wasteful words or redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity tool with a single parameter, an output schema, and informative annotations, the description provides sufficient context about the tool's purpose and effect. It lacks explicit preconditions or examples, but the combination of schema and annotations fills that gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully describes the single 'channel' parameter with a clear description, and schema coverage is 100%. The tool description adds no extra semantic detail beyond what the schema provides, so a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Join' and identifies the resource 'plugin channel', with a clear outcome of establishing a live connection to the Figma document. This clearly distinguishes it from sibling tools focused on node operations and styles.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a clear context for use: when a live connection to the Figma document via a plugin channel is needed. It does not explicitly state exclusions or alternatives, but since no sibling tool handles channels, the usage context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
component_delete_propertyDelete Component PropertyADestructiveIdempotent
Remove a component-property definition from a main component or variant set; propagates to every instance.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | ID of the COMPONENT or COMPONENT_SET | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. | |
| propertyName | Yes | The human-readable name of the property to delete |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the component/component set |
| name | No | Name of the component/component set |
| error | No | |
| results | No | Detailed execution results |
| success | No | Whether property deletion was successful |
| propertyName | No | The deleted property name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint, idempotentHint, and openWorldHint; the description adds meaningful context by stating that the removal propagates to every instance and that it applies to main components or variant sets. It does not contradict the annotations and provides extra side-effect awareness beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the action, target, and consequence. It contains no filler or redundancy, earning its place entirely.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description captures the core purpose, the allowed node types, and the propagation effect. Given that the schema covers parameters and an output schema exists, the description is sufficiently complete for correct tool selection and invocation. It does not mention error cases or prerequisites, but openWorldHint and the existing schema make those less critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for all three parameters, so the schema already explains nodeId, nodeName, and propertyName with adequate detail. The tool description does not add parameter-specific guidance, but it does not need to since the schema covers the semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Remove a component-property definition'), a clear target ('from a main component or variant set'), and a notable effect ('propagates to every instance'). This clearly distinguishes it from sibling tools like component_manage_property, which focuses on property management, and from delete tools for nodes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (when removing a property definition) and notes the propagation consequence, but it does not explicitly name alternatives or when-not-to-use conditions. The sibling list suggests component_manage_property as the related management tool, but the description does not reference it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
component_listList ComponentsARead-only
List components in the document, with filtering and scope options. Document scans isolate page failures and report them in coverage; page-scoped failures return their structured error directly.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | Scope of the search: 'page' (queries a specific page, requiring pageId) or 'document' (entire file, default). | document |
| filter | No | Filter components by origin: 'local' (created in this file) or 'remote' (library components). If omitted, returns all. | |
| pageId | No | The ID of the page to query when scope is 'page' |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | Total count of components |
| error | No | |
| coverage | No | Page-scan coverage; partial read data remains usable when complete is false |
| components | No | List of component objects |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only and open-world behavior, but the description adds valuable context: document scans report failures via a 'coverage' field, while page-scoped scans return structured errors directly. This explains edge-case behavior beyond what the annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is only two sentences long. The first sentence states the core purpose and capabilities; the second provides a concise behavioral nuance about error handling. Every phrase earns its place with no fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is straightforward with optional parameters, and an output schema exists so return values are documented there. The description explains the key difference between document and page scope error behavior, which is essential for correct usage. It lacks nothing critical for an AI agent to invoke it properly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers 100% of parameter descriptions, so the description is not required to repeat them. It does reference 'filtering and scope options' generically, which aligns with the schema but adds no new detail. Given the schema coverage, a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb and resource: 'List components in the document.' It explicitly mentions filtering and scope options, and the additional detail about failure reporting distinguishes it from generic list tools. This leaves no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states the primary use case (listing components) and even distinguishes between document and page scope behaviors. It does not explicitly name alternative tools or say when not to use it, but the resource is so specific that confusion with sibling list tools (style_list, variable_list) is unlikely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
component_manage_propertyManage Component PropertyA
Add or edit a component-property definition (BOOLEAN/TEXT/INSTANCE_SWAP) on a main component or variant set. Deleting is component_delete_property.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Action to perform | |
| nodeId | Yes | ID of the COMPONENT or COMPONENT_SET | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. | |
| defaultValue | No | Required for ADD: Default value for the property. For INSTANCE_SWAP, this must be a component node ID. | |
| propertyName | Yes | For ADD, the required new property name, which must be non-empty. For EDIT, the existing property's exact lookup name. | |
| propertyType | No | Required for ADD: The type of property | |
| newDefaultValue | No | For the EDIT action, to change the default value. For INSTANCE_SWAP, this must be a component node ID. | |
| newPropertyName | No | For EDIT, the optional replacement property name. It must be non-empty when supplied; omit it to leave the existing property name unchanged. | |
| preferredValues | No | Array of preferred values for INSTANCE_SWAP properties during ADD or EDIT. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the component/component set |
| name | No | Name of the component/component set |
| error | No | |
| action | No | The action that was performed (ADD/EDIT) |
| results | No | Detailed execution results |
| success | No | Whether property management was successful |
| propertyName | No | The affected property name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description clarifies the mutating scope ('main component or variant set') and the property types supported, and directs deletion elsewhere. With openWorldHint as the only annotation, this adds useful safety and scope context, though it does not detail side effects on instances or permission requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with the action and resource, followed by a single purposeful pointer to the deletion sibling. No filler or redundant detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich input schema and output schema, the description provides the essential scope (main component/variant set) and deletion alternative. It doesn't explain return value or prereqs, but those are covered by structured fields, making this adequate for a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all 9 parameters. The description repeats type names (BOOLEAN/TEXT/INSTANCE_SWAP) and target concept already in nodeId/nodeName descriptions, adding no extra semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb phrase 'Add or edit' and clearly identifies the resource as 'component-property definition' on 'main component or variant set', with allowed types enumerated. It distinguishes itself from the deletion counterpart by naming component_delete_property, and from sibling tools like instance_set_property by specifying the target scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states that deleting is handled by component_delete_property, giving a clear exclusion. It does not discuss when to choose ADD vs EDIT, but the schema and parameter descriptions cover that. Overall it provides clear context without naming all sibling alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_componentCreate ComponentA
Convert an existing frame into a main component.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the frame to convert to a component | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the created component |
| name | No | Name of the created component |
| error | No | |
| parentId | No | ID of the parent the component was placed into β confirm containment without a follow-up read |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that the tool transforms a frame into a main component, but it does not detail side effects or prerequisites (e.g., that the frame is modified in place, or that nodeName must match exactly). The annotation openWorldHint is present, but the description adds minimal context beyond that; 'convert' implies a state change, yet the potential destructive nature is not clarified.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. It efficiently conveys the tool's purpose and earns its place without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, and the schema covers parameter details while an output schema exists (likely describing the created component). The description is sufficient for the core action, though it could mention the need to fetch nodeName via node_info, but that is already captured in the schema, so the description remains complete enough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the parameters (nodeId and nodeName) are fully described in the input schema, including the requirement that nodeName be passed verbatim from node_info. The description itself adds no parameter information, which is acceptable given the schema's completeness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Convert an existing frame into a main component' clearly states the action (convert), the resource (existing frame), and the result (main component). It distinguishes this tool from siblings like create_instance (which creates an instance) and create_component_set (which creates a set).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when there is an existing frame to convert, but it does not explicitly mention when not to use it or provide alternatives. Sibling tool names suggest related tools, but no direct comparison is made, so guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_component_setCreate Component SetA
Combine components into a component set (variants) with property definitions.
| Name | Required | Description | Default |
|---|---|---|---|
| parentId | Yes | ID of the appendable parent container (frame, group, page, section, etc.) to place the set in; discover it with node_info | |
| components | Yes | Array of component objects | |
| properties | Yes | Array of property names (e.g. ['Size', 'State']) | |
| parentNodeName | Yes | The parent node's current exact name, passed back verbatim from `node_info`. | |
| componentSetName | No | Optional non-empty name for the component set |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the created component set |
| name | No | Name of the component set |
| type | No | Node type (COMPONENT_SET) |
| error | No | |
| warning | No | Warning message if some properties could not be read |
| parentId | No | ID of the parent the set was placed into β confirm containment without a follow-up read |
| childCount | No | Number of variants in the set |
| variantProperties | No | Variant properties definition |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations include only openWorldHint: true, which does not capture safety or side effects. The description states 'Combine components into a component set' but does not disclose that the operation may mutate the source components, alter their parent container, or require specific permissions. This leaves the agent without critical behavioral context for a create/mutation operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence of 11 words that captures the core action and key distinguishing detail. No unnecessary words; structurally ideal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complete parameter schema, existing output schema, and an annotation, the description is adequate but not fully complete. It omits clarifying how propertyValues map positionally to properties (though schema hints at this) and does not explain the practical effect on the component set's parent hierarchy. However, the overall context from schema is strong.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with each parameter having a descriptive comment (e.g., parentId explains it is an appendable container and references node_info). The description itself adds no additional parameter semantics, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the active verb 'Combine' and specifically names the resource 'component set (variants) with property definitions,' making it clear what the tool accomplishes. It differentiates from sibling tools like create_component and create_instance by its focus on combining multiple components into a set.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly mention when to use this tool versus alternatives such as create_component or component_manage_property. It implies that it is used when existing components need to be combined into a set, but provides no explicit exclusions or alternative suggestions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_frameCreate FrameA
Create a frame (container) with optional fill/stroke and full auto-layout configuration.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | X position | |
| y | Yes | Y position | |
| name | No | Optional non-empty name for the frame | |
| width | Yes | Width of the frame | |
| height | Yes | Height of the frame | |
| parentId | Yes | Parent node ID to append the frame to | |
| fillColor | No | Fill color in RGBA format | |
| layoutMode | No | Auto-layout mode for the frame | |
| layoutWrap | No | Whether the auto-layout frame wraps its children | |
| paddingTop | No | Top padding for auto-layout frame | |
| itemSpacing | No | Distance between children in auto-layout frame. Note: This value will be ignored if primaryAxisAlignItems is set to SPACE_BETWEEN. | |
| paddingLeft | No | Left padding for auto-layout frame | |
| strokeColor | No | Stroke color in RGBA format | |
| paddingRight | No | Right padding for auto-layout frame | |
| strokeWeight | No | Stroke weight | |
| paddingBottom | No | Bottom padding for auto-layout frame | |
| parentNodeName | Yes | The parent node's current exact name, passed back verbatim from `node_info`. | |
| layoutSizingVertical | No | Vertical sizing mode for auto-layout frame | |
| counterAxisAlignItems | No | Counter axis alignment for auto-layout frame | |
| primaryAxisAlignItems | No | Primary axis alignment for auto-layout frame. Note: When set to SPACE_BETWEEN, itemSpacing will be ignored as children will be evenly spaced. | |
| layoutSizingHorizontal | No | Horizontal sizing mode for auto-layout frame |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the created frame |
| name | No | Name of the created frame |
| error | No | |
| parentId | No | ID of the parent the node was placed into β confirm containment without a follow-up read |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description only states that it creates a frame, but does not disclose behavioral traits beyond the act of creation. With only openWorldHint annotation and no readOnly/destructive hints, the description fails to mention side effects (e.g., modifying the parent, potential error conditions, irreversibility). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence that is concise and free of redundancy. It conveys the core purpose without unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (21 params, nested objects, output schema), the description is minimal but adequate because the schema covers parameters and an output schema exists. However, it omits useful context such as the requirement for parentNodeName to match exactly and that auto-layout settings are only relevant when layoutMode is set, which would aid correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description adds minimal grouping ('optional fill/stroke and full auto-layout configuration') which maps to params like fillColor, strokeColor, and layoutMode, but does not add significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Create') and resource ('frame') and adds clarifying details ('container with optional fill/stroke and full auto-layout configuration'). This clearly distinguishes it from sibling tools like create_shape, create_text, and create_component_set.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clarifies the tool's purpose as creating a frame/container with auto-layout, implying use for layout containers rather than shapes or text. It does not explicitly mention alternatives or when-not-to-use, but the context is clear enough for selection among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_instanceCreate InstanceB
Instantiate a component (by componentKey or componentId) at a position.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | X position | |
| y | Yes | Y position | |
| parentId | Yes | Parent node ID to append the instance to | |
| componentId | No | Node ID of the component to instantiate (preferred for local components) | |
| componentKey | No | Key of the component to instantiate (for remote/library components) | |
| parentNodeName | Yes | The parent node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the created component instance |
| name | No | Name of the component instance |
| error | No | |
| parentId | No | ID of the parent the instance was placed into β confirm containment without a follow-up read |
| componentId | No | ID of the component the instance was created from |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds no behavioral context beyond the openWorldHint annotation. It doesn't mention side effects, prerequisites (e.g., existing component), or the outcome on the parent node. The annotation already signals open-world behavior, but the description fails to enrich that signal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence with no wasted words. It front-loads the core action and is appropriately sized for a simple tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite complete schema coverage and an output schema, the description is too thin to fully contextualize the tool's role. It doesn't explain the effect on the node tree, the difference between componentKey and componentId, or how it relates to sibling creation tools. This is sparse for a 6-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with each parameter described, so a baseline of 3 is appropriate. The description only names componentKey and componentId without adding meaning beyond the schema, leaving the schema to carry the full semantic load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the action ('Instantiate'), the resource ('a component'), and the method ('by componentKey or componentId') along with a position. This distinguishes it from sibling tools like create_component, which create new component definitions rather than placing instances.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usageβwhen you want to place a component instanceβbut it does not explicitly state when to use this tool over alternatives or mention any exclusions. The distinction from create_component is implied by the word 'instantiate' but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_shapeCreate ShapeA
Create a rectangle, ellipse, polygon, or star via type, with position/size and optional fillColor/strokeColor. Shape-specific params (arcData; pointCount/innerRadius) validated by type. pointCount = sides (polygon) or points (star), native count β no even-parity rule.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | X position | |
| y | Yes | Y position | |
| name | No | Optional non-empty name for the shape | |
| type | Yes | The type of shape to create | |
| width | Yes | Width of the shape | |
| height | Yes | Height of the shape | |
| arcData | No | Optional arc data for creating arcs/donuts (ELLIPSE only) | |
| parentId | Yes | Parent node ID to append the shape to | |
| fillColor | No | Fill color in RGBA format | |
| pointCount | No | Number of sides (polygon) or points (star), β₯3. Required for POLYGON and STAR. | |
| innerRadius | No | 0.0β1.0, star sharpness (default: 1.0). STAR only. | |
| strokeColor | No | Stroke color in RGBA format | |
| parentNodeName | Yes | The parent node's current exact name, passed back verbatim from `node_info`. | |
| useAbsolutePosition | No | If true and parent is an auto-layout frame, forces absolute positioning to prevent layout shifts. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the created shape |
| name | No | Name of the created shape |
| error | No | |
| parentId | No | ID of the parent the node was placed into β confirm containment without a follow-up read |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only openWorldHint=true in annotations, the description takes on substantial behavioral disclosure. It explains that shape-specific params are validated by `type`, clarifies pointCount semantics (sides vs points), and explicitly notes the 'no even-parity rule'βuseful nuance not present in structured metadata.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler, front-loads the primary action, and uses inline code for parameter names. The second sentence adds critical nuance about shape-specific validation and pointCount semantics without bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 14-parameter creation tool with a rich schema and output schema, the description covers the central type-dispatch behavior and key parameter constraints. It does not repeat every parameter (schema covers those) but provides the high-level overview and crucial pointCount clarification needed for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes all 14 parameters (100% coverage), so the baseline is 3. The description adds value beyond the schema by grouping arcData, pointCount, and innerRadius as shape-specific and validated by `type`, and by clarifying pointCount's native-count meaning and the absence of an even-parity rule.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Create') and explicitly enumerates the four shape types ('rectangle, ellipse, polygon, or star') via `type`, which clearly distinguishes it from sibling creation tools. It also specifies position/size and optional colors, giving a precise scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool by naming the exact shape types it supports. However, it does not explicitly mention alternatives or exclusion criteria, though the type enumeration makes the intended use fairly unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_svgCreate Node from SVGB
Create a node from an SVG markup string.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | X position | |
| y | No | Y position | |
| svg | Yes | The SVG XML string | |
| name | No | Optional non-empty name for the new node | |
| parentId | Yes | Parent ID to append to | |
| parentNodeName | Yes | The parent node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the created node |
| name | No | Name of the created node |
| error | No | |
| parentId | No | ID of the parent the node was placed into β confirm containment without a follow-up read |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is minimal and adds no behavioral context beyond the action itself. It doesn't disclose side effects, such as whether the SVG is parsed, whether existing nodes are affected, or any validation rules. The only annotation is openWorldHint, which is not enriched by the description. For a create operation, the mutation is obvious, but other behavioral traits remain opaque.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence with no wasted words. It directly states the core action and object. This is appropriately concise for a tool with rich schema coverage, earning full marks for structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has six parameters and no nested objects, the description is insufficiently complete. It lacks context on when to use this tool, the significance of the required parentId and parentNodeName, and any potential side effects. While the schema and output schema cover technical details, the description fails to provide essential usage context, making the overall description incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides full descriptions for all six parameters, including parentNodeName's 'passed back verbatim from node_info.' With 100% schema coverage, the description adds no additional parameter meaning. Baseline of 3 is appropriate because the schema carries the semantic weight, and the description offers no extra clarification.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Create a node from an SVG markup string.' This uses a specific verb ('Create') and resource ('node from SVG'), and distinguishes it from sibling tools like create_shape, create_text, and create_component, which create different node types. The title reinforces this, making the action unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no guidance on when to use this tool versus alternatives. It doesn't mention that this is for SVG-based nodes or provide any context about prerequisites (e.g., needing an SVG string). Common usage can be inferred from the name and schema, but no explicit or implied usage scenarios or exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_textCreate TextB
Create a text node with content and optional font size/weight/color.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | X position | |
| y | Yes | Y position | |
| name | No | Optional non-empty semantic layer name for the text node | |
| text | Yes | Text content | |
| fontSize | No | Font size, minimum 1 (default: 14) | |
| parentId | Yes | Parent node ID to append the text to | |
| fontColor | No | Font color in RGBA format | |
| fontWeight | No | Font weight: 100β900 in increments of 100 (default: 400) | |
| parentNodeName | Yes | The parent node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the created text node |
| name | No | Name of the created text node |
| error | No | |
| parentId | No | ID of the parent the node was placed into β confirm containment without a follow-up read |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only an openWorldHint annotation and no readOnly or destructive hints, the description carries the transparency burden. It simply states the action and styling options, without disclosing side effects, required parent context, or behavior on invalid input. The openWorldHint is not elaborated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that front-loads the verb and object. No wasted words, perfectly sized for the purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's 9 parameters, nested fontColor object, and openWorldHint, the one-sentence description is fairly sparse. It omits mention of the parent requirement (though present in schema) and potential side effects. However, the rich schema and presence of an output schema reduce the burden, so a mid-range score is appropriate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with descriptions for all 9 parameters. The description adds minimal value by grouping 'font size/weight/color' but doesn't introduce any parameter meaning beyond what the schema already provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Create') and resource ('a text node') and names the key styling options (font size/weight/color). This clearly distinguishes it from sibling creation tools like create_shape or create_frame.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives such as text_set_content or text_set_style. It also omits prerequisites like obtaining parentNodeName from node_info, which is only mentioned in the schema, not in the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
instance_get_overridesGet Instance OverridesARead-only
Read the override properties from a source instance, to later apply them to other instances.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the component instance to get overrides from. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| message | No | Status message |
| success | No | Whether overrides retrieval was successful |
| overridesCount | No | Number of overrides found |
| mainComponentId | No | ID of the main component |
| sourceInstanceId | No | Source instance ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already covers safety, and the description adds scoping ('from a source instance') and purpose ('to later apply them'), which is useful but not rich. It does not disclose additional behaviors like return format or side effects, but the output schema and readOnlyHint mitigate the need.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single clear sentence, front-loaded with the action verb 'Read'. No wasted words; every element adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool with one parameter, full schema coverage, readOnly and openWorld hints, and an output schema, the description provides enough context. It explains the tool's purpose and the source instance, while the structured fields handle return values and parameter details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides a full description for nodeId ('The ID of the component instance to get overrides from'), so the baseline is 3. The tool description's 'source instance' echoes the schema without adding significant new meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Read') and resource ('override properties from a source instance'), clearly distinguishing it from generic read tools like node_info and its counterpart instance_set_overrides. The stated purpose ('to later apply them to other instances') adds context that reinforces the tool's role in copying overrides.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly conveys when to use the tool: when you need to read override properties from a source instance to apply elsewhere. It does not explicitly mention alternatives or exclusions, but the context is unambiguous and the sibling tool instance_set_overrides is implicitly contrasted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
instance_set_overridesSet Instance OverridesAIdempotent
Apply previously-read overrides to target instances; targets are swapped to the source component and all overrides applied. If the status is 'partial_success', treat it as an incomplete operation, report the failed and skipped items to the user, and retry every non-success item (both failed and skipped).
| Name | Required | Description | Default |
|---|---|---|---|
| targetNodes | Yes | Array of target instances with their expected names for verification. | |
| sourceInstanceId | Yes | ID of the source component instance |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| status | No | Overall status of the batch operation |
| results | No | Results per target node (one row per input, in input order) |
| success | No | Whether overrides application was successful |
| failedCount | No | Number of failed targets |
| skippedCount | No | Number of skipped targets |
| requestedCount | No | Number of requested targets |
| succeededCount | No | Number of succeeded targets |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description provides critical behavioral details beyond the annotations (openWorldHint, idempotentHint) by defining how to handle 'partial_success' status: report failed/skipped items and retry all non-success items. This is valuable operational transparency that the agent would otherwise not know.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core action and followed by a crucial conditional instruction. Every word earns its place, with no redundancy or unnecessary elaboration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given full schema coverage, an output schema, and the presence of annotations, the description is complete. It explains the core operation, the swapping behavior, and the critical partial-failure handling, leaving no significant gaps for the agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides complete descriptions for both parameters (sourceInstanceId and targetNodes, including nodeId and nodeName with their expected values). The description does not add new parameter-level details, but it reinforces the workflow by mentioning 'targets' and 'source component', which aligns with the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Apply previously-read overrides') and identifies the target resource ('target instances') plus the mechanism ('targets are swapped to the source component and all overrides applied'). It clearly distinguishes from sibling tools like instance_set_property, which applies a single property override, by emphasizing the batch application of overrides.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'previously-read overrides' implies the tool is used after reading overrides, providing clear context. The description also specifies what happens during the operation (swap and apply), but it doesn't explicitly state when not to use it or name alternatives. However, the context is sufficiently clear for an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
instance_set_propertySet Instance PropertyAIdempotent
Set one property on an instance β boolean toggle, text override, instance swap, or variant selection.
| Name | Required | Description | Default |
|---|---|---|---|
| value | Yes | The new value for the property. For INSTANCE_SWAP properties, this must be a component key (the stable library identifier). | |
| nodeId | Yes | The ID of the instance node | |
| nodeName | Yes | The instance's current exact name, passed back verbatim from `node_info`. | |
| propertyName | Yes | The human-readable name of the component property to change |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| results | No | Execution details |
| success | No | Whether property update was successful |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true, so the safety profile is covered. The description adds the four property-value categories but does not disclose that setting replaces existing values or that INSTANCE_SWAP requires a stable component key (the latter appears in schema). No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded with verb and object, and each clause adds meaning. No filler or redundant restatement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With full schema descriptions, an output schema, and idempotence annotation, the concise description suffices for a single-property mutation. It lacks explicit cross-reference to `instance_set_overrides`, but that is a usage-guideline gap, not a completeness failure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions for all four parameters, including the exact `nodeName` requirement and `value` constraint for INSTANCE_SWAP. The description's category list (boolean toggle, text override, etc.) adds semantic grouping but no additional parameter-level syntax. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Set') and resource ('instance'), plus scope ('one property'), and enumerates property categories. It distinguishes from sibling `instance_set_overrides` by emphasizing single-property scope. Clear and actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies single-property usage but never states when to prefer this over `instance_set_overrides` or how to discover valid property names. No exclusions or alternative tools are mentioned. This is minimal usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_apply_styleApply StyleAIdempotent
Link a node to a shared library style (paint/text/effect/grid) by styleId. Use the raw node_set_* setters for ad-hoc values not backed by a style.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the node to apply style to | |
| styleId | Yes | The ID of the style to apply | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. | |
| styleType | Yes | Type of style to apply (target property) |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Name of the modified node |
| error | No | |
| success | No | Whether the style was applied successfully |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations include idempotentHint and openWorldHint but no destructive/read-only flags. The description clarifies the action as 'link' but doesn't disclose side effects such as whether existing styles are replaced or what happens if the styleId is invalid. It adds some context beyond annotations but lacks deeper behavioral detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the main verb and action, and the second sentence offers direct, useful alternative guidance. There is no wasted wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a fully described schema, an output schema, and annotations, the description covers purpose and usage well. The only minor issue is a slight mismatch between the description's 'paint' and the enum splitting FILL/STROKE, but overall an agent has enough to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes all 4 parameters with 100% coverage, so the baseline is 3. The description adds minimal extra meaning, mainly emphasizing styleId and the distinction from node_set_* setters, but does not introduce details absent from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool links a node to a shared library style by styleId, listing the style types in parentheses. It explicitly distinguishes from the node_set_* setters by noting those are for ad-hoc values, so it effectively separates itself from sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance: use this tool for shared library styles, and use node_set_* setters for ad-hoc values not backed by a style. This covers primary use case and an alternative, satisfying the 'when and when-not' criterion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_bind_variableBind VariableAIdempotent
Bind a variable to a node property, or set an explicit variable mode. Use instead of a literal node_set_* when the value should track a design token. Ordering rules: set auto-layout before binding padding/spacing; set a solid fill before binding a colour token.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the node to bind variables to | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. | |
| bindVariables | No | Map of property names to variable IDs (to bind) or null (to unbind). Valid fields: fills, strokes, height, width, characters, itemSpacing, paddingLeft, paddingRight, paddingTop, paddingBottom, visible, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius, minWidth, maxWidth, minHeight, maxHeight, counterAxisSpacing, strokeWeight, strokeTopWeight, strokeRightWeight, strokeBottomWeight, strokeLeftWeight, opacity, gridRowGap, gridColumnGap, fontFamily, fontSize, fontStyle, fontWeight, letterSpacing, lineHeight, paragraphSpacing, paragraphIndent. E.g., { 'fills': 'VariableID:1:2' } | |
| explicitVariableModes | No | Map of variable collection IDs to mode IDs. E.g., { 'VariableCollectionID:1:2': 'ModeID:1:3' } |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Name of the modified node |
| error | No | |
| message | No | Status message |
| success | No | Whether the variables were bound successfully |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations supply idempotentHint and openWorldHint, but the description adds behavioral nuance beyond those: the design-token tracking semantic and the ordering constraints that affect outcomes. It does not contradict annotations. A slight gap is that it doesn't mention potential side effects of setting explicit variable modes, but the value added is solid.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: functionality, usage guidance, and ordering rules. No redundancy or fluff; front-loaded with the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (nested objects, 4 params, output schema present), the description covers purpose, usage distinction, and ordering constraints. The schema handles parameter details, and annotations handle idempotency/open-world semantics, leaving no significant gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with each parameter already described in detail. The description adds a high-level reason for binding ('track a design token') but doesn't provide additional parameter-level semantics beyond what the schema already covers. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool binds a variable to a node property or sets an explicit variable mode, with a specific verb and resource. It distinguishes itself from sibling tools like node_set_fill by noting it should be used 'instead of a literal `node_set_*`' when tracking design tokens.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on when to use this tool versus alternatives: 'Use instead of a literal `node_set_*` when the value should track a design token.' It also gives ordering rules (set auto-layout before binding padding/spacing, set solid fill before binding colour token), which contextualizes usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_cloneClone NodeA
Duplicate an existing node, optionally at a new x/y. Produces a new node id.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | New X position for the clone | |
| y | No | New Y position for the clone | |
| nodeId | Yes | The ID of the node to clone | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the new cloned node |
| name | No | Name of the cloned node |
| error | No | |
| parentId | No | ID of the parent the clone was placed into β confirm containment without a follow-up read |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the key behavioral trait: it duplicates a node and produces a new id, with optional repositioning. It does not contradict the openWorldHint annotation and adds context about the result. However, it does not elaborate on side effects or preconditions, but the core behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences, front-loads the action, and contains no extraneous information. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a relatively simple clone operation, the description covers the essential behavior. The presence of an output schema and full parameter schema reduces the burden. It lacks explicit prerequisites, but the schema's mention of node_info hints at the workflow, making it sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers all 4 parameters with descriptions, including the notable detail that nodeName must be passed back verbatim from node_info. The description adds no additional parameter semantics beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Duplicate' and identifies the resource 'existing node', clearly distinguishing it from sibling tools like node_rename or node_delete. It also states the outcome (produces a new node id), making the purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use this toolβwhen an existing node needs to be duplicatedβand differentiates from creation tools by specifying 'existing node'. However, it does not explicitly exclude alternatives or mention when not to use it, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_deleteDelete NodesADestructiveIdempotent
Delete one or more nodes in a single batched, per-item-validated call. No API undo. If the status is 'partial_success', treat it as an incomplete operation, report the failed and skipped items to the user, and retry every non-success item (both failed and skipped).
| Name | Required | Description | Default |
|---|---|---|---|
| nodes | Yes | Array of nodes to delete |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| status | No | Overall status of the batch operation |
| results | No | Detailed deletion results (one row per input, in input order) |
| success | No | Whether all deletions succeeded |
| failedCount | No | Number of failed deletions |
| skippedCount | No | Number of skipped deletions |
| requestedCount | No | Number of requested deletions |
| succeededCount | No | Number of succeeded deletions |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond annotations by disclosing 'No API undo,' per-item validation (which implies possible partial success), and specific retry semantics. These details complement the destructiveHint and idempotentHint annotations without contradiction, adding significant behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each purposeful: core function, warning about undo, and failure-handling instructions. It is front-loaded and extremely concise with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering idempotency and destructiveness, and an output schema presumably explaining return values, the description thoroughly covers batching, validation, and partial-success handling. It is complete for a delete operation with no significant gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (nodeId and nodeName are well-described), so the baseline is 3. The description does not add parameter-specific syntax or format details, but the 'per-item-validated' phrasing hints at how the nodes array is processed, which is marginal added value over the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Delete one or more nodes in a single batched, per-item-validated call,' which specifies the verb (delete), resource (nodes), and distinguishes the tool by its batched and per-item-validated nature. This is precise and leaves no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear usage context: a batched deletion with no API undo, and explicitly instructs how to handle partial_success responses (report failed/skipped items and retry them). However, it does not name alternative tools or exclusion cases, though no direct sibling alternative for node deletion exists in the list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_export_visualExport Node ImageARead-only
Render a node to an image (PNG/JPG/SVG/PDF) at a given scale. Read-only; the canonical way to visually verify edits. SVG returns raw XML in svg (directly readable); PNG/JPG/PDF return base64 in imageData (PDF is a delivery artifact β prefer PNG/SVG for inspection).
| Name | Required | Description | Default |
|---|---|---|---|
| scale | No | Export scale, between 0.1 and 4.0 (e.g. 1, 2, 0.5) | |
| format | No | Export format | PNG |
| nodeId | Yes | The ID of the node to export |
Output Schema
| Name | Required | Description |
|---|---|---|
| svg | No | Raw SVG XML markup (returned instead of imageData when format=SVG) |
| error | No | |
| scale | No | Export scale used |
| format | No | Image format |
| nodeId | No | ID of the exported node |
| mimeType | No | MIME type of the exported image |
| imageData | No | Base64-encoded binary data (PNG/JPG/PDF) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses output behavior in detail: SVG returns raw XML in 'svg', while PNG/JPG/PDF return base64 in 'imageData', and PDF is noted as a delivery artifact. This adds significant value and no contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no redundant wording. It front-loads the core purpose and then adds essential output format details, earning a perfect score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (3 params, output schema present), the description covers all necessary context: read-only nature, use case, return format, and caveats like PDF. It is complete and self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description mentions 'scale' and formats but does not add new parameter semantics beyond what the schema provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Render' with a clear resource 'a node to an image' and lists the supported formats. It distinguishes itself from sibling tools by being the visual export/capture tool, especially with 'canonical way to visually verify edits.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool ('canonical way to visually verify edits') and provides format selection guidance ('prefer PNG/SVG for inspection'). It does not explicitly name alternative tools or say when not to use it, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_flattenFlatten NodeADestructive
Flatten a node and its children into a single vector. Lossy β original structure is not recoverable.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the node to flatten | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the flattened node |
| name | No | Name of the flattened node |
| type | No | Type of the flattened node (usually VECTOR) |
| error | No | |
| parentId | No | ID of the container the flattened node was placed in β the source node's original parent, so D11 containment is confirmable from this response without a follow-up node_info |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint and openWorldHint, but the description expands on this with 'Lossy β original structure is not recoverable', explicitly informing the irreversibility of the operation. This adds meaningful behavioral context beyond the structured hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no unnecessary wording. It front-loads the action and follows with a key caveat, achieving maximum clarity in minimal space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 2-parameter tool with an output schema and declarative annotations, the description covers the essential purpose and caution. It does not mention prerequisites like the nodeName must match node_info, but the schema covers that. Overall, it is sufficient given the available structured information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides 100% description coverage for both parameters, so the tool description does not need to explain them. The description adds no additional parameter semantics beyond what is already in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific verb 'Flatten' and the resource 'a node and its children', with the result 'a single vector'. This directly conveys the tool's function and distinguishes it from sibling tools like node_ungroup or node_transform.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It only warns that the operation is lossy, but does not mention scenarios where flattening is appropriate or when another tool should be chosen instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_groupGroup NodesB
Wrap multiple nodes in a new group node.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Optional non-empty name for the new group. Omit to accept Figma's default; `""` is refused rather than silently substituted. | |
| nodes | Yes | Array of nodes to group |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the new group node |
| name | No | Name of the new group node |
| error | No | |
| childCount | No | Number of children in the group |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description only says 'wrap' with no detail about side effects such as nodes being reparented, the group insertion order, or failure modes if the provided nodeName does not match. The openWorldHint annotation warns of unknown effects but does not compensate for the lack of disclosed known behaviors.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler, directly stating the operation. It is appropriately concise for a simple tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description omits critical operational context for a mutation tool: the requirement that nodeName must exactly match the current node name, the reparenting behavior, and any constraints on nodes. The schema covers parameter semantics but not the overall behavioral contract, leaving the agent under-informed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with parameters already well-documented (e.g., name rejects empty strings, nodeName must be passed verbatim). The tool description adds no parameter-specific information, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('wrap') and clear resource ('multiple nodes' into a 'new group node'). It clearly distinguishes the tool from siblings like node_ungroup and node_clone by stating exactly the grouping action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no explicit guidance on when to use grouping versus alternatives, no prerequisites (e.g., nodes sharing the same parent, exact node names), and no exclusions. The action is implied by the tool name but the description itself does not give contextual direction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_infoGet Node InfoARead-only
Read one or more nodes β recursive subtree traversal with properties selection, filter, and maxDepth. Returns only the requested properties (incl. resolved boundVariables/explicitVariableModes) under each node's properties key. A node whose containing page could not be read is listed in pageFailedNodes with that page's ID, and the page's structured reason is in coverage.pageErrors β other pages still return normally. The workhorse read; start here before any write.
| Name | Required | Description | Default |
|---|---|---|---|
| filter | No | Optional filter criteria. | |
| nodeIds | No | Array of node IDs to inspect. If empty, uses editable scope. | |
| maxDepth | No | Maximum depth for recursive child traversal. 0 = self only, 1 = self and immediate children, etc. | |
| properties | No | Array of property names to return (populates each node's `properties` object in the response). | |
| concurrencyLimit | No | Concurrency limit for parallel subtree walk (default: 4) |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| nodes | No | Node entries (id/name/type + optional properties/children/path/descendantCount) |
| coverage | No | Page-scan coverage; partial read data remains usable when complete is false |
| missingNodeIds | No | Requested IDs that weren't found |
| pageFailedNodes | No | Requested nodes that exist but could not be read because their containing page failed; omitted when none |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, but the description adds significant behavioral detail beyond that: it discloses recursive subtree traversal, that only requested properties are returned, that resolved boundVariables/explicitVariableModes are included, and precisely how failed pages are reported (pageFailedNodes and coverage.pageErrors). This enriches the agent's understanding of the tool's edge cases and return structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is tightly written, leading with the core action and then delivering essential details in a logical order. Each sentence adds value: the first defines scope, the second explains the return format, the third covers error handling, and the final sentence provides usage guidance. No filler or redundant text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (5 optional parameters, no required ones, output schema present), the description covers the essential contextual aspects: what it operates on, how parameters influence traversal, how partial failures are surfaced, and when to use it. The output schema already handles return value details, so the description's focus on behaviors and edge cases makes it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% description coverage for all five parameters, so the baseline is 3. The description mentions `properties`, `filter`, and `maxDepth` but does not add syntax or format details beyond the schema. The reference to 'resolved boundVariables/explicitVariableModes' relates to output rather than parameter semantics, so the description does not meaningfully elevate parameter understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Read') and resource ('one or more nodes'), and clearly distinguishes this from sibling tools by calling it 'The workhorse read; start here before any write.' It also outlines key features (properties selection, filter, maxDepth) and return behavior, leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: 'start here before any write' indicates this is the primary read tool, separating it from write operations. It does not explicitly name alternative tools (e.g., page_info) or state when not to use it, but the 'workhorse' framing strongly implies it as the default read choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_insert_childReparent NodeAIdempotent
Reparent a node under a new parent at an optional index. Valid range is 0 to parent's child count. Omit index to append.
| Name | Required | Description | Default |
|---|---|---|---|
| index | No | Position in parent's children array (default: append). The output index reports the actual resolved position (same-parent reorder shifts indices). | |
| childId | Yes | ID of the child node to reparent | |
| parentId | Yes | ID of the new parent node | |
| childNodeName | Yes | The child node's current exact name, passed back verbatim from `node_info`. | |
| parentNodeName | Yes | The parent node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| index | No | Index at which the child was inserted |
| childId | No | ID of the reparented child node |
| newParentId | No | ID of the new parent node |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral details about index validation and default append behavior. The annotations (openWorldHint, idempotentHint) already hint at side effects, but the description does not elaborate on what happens to the old parent or other consequences. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, consisting of three short sentences. It is front-loaded with the primary action and provides necessary index guidance without any redundant phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich schema (100% coverage), output schema, and annotations, the description is adequate for a straightforward reparent operation. It could mention edge-case restrictions (e.g., cannot reparent to itself or a descendant), but such details are not essential for typical use and are not indicated by the structured data.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description only reiterates the index behavior already present in the schema, providing no additional parameter semantics beyond what is structured.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action 'Reparent a node' with a specific resource (node) and optional index. This distinguishes it from sibling node tools like rename, delete, clone, and group by focusing on the parent-child relationship.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context on when to use the tool (reparenting) and how to use the index parameter (valid range, omit to append). However, it does not explicitly mention alternatives or conditions when not to use this tool, so it falls short of fully explicit usage guidelines.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_renameRename NodeAIdempotent
Rename a node (sets name to an exact value).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | New non-empty name for the node. Figma normalizes an empty name to a type default, so `""` is refused rather than silently substituted. | |
| nodeId | Yes | The ID of the node to rename | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | The new name of the node |
| error | No | |
| oldName | No | The old name of the node |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey idempotency and open-world context. The description adds that the tool sets the name to an exact value, implying an overwrite behavior, but does not disclose potential side effects or failure modes. The schema's note on empty names adds context, but it is outside the description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence: 'Rename a node (sets `name` to an exact value).' It is front-loaded with the action, contains zero filler, and effectively communicates the core function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with three clearly documented parameters and an output schema present. The description covers the essential action and the schema covers parameter details, so the description is sufficiently complete for this low-complexity operation. Missing explicit usage guidance is the only minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage with descriptions for all parameters, including a detailed note about the `name` parameter rejecting empty strings. The tool description itself does not add parameter semantics beyond what the schema and the exact-value phrase already provide, so the schema carries the burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Rename a node' with the specific verb 'rename' and resource 'node', and clarifies it sets `name` to an exact value. This unambiguously identifies the tool's function and differentiates it from sibling tools that manipulate other node properties (e.g., node_set_fill, node_set_stroke).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for renaming nodes but does not explicitly state when to use it over alternatives or mention any exclusions. The purpose is clear enough that an agent can infer when to use it, but there is no explicit guidance on alternatives or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_set_auto_layoutSet Auto LayoutAIdempotent
Configure a frame's auto-layout (mode, padding, spacing, alignment, sizing) in one unified setter.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the frame to modify | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. | |
| layoutMode | No | Layout mode for the frame | |
| layoutWrap | No | Whether the auto-layout frame wraps its children | |
| paddingTop | No | Top padding value | |
| itemSpacing | No | Distance between children. Note: This value will be ignored if primaryAxisAlignItems is set to SPACE_BETWEEN. | |
| paddingLeft | No | Left padding value | |
| paddingRight | No | Right padding value | |
| paddingBottom | No | Bottom padding value | |
| counterAxisSpacing | No | Distance between wrapped rows/columns. Only works when layoutWrap is set to WRAP. | |
| layoutSizingVertical | No | Vertical sizing mode (HUG for frames/text only, FILL for auto-layout children only) | |
| counterAxisAlignItems | No | Counter axis alignment (MIN/MAX = top/bottom in horizontal, left/right in vertical) | |
| primaryAxisAlignItems | No | Primary axis alignment (MIN/MAX = left/right in horizontal, top/bottom in vertical). Note: When set to SPACE_BETWEEN, itemSpacing will be ignored as children will be evenly spaced. | |
| layoutSizingHorizontal | No | Horizontal sizing mode (HUG for frames/text only, FILL for auto-layout children only) |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Name of the modified frame |
| error | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true, covering replay safety, and openWorldHint=true, allowing for undiscovered fields. The description adds no behavioral context beyond saying it's a setter. It doesn't disclose side effects like whether unspecified properties are reset, but the schema's conditional notes (e.g., itemSpacing ignored with SPACE_BETWEEN) are present in structured fields, so the bar is lower. No contradiction found.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is exactly one sentence, front-loaded with the verb and resource, and every word adds value. No redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given high complexity (14 parameters, 6 enums) and the presence of an output schema, the description need not enumerate return details. The schema's property descriptions fully cover parameter semantics, so the minimal description is adequate. However, it could have mentioned that unspecified properties are left unchanged, but the schema's additionalProperties false and idempotent hint partially cover this. Overall complete enough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with each parameter having detailed descriptions, including enum values and conditional behavior (e.g., counterAxisSpacing only with WRAP). The tool description itself only lists high-level categories (padding, spacing, etc.) without adding syntax or parameter-specific meaning. Baseline 3 is appropriate as the schema carries the full burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'configure' and resource 'a frame's auto-layout', listing specific aspects (mode, padding, spacing, alignment, sizing). This distinguishes it from sibling tools that handle fills, strokes, effects, etc. The phrase 'in one unified setter' further differentiates it as a single combined operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description scopes usage to frames and auto-layout configuration, making it clear when to apply. It does not explicitly list exclusions or alternatives, but the context is unambiguous enough that an agent can infer it is the dedicated auto-layout setter, especially given the sibling set includes no competing auto-layout tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_set_corner_radiusSet Corner RadiusAIdempotent
Set a node's corner radius β uniform or per-corner.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the node to modify | |
| radius | Yes | Corner radius value | |
| corners | No | Optional array of 4 booleans to specify which corners to round [topLeft, topRight, bottomRight, bottomLeft] | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Name of the modified node |
| error | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide idempotentHint and openWorldHint, covering the safety profile. The description adds minimal behavioral context beyond 'uniform or per-corner', which is more about parameter semantics than behavior. It does not disclose side effects, edge cases, or why openWorldHint is set.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, front-loaded with verb and resource. It conveys the essential capability without unnecessary words or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich schema, output schema, and annotations, the description is largely complete. It explains the tool's purpose and modes, but omits potential constraints like supported node types or why nodeName is required, though those are partially covered in schema descriptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, the baseline is 3. The description adds value by framing the operation as uniform or per-corner, helping the agent understand the optional corners parameter and its purpose. This conceptual distinction enhances the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verb 'Set' and resource 'node's corner radius', clearly distinguishing from sibling node_* property setters. It also specifies the two modes (uniform or per-corner), which uniquely identifies the tool's scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for modifying corner radius but does not explicitly state when to use it vs alternatives like node_set_fill or node_set_stroke. No exclusions, supported node types, or alternative tool references are provided, leaving usage to be inferred from the name and sibling context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_set_effectsSet EffectsAIdempotent
Set a node's effect array (shadows, blurs). Use node_apply_style to link a shared effect style instead.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the node to modify | |
| effects | Yes | Array of strict per-variant Figma effects: DROP_SHADOW/INNER_SHADOW or LAYER_BLUR/BACKGROUND_BLUR | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Name of the modified node |
| error | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide idempotentHint and openWorldHint, and the description adds scope ('shadows, blurs'). However, it does not explicitly state that the effect array is replaced wholesale, nor does it mention preconditions or failure modes. The 'set' verb implies replacement, but the description remains minimal on behavioral detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two succinct, front-loaded sentences with zero filler. The first sentence states the tool's action and scope; the second gives an explicit alternative. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the very rich input schema and the presence of an output schema, the description covers core purpose and usage guidance without redundant details. The only minor gap is not explicitly noting that existing effects are overwritten, though this is strongly implied by the verb 'set'.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has exhaustive descriptions for all three parameters, including nested effect variants, defaults, and constraints (100% coverage). The description adds no extra parameter-level information, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Set') and clearly identifies the target resource ('a node's effect array') and scope ('shadows, blurs'). It also distinguishes this tool from siblings by explicitly naming node_apply_style as the alternative for shared effect styles.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: use this tool for direct effect arrays, and points to node_apply_style as the alternative for shared styles. This clear exclusion and alternative naming makes tool selection straightforward.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_set_fillSet FillAIdempotent
Set a node's fill to a literal RGBA color, an image, or clear it. Use node_apply_style to link a shared paint style, or node_bind_variable to bind a color token.
| Name | Required | Description | Default |
|---|---|---|---|
| a | No | Alpha component (0-1) | |
| b | No | Blue component (0-1) | |
| g | No | Green component (0-1) | |
| r | No | Red component (0-1) | |
| clear | No | Set to true to clear all fills. Must provide exactly one of solid color, image, or clear:true. | |
| image | No | Optional image payload. Must provide exactly one of solid color or image. | |
| nodeId | Yes | The ID of the node to modify | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Name of the modified node |
| error | No | |
| warnings | No | Warnings from the operation (e.g., resizing) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description clarifies that this sets a literal fill rather than a style reference or token binding, which is behavioral context beyond the idempotentHint and openWorldHint annotations. It does not disclose overwriting semantics or error conditions, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, directly states the purpose and alternatives, with no redundancy. The description is front-loaded and every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with nested image object and multiple modes, the description-plus-schema provides a complete picture. The description supplies the key decision point (literal vs style vs token), while the schema covers technical details and constraints. Minor gap: no mention of node type restrictions or potential errors, but these aren't essential given the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all parameters. The description adds a high-level summary of the three modes (color/image/clear) but no additional parameter-specific details beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool sets a node's fill to a literal RGBA color, an image, or clears it. It explicitly distinguishes from alternatives (node_apply_style, node_bind_variable), making the purpose specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance: use this for literal fills, and directs the agent to node_apply_style for shared styles and node_bind_variable for color tokens. This covers when to use and when-not-to-use scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_set_strokeSet StrokeAIdempotent
Set a node's stroke color and weight; supports uniform or per-side weights.
| Name | Required | Description | Default |
|---|---|---|---|
| a | No | Alpha component (0-1) | |
| b | Yes | Blue component (0-1) | |
| g | Yes | Green component (0-1) | |
| r | Yes | Red component (0-1) | |
| nodeId | Yes | The ID of the node to modify | |
| weight | No | Uniform stroke weight (used when individual side weights are not provided) | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. | |
| strokeTopWeight | No | Top side stroke weight | |
| strokeLeftWeight | No | Left side stroke weight | |
| strokeRightWeight | No | Right side stroke weight | |
| strokeBottomWeight | No | Bottom side stroke weight |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Name of the modified node |
| error | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds a useful behavioral nuance ('supports uniform or per-side weights') beyond what annotations provide. However, it does not disclose details like replacing existing strokes, the nodeName verification requirement, or how parameters interact (e.g., whether side weights override uniform weight). Annotations indicate idempotentHint, so safety is partially covered, but the description remains thin on other behavioral aspects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It conveys the core action, target, and key mode distinction in 13 words, achieving maximum efficiency and readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the full schema coverage, output schema, and annotations, the description is adequately complete for a setter tool. It tells the agent what the tool does and the primary decision (uniform vs per-side weights). It doesn't explicitly note that weight is optional or that nodeName serves as a consistency check, but those are covered by the schema and output schema, so the description fills its intended role.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds meaningful semantic grouping by distinguishing 'uniform' (the `weight` parameter) from 'per-side' (the stroke*Weight parameters), clarifying how to choose between them. This goes beyond the individual schema descriptions and helps the agent select the right parameters for the desired outcome.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Set') and the resource ('a node's stroke color and weight'), which is specific and distinguishes it from sibling tools like node_set_fill or node_set_corner_radius. The mention of 'uniform or per-side weights' adds further specificity, making it unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: it is the tool for setting stroke properties on a node. Although it doesn't explicitly name alternatives, the scope is well-defined ('a node's stroke'), making it obvious when to use this tool versus other node_set_* siblings. No exclusions or alternatives are stated, but the specificity makes the usage clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_transformTransform NodeAIdempotent
Move and/or resize a node by setting absolute x/y/width/height (any subset).
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | New X position | |
| y | No | New Y position | |
| width | No | New width | |
| height | No | New height | |
| nodeId | Yes | The ID of the node to transform | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| x | No | Resulting X position |
| y | No | Resulting Y position |
| id | No | ID of the transformed node |
| name | No | Name of the transformed node |
| error | No | |
| width | No | Resulting width |
| height | No | Resulting height |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals behavioral traits beyond annotations: it clarifies that values are absolute (not relative) and that any subset of dimensions can be provided, leaving others unchanged. Annotations (openWorldHint, idempotentHint) do not cover these specifics, so this adds valuable context without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence of 15 words, front-loaded with the action and resource. It provides essential details without unnecessary filler, making it highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity and the presence of a full input schema (100% coverage) and an output schema, the description adequately covers the core functionality. It does not mention prerequisites or edge cases, but these are not critical for such a straightforward transform tool. A minor gap is the lack of explicit node selection details, but these are covered in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaning by explaining that x/y/width/height are absolute and that any subset can be set, which the individual schema descriptions do not explicitly convey. This enriches parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Move and/or resize' and identifies the resource 'a node' with the exact properties (x/y/width/height). It clearly distinguishes from sibling tools like node_set_fill or node_rename by focusing on geometry transformation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by specifying the task ('Move and/or resize') and method ('by setting absolute...') but does not explicitly state when to use this tool versus alternatives or provide exclusions. The sibling context hints at differentiation, but the description itself lacks explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
node_ungroupUngroup NodeADestructive
Dissolve a group, promoting its children to the parent. Removes the group container.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the group to ungroup | |
| nodeName | Yes | The group's current exact name, passed back verbatim from `node_info`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| parentId | No | ID of the parent node (null if the group had no parent) |
| ungroupedChildren | No | List of ungrouped child nodes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already indicating destructive behavior (destructiveHint: true), the description adds valuable context by explicitly stating that children are promoted to the parent and the group container is removed. This explains the differential impact on children versus the container, which is not evident from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, using two short sentences to convey the operation and outcome. Every word earns its place, with no redundant or vague language.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity, full schema documentation, and the presence of an output schema, the description sufficiently covers the essential behavior. It explains the operation's effect on children and the group container without needing further detail about return values or prerequisites.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides comprehensive descriptions for both parameters, including the exact requirement for nodeName to be passed verbatim from node_info. The tool description adds no additional parameter semantics beyond what the schema already covers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (dissolve a group) and its specific outcome (promoting children to the parent and removing the group container). This distinctly separates it from sibling tools like node_delete, which removes a node entirely, and node_group, which creates a group.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the correct usage (ungrouping a group) and highlights the key behavioral effect of preserving children, but it does not explicitly provide when-to-use versus alternative tools or mention any exclusions. There is no direct comparison to node_delete or other siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
page_infoGet PagesARead-only
List the document's pages; no args β all pages (no children), or pass pageIds β those pages with their top-level children. Batch β€25 ids/call. Inspect coverage: a failed page is omitted with a structured pageErrors row while other pages still return.
| Name | Required | Description | Default |
|---|---|---|---|
| pageIds | No | Array of page IDs to inspect |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| pages | No | List of page objects |
| coverage | No | Page-scan coverage; partial read data remains usable when complete is false |
| pageCount | No | Total page count |
| documentId | No | ID of the Figma document |
| documentName | No | Name of the Figma document |
| missingPageIds | No | Every requested page ID absent from `pages`, whatever the cause; `coverage.pageErrors` carries the structured reason for each |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate a safe read, but the description adds rich behavioral detail: all-pages mode returns no children, pageIds mode includes top-level children, batch size is capped, and partial failures are handled with a structured pageErrors row while other pages still return. This goes well beyond the annotation's coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences that front-load the purpose, then explain conditional behavior and error handling. Every word earns its place, with no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return value details are handled elsewhere. The description covers the two main usage modes, batch limitation, and failure semantics, making it fully complete for a listing tool with one optional parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already describes pageIds with 100% coverage, so the baseline is 3. The description adds extra meaning by detailing the mode contrast (with vs without pageIds) and the batching constraint, giving deeper insight into how the parameter affects behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('List the document's pages'), clearly distinguishing it from sibling node operations. It also differentiates two invocation modes (all pages vs specific pages with children), leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use each mode (no args for all pages, pageIds for specific pages) and includes the batch limit of 25 ids/call. It doesn't explicitly name alternatives like node_info for non-page nodes, but the intended usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reaction_listList ReactionsARead-only
Read prototype reactions from one or more nodes and their descendants.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeIds | Yes | Array of node IDs to get reactions from |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| nodes | No | List of node entries with their reactions |
| nodesCount | No | Number of inspected nodes |
| nodesWithReactions | No | Number of nodes found that have reactions |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and openWorldHint, so the safety profile is established. The description adds meaningful behavioral context by specifying that reactions are retrieved from the specified nodes and their descendants, which is not inferable from the annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no redundant wording. It efficiently conveys the action, resource, and scope in one breath.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list operation with one parameter and an output schema, the description covers all necessary context: it names the resource, the traversal behavior, and the input nodes. No further details are needed given the schema and annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema describes nodeIds as 'Array of node IDs to get reactions from,' but the description enriches this by explaining that descendants are included. This clarifies the traversal scope beyond the schema's bare parameter description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Read' with the resource 'prototype reactions' and the scope 'from one or more nodes and their descendants.' This clearly distinguishes it from sibling tools like reaction_update (write) and other list tools for different resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly conveys the intended use case (reading reactions from nodes and descendants) without explicitly naming alternatives or exclusions. The context is unambiguous for a read-only listing tool, though it lacks explicit 'when not to use' guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reaction_updateUpdate ReactionsAIdempotent
Replace a node's prototype reactions with a full new reactions array (read first via reaction_list).
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the node to update reactions for | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. | |
| reactions | Yes | The full array of Reaction objects to set |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| success | No | Whether the reactions were updated successfully |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide idempotentHint and openWorldHint, but the description adds the critical semantic of full replacement ('Replace ... with a full new reactions array'), clarifying that this is an overwrite, not an incremental edit. This goes beyond what annotations already convey, offering useful behavioral context without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the core action ('Replace...') and immediately follows with the crucial usage caveat ('read first via reaction_list'). Every word earns its place, with zero redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and rich schema (extensive reactions definition) plus presence of an output schema, the description effectively covers the key operational requirements: the full-replacement behavior and the read-first prerequisite. It could mention error cases or node existence, but for an agent with access to schema and annotations, it is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and all parameters (nodeId, nodeName, reactions) are fully described in the input schema. The description doesn't add parameter-specific guidance beyond what the schema already provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Replace') and resource ('node's prototype reactions'), clearly stating the tool's action. It also distinguishes itself from the sibling 'reaction_list' read tool by implying that this is the write counterpart, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear prerequisite: 'read first via reaction_list,' which guides the agent to fetch existing data before writing. It also emphasizes that the operation expects a 'full new reactions array,' implying a read-modify-write workflow. However, it does not explicitly exclude alternatives or explain when not to use this tool, falling short of a perfect score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
style_deleteDelete StyleADestructiveIdempotent
Delete a local style by id. Detaches consumers β they keep their resolved values and lose only the style link.
| Name | Required | Description | Default |
|---|---|---|---|
| styleId | Yes | ID of style to delete | |
| styleName | Yes | The style's current exact name, passed back verbatim from `style_list`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| message | No | Success/failure status message |
| success | No | Whether style was successfully deleted |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
While annotations already declare destructiveHint=true and idempotentHint=true, the description adds meaningful behavioral context: 'Detaches consumers β they keep their resolved values and lose only the style link.' This explains the non-destructive impact on consumers, which is not present in the annotations. It also clarifies that only local styles are affected.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences. The first sentence front-loads the core purpose, and the second sentence adds a valuable behavioral detail. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple delete operation with two well-documented parameters, an output schema, and safety annotations, the description covers the essential context: the action, the target, and the key side effect on consumers. It does not discuss error cases or prerequisites, but those are not critical for this straightforward tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides full descriptions for both parameters (styleId and styleName) with 100% coverage. The description only mentions deletion by id and does not elaborate on the styleName parameter, which the schema already explains as the verbatim name from style_list. Thus, the description adds no additional parameter meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Delete a local style by id,' which clearly states the action (delete), the resource (local style), and the method (by id). It distinguishes this tool from siblings like style_list and style_manage by focusing specifically on deletion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly state when to use this tool versus alternatives. It implies deletion but lacks guidance on when to prefer style_delete over style_manage or other style-related tools. The 'local style' qualifier hints at scope but does not clarify alternative selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
style_listList StylesARead-only
List all local styles (paint/text/effect/grid) in the document.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| grids | No | List of grid styles |
| texts | No | List of text styles |
| colors | No | List of paint/color styles |
| effects | No | List of effect styles |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true, and the description adds the specific scope (local styles) and style categories, which clarifies what the read operation returns. No other behavioral traits are disclosed, but none are needed for a simple list operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence, front-loading the action and object, with no filler words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters, an output schema present, and annotations covering safety, the description fully covers the tool's purpose and scope. There is nothing missing for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, so the description isn't required to explain parameter semantics. The baseline score of 4 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'List' with a clear resource 'local styles' and specifies the style types (paint/text/effect/grid) and scope ('in the document'), distinguishing it from sibling tools like style_manage or style_delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit usage guidance is provided; the description doesn't mention alternatives or when to avoid this tool. Usage is implied by its simple listing nature, but the lack of exclusions or alternative references means the agent must infer when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
style_manageManage StyleA
Create a named style (paint/text/effect/grid), or update an existing one when styleId is given. UPDATE requires currentStyleName.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Style name. Must be non-empty when supplied. REQUIRED for CREATE; omit it on UPDATE to leave the current style name unchanged. | |
| type | Yes | Type of style to create or update | |
| styleId | No | ID of the style to update (if not creating a new one) | |
| properties | No | Style properties to set; which subset applies depends on `type` (TEXT/PAINT/EFFECT/GRID). | |
| description | No | Description of the style | |
| bindVariables | No | Map of field names to variable IDs (to bind) or null (to unbind). For PAINT styles, valid fields include 'color'. For TEXT styles, fields include 'fontSize', 'fontFamily', etc. | |
| currentStyleName | No | REQUIRED for UPDATE when styleId is supplied β the style's **current exact** name, passed back verbatim from `style_list` |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the style |
| name | No | Name of the style |
| type | No | Type of the style |
| error | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only include openWorldHint, so the description carries the burden of behavioral disclosure. It mentions the currentStyleName requirement but omits side effects on existing nodes, whether update overwrites properties, what happens if the style doesn't exist, or permission requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences, front-loaded with the core purpose, and contains no redundant words or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The complex nested schema and output schema cover field-level details, but the description lacks complete contextual guidance on mutation behavior, side effects, or failure modes. It's minimally sufficient for a well-schema'd tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description adds minimal value beyond restating that styleId switches to update mode and currentStyleName is required, which is also present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool creates or updates named styles (paint/text/effect/grid), and distinguishes between create (no styleId) and update (with styleId) modes. This differentiates it from siblings like style_delete and style_list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit usage conditions: use create when no styleId is provided, and update with styleId plus currentStyleName. It doesn't explicitly say when NOT to use it versus alternatives like node_apply_style, but the create/update branching provides clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
text_set_contentSet Text ContentsAIdempotent
Set the text of one or more text nodes in a single batched, per-item-validated call. If the status is 'partial_success', treat it as an incomplete operation, report the failed and skipped items to the user, and retry every non-success item (both failed and skipped).
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Array of text objects |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| status | No | Overall status of the batch operation |
| results | No | Detailed results per node (one row per input, in input order) |
| success | No | Whether all replacements succeeded |
| failedCount | No | Number of failed text replacements |
| skippedCount | No | Number of skipped text replacements |
| requestedCount | No | Number of requested text replacements |
| succeededCount | No | Number of succeeded text replacements |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide idempotentHint and openWorldHint, but the description adds crucial behavioral context about per-item validation and partial_success handling. This goes beyond annotations by telling the agent exactly how to react to partial success, which is essential for correct invocation. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: the first states the operation, the second provides critical success-handling guidance. Every sentence earns its place, with no redundancy or fluff, and the most important information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity, the existing output schema, and annotations, the description is complete. It captures the batch aspect, validation, and the critical partial_success retry protocol. No missing prerequisites or behavioral caveats are evident.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with each property (nodeId, nodeName, characters) having a description. The tool description adds no additional parameter-level meaning, such as edge cases or format details. Baseline 3 is appropriate since the schema carries the full parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool sets the text of one or more text nodes, using specific verbs and resources ('Set the text', 'text nodes') and highlights the batched, per-item-validated nature. This distinguishes it from siblings like text_set_style and node_set_fill, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for updating text content across one or more nodes, and provides explicit guidance on handling partial_success: treat as incomplete, report failures/skips, and retry non-success items. It lacks explicit when-not-to-use or alternatives, but the context is clear enough for an agent to decide appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
text_set_styleSet Text StyleAIdempotent
Set any combination of typography properties (font, size, weight, spacing, decoration, β¦) on a text node.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | The ID of the text node to modify | |
| fontName | No | Font family and style | |
| fontSize | No | Font size | |
| nodeName | Yes | The node's current exact name, passed back verbatim from `node_info`. | |
| textCase | No | Case transformation on the text | |
| lineHeight | No | Line height settings | |
| letterSpacing | No | Letter spacing settings | |
| textDecoration | No | Text decoration | |
| paragraphIndent | No | Paragraph indent in pixels | |
| paragraphSpacing | No | Paragraph spacing in pixels | |
| textAlignVertical | No | Vertical text alignment | |
| textAlignHorizontal | No | Horizontal text alignment |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Name of the modified node |
| error | No | |
| success | No | Whether style was set successfully |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations providing idempotentHint and openWorldHint, the description adds a little extra context by noting 'any combination' can be set, but it does not disclose potential side effects, failure modes, or permission requirements. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the verb and core subject. It is concise with no redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is complex (12 parameters, nested objects, enums) but the rich input schema and presence of an output schema cover parameter details and return values. The description effectively conveys the purpose and flexibility ('any combination'), though it does not address edge cases like transactional behavior. Overall, it is sufficiently complete for an agent to select and use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 12 parameters are already documented in the input schema. The description lists property categories (font, size, weight, spacing, decoration) that map to parameters but adds no technical detail beyond what the schema provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Set') and clearly identifies the resource ('typography properties on a text node'). It distinguishes this tool from siblings like text_set_content (which changes text content) and node_apply_style (which applies a named style) by focusing on direct typography property manipulation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when needing to set typography properties, but it does not explicitly state when not to use it or name alternatives like text_set_content or style_list. No exclusion criteria are provided, so guidance is only implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
variable_deleteDelete VariablesADestructiveIdempotent
Delete specific variables or an entire collection. Runs a full-document consumer check first, before any removal: if a target is still in use the call is refused with VARIABLE_IN_USE, whose details.variablesInUse lists every consumer; if any page cannot be loaded and read it is refused with DOCUMENT_SCAN_INCOMPLETE, because a page error can never mean zero consumers.
| Name | Required | Description | Default |
|---|---|---|---|
| variableIds | No | Array of variable IDs to delete. Mutually exclusive with collectionId. | |
| collectionId | No | ID of a variable collection to delete. Mutually exclusive with variableIds. | |
| variableNames | No | Array of variable names corresponding to variableIds, for safety verification. Required if variableIds is used. | |
| collectionName | No | Name of the collection to delete, for safety verification. Required if collectionId is used. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| message | No | Status message |
| success | No | Whether variables were deleted successfully |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the destructiveHint annotation by disclosing a full-document consumer check before any removal, refusal with VARIABLE_IN_USE including details.variablesInUse, and refusal with DOCUMENT_SCAN_INCOMPLETE when pages cannot be loaded. This gives the agent concrete knowledge of failure modes and safety behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The first sentence states the action and scope; the second explains the preflight check and error behavior. It is front-loaded and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive tool, the description covers the operation, the consumer-check precondition, and the possible error conditions in detail. Combined with the output schema and annotations, this is complete enough for an agent to select and invoke it safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents 100% of parameters, including mutual exclusivity between variableIds and collectionId, as well as the required verification names. The description only refers to 'specific variables or an entire collection,' which adds no new parameter-level meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with 'Delete specific variables or an entire collection,' naming the verb and resource clearly. It is a specific delete operation, but it doesn't explicitly distinguish itself from sibling tools like variable_manage or style_delete, so it lacks explicit sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended usage is implied by the title and delete semantics, and the description explains when the tool will succeed or fail. However, it does not explicitly state when to use this tool versus alternatives, nor does it name any sibling tool for contrast.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
variable_listList VariablesARead-only
List local variables/collections, or detailed info for specific variable ids; optionally scan for consumers. Document consumer scans isolate page failures and report them in coverage; page-scoped failures return their structured error directly.
| Name | Required | Description | Default |
|---|---|---|---|
| pageId | No | The page ID to scan for consumers when includeConsumers is 'page'. | |
| variableId | No | Optional array of variable IDs to retrieve detailed information for. If omitted, lists all local variables. | |
| includeConsumers | No | Only used when variableId is provided; ignored otherwise. 'page' scans a specific page, requiring pageId. 'document' scans all pages (streams progress page-by-page). |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| coverage | No | Page-scan coverage; partial read data remains usable when complete is false |
| variables | No | List of variables β present in both list-all and lookup modes (each may carry nodeConsumers/styleConsumers/aliasConsumers when includeConsumers is set) |
| missingIds | No | Requested variable IDs that did not resolve (lookup mode only; omitted when none) |
| collections | No | List of variable collections (list-all mode only) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true already declared, the description adds valuable behavioral context by explaining how document and page consumer scans handle failures differently. This goes beyond the annotation by disclosing error-reporting behavior, which is useful for selecting the right mode.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the main purpose and followed by a concise explanation of consumer scan behavior. Every sentence earns its place with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a read-only listing operation with an output schema and good annotations. The description covers the primary use cases (list all, detailed info, consumer scans) and error-handling nuances. Minor ambiguity around 'local' scope and the `coverage` field exists, but overall it is complete enough for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces parameter behavior (e.g., variableId optional, includeConsumers modes) but does not significantly add beyond the schema. The failure-reporting detail is behavioral output context rather than parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'List local variables/collections, or detailed info for specific variable ids; optionally scan for consumers.' This uses a specific verb (list) and resource (variables/collections), and distinguishes it from sibling mutation tools like variable_manage and variable_delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides context for using the consumer scan modes: document scans isolate page failures and report them in `coverage`, while page-scoped failures return structured errors directly. It implies this is for read-only inspection versus alternatives like variable_manage, though it does not explicitly state exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
variable_manageManage VariablesA
Create collections and variables and set their values/aliases (create/update router). UPDATE_VARIABLE requires currentVariableName. CREATE_VARIABLE requires collectionName and scopes.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Name for collection/variable creation or variable update. Must be non-empty when supplied. It is required for CREATE_COLLECTION and CREATE_VARIABLE; omit it only on UPDATE_VARIABLE to leave the current name unchanged. | |
| type | No | Variable type (for CREATE_VARIABLE) | |
| value | No | Value for the variable (or alias) (for CREATE or UPDATE) | |
| action | Yes | Action type | |
| modeId | No | Mode ID (for UPDATE_VARIABLE value setting) | |
| scopes | No | REQUIRED for CREATE_VARIABLE β variable scopes. ALWAYS set explicitly on create; omit on update to leave unchanged. | |
| modeName | No | Optional initial mode name for CREATE_COLLECTION. Must be non-empty when supplied; omit it to keep the collection's native default mode name. | |
| variableId | No | Variable ID (for UPDATE_VARIABLE) | |
| description | No | Description (for UPDATE_VARIABLE) | |
| collectionId | No | Collection ID (for CREATE_VARIABLE) | |
| collectionName | No | REQUIRED for CREATE_VARIABLE β the parent collection's exact name, passed back verbatim from `variable_list` | |
| currentVariableName | No | REQUIRED for UPDATE_VARIABLE β the variable's **current exact** name, passed back verbatim from `variable_list` |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the collection or variable |
| name | No | Name of the collection or variable |
| error | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only openWorldHint annotation, the description carries a moderate transparency burden. It discloses action-specific required parameters, which is useful, but it does not mention side effects, error behavior, or whether updates overwrite existing values. The schema and output schema cover some detail, so this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences that front-load the core purpose and then add key constraints. There is no redundancy or filler; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (12 parameters, 3 actions, union value types), the description plus the detailed schema creates a fairly complete picture. The existence of an output schema covers return values. A minor gap is the lack of workflow guidance (e.g., how to use variable_list results here), but the description is sufficient for an agent to act.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The tool description restates requirements already present in the schema (e.g., currentVariableName for UPDATE_VARIABLE), adding no new semantic depth. The schema itself thoroughly documents each parameter, so the description does not need to compensate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as a create/update router for collections and variables, with the specific verbs 'Create' and 'set their values/aliases.' This distinguishes it from sibling tools like variable_list (listing) and variable_delete (deletion), making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit parameter requirements for two actions (UPDATE_VARIABLE requires currentVariableName; CREATE_VARIABLE requires collectionName and scopes), which helps the agent know what inputs are needed. It does not explicitly state when to avoid this tool or name alternatives, but the 'create/update router' framing implies its role among siblings.
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. Dates show when Glama detected each change.
46 tool updates
v2.3.3- Changed
annotation_list9 fields changed- changed
Input schema / properties / includeCategories / descriptionPrevious value: -"If true, retrieves the list of global annotation categories in the file"New value: +"Include the file's global annotation categories in the result. Defaults to true; pass false to omit them." - added
Output schema / properties / annotatedNodesAdded value: +{ + "description": "Grouped annotations, preserving the owning node in page and node modes", + "items": { + "additionalProperties": {}, + "properties": { + "annotations": { + "description": "Annotations owned by this node", + "items": { + "additionalProperties": {}, + "properties": { + "categoryId": { + "type": "string" + }, + "label": { + "description": "Optional plain-text annotation label", + "type": "string" + }, + "labelMarkdown": { + "description": "Optional Markdown annotation label", + "type": "string" + }, + "properties": { + "items": { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "width", + "height", + "maxWidth", + "minWidth", + "maxHeight", + "minHeight", + "fills", + "strokes", + "effects", + "strokeWeight", + "cornerRadius", + "textStyleId", + "textAlignHorizontal", + "fontFamily", + "fontStyle", + "fontSize", + "fontWeight", + "lineHeight", + "letterSpacing", + "itemSpacing", + "padding", + "layoutMode", + "alignItems", + "opacity", + "mainComponent", + "gridRowGap", + "gridColumnGap", + "gridRowCount", + "gridColumnCount", + "gridRowAnchorIndex", + "gridColumnAnchorIndex", + "gridRowSpan", + "gridColumnSpan" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "name": { + "description": "Current name of the owning node", + "type": "string" + }, + "nodeId": { + "description": "ID of the node that owns these annotations", + "type": "string" + } + }, + "required": [ + "nodeId", + "name", + "annotations" + ], + "type": "object" + }, + "type": "array" +} - removed
Output schema / properties / annotationsRemoved value: -{ - "description": "List of annotations", - "items": {}, - "type": "array" -} - added
Output schema / properties / categories / items / additionalPropertiesAdded value: +{} - added
Output schema / properties / categories / items / propertiesAdded value: +{ + "color": { + "enum": [ + "yellow", + "orange", + "red", + "pink", + "violet", + "blue", + "teal", + "green" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "isPreset": { + "type": "boolean" + }, + "label": { + "type": "string" + } +} - added
Output schema / properties / categories / items / requiredAdded value: +[ + "id", + "label", + "color", + "isPreset" +] - added
Output schema / properties / categories / items / typeAdded value: +"object" - added
Output schema / properties / coverageAdded value: +{ + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "complete": { + "const": true, + "description": "Every attempted page succeeded", + "type": "boolean" + }, + "pageErrors": { + "description": "Empty: no page failed", + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "description": "Structured per-page failure", + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "pageId": { + "description": "ID of the page that could not be loaded, resolved, or read", + "type": "string" + } + }, + "required": [ + "pageId", + "error" + ], + "type": "object" + }, + "maxItems": 0, + "type": "array" + }, + "pagesAttempted": { + "description": "Distinct pages this call tried to resolve, load, or read. 0 means the result required no page access at all β it does NOT mean the document was checked and found clean.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "pagesAttempted", + "pageErrors" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "complete": { + "const": false, + "description": "At least one attempted page failed", + "type": "boolean" + }, + "pageErrors": { + "description": "Structured failures for pages omitted from this result; successful pages are still returned", + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "description": "Structured per-page failure", + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "pageId": { + "description": "ID of the page that could not be loaded, resolved, or read", + "type": "string" + } + }, + "required": [ + "pageId", + "error" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "pagesAttempted": { + "description": "Distinct pages this call tried to resolve, load, or read. 0 means the result required no page access at all β it does NOT mean the document was checked and found clean.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "pagesAttempted", + "pageErrors" + ], + "type": "object" + } + ], + "description": "Page-scan coverage; partial read data remains usable when complete is false" +} - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
annotation_set23 fields changed- added
Input schema / properties / annotations / items / additionalPropertiesAdded value: +false - removed
Input schema / properties / annotations / items / properties / annotationIdRemoved value: -{ - "description": "If updating: ID of the existing annotation", - "type": "string" -} - changed
Input schema / properties / annotations / items / properties / categoryId / descriptionPrevious value: -"The ID of the category"New value: +"Optional annotation category ID from annotation_list" - added
Input schema / properties / annotations / items / properties / labelMarkdownAdded value: +{ + "description": "Markdown annotation text; required and rejected when blank", + "type": "string" +} - changed
Input schema / properties / annotations / items / properties / nodeName / descriptionPrevious value: -"Expected name of the node (verification)"New value: +"The node's current exact name, passed back verbatim from `node_info`." - removed
Input schema / properties / annotations / items / properties / properties / additionalPropertiesRemoved value: -{} - changed
Input schema / properties / annotations / items / properties / properties / descriptionPrevious value: -"Custom metadata properties"New value: +"Optional duplicate-free Figma annotation property references. The enum is the full catalogue; Figma gates each entry by node type and refuses the append for one the target node does not support (e.g. 'fontSize' on a RECTANGLE), so a rejection here is a per-row failure rather than a schema error. Omit this field unless the property is clearly one the target node has." - added
Input schema / properties / annotations / items / properties / properties / itemsAdded value: +{ + "additionalProperties": false, + "properties": { + "type": { + "description": "The annotated Figma property", + "enum": [ + "width", + "height", + "maxWidth", + "minWidth", + "maxHeight", + "minHeight", + "fills", + "strokes", + "effects", + "strokeWeight", + "cornerRadius", + "textStyleId", + "textAlignHorizontal", + "fontFamily", + "fontStyle", + "fontSize", + "fontWeight", + "lineHeight", + "letterSpacing", + "itemSpacing", + "padding", + "layoutMode", + "alignItems", + "opacity", + "mainComponent", + "gridRowGap", + "gridColumnGap", + "gridRowCount", + "gridColumnCount", + "gridRowAnchorIndex", + "gridColumnAnchorIndex", + "gridRowSpan", + "gridColumnSpan" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" +} - removed
Input schema / properties / annotations / items / properties / properties / propertyNamesRemoved value: -{ - "type": "string" -} - changed
Input schema / properties / annotations / items / properties / properties / typePrevious value: -"object"New value: +"array" - removed
Input schema / properties / annotations / items / properties / statusRemoved value: -{ - "description": "Annotation status", - "enum": [ - "TODO", - "DONE", - "NONE" - ], - "type": "string" -} - changed
Input schema / properties / annotations / items / requiredPrevious value: -[ - "nodeId", - "nodeName", - "categoryId" -]New value: +[ + "nodeId", + "nodeName", + "labelMarkdown" +] - added
Input schema / properties / annotations / minItemsAdded value: +1 - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / failedCountAdded value: +{ + "description": "Number of failed annotations", + "type": "number" +} - added
Output schema / properties / requestedCountAdded value: +{ + "description": "Number of requested annotations", + "type": "number" +} - changed
Output schema / properties / results / descriptionPrevious value: -"Detailed execution results"New value: +"Detailed execution results with before/after annotation counts (one row per input, in input order)" - added
Output schema / properties / results / itemsAdded value: +{ + "additionalProperties": {}, + "properties": { + "afterCount": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Verified annotation count after this row's attempt, or null when post-attempt state is unknown" + }, + "afterCountVerified": { + "description": "Whether afterCount is a verified observation (false requires afterCount:null)", + "type": "boolean" + }, + "before": { + "description": "Q9/Q24: diagnostic evidence of the known pre-mutation state; not guaranteed to be a directly executable restoring-write input" + }, + "beforeCount": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "description": "Verified annotation count immediately before this row, or null when the count could not be read" + }, + "beforeCountVerified": { + "description": "Whether beforeCount is a verified observation (false requires beforeCount:null)", + "type": "boolean" + }, + "error": { + "description": "Actionable reason, REQUIRED on any non-success row (Q25 contract key)", + "type": "string" + }, + "nodeId": { + "description": "Identity of the target node (Q25 contract key)", + "type": "string" + }, + "outcomeUnknown": { + "const": true, + "description": "Present when an append was attempted but post-attempt state could not be verified; never retry blindly", + "type": "boolean" + }, + "partialMutation": { + "description": "Q9/Q24: set when the item mutated before it failed", + "type": "boolean" + }, + "postStateError": { + "description": "Secondary readback failure explaining why annotation state is unknown; the row error remains the initiating failure", + "type": "string" + }, + "status": { + "description": "Per-item outcome (Q25 contract key)", + "enum": [ + "success", + "failed", + "skipped" + ], + "type": "string" + }, + "success": { + "description": "Legacy per-row boolean; mirrors status === 'success'", + "type": "boolean" + }, + "whatChanged": { + "description": "Q9/Q24: plain-language statement of what changed", + "type": "string" + } + }, + "required": [ + "nodeId", + "status", + "beforeCount", + "afterCount", + "beforeCountVerified", + "afterCountVerified" + ], + "type": "object" +} - added
Output schema / properties / results / typeAdded value: +"array" - added
Output schema / properties / skippedCountAdded value: +{ + "description": "Number of skipped annotations", + "type": "number" +} - added
Output schema / properties / statusAdded value: +{ + "description": "Overall status of the batch operation", + "enum": [ + "success", + "partial_success", + "failed" + ], + "type": "string" +} - added
Output schema / properties / succeededCountAdded value: +{ + "description": "Number of succeeded annotations", + "type": "number" +} - changed
Output schema / properties / success / descriptionPrevious value: -"Whether annotations were set successfully"New value: +"Whether all annotations were set successfully"
- Changed
channel_join6 fields changed- added
Input schema / properties / channel / minLengthAdded value: +1 - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / errorDetailsAdded value: +{ + "description": "Structured error context if status is error and the underlying failure carried any" +} - added
Output schema / properties / pluginVersionAdded value: +{ + "description": "Self-reported bound Figma plugin build version (present on every successful join)", + "type": "string" +} - added
Output schema / properties / serverVersionAdded value: +{ + "description": "Self-reported MCP server build version (present on every successful join)", + "type": "string" +} - removed
Output schema / requiredRemoved value: -[ - "status", - "channel" -]
- Changed
component_delete_property2 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node for verification"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
component_list3 fields changed- added
Output schema / properties / coverageAdded value: +{ + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "complete": { + "const": true, + "description": "Every attempted page succeeded", + "type": "boolean" + }, + "pageErrors": { + "description": "Empty: no page failed", + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "description": "Structured per-page failure", + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "pageId": { + "description": "ID of the page that could not be loaded, resolved, or read", + "type": "string" + } + }, + "required": [ + "pageId", + "error" + ], + "type": "object" + }, + "maxItems": 0, + "type": "array" + }, + "pagesAttempted": { + "description": "Distinct pages this call tried to resolve, load, or read. 0 means the result required no page access at all β it does NOT mean the document was checked and found clean.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "pagesAttempted", + "pageErrors" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "complete": { + "const": false, + "description": "At least one attempted page failed", + "type": "boolean" + }, + "pageErrors": { + "description": "Structured failures for pages omitted from this result; successful pages are still returned", + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "description": "Structured per-page failure", + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "pageId": { + "description": "ID of the page that could not be loaded, resolved, or read", + "type": "string" + } + }, + "required": [ + "pageId", + "error" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "pagesAttempted": { + "description": "Distinct pages this call tried to resolve, load, or read. 0 means the result required no page access at all β it does NOT mean the document was checked and found clean.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "pagesAttempted", + "pageErrors" + ], + "type": "object" + } + ], + "description": "Page-scan coverage; partial read data remains usable when complete is false" +} - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "count", - "components" -]
- Changed
component_manage_property6 fields changed- changed
Input schema / properties / newPropertyName / descriptionPrevious value: -"For the EDIT action, to rename the property"New value: +"For EDIT, the optional replacement property name. It must be non-empty when supplied; omit it to leave the existing property name unchanged." - added
Input schema / properties / newPropertyName / minLengthAdded value: +1 - changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node for verification"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Input schema / properties / preferredValues / items / additionalPropertiesAdded value: +false - changed
Input schema / properties / propertyName / descriptionPrevious value: -"The human-readable name of the property to affect"New value: +"For ADD, the required new property name, which must be non-empty. For EDIT, the existing property's exact lookup name." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
create_component4 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to verify against"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / parentIdAdded value: +{ + "description": "ID of the parent the component was placed into β confirm containment without a follow-up read", + "type": "string" +} - removed
Output schema / requiredRemoved value: -[ - "id", - "name" -]
- Changed
create_component_set10 fields changed- changed
Input schema / properties / componentSetName / descriptionPrevious value: -"Name for the component set"New value: +"Optional non-empty name for the component set" - added
Input schema / properties / componentSetName / minLengthAdded value: +1 - added
Input schema / properties / components / items / additionalPropertiesAdded value: +false - changed
Input schema / properties / components / items / properties / nodeName / descriptionPrevious value: -"Current name (for verification)"New value: +"The component's current exact name, passed back verbatim from `node_info`." - changed
Input schema / properties / parentId / descriptionPrevious value: -"Parent frame to place the set in"New value: +"ID of the appendable parent container (frame, group, page, section, etc.) to place the set in; discover it with node_info" - changed
Input schema / properties / parentNodeName / descriptionPrevious value: -"Name of parent node (required if parentId provided, for verification)"New value: +"The parent node's current exact name, passed back verbatim from `node_info`." - changed
Input schema / requiredPrevious value: -[ - "components", - "properties" -]New value: +[ + "components", + "properties", + "parentId", + "parentNodeName" +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / parentIdAdded value: +{ + "description": "ID of the parent the set was placed into β confirm containment without a follow-up read", + "type": "string" +} - removed
Output schema / requiredRemoved value: -[ - "id", - "name" -]
- Removed
create_connection - Changed
create_frame9 fields changed- added
Input schema / properties / fillColor / additionalPropertiesAdded value: +false - changed
Input schema / properties / name / descriptionPrevious value: -"Optional name for the frame"New value: +"Optional non-empty name for the frame" - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / parentNodeName / descriptionPrevious value: -"Name of the parent node to verify against"New value: +"The parent node's current exact name, passed back verbatim from `node_info`." - added
Input schema / properties / strokeColor / additionalPropertiesAdded value: +false - changed
Input schema / requiredPrevious value: -[ - "x", - "y", - "width", - "height", - "parentId" -]New value: +[ + "x", + "y", + "width", + "height", + "parentId", + "parentNodeName" +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / parentIdAdded value: +{ + "description": "ID of the parent the node was placed into β confirm containment without a follow-up read", + "type": "string" +} - removed
Output schema / requiredRemoved value: -[ - "id", - "name" -]
- Changed
create_instance6 fields changed- changed
Input schema / properties / parentNodeName / descriptionPrevious value: -"Name of the parent node to verify against"New value: +"The parent node's current exact name, passed back verbatim from `node_info`." - changed
Input schema / requiredPrevious value: -[ - "x", - "y", - "parentId" -]New value: +[ + "x", + "y", + "parentId", + "parentNodeName" +] - added
Output schema / properties / componentIdAdded value: +{ + "description": "ID of the component the instance was created from", + "type": "string" +} - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / parentIdAdded value: +{ + "description": "ID of the parent the instance was placed into β confirm containment without a follow-up read", + "type": "string" +} - removed
Output schema / requiredRemoved value: -[ - "id", - "name" -]
- Changed
create_shape10 fields changed- added
Input schema / properties / arcData / additionalPropertiesAdded value: +false - added
Input schema / properties / fillColor / additionalPropertiesAdded value: +false - changed
Input schema / properties / name / descriptionPrevious value: -"Optional name for the shape"New value: +"Optional non-empty name for the shape" - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / parentNodeName / descriptionPrevious value: -"Name of the parent node to verify against"New value: +"The parent node's current exact name, passed back verbatim from `node_info`." - added
Input schema / properties / strokeColor / additionalPropertiesAdded value: +false - changed
Input schema / requiredPrevious value: -[ - "type", - "x", - "y", - "width", - "height", - "parentId" -]New value: +[ + "type", + "x", + "y", + "width", + "height", + "parentId", + "parentNodeName" +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / parentIdAdded value: +{ + "description": "ID of the parent the node was placed into β confirm containment without a follow-up read", + "type": "string" +} - removed
Output schema / requiredRemoved value: -[ - "id", - "name" -]
- Changed
create_svg7 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"Name for the new node"New value: +"Optional non-empty name for the new node" - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / parentNodeName / descriptionPrevious value: -"Parent Name to verify against"New value: +"The parent node's current exact name, passed back verbatim from `node_info`." - changed
Input schema / requiredPrevious value: -[ - "svg", - "parentId" -]New value: +[ + "svg", + "parentId", + "parentNodeName" +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / parentIdAdded value: +{ + "description": "ID of the parent the node was placed into β confirm containment without a follow-up read", + "type": "string" +} - removed
Output schema / requiredRemoved value: -[ - "id", - "name" -]
- Changed
create_text15 fields changed- added
Input schema / properties / fontColor / additionalPropertiesAdded value: +false - changed
Input schema / properties / fontSize / descriptionPrevious value: -"Font size (default: 14)"New value: +"Font size, minimum 1 (default: 14)" - added
Input schema / properties / fontSize / minimumAdded value: +1 - changed
Input schema / properties / fontWeight / descriptionPrevious value: -"Font weight (e.g., 400 for Regular, 700 for Bold)"New value: +"Font weight: 100β900 in increments of 100 (default: 400)" - added
Input schema / properties / fontWeight / maximumAdded value: +900 - added
Input schema / properties / fontWeight / minimumAdded value: +100 - added
Input schema / properties / fontWeight / multipleOfAdded value: +100 - changed
Input schema / properties / fontWeight / typePrevious value: -"number"New value: +"integer" - changed
Input schema / properties / name / descriptionPrevious value: -"Semantic layer name for the text node"New value: +"Optional non-empty semantic layer name for the text node" - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / parentNodeName / descriptionPrevious value: -"Name of the parent node to verify against"New value: +"The parent node's current exact name, passed back verbatim from `node_info`." - changed
Input schema / requiredPrevious value: -[ - "x", - "y", - "text", - "parentId" -]New value: +[ + "x", + "y", + "text", + "parentId", + "parentNodeName" +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / parentIdAdded value: +{ + "description": "ID of the parent the node was placed into β confirm containment without a follow-up read", + "type": "string" +} - removed
Output schema / requiredRemoved value: -[ - "id", - "name" -]
- Changed
instance_get_overrides1 field changed- added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
instance_set_overrides16 fields changed- added
Input schema / properties / targetNodes / items / additionalPropertiesAdded value: +false - changed
Input schema / properties / targetNodes / items / properties / nodeName / descriptionPrevious value: -"Name of the node to modify"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Input schema / properties / targetNodes / minItemsAdded value: +1 - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / failedCountAdded value: +{ + "description": "Number of failed targets", + "type": "number" +} - removed
Output schema / properties / messageRemoved value: -{ - "description": "Status message", - "type": "string" -} - added
Output schema / properties / requestedCountAdded value: +{ + "description": "Number of requested targets", + "type": "number" +} - changed
Output schema / properties / results / descriptionPrevious value: -"Results per target node"New value: +"Results per target node (one row per input, in input order)" - added
Output schema / properties / results / items / additionalPropertiesAdded value: +{} - added
Output schema / properties / results / items / propertiesAdded value: +{ + "before": { + "description": "Q9/Q24: diagnostic evidence of the known pre-mutation state; not guaranteed to be a directly executable restoring-write input" + }, + "error": { + "description": "Actionable reason, REQUIRED on any non-success row (Q25 contract key)", + "type": "string" + }, + "nodeId": { + "description": "Identity of the target node (Q25 contract key)", + "type": "string" + }, + "partialMutation": { + "description": "Q9/Q24: set when the item mutated before it failed", + "type": "boolean" + }, + "status": { + "description": "Per-item outcome (Q25 contract key)", + "enum": [ + "success", + "failed", + "skipped" + ], + "type": "string" + }, + "success": { + "description": "Legacy per-row boolean; mirrors status === 'success'", + "type": "boolean" + }, + "whatChanged": { + "description": "Q9/Q24: plain-language statement of what changed", + "type": "string" + } +} - added
Output schema / properties / results / items / requiredAdded value: +[ + "nodeId", + "status" +] - added
Output schema / properties / results / items / typeAdded value: +"object" - added
Output schema / properties / skippedCountAdded value: +{ + "description": "Number of skipped targets", + "type": "number" +} - added
Output schema / properties / statusAdded value: +{ + "description": "Overall status of the batch operation", + "enum": [ + "success", + "partial_success", + "failed" + ], + "type": "string" +} - added
Output schema / properties / succeededCountAdded value: +{ + "description": "Number of succeeded targets", + "type": "number" +} - removed
Output schema / properties / totalCountRemoved value: -{ - "description": "Total overrides count", - "type": "number" -}
- Changed
instance_set_property2 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the instance node for verification"New value: +"The instance's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
node_apply_style3 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to verify against"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "success" -]
- Changed
node_bind_variable2 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to verify against"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
node_clone4 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to modify"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / parentIdAdded value: +{ + "description": "ID of the parent the clone was placed into β confirm containment without a follow-up read", + "type": "string" +} - removed
Output schema / requiredRemoved value: -[ - "id", - "name" -]
- Changed
node_delete17 fields changed- added
Input schema / properties / nodes / items / additionalPropertiesAdded value: +false - changed
Input schema / properties / nodes / items / properties / nodeName / descriptionPrevious value: -"Name of the node to modify"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Input schema / properties / nodes / minItemsAdded value: +1 - removed
Output schema / properties / deletedCountRemoved value: -{ - "description": "Number of deleted nodes", - "type": "number" -} - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / failedCountAdded value: +{ + "description": "Number of failed deletions", + "type": "number" +} - added
Output schema / properties / requestedCountAdded value: +{ + "description": "Number of requested deletions", + "type": "number" +} - changed
Output schema / properties / results / descriptionPrevious value: -"Detailed deletion results"New value: +"Detailed deletion results (one row per input, in input order)" - added
Output schema / properties / results / items / additionalPropertiesAdded value: +{} - added
Output schema / properties / results / items / propertiesAdded value: +{ + "before": { + "description": "Q9/Q24: diagnostic evidence of the known pre-mutation state; not guaranteed to be a directly executable restoring-write input" + }, + "error": { + "description": "Actionable reason, REQUIRED on any non-success row (Q25 contract key)", + "type": "string" + }, + "nodeId": { + "description": "Identity of the target node (Q25 contract key)", + "type": "string" + }, + "partialMutation": { + "description": "Q9/Q24: set when the item mutated before it failed", + "type": "boolean" + }, + "status": { + "description": "Per-item outcome (Q25 contract key)", + "enum": [ + "success", + "failed", + "skipped" + ], + "type": "string" + }, + "success": { + "description": "Legacy per-row boolean; mirrors status === 'success'", + "type": "boolean" + }, + "whatChanged": { + "description": "Q9/Q24: plain-language statement of what changed", + "type": "string" + } +} - added
Output schema / properties / results / items / requiredAdded value: +[ + "nodeId", + "status" +] - added
Output schema / properties / results / items / typeAdded value: +"object" - added
Output schema / properties / skippedCountAdded value: +{ + "description": "Number of skipped deletions", + "type": "number" +} - added
Output schema / properties / statusAdded value: +{ + "description": "Overall status of the batch operation", + "enum": [ + "success", + "partial_success", + "failed" + ], + "type": "string" +} - added
Output schema / properties / succeededCountAdded value: +{ + "description": "Number of succeeded deletions", + "type": "number" +} - changed
Output schema / properties / success / descriptionPrevious value: -"Whether the operation succeeded"New value: +"Whether all deletions succeeded" - removed
Output schema / requiredRemoved value: -[ - "success" -]
- Changed
node_export_visual1 field changed- added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
node_flatten4 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to verify against"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / parentIdAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ID of the container the flattened node was placed in β the source node's original parent, so D11 containment is confirmable from this response without a follow-up node_info" +} - removed
Output schema / requiredRemoved value: -[ - "id", - "name", - "type" -]
- Changed
node_group6 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"Name for the new group"New value: +"Optional non-empty name for the new group. Omit to accept Figma's default; `\"\"` is refused rather than silently substituted." - added
Input schema / properties / name / minLengthAdded value: +1 - added
Input schema / properties / nodes / items / additionalPropertiesAdded value: +false - changed
Input schema / properties / nodes / items / properties / nodeName / descriptionPrevious value: -"Name of the node to modify"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "id", - "name", - "childCount" -]
- Changed
node_info4 fields changed- added
Output schema / properties / coverageAdded value: +{ + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "complete": { + "const": true, + "description": "Every attempted page succeeded", + "type": "boolean" + }, + "pageErrors": { + "description": "Empty: no page failed", + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "description": "Structured per-page failure", + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "pageId": { + "description": "ID of the page that could not be loaded, resolved, or read", + "type": "string" + } + }, + "required": [ + "pageId", + "error" + ], + "type": "object" + }, + "maxItems": 0, + "type": "array" + }, + "pagesAttempted": { + "description": "Distinct pages this call tried to resolve, load, or read. 0 means the result required no page access at all β it does NOT mean the document was checked and found clean.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "pagesAttempted", + "pageErrors" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "complete": { + "const": false, + "description": "At least one attempted page failed", + "type": "boolean" + }, + "pageErrors": { + "description": "Structured failures for pages omitted from this result; successful pages are still returned", + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "description": "Structured per-page failure", + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "pageId": { + "description": "ID of the page that could not be loaded, resolved, or read", + "type": "string" + } + }, + "required": [ + "pageId", + "error" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "pagesAttempted": { + "description": "Distinct pages this call tried to resolve, load, or read. 0 means the result required no page access at all β it does NOT mean the document was checked and found clean.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "pagesAttempted", + "pageErrors" + ], + "type": "object" + } + ], + "description": "Page-scan coverage; partial read data remains usable when complete is false" +} - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / pageFailedNodesAdded value: +{ + "description": "Requested nodes that exist but could not be read because their containing page failed; omitted when none", + "items": { + "additionalProperties": false, + "properties": { + "nodeId": { + "description": "Requested node ID that could not be read", + "type": "string" + }, + "pageId": { + "description": "Its containing page β match this against `coverage.pageErrors` for the reason and the recovery", + "type": "string" + } + }, + "required": [ + "nodeId", + "pageId" + ], + "type": "object" + }, + "type": "array" +} - removed
Output schema / requiredRemoved value: -[ - "nodes" -]
- Changed
node_insert_child4 fields changed- changed
Input schema / properties / childNodeName / descriptionPrevious value: -"Name of the child node to verify against"New value: +"The child node's current exact name, passed back verbatim from `node_info`." - changed
Input schema / properties / parentNodeName / descriptionPrevious value: -"Name of the parent node to verify against"New value: +"The parent node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "childId", - "newParentId", - "index" -]
- Changed
node_rename5 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"New name for the node"New value: +"New non-empty name for the node. Figma normalizes an empty name to a type default, so `\"\"` is refused rather than silently substituted." - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to modify"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "name", - "oldName" -]
- Changed
node_set_auto_layout3 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to modify"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "name" -]
- Changed
node_set_corner_radius3 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to modify"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "name" -]
- Changed
node_set_effects8 fields changed- changed
Input schema / properties / effects / descriptionPrevious value: -"Array of effect objects"New value: +"Array of strict per-variant Figma effects: DROP_SHADOW/INNER_SHADOW or LAYER_BLUR/BACKGROUND_BLUR" - removed
Input schema / properties / effects / items / descriptionRemoved value: -"Figma effect settings" - added
Input schema / properties / effects / items / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "blendMode": { + "description": "Figma BlendMode (default 'NORMAL')", + "enum": [ + "PASS_THROUGH", + "NORMAL", + "DARKEN", + "MULTIPLY", + "LINEAR_BURN", + "COLOR_BURN", + "LIGHTEN", + "SCREEN", + "LINEAR_DODGE", + "COLOR_DODGE", + "OVERLAY", + "SOFT_LIGHT", + "HARD_LIGHT", + "DIFFERENCE", + "EXCLUSION", + "HUE", + "SATURATION", + "COLOR", + "LUMINOSITY" + ], + "type": "string" + }, + "color": { + "additionalProperties": false, + "description": "Shadow colour (default {r:0,g:0,b:0,a:0.25})", + "properties": { + "a": { + "description": "Alpha, 0β1 β required: Figma rejects an effect colour without it", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "b": { + "description": "Blue, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "g": { + "description": "Green, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "r": { + "description": "Red, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "r", + "g", + "b", + "a" + ], + "type": "object" + }, + "offset": { + "additionalProperties": false, + "description": "Shadow offset (default {x:0,y:4})", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "radius": { + "description": "Blur radius, px; must be β₯ 0 (default 4)", + "minimum": 0, + "type": "number" + }, + "showShadowBehindNode": { + "description": "DROP_SHADOW only (default false)", + "type": "boolean" + }, + "spread": { + "description": "Shadow spread, px (default 0)", + "type": "number" + }, + "type": { + "const": "DROP_SHADOW", + "type": "string" + }, + "visible": { + "description": "default true", + "type": "boolean" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "blendMode": { + "description": "Figma BlendMode (default 'NORMAL')", + "enum": [ + "PASS_THROUGH", + "NORMAL", + "DARKEN", + "MULTIPLY", + "LINEAR_BURN", + "COLOR_BURN", + "LIGHTEN", + "SCREEN", + "LINEAR_DODGE", + "COLOR_DODGE", + "OVERLAY", + "SOFT_LIGHT", + "HARD_LIGHT", + "DIFFERENCE", + "EXCLUSION", + "HUE", + "SATURATION", + "COLOR", + "LUMINOSITY" + ], + "type": "string" + }, + "color": { + "additionalProperties": false, + "description": "Shadow colour (default {r:0,g:0,b:0,a:0.25})", + "properties": { + "a": { + "description": "Alpha, 0β1 β required: Figma rejects an effect colour without it", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "b": { + "description": "Blue, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "g": { + "description": "Green, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "r": { + "description": "Red, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "r", + "g", + "b", + "a" + ], + "type": "object" + }, + "offset": { + "additionalProperties": false, + "description": "Shadow offset (default {x:0,y:4})", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "radius": { + "description": "Blur radius, px; must be β₯ 0 (default 4)", + "minimum": 0, + "type": "number" + }, + "spread": { + "description": "Shadow spread, px (default 0)", + "type": "number" + }, + "type": { + "const": "INNER_SHADOW", + "type": "string" + }, + "visible": { + "description": "default true", + "type": "boolean" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "blurType": { + "description": "default 'NORMAL'", + "enum": [ + "NORMAL", + "PROGRESSIVE" + ], + "type": "string" + }, + "endOffset": { + "additionalProperties": false, + "description": "PROGRESSIVE only: where the ramp ends", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "radius": { + "description": "Blur radius, px; must be β₯ 0 (default 4)", + "minimum": 0, + "type": "number" + }, + "startOffset": { + "additionalProperties": false, + "description": "PROGRESSIVE only: where the ramp starts", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "startRadius": { + "description": "PROGRESSIVE only: radius at the start of the ramp", + "type": "number" + }, + "type": { + "const": "LAYER_BLUR", + "type": "string" + }, + "visible": { + "description": "default true", + "type": "boolean" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "blurType": { + "description": "default 'NORMAL'", + "enum": [ + "NORMAL", + "PROGRESSIVE" + ], + "type": "string" + }, + "endOffset": { + "additionalProperties": false, + "description": "PROGRESSIVE only: where the ramp ends", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "radius": { + "description": "Blur radius, px; must be β₯ 0 (default 4)", + "minimum": 0, + "type": "number" + }, + "startOffset": { + "additionalProperties": false, + "description": "PROGRESSIVE only: where the ramp starts", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "startRadius": { + "description": "PROGRESSIVE only: radius at the start of the ramp", + "type": "number" + }, + "type": { + "const": "BACKGROUND_BLUR", + "type": "string" + }, + "visible": { + "description": "default true", + "type": "boolean" + } + }, + "required": [ + "type" + ], + "type": "object" + } +] - removed
Input schema / properties / effects / items / propertiesRemoved value: -{ - "blendMode": { - "description": "Blend mode", - "type": "string" - }, - "color": { - "description": "Effect color", - "properties": { - "a": { - "description": "Alpha (0-1)", - "type": "number" - }, - "b": { - "description": "Blue (0-1)", - "type": "number" - }, - "g": { - "description": "Green (0-1)", - "type": "number" - }, - "r": { - "description": "Red (0-1)", - "type": "number" - } - }, - "required": [ - "r", - "g", - "b" - ], - "type": "object" - }, - "offset": { - "description": "Shadow offset", - "properties": { - "x": { - "description": "X offset", - "type": "number" - }, - "y": { - "description": "Y offset", - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": "object" - }, - "radius": { - "description": "Blur radius", - "type": "number" - }, - "showShadowBehindNode": { - "description": "Show shadow behind node", - "type": "boolean" - }, - "spread": { - "description": "Shadow spread", - "type": "number" - }, - "type": { - "description": "Effect type", - "enum": [ - "DROP_SHADOW", - "INNER_SHADOW", - "LAYER_BLUR", - "BACKGROUND_BLUR" - ], - "type": "string" - }, - "visible": { - "description": "Visibility", - "type": "boolean" - } -} - removed
Input schema / properties / effects / items / requiredRemoved value: -[ - "type" -] - removed
Input schema / properties / effects / items / typeRemoved value: -"object" - changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to verify against"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
node_set_fill4 fields changed- added
Input schema / properties / image / additionalPropertiesAdded value: +false - changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to modify"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "name" -]
- Changed
node_set_stroke3 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to modify"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "name" -]
- Changed
node_transform2 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to modify"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
node_ungroup3 fields changed- changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the group to verify against"New value: +"The group's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "parentId", - "ungroupedChildren" -]
- Changed
page_info4 fields changed- added
Output schema / properties / coverageAdded value: +{ + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "complete": { + "const": true, + "description": "Every attempted page succeeded", + "type": "boolean" + }, + "pageErrors": { + "description": "Empty: no page failed", + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "description": "Structured per-page failure", + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "pageId": { + "description": "ID of the page that could not be loaded, resolved, or read", + "type": "string" + } + }, + "required": [ + "pageId", + "error" + ], + "type": "object" + }, + "maxItems": 0, + "type": "array" + }, + "pagesAttempted": { + "description": "Distinct pages this call tried to resolve, load, or read. 0 means the result required no page access at all β it does NOT mean the document was checked and found clean.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "pagesAttempted", + "pageErrors" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "complete": { + "const": false, + "description": "At least one attempted page failed", + "type": "boolean" + }, + "pageErrors": { + "description": "Structured failures for pages omitted from this result; successful pages are still returned", + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "description": "Structured per-page failure", + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "pageId": { + "description": "ID of the page that could not be loaded, resolved, or read", + "type": "string" + } + }, + "required": [ + "pageId", + "error" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "pagesAttempted": { + "description": "Distinct pages this call tried to resolve, load, or read. 0 means the result required no page access at all β it does NOT mean the document was checked and found clean.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "pagesAttempted", + "pageErrors" + ], + "type": "object" + } + ], + "description": "Page-scan coverage; partial read data remains usable when complete is false" +} - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - changed
Output schema / properties / missingPageIds / descriptionPrevious value: -"Page IDs that could not be found"New value: +"Every requested page ID absent from `pages`, whatever the cause; `coverage.pageErrors` carries the structured reason for each" - removed
Output schema / requiredRemoved value: -[ - "documentId", - "documentName", - "pageCount", - "pages" -]
- Changed
reaction_list1 field changed- added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
reaction_update5 fields changed- changed
Input schema / definitions / __schema0 / anyOfPrevious value: -[ - { - "properties": { - "type": { - "enum": [ - "BACK", - "CLOSE" - ], - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "properties": { - "openInNewTab": { - "type": "boolean" - }, - "type": { - "const": "URL", - "type": "string" - }, - "url": { - "type": "string" - } - }, - "required": [ - "type", - "url" - ], - "type": "object" - }, - { - "properties": { - "amountToSkip": { - "type": "number" - }, - "destinationId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "mediaAction": { - "type": "string" - }, - "newTimestamp": { - "type": "number" - }, - "type": { - "const": "UPDATE_MEDIA_RUNTIME", - "type": "string" - } - }, - "required": [ - "type", - "mediaAction" - ], - "type": "object" - }, - { - "properties": { - "type": { - "const": "SET_VARIABLE", - "type": "string" - }, - "variableId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "variableValue": { - "properties": { - "resolvedType": { - "type": "string" - }, - "type": { - "type": "string" - }, - "value": {} - }, - "type": "object" - } - }, - "required": [ - "type", - "variableId" - ], - "type": "object" - }, - { - "properties": { - "type": { - "const": "SET_VARIABLE_MODE", - "type": "string" - }, - "variableCollectionId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "variableModeId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "type", - "variableCollectionId", - "variableModeId" - ], - "type": "object" - }, - { - "properties": { - "conditionalBlocks": { - "items": { - "properties": { - "actions": { - "items": { - "$ref": "#/definitions/__schema0" - }, - "type": "array" - }, - "condition": { - "properties": { - "resolvedType": { - "type": "string" - }, - "type": { - "type": "string" - }, - "value": {} - }, - "type": "object" - } - }, - "required": [ - "actions" - ], - "type": "object" - }, - "type": "array" - }, - "type": { - "const": "CONDITIONAL", - "type": "string" - } - }, - "required": [ - "type", - "conditionalBlocks" - ], - "type": "object" - }, - { - "properties": { - "destinationId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "navigation": { - "type": "string" - }, - "overlayRelativePosition": {}, - "preserveScrollPosition": { - "type": "boolean" - }, - "resetInteractiveComponents": { - "type": "boolean" - }, - "resetScrollPosition": { - "type": "boolean" - }, - "resetVideoPosition": { - "type": "boolean" - }, - "transition": { - "anyOf": [ - {}, - { - "type": "null" - } - ] - }, - "type": { - "const": "NODE", - "type": "string" - } - }, - "required": [ - "type", - "destinationId", - "navigation" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "BACK", + "CLOSE" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "openInNewTab": { + "type": "boolean" + }, + "type": { + "const": "URL", + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "type", + "url" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "amountToSkip": { + "type": "number" + }, + "destinationId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "mediaAction": { + "type": "string" + }, + "newTimestamp": { + "type": "number" + }, + "type": { + "const": "UPDATE_MEDIA_RUNTIME", + "type": "string" + } + }, + "required": [ + "type", + "mediaAction" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "const": "SET_VARIABLE", + "type": "string" + }, + "variableId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "variableValue": { + "additionalProperties": false, + "properties": { + "resolvedType": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "type": "object" + } + }, + "required": [ + "type", + "variableId" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "const": "SET_VARIABLE_MODE", + "type": "string" + }, + "variableCollectionId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "variableModeId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "type", + "variableCollectionId", + "variableModeId" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "conditionalBlocks": { + "items": { + "additionalProperties": false, + "properties": { + "actions": { + "items": { + "$ref": "#/definitions/__schema0" + }, + "type": "array" + }, + "condition": { + "additionalProperties": false, + "properties": { + "resolvedType": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "type": "object" + } + }, + "required": [ + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "type": { + "const": "CONDITIONAL", + "type": "string" + } + }, + "required": [ + "type", + "conditionalBlocks" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "destinationId": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "navigation": { + "type": "string" + }, + "overlayRelativePosition": {}, + "preserveScrollPosition": { + "type": "boolean" + }, + "resetInteractiveComponents": { + "type": "boolean" + }, + "resetScrollPosition": { + "type": "boolean" + }, + "resetVideoPosition": { + "type": "boolean" + }, + "transition": { + "anyOf": [ + {}, + { + "type": "null" + } + ] + }, + "type": { + "const": "NODE", + "type": "string" + } + }, + "required": [ + "type", + "destinationId", + "navigation" + ], + "type": "object" + } +] - changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to update reactions for (for verification)"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Input schema / properties / reactions / items / additionalPropertiesAdded value: +false - changed
Input schema / properties / reactions / items / properties / trigger / anyOfPrevious value: -[ - { - "properties": { - "delay": { - "description": "Delay before trigger fires", - "type": "number" - }, - "deprecatedVersion": { - "description": "Whether the trigger is deprecated", - "type": "boolean" - }, - "device": { - "description": "Device setting", - "type": "string" - }, - "keyCodes": { - "description": "Key codes for key trigger", - "items": { - "type": "number" - }, - "type": "array" - }, - "mediaHitTime": { - "description": "Media hit time", - "type": "number" - }, - "timeout": { - "description": "Timeout for delay triggers", - "type": "number" - }, - "type": { - "description": "Trigger type (e.g. ON_CLICK, ON_HOVER)", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "type": "null" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "delay": { + "description": "Delay before trigger fires", + "type": "number" + }, + "deprecatedVersion": { + "description": "Whether the trigger is deprecated", + "type": "boolean" + }, + "device": { + "description": "Device setting", + "type": "string" + }, + "keyCodes": { + "description": "Key codes for key trigger", + "items": { + "type": "number" + }, + "type": "array" + }, + "mediaHitTime": { + "description": "Media hit time", + "type": "number" + }, + "timeout": { + "description": "Timeout for delay triggers", + "type": "number" + }, + "type": { + "description": "Trigger type (e.g. ON_CLICK, ON_HOVER)", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "type": "null" + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
style_delete3 fields changed- changed
Input schema / properties / styleName / descriptionPrevious value: -"Expected name of style to delete (verification)"New value: +"The style's current exact name, passed back verbatim from `style_list`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "success", - "message" -]
- Changed
style_list2 fields changed- added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "colors", - "texts", - "effects", - "grids" -]
- Changed
style_manage16 fields changed- added
Input schema / properties / currentStyleNameAdded value: +{ + "description": "REQUIRED for UPDATE when styleId is supplied β the style's **current exact** name, passed back verbatim from `style_list`", + "type": "string" +} - changed
Input schema / properties / name / descriptionPrevious value: -"Name of the style"New value: +"Style name. Must be non-empty when supplied. REQUIRED for CREATE; omit it on UPDATE to leave the current style name unchanged." - added
Input schema / properties / properties / additionalPropertiesAdded value: +false - changed
Input schema / properties / properties / properties / effects / descriptionPrevious value: -"EFFECT: array of Figma Effect objects, e.g. {type:'DROP_SHADOW', color, offset:{x,y}, radius, spread?, visible?, blendMode?}"New value: +"EFFECT: array of Figma Effect objects, one shape per `type` β DROP_SHADOW/INNER_SHADOW (color, offset, radius, spread), LAYER_BLUR/BACKGROUND_BLUR (radius, blurType), NOISE (noiseType, color, noiseSize, density), TEXTURE (noiseSize, radius, clipToShape), GLASS (lightIntensity, lightAngle, refraction, depth, dispersion, radius). At most one GLASS effect is allowed per node. Required-vs-optional and numeric bounds are authoritative in each variant's schema." - removed
Input schema / properties / properties / properties / effects / items / additionalPropertiesRemoved value: -{} - added
Input schema / properties / properties / properties / effects / items / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "blendMode": { + "description": "Figma BlendMode (default 'NORMAL')", + "enum": [ + "PASS_THROUGH", + "NORMAL", + "DARKEN", + "MULTIPLY", + "LINEAR_BURN", + "COLOR_BURN", + "LIGHTEN", + "SCREEN", + "LINEAR_DODGE", + "COLOR_DODGE", + "OVERLAY", + "SOFT_LIGHT", + "HARD_LIGHT", + "DIFFERENCE", + "EXCLUSION", + "HUE", + "SATURATION", + "COLOR", + "LUMINOSITY" + ], + "type": "string" + }, + "color": { + "additionalProperties": false, + "description": "Shadow colour (default {r:0,g:0,b:0,a:0.25})", + "properties": { + "a": { + "description": "Alpha, 0β1 β required: Figma rejects an effect colour without it", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "b": { + "description": "Blue, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "g": { + "description": "Green, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "r": { + "description": "Red, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "r", + "g", + "b", + "a" + ], + "type": "object" + }, + "offset": { + "additionalProperties": false, + "description": "Shadow offset (default {x:0,y:4})", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "radius": { + "description": "Blur radius, px; must be β₯ 0 (default 4)", + "minimum": 0, + "type": "number" + }, + "showShadowBehindNode": { + "description": "DROP_SHADOW only (default false)", + "type": "boolean" + }, + "spread": { + "description": "Shadow spread, px (default 0)", + "type": "number" + }, + "type": { + "const": "DROP_SHADOW", + "type": "string" + }, + "visible": { + "description": "default true", + "type": "boolean" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "blendMode": { + "description": "Figma BlendMode (default 'NORMAL')", + "enum": [ + "PASS_THROUGH", + "NORMAL", + "DARKEN", + "MULTIPLY", + "LINEAR_BURN", + "COLOR_BURN", + "LIGHTEN", + "SCREEN", + "LINEAR_DODGE", + "COLOR_DODGE", + "OVERLAY", + "SOFT_LIGHT", + "HARD_LIGHT", + "DIFFERENCE", + "EXCLUSION", + "HUE", + "SATURATION", + "COLOR", + "LUMINOSITY" + ], + "type": "string" + }, + "color": { + "additionalProperties": false, + "description": "Shadow colour (default {r:0,g:0,b:0,a:0.25})", + "properties": { + "a": { + "description": "Alpha, 0β1 β required: Figma rejects an effect colour without it", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "b": { + "description": "Blue, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "g": { + "description": "Green, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "r": { + "description": "Red, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "r", + "g", + "b", + "a" + ], + "type": "object" + }, + "offset": { + "additionalProperties": false, + "description": "Shadow offset (default {x:0,y:4})", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "radius": { + "description": "Blur radius, px; must be β₯ 0 (default 4)", + "minimum": 0, + "type": "number" + }, + "spread": { + "description": "Shadow spread, px (default 0)", + "type": "number" + }, + "type": { + "const": "INNER_SHADOW", + "type": "string" + }, + "visible": { + "description": "default true", + "type": "boolean" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "blurType": { + "description": "default 'NORMAL'", + "enum": [ + "NORMAL", + "PROGRESSIVE" + ], + "type": "string" + }, + "endOffset": { + "additionalProperties": false, + "description": "PROGRESSIVE only: where the ramp ends", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "radius": { + "description": "Blur radius, px; must be β₯ 0 (default 4)", + "minimum": 0, + "type": "number" + }, + "startOffset": { + "additionalProperties": false, + "description": "PROGRESSIVE only: where the ramp starts", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "startRadius": { + "description": "PROGRESSIVE only: radius at the start of the ramp", + "type": "number" + }, + "type": { + "const": "LAYER_BLUR", + "type": "string" + }, + "visible": { + "description": "default true", + "type": "boolean" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "blurType": { + "description": "default 'NORMAL'", + "enum": [ + "NORMAL", + "PROGRESSIVE" + ], + "type": "string" + }, + "endOffset": { + "additionalProperties": false, + "description": "PROGRESSIVE only: where the ramp ends", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "radius": { + "description": "Blur radius, px; must be β₯ 0 (default 4)", + "minimum": 0, + "type": "number" + }, + "startOffset": { + "additionalProperties": false, + "description": "PROGRESSIVE only: where the ramp starts", + "properties": { + "x": { + "description": "X offset, px", + "type": "number" + }, + "y": { + "description": "Y offset, px", + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": "object" + }, + "startRadius": { + "description": "PROGRESSIVE only: radius at the start of the ramp", + "type": "number" + }, + "type": { + "const": "BACKGROUND_BLUR", + "type": "string" + }, + "visible": { + "description": "default true", + "type": "boolean" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "blendMode": { + "description": "Figma BlendMode (default 'NORMAL')", + "enum": [ + "PASS_THROUGH", + "NORMAL", + "DARKEN", + "MULTIPLY", + "LINEAR_BURN", + "COLOR_BURN", + "LIGHTEN", + "SCREEN", + "LINEAR_DODGE", + "COLOR_DODGE", + "OVERLAY", + "SOFT_LIGHT", + "HARD_LIGHT", + "DIFFERENCE", + "EXCLUSION", + "HUE", + "SATURATION", + "COLOR", + "LUMINOSITY" + ], + "type": "string" + }, + "color": { + "additionalProperties": false, + "description": "Primary noise colour", + "properties": { + "a": { + "description": "Alpha, 0β1 β required: Figma rejects an effect colour without it", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "b": { + "description": "Blue, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "g": { + "description": "Green, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "r": { + "description": "Red, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "r", + "g", + "b", + "a" + ], + "type": "object" + }, + "density": { + "description": "Noise density, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "noiseSize": { + "description": "Noise grain size, 0β100 (Figma clamps above 100)", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "noiseType": { + "description": "Noise variant", + "enum": [ + "MONOTONE", + "DUOTONE", + "MULTITONE" + ], + "type": "string" + }, + "opacity": { + "description": "MULTITONE only: 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "secondaryColor": { + "additionalProperties": false, + "description": "DUOTONE only: the second colour", + "properties": { + "a": { + "description": "Alpha, 0β1 β required: Figma rejects an effect colour without it", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "b": { + "description": "Blue, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "g": { + "description": "Green, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "r": { + "description": "Red, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "r", + "g", + "b", + "a" + ], + "type": "object" + }, + "type": { + "const": "NOISE", + "type": "string" + }, + "visible": { + "description": "default true", + "type": "boolean" + } + }, + "required": [ + "type", + "noiseType", + "color", + "noiseSize", + "density" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "clipToShape": { + "description": "Clip the texture to the shape", + "type": "boolean" + }, + "noiseSize": { + "description": "Texture grain size, 0β100 (Figma clamps above 100)", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "radius": { + "description": "Texture radius, 0β100 (Figma clamps above 100)", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "TEXTURE", + "type": "string" + }, + "visible": { + "description": "default true", + "type": "boolean" + } + }, + "required": [ + "type", + "noiseSize", + "radius", + "clipToShape" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "depth": { + "description": "Glass depth; must be β₯ 1", + "minimum": 1, + "type": "number" + }, + "dispersion": { + "description": "Chromatic dispersion, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "lightAngle": { + "description": "Light angle, degrees", + "type": "number" + }, + "lightIntensity": { + "description": "Light intensity, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "radius": { + "description": "Corner/blur radius; must be β₯ 0", + "minimum": 0, + "type": "number" + }, + "refraction": { + "description": "Refraction amount, 0β1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "type": { + "const": "GLASS", + "type": "string" + }, + "visible": { + "description": "default true", + "type": "boolean" + } + }, + "required": [ + "type", + "lightIntensity", + "lightAngle", + "refraction", + "depth", + "dispersion", + "radius" + ], + "type": "object" + } +] - removed
Input schema / properties / properties / properties / effects / items / propertiesRemoved value: -{ - "blendMode": { - "description": "Blend mode for shadow effects, e.g. 'NORMAL', 'MULTIPLY'", - "type": "string" - }, - "type": { - "description": "DROP_SHADOW|INNER_SHADOW|LAYER_BLUR|BACKGROUND_BLUR", - "type": "string" - } -} - removed
Input schema / properties / properties / properties / effects / items / requiredRemoved value: -[ - "type" -] - removed
Input schema / properties / properties / properties / effects / items / typeRemoved value: -"object" - added
Input schema / properties / properties / properties / fontName / additionalPropertiesAdded value: +false - added
Input schema / properties / properties / properties / letterSpacing / additionalPropertiesAdded value: +false - changed
Input schema / properties / properties / properties / lineHeight / anyOfPrevious value: -[ - { - "properties": { - "unit": { - "const": "AUTO", - "type": "string" - } - }, - "required": [ - "unit" - ], - "type": "object" - }, - { - "properties": { - "unit": { - "enum": [ - "PIXELS", - "PERCENT" - ], - "type": "string" - }, - "value": { - "type": "number" - } - }, - "required": [ - "value", - "unit" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "unit": { + "const": "AUTO", + "type": "string" + } + }, + "required": [ + "unit" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "unit": { + "enum": [ + "PIXELS", + "PERCENT" + ], + "type": "string" + }, + "value": { + "type": "number" + } + }, + "required": [ + "value", + "unit" + ], + "type": "object" + } +] - added
Input schema / properties / properties / properties / paints / items / properties / color / additionalPropertiesAdded value: +false - changed
Input schema / requiredPrevious value: -[ - "type", - "name" -]New value: +[ + "type" +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "id", - "name", - "type" -]
- Changed
text_set_content16 fields changed- added
Input schema / properties / text / items / additionalPropertiesAdded value: +false - changed
Input schema / properties / text / items / properties / nodeName / descriptionPrevious value: -"Expected name of the node (verification)"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Input schema / properties / text / minItemsAdded value: +1 - removed
Output schema / properties / countRemoved value: -{ - "description": "Number of updated text nodes", - "type": "number" -} - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - added
Output schema / properties / failedCountAdded value: +{ + "description": "Number of failed text replacements", + "type": "number" +} - added
Output schema / properties / requestedCountAdded value: +{ + "description": "Number of requested text replacements", + "type": "number" +} - changed
Output schema / properties / results / descriptionPrevious value: -"Detailed results per node"New value: +"Detailed results per node (one row per input, in input order)" - added
Output schema / properties / results / items / additionalPropertiesAdded value: +{} - added
Output schema / properties / results / items / propertiesAdded value: +{ + "before": { + "description": "Q9/Q24: diagnostic evidence of the known pre-mutation state; not guaranteed to be a directly executable restoring-write input" + }, + "error": { + "description": "Actionable reason, REQUIRED on any non-success row (Q25 contract key)", + "type": "string" + }, + "nodeId": { + "description": "Identity of the target node (Q25 contract key)", + "type": "string" + }, + "partialMutation": { + "description": "Q9/Q24: set when the item mutated before it failed", + "type": "boolean" + }, + "status": { + "description": "Per-item outcome (Q25 contract key)", + "enum": [ + "success", + "failed", + "skipped" + ], + "type": "string" + }, + "success": { + "description": "Legacy per-row boolean; mirrors status === 'success'", + "type": "boolean" + }, + "whatChanged": { + "description": "Q9/Q24: plain-language statement of what changed", + "type": "string" + } +} - added
Output schema / properties / results / items / requiredAdded value: +[ + "nodeId", + "status" +] - added
Output schema / properties / results / items / typeAdded value: +"object" - added
Output schema / properties / skippedCountAdded value: +{ + "description": "Number of skipped text replacements", + "type": "number" +} - added
Output schema / properties / statusAdded value: +{ + "description": "Overall status of the batch operation", + "enum": [ + "success", + "partial_success", + "failed" + ], + "type": "string" +} - added
Output schema / properties / succeededCountAdded value: +{ + "description": "Number of succeeded text replacements", + "type": "number" +} - added
Output schema / properties / successAdded value: +{ + "description": "Whether all replacements succeeded", + "type": "boolean" +}
- Changed
text_set_style5 fields changed- added
Input schema / properties / fontName / additionalPropertiesAdded value: +false - added
Input schema / properties / letterSpacing / additionalPropertiesAdded value: +false - changed
Input schema / properties / lineHeight / anyOfPrevious value: -[ - { - "properties": { - "unit": { - "const": "AUTO", - "description": "Auto line height", - "type": "string" - } - }, - "required": [ - "unit" - ], - "type": "object" - }, - { - "properties": { - "unit": { - "description": "Line height unit", - "enum": [ - "PIXELS", - "PERCENT" - ], - "type": "string" - }, - "value": { - "description": "Line height value", - "type": "number" - } - }, - "required": [ - "value", - "unit" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "unit": { + "const": "AUTO", + "description": "Auto line height", + "type": "string" + } + }, + "required": [ + "unit" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "unit": { + "description": "Line height unit", + "enum": [ + "PIXELS", + "PERCENT" + ], + "type": "string" + }, + "value": { + "description": "Line height value", + "type": "number" + } + }, + "required": [ + "value", + "unit" + ], + "type": "object" + } +] - changed
Input schema / properties / nodeName / descriptionPrevious value: -"Name of the node to verify against"New value: +"The node's current exact name, passed back verbatim from `node_info`." - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
variable_delete1 field changed- added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
variable_list2 fields changed- added
Output schema / properties / coverageAdded value: +{ + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "complete": { + "const": true, + "description": "Every attempted page succeeded", + "type": "boolean" + }, + "pageErrors": { + "description": "Empty: no page failed", + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "description": "Structured per-page failure", + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "pageId": { + "description": "ID of the page that could not be loaded, resolved, or read", + "type": "string" + } + }, + "required": [ + "pageId", + "error" + ], + "type": "object" + }, + "maxItems": 0, + "type": "array" + }, + "pagesAttempted": { + "description": "Distinct pages this call tried to resolve, load, or read. 0 means the result required no page access at all β it does NOT mean the document was checked and found clean.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "pagesAttempted", + "pageErrors" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "complete": { + "const": false, + "description": "At least one attempted page failed", + "type": "boolean" + }, + "pageErrors": { + "description": "Structured failures for pages omitted from this result; successful pages are still returned", + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "description": "Structured per-page failure", + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "pageId": { + "description": "ID of the page that could not be loaded, resolved, or read", + "type": "string" + } + }, + "required": [ + "pageId", + "error" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "pagesAttempted": { + "description": "Distinct pages this call tried to resolve, load, or read. 0 means the result required no page access at all β it does NOT mean the document was checked and found clean.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "complete", + "pagesAttempted", + "pageErrors" + ], + "type": "object" + } + ], + "description": "Page-scan coverage; partial read data remains usable when complete is false" +} - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
variable_manage7 fields changed- added
Input schema / properties / collectionNameAdded value: +{ + "description": "REQUIRED for CREATE_VARIABLE β the parent collection's exact name, passed back verbatim from `variable_list`", + "type": "string" +} - changed
Input schema / properties / currentVariableName / descriptionPrevious value: -"Current name of the variable to verify against (for UPDATE_VARIABLE)"New value: +"REQUIRED for UPDATE_VARIABLE β the variable's **current exact** name, passed back verbatim from `variable_list`" - changed
Input schema / properties / modeName / descriptionPrevious value: -"Mode name (for CREATE_COLLECTION)"New value: +"Optional initial mode name for CREATE_COLLECTION. Must be non-empty when supplied; omit it to keep the collection's native default mode name." - changed
Input schema / properties / name / descriptionPrevious value: -"Name (for CREATE or UPDATE actions)"New value: +"Name for collection/variable creation or variable update. Must be non-empty when supplied. It is required for CREATE_COLLECTION and CREATE_VARIABLE; omit it only on UPDATE_VARIABLE to leave the current name unchanged." - changed
Input schema / properties / scopes / descriptionPrevious value: -"Variable scopes. ALWAYS set explicitly on create; omit on update to leave unchanged."New value: +"REQUIRED for CREATE_VARIABLE β variable scopes. ALWAYS set explicitly on create; omit on update to leave unchanged." - changed
Input schema / properties / value / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "description": "RGBA color", - "properties": { - "a": { - "description": "Alpha (0-1)", - "type": "number" - }, - "b": { - "description": "Blue (0-1)", - "type": "number" - }, - "g": { - "description": "Green (0-1)", - "type": "number" - }, - "r": { - "description": "Red (0-1)", - "type": "number" - } - }, - "required": [ - "r", - "g", - "b" - ], - "type": "object" - }, - { - "description": "Variable alias", - "properties": { - "id": { - "description": "Target variable ID", - "type": "string" - }, - "type": { - "const": "VARIABLE_ALIAS", - "type": "string" - } - }, - "required": [ - "type", - "id" - ], - "type": "object" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "additionalProperties": false, + "description": "RGBA color", + "properties": { + "a": { + "description": "Alpha (0-1)", + "type": "number" + }, + "b": { + "description": "Blue (0-1)", + "type": "number" + }, + "g": { + "description": "Green (0-1)", + "type": "number" + }, + "r": { + "description": "Red (0-1)", + "type": "number" + } + }, + "required": [ + "r", + "g", + "b" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Variable alias", + "properties": { + "id": { + "description": "Target variable ID", + "type": "string" + }, + "type": { + "const": "VARIABLE_ALIAS", + "type": "string" + } + }, + "required": [ + "type", + "id" + ], + "type": "object" + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
- Changed
view_navigate1 field changed- added
Output schema / properties / errorAdded value: +{ + "additionalProperties": false, + "properties": { + "code": { + "description": "Stable machine-readable failure code (see the error playbook)", + "type": "string" + }, + "details": { + "description": "Optional structured context (e.g. partialMutation, before-values)" + }, + "message": { + "description": "Human/agent-readable message embedding its own recovery", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +}
46 tool updates
v2.3.2- Changed
annotation_list1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
annotation_set1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
channel_join4 fields changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / nodeAdded value: +{ + "additionalProperties": false, + "properties": { + "children": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "descendantCount": { + "type": "number" + }, + "nodeId": { + "type": "string" + }, + "nodeName": { + "type": "string" + }, + "path": { + "items": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": { + "type": "string" + } + }, + "required": [ + "nodeId", + "nodeName", + "type" + ], + "type": "object" +} - added
Output schema / properties / pageCountAdded value: +{ + "description": "Number of pages in the document", + "type": "number" +} - added
Output schema / properties / pagesAdded value: +{ + "items": { + "additionalProperties": false, + "properties": { + "children": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "descendantCount": { + "type": "number" + }, + "pageId": { + "type": "string" + }, + "pageName": { + "type": "string" + } + }, + "required": [ + "pageId", + "pageName" + ], + "type": "object" + }, + "type": "array" +}
- Changed
component_delete_property1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
component_list1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
component_manage_property1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
create_component1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
create_component_set5 fields changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{} - added
Output schema / properties / childCountAdded value: +{ + "description": "Number of variants in the set", + "type": "number" +} - added
Output schema / properties / typeAdded value: +{ + "description": "Node type (COMPONENT_SET)", + "type": "string" +} - added
Output schema / properties / variantPropertiesAdded value: +{ + "additionalProperties": {}, + "description": "Variant properties definition", + "propertyNames": { + "type": "string" + }, + "type": "object" +} - added
Output schema / properties / warningAdded value: +{ + "description": "Warning message if some properties could not be read", + "type": "string" +}
- Changed
create_connection1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
create_frame1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
create_instance1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
create_shape1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
create_svg1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
create_text1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
instance_get_overrides1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
instance_set_overrides1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
instance_set_property1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_apply_style1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_bind_variable1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_clone1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_delete1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_export_visual1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_flatten1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_group1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_info1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_insert_child1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_rename1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_set_auto_layout1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_set_corner_radius1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_set_effects1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_set_fill1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_set_stroke1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_transform1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
node_ungroup1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
page_info1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
reaction_list1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
reaction_update1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
style_delete1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
style_list1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
style_manage1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
text_set_content1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
text_set_style1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
variable_delete1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
variable_list1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
variable_manage1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
- Changed
view_navigate1 field changed- changed
Output schema / additionalPropertiesPrevious value: -falseNew value: +{}
2 tool updates
v2.3.1- Changed
node_bind_variable2 fields changed- changed
Input schema / properties / bindVariables / descriptionPrevious value: -"Map of property names to variable IDs (to bind) or null (to unbind). E.g., { 'fills': 'VariableID:1:2' }"New value: +"Map of property names to variable IDs (to bind) or null (to unbind). Valid fields: fills, strokes, height, width, characters, itemSpacing, paddingLeft, paddingRight, paddingTop, paddingBottom, visible, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius, minWidth, maxWidth, minHeight, maxHeight, counterAxisSpacing, strokeWeight, strokeTopWeight, strokeRightWeight, strokeBottomWeight, strokeLeftWeight, opacity, gridRowGap, gridColumnGap, fontFamily, fontSize, fontStyle, fontWeight, letterSpacing, lineHeight, paragraphSpacing, paragraphIndent. E.g., { 'fills': 'VariableID:1:2' }" - added
Input schema / properties / bindVariables / propertyNames / enumAdded value: +[ + "fills", + "strokes", + "height", + "width", + "characters", + "itemSpacing", + "paddingLeft", + "paddingRight", + "paddingTop", + "paddingBottom", + "visible", + "topLeftRadius", + "topRightRadius", + "bottomLeftRadius", + "bottomRightRadius", + "minWidth", + "maxWidth", + "minHeight", + "maxHeight", + "counterAxisSpacing", + "strokeWeight", + "strokeTopWeight", + "strokeRightWeight", + "strokeBottomWeight", + "strokeLeftWeight", + "opacity", + "gridRowGap", + "gridColumnGap", + "fontFamily", + "fontSize", + "fontStyle", + "fontWeight", + "letterSpacing", + "lineHeight", + "paragraphSpacing", + "paragraphIndent" +]
- Changed
node_set_fill1 field changed- added
Input schema / properties / clearAdded value: +{ + "description": "Set to true to clear all fills. Must provide exactly one of solid color, image, or clear:true.", + "type": "boolean" +}
46 tool updates
v2.3.0- Changed
annotation_list1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
annotation_set1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
channel_join6 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Output schema / properties / allowEditNodeAdded value: +{ + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + } + ], + "description": "false | 'page' | 'node'" +} - added
Output schema / properties / allowEditStyleAdded value: +{ + "description": "Whether style edits are allowed", + "type": "boolean" +} - added
Output schema / properties / allowEditVariableAdded value: +{ + "description": "Whether variable edits are allowed", + "type": "boolean" +} - added
Output schema / properties / editableScopeTypeAdded value: +{ + "description": "readonly, page, or node", + "type": "string" +} - removed
Output schema / properties / readOnlyRemoved value: -{ - "description": "Whether the connection is read-only", - "type": "boolean" -}
- Changed
component_delete_property1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
component_list1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
component_manage_property1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
create_component1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
create_component_set1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
create_connection1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
create_frame1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
create_instance1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
create_shape1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
create_svg1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
create_text1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
instance_get_overrides1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
instance_set_overrides1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
instance_set_property1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_apply_style1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_bind_variable1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_clone1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_delete1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_export_visual1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_flatten1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_group1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_info3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / fieldsRemoved value: -{ - "description": "Array of field names to return.", - "items": { - "type": "string" - }, - "type": "array" -} - added
Input schema / properties / propertiesAdded value: +{ + "description": "Array of property names to return (populates each node's `properties` object in the response).", + "items": { + "type": "string" + }, + "type": "array" +}
- Changed
node_insert_child2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / index / descriptionPrevious value: -"Position in parent's children array (default: append)"New value: +"Position in parent's children array (default: append). The output index reports the actual resolved position (same-parent reorder shifts indices)."
- Changed
node_rename1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_set_auto_layout1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_set_corner_radius1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_set_effects1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_set_fill4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / imageAdded value: +{ + "description": "Optional image payload. Must provide exactly one of solid color or image.", + "properties": { + "bytesBase64": { + "description": "Base64-encoded raw PNG/JPEG/GIF bytes. PNG/JPEG over 4096px per side are auto-downscaled server-side (aspect ratio preserved); GIF is not resized. Very large PNG/JPEG (over ~45 megapixels) exceed the server resize budget and are rejected β pre-resize those yourself. Heavier over the socket.", + "type": "string" + }, + "opacity": { + "description": "Alpha opacity component for the image (0-1)", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "scaleMode": { + "description": "default FILL", + "enum": [ + "FILL", + "FIT", + "CROP", + "TILE" + ], + "type": "string" + }, + "url": { + "description": "HTTP(S) URL to a PNG/JPEG/GIF the plugin fetches via createImageAsync. Max 4096px per side and NOT resized β pre-resize larger images yourself, or use bytesBase64 (which is auto-resized).", + "format": "uri", + "type": "string" + } + }, + "type": "object" +} - changed
Input schema / requiredPrevious value: -[ - "nodeId", - "nodeName", - "r", - "g", - "b" -]New value: +[ + "nodeId", + "nodeName" +] - added
Output schema / properties / warningsAdded value: +{ + "description": "Warnings from the operation (e.g., resizing)", + "items": { + "type": "string" + }, + "type": "array" +}
- Changed
node_set_stroke1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_transform1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
node_ungroup1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
page_info1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
reaction_list1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
reaction_update3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / nodeNameAdded value: +{ + "description": "Name of the node to update reactions for (for verification)", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "nodeId", - "reactions" -]New value: +[ + "nodeId", + "nodeName", + "reactions" +]
- Changed
style_delete1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
style_list1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
style_manage3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / properties / properties / effects / descriptionPrevious value: -"EFFECT: array of Figma Effect objects, e.g. {type:'DROP_SHADOW', color, offset:{x,y}, radius, spread?, visible?}"New value: +"EFFECT: array of Figma Effect objects, e.g. {type:'DROP_SHADOW', color, offset:{x,y}, radius, spread?, visible?, blendMode?}" - added
Input schema / properties / properties / properties / effects / items / properties / blendModeAdded value: +{ + "description": "Blend mode for shadow effects, e.g. 'NORMAL', 'MULTIPLY'", + "type": "string" +}
- Changed
text_set_content1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
text_set_style7 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / lineHeight / anyOfAdded value: +[ + { + "properties": { + "unit": { + "const": "AUTO", + "description": "Auto line height", + "type": "string" + } + }, + "required": [ + "unit" + ], + "type": "object" + }, + { + "properties": { + "unit": { + "description": "Line height unit", + "enum": [ + "PIXELS", + "PERCENT" + ], + "type": "string" + }, + "value": { + "description": "Line height value", + "type": "number" + } + }, + "required": [ + "value", + "unit" + ], + "type": "object" + } +] - removed
Input schema / properties / lineHeight / propertiesRemoved value: -{ - "unit": { - "description": "Line height unit", - "enum": [ - "PIXELS", - "PERCENT" - ], - "type": "string" - }, - "value": { - "description": "Line height value", - "type": "number" - } -} - removed
Input schema / properties / lineHeight / requiredRemoved value: -[ - "value", - "unit" -] - removed
Input schema / properties / lineHeight / typeRemoved value: -"object" - added
Input schema / properties / textAlignHorizontalAdded value: +{ + "description": "Horizontal text alignment", + "enum": [ + "LEFT", + "CENTER", + "RIGHT", + "JUSTIFIED" + ], + "type": "string" +} - added
Input schema / properties / textAlignVerticalAdded value: +{ + "description": "Vertical text alignment", + "enum": [ + "TOP", + "CENTER", + "BOTTOM" + ], + "type": "string" +}
- Changed
variable_delete3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / collectionNameAdded value: +{ + "description": "Name of the collection to delete, for safety verification. Required if collectionId is used.", + "type": "string" +} - added
Input schema / properties / variableNamesAdded value: +{ + "description": "Array of variable names corresponding to variableIds, for safety verification. Required if variableIds is used.", + "items": { + "type": "string" + }, + "type": "array" +}
- Changed
variable_list1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
variable_manage2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / scopesAdded value: +{ + "description": "Variable scopes. ALWAYS set explicitly on create; omit on update to leave unchanged.", + "items": { + "enum": [ + "ALL_SCOPES", + "TEXT_CONTENT", + "CORNER_RADIUS", + "WIDTH_HEIGHT", + "GAP", + "ALL_FILLS", + "FRAME_FILL", + "SHAPE_FILL", + "TEXT_FILL", + "STROKE_COLOR", + "STROKE_FLOAT", + "EFFECT_FLOAT", + "EFFECT_COLOR", + "OPACITY", + "FONT_FAMILY", + "FONT_STYLE", + "FONT_WEIGHT", + "FONT_SIZE", + "LINE_HEIGHT", + "LETTER_SPACING", + "PARAGRAPH_SPACING", + "PARAGRAPH_INDENT" + ], + "type": "string" + }, + "type": "array" +}
- Changed
view_navigate1 field changed- added
Input schema / additionalPropertiesAdded value: +false
13 tool updates
v2.1.0- Changed
annotation_list3 fields changed- changed
Input schema / properties / nodeId / descriptionPrevious value: -"The node ID to get annotations from"New value: +"The node ID to get annotations from. Exactly one of pageId or nodeId is required." - added
Input schema / properties / pageIdAdded value: +{ + "description": "The page ID to get annotations from. Exactly one of pageId or nodeId is required.", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "nodeId" -]
- Changed
component_list4 fields changed- added
Input schema / properties / pageIdAdded value: +{ + "description": "The ID of the page to query when scope is 'page'", + "type": "string" +} - changed
Input schema / properties / scope / defaultPrevious value: -"current_page"New value: +"document" - changed
Input schema / properties / scope / descriptionPrevious value: -"Scope of the search: 'current_page' (default) or 'document' (entire file, streams progress page-by-page)."New value: +"Scope of the search: 'page' (queries a specific page, requiring pageId) or 'document' (entire file, default)." - changed
Input schema / properties / scope / enumPrevious value: -[ - "current_page", - "document" -]New value: +[ + "page", + "document" +]
- Changed
create_frame2 fields changed- changed
Input schema / properties / parentId / descriptionPrevious value: -"Optional parent node ID to append the frame to"New value: +"Parent node ID to append the frame to" - changed
Input schema / requiredPrevious value: -[ - "x", - "y", - "width", - "height" -]New value: +[ + "x", + "y", + "width", + "height", + "parentId" +]
- Changed
create_instance2 fields changed- changed
Input schema / properties / parentId / descriptionPrevious value: -"Optional parent node ID to append the instance to"New value: +"Parent node ID to append the instance to" - changed
Input schema / requiredPrevious value: -[ - "x", - "y" -]New value: +[ + "x", + "y", + "parentId" +]
- Changed
create_shape2 fields changed- changed
Input schema / properties / parentId / descriptionPrevious value: -"Optional parent node ID to append the shape to"New value: +"Parent node ID to append the shape to" - changed
Input schema / requiredPrevious value: -[ - "type", - "x", - "y", - "width", - "height" -]New value: +[ + "type", + "x", + "y", + "width", + "height", + "parentId" +]
- Changed
create_svg1 field changed- changed
Input schema / requiredPrevious value: -[ - "svg" -]New value: +[ + "svg", + "parentId" +]
- Changed
create_text2 fields changed- changed
Input schema / properties / parentId / descriptionPrevious value: -"Optional parent node ID to append the text to"New value: +"Parent node ID to append the text to" - changed
Input schema / requiredPrevious value: -[ - "x", - "y", - "text" -]New value: +[ + "x", + "y", + "text", + "parentId" +]
- Changed
instance_get_overrides2 fields changed- changed
Input schema / properties / nodeId / descriptionPrevious value: -"Optional ID of the component instance to get overrides from. If not provided, currently selected instance will be used."New value: +"The ID of the component instance to get overrides from." - added
Input schema / requiredAdded value: +[ + "nodeId" +]
- Changed
node_export_visual3 fields changed- changed
Input schema / properties / scale / descriptionPrevious value: -"Export scale (e.g. 1, 2, 0.5)"New value: +"Export scale, between 0.1 and 4.0 (e.g. 1, 2, 0.5)" - added
Input schema / properties / scale / maximumAdded value: +4 - added
Input schema / properties / scale / minimumAdded value: +0.1
- Changed
node_info1 field changed- added
Input schema / properties / concurrencyLimitAdded value: +{ + "description": "Concurrency limit for parallel subtree walk (default: 4)", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" +}
- Removed
node_select - Changed
variable_list7 fields changed- changed
Input schema / properties / includeConsumers / descriptionPrevious value: -"Only used when variableId is provided; ignored otherwise. 'current_page' scans the active page (fast). 'document' scans all pages (streams progress page-by-page)."New value: +"Only used when variableId is provided; ignored otherwise. 'page' scans a specific page, requiring pageId. 'document' scans all pages (streams progress page-by-page)." - changed
Input schema / properties / includeConsumers / enumPrevious value: -[ - "current_page", - "document" -]New value: +[ + "page", + "document" +] - added
Input schema / properties / pageIdAdded value: +{ + "description": "The page ID to scan for consumers when includeConsumers is 'page'.", + "type": "string" +} - changed
Output schema / properties / collections / descriptionPrevious value: -"List of variable collections"New value: +"List of variable collections (list-all mode only)" - removed
Output schema / properties / consumersRemoved value: -{ - "description": "Consumer mapping for the requested variables" -} - added
Output schema / properties / missingIdsAdded value: +{ + "description": "Requested variable IDs that did not resolve (lookup mode only; omitted when none)", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Output schema / properties / variables / descriptionPrevious value: -"List of variables"New value: +"List of variables β present in both list-all and lookup modes (each may carry nodeConsumers/styleConsumers/aliasConsumers when includeConsumers is set)"
- Added
view_navigate
90 tool updates
v2.0.0- Added
annotation_list - Added
annotation_set - Removed
apply_style - Added
channel_join - Removed
clone_node - Added
component_delete_property - Added
component_list - Added
component_manage_property - Changed
create_component1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "id": { + "description": "ID of the created component", + "type": "string" + }, + "name": { + "description": "Name of the created component", + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" +}
- Removed
create_component_instance - Changed
create_component_set1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "id": { + "description": "ID of the created component set", + "type": "string" + }, + "name": { + "description": "Name of the component set", + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" +}
- Added
create_connection - Removed
create_connections - Removed
create_ellipse - Changed
create_frame1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "id": { + "description": "ID of the created frame", + "type": "string" + }, + "name": { + "description": "Name of the created frame", + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" +}
- Added
create_instance - Removed
create_node_from_svg - Removed
create_polygon_star - Removed
create_rectangle - Added
create_shape - Added
create_svg - Changed
create_text1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "id": { + "description": "ID of the created text node", + "type": "string" + }, + "name": { + "description": "Name of the created text node", + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" +}
- Removed
delete_multiple_nodes - Removed
delete_variables - Removed
export_node_as_image - Removed
flatten_node - Removed
get_annotations - Removed
get_components - Removed
get_instance_overrides - Removed
get_node_variables - Removed
get_nodes_info - Removed
get_pages_info - Removed
get_reactions - Removed
get_styles - Removed
get_variables - Removed
group_nodes - Removed
insert_child - Added
instance_get_overrides - Added
instance_set_overrides - Added
instance_set_property - Removed
join_channel - Removed
manage_component_property - Removed
manage_style - Removed
manage_variables - Removed
move_node - Added
node_apply_style - Added
node_bind_variable - Added
node_clone - Added
node_delete - Added
node_export_visual - Added
node_flatten - Added
node_group - Added
node_info - Added
node_insert_child - Added
node_rename - Added
node_select - Added
node_set_auto_layout - Added
node_set_corner_radius - Added
node_set_effects - Added
node_set_fill - Added
node_set_stroke - Added
node_transform - Added
node_ungroup - Added
page_info - Added
reaction_list - Added
reaction_update - Removed
resize_node - Removed
set_auto_layout - Removed
set_bound_variable - Removed
set_component_instance_property - Removed
set_corner_radius - Removed
set_effects - Removed
set_fill_color - Removed
set_instance_overrides - Removed
set_multiple_annotations - Removed
set_multiple_text_contents - Removed
set_node_name - Removed
set_selections - Removed
set_stroke - Removed
set_text_style - Added
style_delete - Added
style_list - Added
style_manage - Added
text_set_content - Added
text_set_style - Removed
ungroup_nodes - Removed
update_reactions - Added
variable_delete - Added
variable_list - Added
variable_manage
48 tool updates
v1.5.2- First observed
apply_style - First observed
clone_node - First observed
create_component - First observed
create_component_instance - First observed
create_component_set - First observed
create_connections - First observed
create_ellipse - First observed
create_frame - First observed
create_node_from_svg - First observed
create_polygon_star - First observed
create_rectangle - First observed
create_text - First observed
delete_multiple_nodes - First observed
delete_variables - First observed
export_node_as_image - First observed
flatten_node - First observed
get_annotations - First observed
get_components - First observed
get_instance_overrides - First observed
get_node_variables - First observed
get_nodes_info - First observed
get_pages_info - First observed
get_reactions - First observed
get_styles - First observed
get_variables - First observed
group_nodes - First observed
insert_child - First observed
join_channel - First observed
manage_component_property - First observed
manage_style - First observed
manage_variables - First observed
move_node - First observed
resize_node - First observed
set_auto_layout - First observed
set_bound_variable - First observed
set_component_instance_property - First observed
set_corner_radius - First observed
set_effects - First observed
set_fill_color - First observed
set_instance_overrides - First observed
set_multiple_annotations - First observed
set_multiple_text_contents - First observed
set_node_name - First observed
set_selections - First observed
set_stroke - First observed
set_text_style - First observed
ungroup_nodes - First observed
update_reactions
TDQS
Each tool targets a distinct resource/action pair, and even the three fill-related setters (node_set_fill, node_apply_style, node_bind_variable) have explicit routing guidance in their descriptions. No two tools perform the same operation, so an agent can reliably select the correct one.
Tools consistently use a resource_verb pattern (e.g., page_, node_, create_, style_), but read operations use both 'info' and 'list' (page_info vs style_list), and write operations mix 'set', 'apply', 'bind', 'manage', and 'update'. This is mostly consistent but not fully uniform.
With 45 tools, the server far exceeds the typical well-scoped range. While the broad Figma domain justifies extensive coverage, the highly granular setters (fill, stroke, corner radius, effects, auto layout) could be consolidated, making the tool surface disproportionately large and harder to navigate.
The server provides comprehensive coverage of node, style, component, variable, annotation, and reaction operations, with read/update/delete for most resources. Minor gaps include no annotation deletion or page-level manipulation beyond listing, but these are workable and do not create dead ends.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
The Figma MCP server brings Figma design context directly into your AI workflow.
Let AI agents query data and act across all your business apps via MCP.
Automate 1,000+ services from any MCP-compatible AI agent: build Applets, run actions and queries.
Render, verify, describe, and safely edit Mermaid diagrams through MCP.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to create, modify, and manage Figma designs through natural language commands via a specialized MCP server and plugin bridge. It supports a wide range of operations including element creation, property modification, component management, and accessibility checks.13104MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that connects AI clients to Figma, enabling real-time reading, creation, and modification of designs using natural language.MIT
- FlicenseNot gradedqualityDmaintenanceAn MCP server that provides write access to Figma through the Plugin API, enabling AI agents to create, modify, and manage Figma designs programmatically.23-

Figma MCP Serverofficial
FlicenseNot gradedqualityBmaintenanceProvides Figma design context to AI agents, enabling code generation, design system integration, and canvas manipulation through MCP.1,960-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/neozhehan/figma-edit-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server