Skip to main content
Glama
KaiUweHella

figma-bridge-mcp

by KaiUweHella

figma-bridge-mcp

一个本地 MCP 服务器,让 AI 助手能够检查、创建和更新 Figma Desktop 中的设计。它通过一个小型 Figma 开发插件进行连接,并提供针对截图、设计规范、JSX 渲染、令牌、资源、组件、FigJam 和 Figma Slides 的专注工具。

所有内容都在 127.0.0.1 上运行。无需 Figma 个人访问令牌。无需云服务。无需对 Figma 应用进行二进制修补。

一个可选的 REST 附加组件增加了版本历史、评论和已发布库的元数据。其 Figma 令牌保留在您的机器上,绝不会放入您的 MCP 客户端配置或聊天中。

要求:Node.js 18 或更新版本、Figma Desktop,以及一个能够启动本地 stdio 服务器的 MCP 客户端。

Codex、Claude Code 和 Cursor:MCP 与技能合为一体

Figma Bridge 提供了三个专注的共享技能,以及针对所有三个客户端的轻量插件适配器:

  • figma-bridge-design-to-code — 在目标栈中精确实现 Figma

  • figma-bridge-code-to-figma — 从代码生成语义化、组件化的屏幕

  • figma-bridge-component-library — 令牌、样式、组件、变体和属性

客户端

插件格式

完整安装路径

Codex / ChatGPT

.codex-plugin/plugin.json

此仓库的 Codex 市场

Claude Code

.claude-plugin/plugin.json

此仓库的 Claude 市场

Cursor

Agent Plugins 1.0 (plugin.json)

GitHub 支持的团队市场或本地检出

适配器都会发现相同的 skills/ 目录,并启动相同的本地 MCP 包。用户无需单独下载或维护这些技能。

对于 Codex,将此仓库添加为市场并安装该捆绑包:

codex plugin marketplace add KaiUweHella/figma-bridge-mcp
codex plugin add figma-bridge-mcp@figma-bridge

这是一个由 GitHub 托管的仓库市场,并非提交到通用 OpenAI 插件目录。目录跟随仓库,而每个已发布的插件条目固定一个确切的 v<version> Git 标签,并启动匹配的 npm 运行时版本。因此,main@latest 无法静默地将已安装的技能包移动到不同的服务器契约上。

对于 Claude Code,将此仓库添加为市场并安装该捆绑包:

claude plugin marketplace add KaiUweHella/figma-bridge-mcp
claude plugin install figma-bridge-mcp@figma-bridge

Claude 市场使用相同的固定 GitHub 发布版本和共享技能树。匹配的 npm 包必须在用户安装该发布版本之前发布,因为插件通过 npx 启动其本地 stdio 服务器。

对于 Cursor Teams 或 Enterprise,将此 GitHub 仓库导入团队市场,并从 Customize 安装 Figma Bridge。个人用户和贡献者可以使用相同的 GitHub 源,无需中央 Cursor 列表:克隆标记的发布版本,将该检出链接到 Cursor,然后重新加载窗口:

mkdir -p ~/.cursor/plugins/local
ln -s /absolute/path/to/figma-bridge-mcp ~/.cursor/plugins/local/figma-bridge-mcp

Cursor 检测根 Agent Plugin 清单,并同时加载技能和 MCP 服务器。

没有插件或 Agent Skill 支持的客户端继续使用下面的普通服务器配置。它们仍然通过 MCP 指令接收紧凑的强制工作流,用户调用的 design-to-codecode-to-figmacreate-figma-component MCP 提示,以及 figma_reference {name:"workflow"}

快速开始

1. 添加 MCP 服务器(仅 MCP 回退)

当完整插件安装不可用,或者您只想要 MCP 工具而不需要捆绑技能时,使用此方法。npx 设置无需克隆或构建步骤。对于 Claude Code:

claude mcp add figma-bridge -- npx -y figma-bridge-mcp@latest

对于其他 MCP 客户端,添加等效的服务器配置:

{
  "mcpServers": {
    "figma-bridge": {
      "command": "npx",
      "args": ["-y", "figma-bridge-mcp@latest"]
    }
  }
}

如果 MCP 客户端没有立即发现服务器,请重新启动它。故意没有 env 块:桥接器在配对期间创建其本地凭据。

git clone https://github.com/KaiUweHella/figma-bridge-mcp.git
cd figma-bridge-mcp
npm install
{
  "mcpServers": {
    "figma-bridge": {
      "command": "node",
      "args": ["/absolute/path/to/figma-bridge-mcp/src/server.js"]
    }
  }
}

2. 配对 Figma Desktop 一次

  1. 让您的 AI 助手连接到 Figma,或直接调用 figma_connect。它会启动本地桥接器并返回一个访问密钥和一个插件清单路径。

  2. Figma Desktop 中:插件 → 开发 → 从清单导入插件… 并选择 ~/.figma-bridge-mcp/plugin/manifest.jsonfigma_connect 返回的路径)。

  3. 打开 插件 → 开发 → Figma Bridge,粘贴访问密钥,然后点击 保存并连接

  4. 当插件显示 已连接(已验证) 时,助手就可以处理该 Figma 文件。配对会被记住;在后续会话中,只需在您要使用的文件中重新打开插件即可。

Figma Dev Mode 需要单独的适配器,因为 Figma 不支持将现有的 FigJam 编辑器目标与 dev 合并到一个清单中:

  • 导入 ~/.figma-bridge-mcp/plugin/manifest.dev.json 用于 Figma Bridge Dev Mode。它保持已验证的 MCP 桥接器连接,用于选择、检查、规范和导出。Dev Mode 是只读的,因此渲染和画布编辑仍然需要将文件切换到 Design 模式,并在那里打开普通的 Figma Bridge 插件。

3. 与 Figma 一起使用

在 Figma 中选择一个画框或图层,然后描述您想要的结果。例如:

  • "检查我当前的选择并解释其布局。"

  • "在所选画框旁边创建一个设置卡片。"

  • "将所选屏幕的令牌和资源导出到此项目中。"

  • "实现所选画框,然后将结果与 Figma 进行比较。"

助手可以读取当前选择、捕获截图和规范、渲染 JSX、导出资源或应用有针对性的编辑。在助手应访问的每个文档中保持 Figma Bridge 插件打开。如果连接了多个文档,请传递 Figma URL 或文件密钥,以便目标明确。

Related MCP server: tellfigma

工作原理

MCP client ──stdio──▶ figma-bridge-mcp (src/)
                        │
                    MCP tool adapters ─▶ Capability Catalog ─▶ CommandPlan
                                                                  │
                                          ┌───────────────────────┴──────────┐
                                  Command Application Modules   generic CLI adapter
                                             │            │
                                      Design Capture      │
                                      Asset Policy        │
                                             └──────┬─────┘
                                      Daemon Client Module
                                             │  HTTP: signed requests
                                             ▼
                                  local daemon :3456–3460
                                             │  WS: challenge/response
                                             ▼
                                  Figma Bridge plugin in Figma Desktop
  • 引擎位于 engine/ 下。它最初是 figma-ds-cli v2.1.0 的一个分支,并且已经远远偏离了它(参见归属)。Chrome-DevTools 的“Yolo 模式”——它会修补 Figma 应用二进制文件——已被完全移除;没有代码路径指向它。

  • 专门的 MCP 读取(figma_specfigma_inspectfigma_screenshot)通过返回值的命令应用模块直接执行。MCP 和 CLI 是相同实现上的轻量适配器;通用的 figma_run 仍然是故意宽泛的子进程 CLI 适配器。一个守护进程客户端模块负责两个路径的签名、超时和传输错误。

  • 设计捕获模块遍历一个显式节点一次,并本地投影结构、样式以及来自这些相同事实的无损输出格式。只有在廉价的修订探测证明已验证的插件连接和 Figma 文档修订未更改时,捕获才会被重用。缺失或不稳定的修订元数据会禁用重用;选择和命名部分调用在此第一个切片中保持未缓存。捕获区分了作者编写的 Figma Auto Layout/Grid、Figma 标记的 inferredAutoLayout 启发式方法和几何回退。它们还将 Code-to-Figma 语义/回退元数据与后来的原生 Figma 注释分开保存,以及完整的组件和变量模式契约。

  • 设计链接注册表为组件、屏幕或画框提供一个持久的、仓库拥有的设计实体 ID。figma-bridge.json 保存可移植的代码/Storybook/Figma 链接;Figma 插件数据仅保存相同的 ID 和种类。这种双重锚点让未来的代理可以从任一侧解析确切存在的组件,而无需将仓库路径放入 Figma 文档中。

  • 仅报告的往返规划器将当前代码和当前标准化的 Figma 子树与明确的已接受设计基线进行比较。项目设计上下文通过一个进程内命令应用投影该状态、实体链接和确切的下一次读取。当存在语义路径时,更改的子树会以其当前节点 ID 报告;插件标记本身从不计为视觉更改。

  • 设计契约将一个链接的设计实体的完整设计捕获转换为确定性的仓库门。运行 figma_run ["contract", "capture","ui.button"] 一次并查看 JSON;之后 figma_run ["contract","check","ui.button"] 报告规范漂移,并分别强制执行变体矩阵、令牌绑定下限、几何公差和原型过渡。易变的 Figma 句柄被忽略,深度受限的捕获被拒绝。

  • 一个能力目录将每个通过 MCP 进入的 Figma 命令解析为不可变计划,然后任一执行适配器运行它。该计划是暴露、Figma/工作区/共享状态效果、目标需求、确认、标准化路径、重试、超时、接受的退出代码和后台作业标识的唯一来源。未知命令默认为拒绝/写入/不重试。

  • 一个不可变的Figma 目标上下文每个命令解析一次显式的 fileKey、粘贴的 Figma URL 或隐式的单窗口定位,然后伴随规划、审计、作业标识和守护进程执行。一个共享的资产策略对图像填充、矢量图和矢量簇进行分类,用于设计捕获投影和导出。

  • 运行时协议验证器在传输边界拒绝格式错误的 HTTP 执行负载和插件帧。TypeScript 检查 JavaScript 接缝(包括 Figma 插件),而确定性上下文、负载以及中位数和尾部延迟预算在 CI 中捕获架构回归,而不会将短暂的共享运行器调度暂停视为持续回归。

  • 守护进程通过本地主机 WebSocket 将命令代理到 Figma 插件。两个门保护它:

    • HTTP 路由/health/exec)要求每个请求使用会话令牌(一个 0600 文件)作为密钥的 HMAC 签名——令牌本身永远不会通过网络传输。

    • 插件 WebSocket/plugin)要求访问密钥:一个 Origin/Host 允许列表加上一个相互质询-响应握手,其中密钥仅作为 HMAC 秘密,也永远不会通过网络传输。这关闭了上游的缺口——即任何本地进程都可以连接到插件套接字并在您的 Figma 文档中运行代码——以及反向缺口,即任何在本地端口上应答的东西都可以驱动一个诚实的插件。

工具

用途

figma_connect

启动安全模式,生成/显示访问密钥,打印插件设置步骤。

figma_status

立即报告本地守护进程/插件/文件/密钥状态;validateRest:true 会显式检查可选的 REST 令牌。

figma_pairing

显示访问密钥;{rotate:true} 会生成一个新的密钥。

figma_run

运行 Capability Catalog 批准的引擎命令;通过 figma_reference {name:"capabilities"} 发现这些命令。

figma_render

将 JSX 渲染到打开的 Figma 设计中。

figma_inspect

按 id 检查节点:几何、填充/描边/效果、裁剪、不透明度(YAML 格式)。

figma_screenshot

将节点/选区的 PNG 保存到临时文件(返回路径 + 尺寸 + 应用的比例)。

figma_spec

节点的设计到代码规范:真实内容、组件名称、令牌、矢量艺术引用、裁剪/绝对值——分阶段进行。

figma_reference

离线 Figma 插件 API 参考(api setup 一次);{name:"capabilities"} 列出生成的命令索引,无需启动引擎。

figma_history

来自审计日志的本地更改历史——按 nodeId 过滤,可选地合并生成代码文件的 git log 以及(REST 附加组件)通过 includeVersions:true 获取文件的真实 Figma 版本历史。或者传递 diff:{from,to} 对文档本身进行结构差异比较(添加/删除/替换/移动/更改)。figma_run/figma_render 接受一个 label 来注释条目。

figma_selection

用户在 Figma 中的当前选区(id、名称、类型、尺寸)——由插件实时推送。实例解析为其稳定的发布 key;链接的节点显示其设计实体、代码文件和 Storybook 故事。

figma_comments

REST 附加组件:读取设计评审评论(action:"list")或发布/回复(action:"post"——始终先预览,需要 confirm:true)。

节点 id 接受用户手头的任何形式:12:34、URL 形式 12-34 或完整的 Figma URL(其文件密钥会与你实际打开的文件进行核对——参见同时处理多个文件)。

写入命令可以通过在服务器环境中设置 FIGMA_WRITE_CONFIRM=1 来要求显式的 confirm:true。此门控在子命令级别生效:像 node treecomponent list 这样的读取操作可以自由通过,而像 node deletecombostokens spacing 这样的修改操作则需要确认。

原生 JSX 实例需要持久的注册表身份(entity 加上已发布的 key 或本地 id)。它们的可编辑覆盖使用组件的真实 Figma 结构:

<Instance entity="ui.card" key="..."
  prop:Selected="true"
  text:Title="New title"
  fill:StatusDot="var:status/healthy|#22c55e"
  swap:LeadingIcon="ui.icon.leaf" />

prop: 解析一个组件属性定义;text:fill: 解析一个命名的后代。swap: 值和 INSTANCE_SWAP 属性值是设计实体 id,从 figma-bridge.json 解析;组件显示名称有意不被接受作为交换身份。缺失、歧义或未链接的目标会在创建第一个画布节点之前停止预检。

尺寸和排版接受相同的 var:name|fallback 形式。原生执行器绑定宽度、高度和最小/最大约束,以及字体系列/样式、粗细、大小、行高、字间距、段落间距和段落缩进。系列/样式使用 STRING 变量;其他排版和尺寸字段使用 FLOAT 变量。缺失的绑定字体会停止预检,并显示安装或选择其他字体的消息,而不是静默替换。命名的文本样式也会在画布创建之前进行协调:显式的 style="Typography/Eyebrow" 仅在其完整排版匹配时才被重用;同名的冲突样式会停止,否则精确的排版会在确定的 Typography/Generated/... 名称下被重用或创建。Figma float32 度量回读被归一化以进行稳定比较,并且特定于系列的字体,如 DM Sans/Manrope SemiBoldExtraBold,会在任何后备系列之前尝试。成功的原生渲染会返回 textStyleReportvariableReport 计数,用于引用、唯一重用的变量、创建的变量和绑定的属性。歧义或不支持的预检错误包括相应的零/非零计数,并且不会留下新创建的变量或画布节点。

<Text> 还保留可编辑的内联富文本。嵌套的 <strong>/<b><em>/<i><u><Span ...><a href="..."> 标记成为原生 Figma 范围;HTML 实体在计算 UTF-16 范围偏移之前被解码。Span 运行支持 fontfontStyleweightitalicsizecolorletterSpacingunderline/decoration 和安全链接:

<Text font="Inter" size="14">
  Hello <strong>bold <em>and italic</em></strong>
  <Span color="#ef4444" size="18">red</Span>
  <a href="https://example.com">link</a>
</Text>

插件窗口

Figma Bridge 插件窗口不仅仅是连接状态:

  • 活动 — 代理运行的每个命令,实时显示,带有持续时间和 ok/error 状态;写入操作会高亮显示。折叠行包含计数(12 ok · 1 failed);连接的端口和往返延迟位于标题栏中。

  • 暂停代理 — 一个终止开关:暂停时,插件会拒绝所有传入的代理命令,并返回显式错误。

  • 保存版本 — 在 Figma 自身的版本历史中写入一个带标签的条目(Figma Bridge — <timestamp>),作为在让代理操作之前的手动恢复点。插件没有恢复 API:你需要通过 Figma 的版本历史面板回滚。

  • 选区读取 — 用户选择的任何内容都会自动(防抖后)推送给代理,并显示为"Agent sees: …",因此用户始终可以看到 figma_selection 将返回什么。选择一个画框,说"构建这个"——无需复制节点 id。

  • 设置 — 访问密钥和可选的 REST 令牌,无论桥接是否连接,始终可访问。

设计到代码工作流

设计就是完整的规范——工具使复制它比解释它更容易。从 Figma 构建一个屏幕需要六个步骤:

保持目标项目的框架和样式系统。不要仅仅为了屏幕而添加 Tailwind、UI 套件或图标库,并且永远不要用方便的近似值替换导出的 Figma 图稿。仅当其渲染的设计和状态实际匹配时,才重用项目组件。

  1. figma_screenshot 作用于目标画板,然后读取保存的 PNG——这是视觉真实依据。切勿仅从节点树构建。

  2. figma_spec 配合 phase: "structure" ——构建标记骨架:真实文本字符、已解析的图标/组件名称(实例会被深入展开,因此会显示覆盖项和真实主组件名称)、层级结构和弹性方向。逐字复制文本和图标。标记为 layout:inferred (Figma heuristic — verify) 的布局并非作者定义的自动布局;在将其视为组件契约之前,请检查层级结构。

  3. 导出令牌figma_run 配合 ["export","css"]["export","dtcg"])并将其连接为 CSS 变量/主题。输出会标明其来源的 Figma 文件——请检查它是否是你正在构建的文件。

  4. 导出资源figma_run 配合 ["export","assets","<nodeId>","-o","/abs/path/src/assets"])——规范中每个 → assets/… 引用都指向此命令写入的文件。传入绝对路径;大型导出会在后台持续运行(状态显示“still RUNNING”)——重新运行相同的调用以轮询。assets.json 会在多次运行中合并,字节相同的资源会被去重。每个条目都包含放置数据(x/y 偏移量、parent 名称路径、parentIdabsolutePositionoverhang),因此仅凭清单即可定位覆盖层——无需交叉引用规范。导出摘要会明确列出绝对定位和悬垂的文件:这些正是构建会丢失的文件。过大的 PNG 默认会降采样到其在 Figma 中最大使用尺寸的 2 倍(视网膜密度),仅在编码文件变小时进行,且不会放大。宽高比、清单放置和 CSS 裁剪行为保持不变;传入 --raster-scale 0 以保留原始 PNG 字节。

  5. figma_spec 配合 phase: "style" ——应用尺寸、间距、内边距、对齐、填充/包裹尺寸、包括渐变在内的填充(→ var(name) 标记设计令牌绑定)、圆角、阴影、排版、opacityclip(溢出隐藏)和 abs 定位。装饰性矢量会显示为 vector art → assets/… 行并附带放置信息——放置导出的 SVG,切勿用 CSS 近似。

    结构化的 YAML/JSON 还会保留精确的组件属性定义和值(包括 INSTANCE_SWAP 和 SLOT)、属性引用、首选值、直接覆盖、暴露的实例和插槽违规。变量绑定包括集合标识、作者定义的作用域、显式/已解析模式、codeSyntax.WEB 和已解析的值;inferredVariables 会作为仅建议的证据单独输出。

    对于大型区块,首先请求 depth:0。这是区块容器本身的完整契约(包括背景、边框、圆角和布局),不包含后代。然后在有界调用中请求子节点 ID。对重复的卡片/列表使用 dedup:true;共享的 S<n> 引用保持无损,并防止相同的实例样式耗尽结果预算。

  6. 验证——截取你的构建截图,与步骤 1 中的 PNG 进行比较,然后运行机械检查:

    figma_run ["verify-build", "/abs/path/to/project"]

    它会在项目中搜索 assets.json,并列出每个已导出但在构建中引用的文件——包含尺寸、偏移量和父级信息,因此放置它只需一步——同时还会进行 border-image 检查(CSS border-image 会忽略 border-radius;圆角框上的渐变描边需要包装器或遮罩模式)。当文件缺失时退出码为 1,因此它也可以作为 CI 门控。

    配合构建截图,它还会运行视觉检查

    figma_run ["verify-build", "/abs/path/to/project", "--compare", "/abs/build.png"]

    参考渲染图会从 Figma 实时获取(--node <id>,默认为清单的导出根节点),或通过 --design <png> 离线提供。两张图片会被归一化到相同的宽度并进行像素差异比较(抗锯齿容忍);输出会报告整体差异百分比、高度不匹配发现(构建过高/过短 = 插入或删除了块)、以节点像素坐标表示的最差差异区域——与规范和 assets.json 使用的坐标空间相同——并写入差异 PNG(红色 = 差异,叠加在变暗的设计图上)。默认为信息性;--max-diff <pct> 控制退出码。

对于大屏幕,在截图、结构图、令牌和资源固定之后,区块级代理是可选的耗时优化。仅对具有不相关组件/样式文件的大型区块使用它们;协调者保留对共享外壳、令牌、assets.json、集成和最终像素差异的所有权。并行代理通常会消耗更多总令牌,因为每个代理都需要项目上下文,因此当令牌成本比挂钟时间更重要时,请使用顺序工作。

使用现有的浏览器工具或项目框架进行构建截图。未经用户同意,请勿仅为了截图而安装 Playwright(或其他浏览器依赖项);如果它已存在,则它是有效的截图机制,而不是 Figma Bridge 的依赖项。

相同的规范也可以通过 figma_run ["export", "code-spec", "<nodeId>"] 获得。其默认输出是可读树;传入 -f yaml-f json 以获取规范模型。

无损结构化规范格式

figma_specexport code-spec 默认使用 format:"tree",这是一种简洁的、面向行的代理视图,其页脚包含所需的资源和保真度操作。当消费者需要版本化的规范模型时,请显式使用 yaml 或格式化的 json。两种结构化格式都序列化相同的模型;仅语法不同。往返测试要求每个字段——文本、ID、布局来源、填充、排版、模式感知变量、资源、组件契约、Bridge 意图、原生注释、捕获完整性和保真度检查——都能精确存活。不提供压缩的 JSON:真实的代理测试表明,尽管携带相同的原始字段,但单行超长文本实际上更难处理。

模型的 capture 字段会显式报告请求/实际深度、负载完整性、隐藏节点策略,以及请求的深度是否截断了后代。没有静默的工具结果截断:如果规范超过配置的输出预算,调用会返回 complete:false,并附带逐节重试方案,且不会返回误导性的部分设计depth:0 明确表示“仅请求的节点”,并且是完整的,而不是深度截断的树。

IMAGE 填充的文件名由 Figma 的稳定图像哈希键控,而不是由本地图层名称/路径键控。这确保了 figma_spec、独立的子节点调用、资源导出和 assets.json 即使在通过不同根节点访问“Frame 64”等通用图层时也能使用相同的文件名。

对于 MCP 设计到代码的调用,dedup:false 是默认值:每个可见图层都保留自己的 ID、原生 Figma Inspect css{…}、布局/填充/令牌事实和完整文本。混合富文本图层会携带其各自的样式化范围。页脚会将实时可见图层计数与显式行、SVG 内部、组件内部和非渲染辅助工具进行协调。当深度限制或未说明的图层会迫使猜测时,样式投影会被拒绝;根据结构图中的节点 ID 进行拆分。仅在对使用共享 S<n> 样式和重复引用的紧凑概览时设置 dedup:true

对于重复的显式节点调用,phaseformat 和去重不会触发另一次完整的 Figma 遍历。内存中的 Design Capture 缓存默认限制为 8 个条目 / 8 MiB(通过 DESIGN_CAPTURE_CACHE_ENTRIESDESIGN_CAPTURE_CACHE_BYTES 配置)。每次命中仍会探测实时文档修订版;没有 TTL,也没有 stale-while-revalidate 路径。

代码 ↔ Figma 设计记忆

为每个重要的组件、屏幕或画板赋予一个持久的设计实体 ID。该 ID 描述的是概念,而不是其当前位置:使用诸如 ui.buttonui.account-cardscreen.settings 之类的名称。

在选择或识别 Figma 节点后,代理可以通过以下方式创建链接:

figma_run {args:["link","set","9:9","screen.settings","--kind","screen","--source","src/routes/settings.tsx","--export","SettingsScreen","--story","screens-settings--default"], confirm:true}

这汇聚了两个小型适配器:

  • figma-bridge.json 是已提交的、可审查的注册表,包含相对于仓库的代码路径,以及可选的 Storybook 和 Figma 句柄。

  • Figma 仅在节点上存储 {version,id,kind} 作为插件数据。它不包含本地路径、凭据或特定于机器的状态。

使用 figma_run ["link","inspect","9:9"] 来解析节点,使用 figma_run ["link","list"] 来检查仓库记忆而无需读取 Figma。一旦链接,figma_selectionfigma_spec 会自动暴露相同的 ID 以及注册表的代码/Storybook 目标。代理应重用或编辑该代码组件,而不是创建外观相似的组件。重复相同的 set 命令是安全的,并且可以在写入中断后修复任一侧。

在视觉验证代码和 Figma 对应后,显式记录它们当前的指纹。屏幕实体需要真实的浏览器截图和通过的像素阈值:

figma_run ["link","accept","screen.settings","--compare","/abs/build.png","--max-diff","5"]

源代码永远不会存储在注册表中。初始代码适配器会对完整的链接文件及其导出标识进行哈希处理;因此,共享文件中的无关编辑可能会保守地报告代码更改,但真正的更改永远不会被隐藏。Figma 适配器会对规范化的链接子树进行哈希处理。对于代码到 Figma 的节点,它还会将每个唯一的 figmaBridge.semanticPath 与该节点的子树哈希一起存储。后续的 link status 因此可以列出确切添加、删除或更改的语义路径,并推荐节点范围的规范。仅更改语义标记不会改变视觉指纹;重复的路径会被报告为不明确,而不是被猜测。

figma_run ["link","status","screen.settings"]
figma_run ["link","context","screen.settings"]

状态

含义

unchanged

双方均未偏离已接受的基线。

code-only

仅链接的代码文件发生了变化。

figma-only

仅链接的 Figma 子树发生了变化。

conflict

双方都发生了变化;任一侧都不会被覆盖。

untracked

尚未显式接受任何基线。

link context 是链接存在后首选的代理入口点。它返回最小的相关投影:实体、代码/导出、Figma 根节点、Storybook 故事、当前往返计划、发现的 DESIGN.md/令牌文件以及确切的下一次读取。它是按需生成的,不会作为另一个记忆文件持久化。link accept 仅写入 figma-bridge.json;它永远不会更改 Figma 或代码。对于屏幕,它还会存储测量的差异和两个比较图像的 SHA-256 哈希值,因此结构指纹不能证明视觉上错误的基线是有效的。

常规的 DESIGN.mddesign/DESIGN.mdtokens.jsondesign/tokens.json 位置会被自动发现。在需要时配置一次自定义的仓库相对位置:

figma_run ["link","configure","--design-doc","docs/product-design.md","--tokens","src/theme/tokens.json"]

提交 figma-bridge.json。不要在其中放入密钥、绝对路径或生成的凭据。模式和冲突规则记录在 docs/adr/0007-dual-anchor-design-entities.md 中,基线和上下文决策在 ADR-0008 和 ADR-0009 中。

已审查的 CSS ↔ Figma 边界策略

语义代码到 Figma 使用稳定的策略 ID,而不是静默的视觉替换:minmax.native-gridspace-around.equal-slotsborder.single-paint-nativesticky.metadata-onlyfilters.layer-stackmasks.vector-maskfont.named-facesfigma-effects.native。完整的矩阵及其剩余的硬性限制位于 docs/css-figma-semantic-matrix.md

已审核的有损策略可以选择加入自动原生 Figma 注释,标注在受影响的精确语义节点上。注释会解释不支持的 CSS 事实,链接相关的 Figma 属性,并作为带版本号的 figmaBridge.fallbackAnnotations 插件数据镜像,供未来的代理使用。等效的原生转换保持无注释,以避免审查噪音。第一个活跃策略是 border.single-paint-native:Figma 接收第一个显式绘制的 CSS 边作为共享的原生描边,保留所有四个边的权重,并标记 strokesstrokeWeight。原生渲染会报告添加、去重或不支持的降级注释数量。

固有的单行 DOM 文本映射到 Figma HUG 尺寸。定位和多行文本保持测量的盒几何形状;桥接器不会添加任意的百分比宽度余量来防止换行。

可变字体轴会被捕获,但结构门控会询问在渲染前是应安装所需字体,还是使用可用的命名字体。原生 Figma Glass 保持为可编辑的原生效,所有效果参数均保留;它不会被静默视为 CSS backdrop-filter,因为 Figma 的 CSS 导出不暴露这些 Glass 参数。

Storybook 镜像

Figma 组件携带一个稳定的发布键(在库发布后仍存在;节点 ID 是文件本地的)。该键现在通过 figma_spec(规范结构化模型 + “使用的组件集”树尾部)、figma_selectioncomponent listfigma_inspect 和 DESIGN.md 流动。

要将它们链接到代码镜像:

figma_run ["map", "storybook", "http://localhost:6006"]

这会将文件的组件与 Storybook 索引按规范化名称匹配,并将 figma-map.json 写入你的项目:Figma 键 ↔ story id / 导入路径,每个匹配附带 confidence,以及两个未匹配的列表。手动编辑条目并设置 "matchedBy": "manual" 以固定它们——固定的条目在重新运行后仍会保留。当文件存在时,figma_selectionfigma_spec 会自动用 ↔ story <id> (<importPath>) 注释组件。

figma-map.json 仍然是一个遗留的读取适配器,因此现有映射继续工作。新的持久链接属于 figma-bridge.jsonlink set 永远不会将遗留行复制到其中。当你下次接触组件时,通过分配其真实的 Design Entity ID 并通过 --story 传递其 story 来迁移它。仅在 link list 显示你仍然需要的每个映射后,才删除遗留文件。

自带设计系统

该项目附带任何设计系统——没有 shadcn、没有 Tailwind 预设、没有图标包。这是故意的:捆绑的系统是别人的意见渲染到你的文件中。它提供的是通过一个命令让你的系统对代理可读的方法:

figma_run ["kit", "init", "./my-app", "--storybook", "http://localhost:6006"]

四次读取,一份报告:

步骤

结果

extract

design/DESIGN.md — 结构、令牌、变体矩阵

export dtcg

design/tokens.json — W3C 设计令牌

component list --all-pages

带有稳定发布键的清单

map storybook

figma-map.json — Figma 组件 ↔ story

它最后会指出仍然缺少的内容——未映射的 Storybook、没有 story 的组件、使两者保持同步的 tokens sync 命令——因为一个静默缺少映射的设置看起来是完整的,直到代理需要它。

DESIGN.md 是代理应首先读取的内容;tokens.json 是它绑定的内容。

同时处理多个文件

桥接器在你启动插件的每个 Figma 窗口中持有一个连接。这是同意模型:一个文件可访问是因为打开了它并在那里启动了插件——而不是因为某个标志扩大了范围。

  • 一个窗口——没有变化。命令发送到那里。

  • 多个窗口——命令必须指定其目标,否则会失败并显示已连接文件的列表:

    figma_status                                        # lists every connected window
    figma_run {args: ["canvas","info"], fileKey: "GY5SasBJ…"}
    figma_spec {nodeId: "12:34", fileKey: "GY5SasBJ…"}

    figma_renderfigma_selectionfigma_inspectfigma_screenshotfigma_spec 接受相同的 fileKey 参数。完整的 Figma 节点 URL 也会自动提供其文件键。没有目标时,figma_selection 会说明哪些文件是打开的,而不是猜测。在引擎 CLI 上,标志是 --figma-file,而不是 --fileevalspec 已经使用 -f, --file 表示本地路径。

故意没有“所有文件”选项。每次写入都命名一个文件,因此错误的命令不会扩散到整个库。同一文件上的两个窗口在路由上无法区分,因此较新的窗口接管,较旧的窗口被告知它失去了桥接器。审计条目携带文件键,因此当涉及多个文件时,figma_history 仍然可读。

访问你打开的文件不在范围内:Figma 的 REST API 无法写入文档内容,因此跨三十个库文件进行批量重命名不是此工具能诚实提供的功能。

FigJam

该插件也在 FigJam 面板中运行,通过相同的桥接器——没有第二个传输层,没有额外权限:

figma_run ["jam", "sticky", "Ship the handshake", "--color", "green"]
figma_run ["jam", "stickies", "[\"Discovery\",\"Build\",\"Ship\"]", "--columns", "3"]
figma_run ["jam", "shape", "Decide?", "--type", "DIAMOND"]
figma_run ["jam", "connector", "1:2", "3:4", "--text", "yes"]
figma_run ["jam", "table", "3", "4", "--data", "[[\"Step\",\"Owner\"],[\"Handshake\",\"Alex\"]]"]
figma_run ["jam", "board"]      # read everything back, with connectors
figma_run ["jam", "arrange"]    # arrange only the current selection
figma_run ["jam", "arrange", "--ids", "1:2,3:4"]
figma_run ["jam", "arrange", "--all"] # explicit: whole page

新节点会放置在面板上已有内容的右侧,除非你传递 --at x,y,因此向已填充的面板添加内容的代理不会将所有内容堆叠在原点。每个命令首先检查 figma.editorType,并说“这是一个 figma 文件,而不是 FigJam 面板”,而不是在未定义的 API 上失败。figma_status 报告桥接器连接到了哪个编辑器。

jam arrange 故意限定在选择范围内。代理可以传递精确的节点 ID 而不更改用户的选择;重新排列整个页面需要可见的 --all 标志。此命令永远不会移动分区和连接器。公共表面已于 2026-08-10 在 Figma Desktop 上测试。维护者将详细的命令和回读证据保存在公共存储库之外。

Figma Slides 测试版

Slides 使用相同的经过身份验证的插件桥接器。测试版表面涵盖幻灯片结构和原生幻灯片属性,而不是单独的演示渲染器:

figma_run ["slides", "inspect"]
figma_run ["slides", "create", "Agenda", "--row", "0", "--col", "1"]
figma_run ["slides", "duplicate", "Agenda", "--label", "Agenda alternative"]
figma_run ["slides", "move", "Agenda alternative", "1", "0"]
figma_run ["slides", "transition", "Agenda", "DISSOLVE", "--duration", "0.4"]
figma_run ["slides", "skip", "Appendix", "on"]
figma_run ["slides", "delete", "1:42"]

每当画布网格更改时,Figma 会重新编号原生幻灯片名称。因此,create 的可选参数和 duplicate 上的 --label 会在插件数据中存储一个持久的 Bridge 标签;inspect 报告原生 name 和稳定的 label。引用通过 ID、精确的原生名称或标签,然后是唯一的子字符串来解析。歧义是一个错误,删除始终需要显式引用,并且 duplicate/move 拒绝不存在的目标行,而不是接受 Figma 的回退放置。每个操作在触及仅 Slides 的 API 之前都会检查 figma.editorType === "slides"。开放的候选条件和退出测试版的标准位于 docs/slides-roadmap.md;编辑器接受度由维护者独立于公共存储库进行验证。

令牌同步(双向)

tokens import 只创建,因此在代码中编辑的值永远不会到达现有的 Figma 变量,在 Figma 中编辑的值也永远不会到达代码。tokens sync 关闭了这个循环:

figma_run ["tokens", "sync", "src/tokens.json"]              # plan only
figma_run ["tokens", "sync", "src/tokens.json", "--apply"]   # write it

导入表面比同步表面更广。一次性 import 接受 Tailwind v3 配置、Tailwind v4/CSS、Storybook 索引、DTCG/W3C JSON 以及 Style Dictionary 和 Tokens Studio 导出的 DTCG 兼容令牌形状。这种兼容性不包括 Tokens Studio 主题语义或任意预处理器;诸如 $themes 之类的元数据被忽略,而令牌集和别名被读取。

显式 spacing/*space/* 命名空间中的新 FLOAT 变量仅限定于 Figma 的 GAP 消费者。radius/*radii/* 变量仅限定于 CORNER_RADIUS。推断故意是命名空间精确的:诸如 spacingFactor 之类的名称保留在 Figma 的默认范围内,并且渲染不会静默更改现有用户或库变量的范围。其他新的 COLOR、FLOAT 或 STRING 变量会显示 SCOPE DECISION REQUIRED,并仅提供兼容的 Figma 选项。代理应在缩小范围之前询问;使用 figma_reference {name:"variable-scopes"} 检查目录,并使用 figma_run ["var","update","<name>","--collection", "<collection>","--scopes","TEXT_FILL,STROKE_COLOR"] 应用答案。

安全的三向同步仅接受 DTCG / W3C 设计令牌.jsonexport dtcg 输出的内容)和 CSS 自定义属性.cssexport css 输出的内容)。Sass $variables 不是 CSS 自定义属性,并且 .scss 会被拒绝,而不是被部分解析。请注意,export dtcg每个本地变量写入一个文件,而同步针对一个集合——相应地传递 --collection。如果文件中的大多数名称已经存在于另一个集合中,同步会说明这一点,而不是提供复制它们。Tailwind 配置仅是导入源——它们的解析器将值分类为颜色/间距/半径,并且无法往返,因此同步会按名称拒绝它们,而不是静默丢弃它无法理解的令牌。

为什么需要锁文件。 没有记忆的双向同步无法区分“代码更改了”和“Figma 更改了”——它只看到两者不同,并且无论它选择哪个方向,都会破坏另一侧的工作。figma-tokens.lock.json 记录上次成功同步时的状态,因此每个决策都是三向比较:

代码

Figma

结果

已更改

未更改

更新 Figma

未更改

已更改

报告,从不覆盖 — 更新你的代码文件

两者都更改

冲突 — 不应用任何内容

未更改

未更改

未更改

冲突会停止整个运行。通过编辑一侧来解决它们,或者使用 --ours(代码文件获胜)/ --theirs(Figma 获胜,并且不向 Figma 写入任何内容)一次性决定所有冲突。

删除需要 --prune,即便如此,也只触及同步自身创建的变量——它从未跟踪的变量会被报告为未跟踪并保持原样。

锁文件还存储每个变量的 Figma ID,这就是使重命名成为一次重命名而不是删除加创建(这会丢失每个层绑定)的原因。配对基于值,并且仅在无歧义时进行:在同一提交中重命名更改令牌值会回退到创建加删除,因此如果绑定很重要,请分两步执行。

没有 --apply 时,当有更改待处理时,命令会以退出码 1 退出,因此它可以用作 CI 检查“Figma 是否与仓库同步?”。

绑定,以及切换设计遵循的集合

tokens sync 写入令牌。它故意不做两件相邻的事情:

figma_run ["node", "bind", "12:34", "radius", "radius/lg", "--collection", "TARGET_COLLECTION"]
figma_run ["tokens", "rebind", "TARGET_COLLECTION", "--node", "12:34"]            # plan
figma_run ["tokens", "rebind", "TARGET_COLLECTION", "--node", "12:34", "--apply"] # write

node bind 将一个变量附加到现有节点的属性上——fillstrokeradiusgappadding(或一侧)、opacitystroke-widthwidthheight。其读取对应项是 node bindings。传递 --batch 和一个 JSON 数组,以在一次调用中绑定多个属性或节点。

不唯一的变量名会被拒绝,而不是猜测——此文件在两个集合中都有 radius/lg,答案会命名两者,以便 --collection 可以解决它。变量的类型会首先针对属性进行检查,因此将 COLOR 应用于 radius 会失败并显示一条句子,而不是插件堆栈跟踪。

排版变量有自己的范围感知命令,因为文本可以在不同的字符跨度上携带不同的绑定:

figma_run ["font", "bind", "12:36", "fontWeight", "type/weight", "--collection", "Typography"]
figma_run ["font", "bind", "12:36", "line-height", "type/line-height", "--start", "0", "--end", "12"]
figma_run ["font", "unbind", "12:36", "lineHeight", "--start", "0", "--end", "12"]

可绑定字段包括 fontFamilyfontSizefontStylefontWeightletterSpacinglineHeightparagraphSpacingparagraphIndent;也接受短横线命名(kebab-case)拼写。在更改绑定之前,会加载现有字体——对于字体系列/样式/粗细绑定,还会加载相关的可用系列样式。变量名在存在歧义时会被拒绝,并且在调用 Figma 之前会检查 STRING 与 FLOAT 类型。数值型的 fontWeight 绑定仍然不是通用的可变字体轴设置器:Figma 会为当前字体选择一个有效的粗细值。

tokens rebind 是主题切换命令:它会遍历一个子树,并将每个绑定重新指向目标集合中同名的变量。针对 SOURCE_COLLECTION 设计一个卡片,然后使用 TARGET_COLLECTION 运行 rebind,同一个卡片就会跟随目标集合的值——无需重新设计。默认情况下它会进行计划;--apply 参数会执行写入。在目标集合中没有对应项的令牌会被列出,并保持原来的指向,因此部分主题会生成一份报告,而不是导致设计半损坏。

node set 用于更改已存在节点的属性——fillstrokestrokeWidthradiusopacityxywidth/heightnamevisible——可以一次操作一个节点,也可以通过 --batch 批量操作,这一点很重要,因为批量形式只需一次往返:

figma_run ["node", "set", "12:34", "--name", "Card", "--radius", "12"]
figma_run ["node", "set", "--batch", "[{\"node\":\"12:35\",\"fill\":\"var:sage/50\",\"name\":\"Badge\"}]"]

颜色可以采用十六进制值或 var:<name> 形式。区别并非表面上的:十六进制值是固定的,而 var: 引用保持绑定状态,因此后续的 tokens rebind 仍然可以移动它。

本地样式、变量元数据和模式

过去需要手动 UI 操作的本地设计系统原语现在有了头等公民的 Figma 命令。它们使用实时插件 API,而非 REST:

figma_run ["style", "list", "--type", "TEXT"]
figma_run ["style", "show", "Heading/H1"]
figma_run ["style", "create", "PAINT", "Brand/Primary", "--properties", "{\"paints\":[{\"type\":\"SOLID\",\"color\":{\"r\":0.1,\"g\":0.3,\"b\":0.9}}]}"]
figma_run ["style", "apply", "Brand/Primary", "12:34,12:35", "--field", "fill"]
figma_run ["style", "consumers", "Brand/Primary"]
figma_run ["style", "publish-status", "Brand/Primary"]
figma_run ["style", "bind-font", "Body", "fontSize", "--variable", "type/size/body"]
figma_run ["style", "unbind-font", "Body", "fontSize"]

style 涵盖本地 PAINT、TEXT、EFFECT 和 GRID 样式。update 接受与 create 相同的类型特定 JSON 属性;apply 会根据 fillstroketexteffectgrid 验证样式类型。名称查找会拒绝歧义。消费者来自 getStyleConsumersAsync(),发布状态是 Figma 的 UNPUBLISHEDCURRENTCHANGED 值之一。

变量公开了令牌文件同步不拥有的元数据和模式操作:

figma_run ["var", "show", "space/md", "--collection", "Primitives"]
figma_run ["var", "update", "space/md", "--description", "Medium spacing", "--scopes", "GAP"]
figma_run ["var", "set-value", "space/md", "12", "--mode", "Light"]
figma_run ["var", "set-value", "space/card", "--alias", "space/md", "--mode", "Light"]
figma_run ["var", "code-syntax", "space/md", "WEB", "var(--space-md)"]
figma_run ["var", "resolve", "space/md", "12:34"]
figma_run ["col", "mode-add", "Primitives", "Dark"]
figma_run ["col", "mode-rename", "Primitives", "Dark", "Dim"]
figma_run ["col", "extend", "Primitives", "Brand"]

var show 按模式、作用域、代码语法、集合元数据和发布状态返回值。var resolve 故意需要一个消费者节点,因为别名在该节点选定的模式下可能解析不同。集合的 showupdatemode-addmode-renamemode-removepublish-status 遵循相同的 ID/精确名称/唯一子字符串查找策略。Figma 对模式数量的计划限制仍由 Figma 强制执行,并以错误形式呈现。集合扩展使用 VariableCollection.extend() 处理本地集合,使用 extendLibraryCollectionByKeyAsync() 处理已发布的键。Figma 将此功能限制在企业版计划中;CLI 会原样报告 Figma 的计划错误。文本样式绑定完全支持 Figma 可绑定的排版字段:系列、样式、粗细、字号、行高、字间距和段落值。

启用的团队库

库的发现和导入也保持在经过身份验证的插件传输层上:

figma_run ["library", "collections"]
figma_run ["library", "variables", "Acme/Primitives", "--type", "COLOR"]
figma_run ["library", "import-variable", "<published-variable-key>"]
figma_run ["library", "import-style", "<published-style-key>"]
figma_run ["library", "import-component", "<published-component-key>"]
figma_run ["library", "import-component-set", "<published-component-set-key>"]

collectionsvariables 是读取操作。四个 import-* 命令将已发布的资产物化到当前文件中,因此在能力目录中属于写入操作。Figma 仅暴露变量集合和变量的发现功能。已发布的样式、组件和组件集可以在其稳定键已知时导入,但插件 API 无法枚举它们。

库必须在 Figma UI 中为当前文件启用后,library collections 才能看到它们;插件 API 无法启用库。已发布的插件已经声明了所需的 teamlibrary 权限。名称查找使用集合键、精确集合名称,然后是明确的集合或库名称子字符串。库发现拥有一个 18 秒的插件 API 超时时间(低于桥接层的截止时间),因此停滞的 Figma 库请求会命名该操作,并建议检查库是否已启用,而不是退化为通用的执行超时。

原型、开发模式测量和注释

这些文档功能也是优先使用插件 API:

figma_run ["prototype", "inspect", "12:34"]
figma_run ["prototype", "add", "12:34", "--trigger", "click", "--navigate-to", "12:36"]
figma_run ["prototype", "set", "12:34", "--json", "[{\"trigger\":{\"type\":\"ON_CLICK\"},\"actions\":[{\"type\":\"BACK\"}]}]"]
figma_run ["measure", "add", "12:34:right", "12:36:left", "--offset", "16", "--text", "gap"]
figma_run ["annotate", "categories"]
figma_run ["annotate", "add", "Review spacing", "--node", "12:34", "--category", "Review", "--properties", "width,fontSize"]
figma_run ["annotate", "edit", "12:34", "0", "--text", "Resolved"]

prototype set --json 是处理 Figma 多个动作(SET_VARIABLESET_VARIABLE_MODE 和条件块)的无损形式。它通过 setReactionsAsync() 写入,因此支持动态页面清单。测量写入受到 Figma 开发模式的保护,并使用 PageNode 的原生测量方法。注释索引从零开始;自定义类别的创建/编辑/删除命令与 categories 一起可用。这些手动审查注释独立于语义渲染器的自动边界回退注释,后者仅由明确选择加入的有损映射策略发出,并通过插件数据保持机器可读。

2026 插件 API:视频、着色器、网格、插槽和绘图

当前的官方插件 API 表面以 Figma 命令而非 REST 调用的形式暴露:

figma_run ["export", "video", "12:34", "--format", "mp4", "--fps", "30", "-o", "/abs/demo.mp4"]
figma_run ["shader", "list"]
figma_run ["shader", "import", "<shader-id>"]
figma_run ["shader", "apply", "12:34", "<shader-id>", "--field", "fill", "--properties", "{\"definition-id\":0.8}"]
figma_run ["layout", "grid", "set", "12:34", "--rows", "2", "--columns", "3", "--row-gap", "12"]
figma_run ["layout", "grid", "auto-flow", "12:34", "--auto-tracks", "rows", "--positioning", "row_auto_flow"]
figma_run ["slot", "create", "12:37", "Content", "--settings", "{\"minChildren\":1,\"maxChildren\":3}"]
figma_run ["slot", "validate", "12:37"]
figma_run ["draw", "inspect", "12:38"]
figma_run ["draw", "text-path", "12:38", "--text", "Around the curve"]
figma_run ["draw", "stroke-profile", "12:38", "--preset", "TAPER"]
figma_run ["draw", "pattern", "12:38", "12:39", "--field", "fill"]

视频导出会将选定的后代解析为其顶级动画帧,并仅接受 Figma 特定格式的 FPS 值。着色器属性按定义 ID(而非显示名称)键控,并且必须先导入可用的着色器才能应用。layout grid 指的是自动布局的 GRID 模型;旧的顶级 grid 命令仍然是布局参考线管理。插槽暴露了 GA 版本的 SlotSettings、首选值、重置和限制违规;JSX <Slot> 现在使用 ComponentNode.createSlot(),并在渲染后验证配置的限制。绘图命令涵盖文本路径、重复变换组、拉伸/散布/动态描边、可变宽度轮廓以及异步图案填充/描边设置器。在修改不熟悉的文档之前,先运行相应的 inspect/validate 读取操作。

查找需要修复的内容

figma_run ["analyze", "lint", "--node", "12:34"]

一次遍历即可完成设计系统审查所关注的四个方面:与现有变量匹配但未绑定的颜色、仍带有默认名称的图层、没有样式的文本、小于 12px 的文本。--fail-on-issues 使其成为 CI 门控;--kind 缩小范围;--json 从不截断。

硬编码的颜色仅当变量已经持有该精确值时才会被报告——否则该发现就是无法操作的噪音。由于匹配已知,每个发现都附带修复命令:

unbound token colour — 1
  12:35    Badge  fill is #8a9a8d, which is sage/400
    fix: node bind 12:35 fill "sage/400" --collection "Sprout Primitives"

analyze colors|typography|spacing 仍然提供完整的普查。Lint 是回答是否需要做任何事情的遍历。

可变字体和 OpenType 事实

Figma 不通过插件 API 暴露通用的变化轴元组。因此,桥接层将 Figma 实际报告的事实与调用者显式记录的轴意图分开:

figma_run ["font", "inspect", "12:36"]
figma_run ["font", "inspect", "12:36", "--start", "0", "--end", "12", "--all-open-type"]

font inspect 返回带样式的文本范围,包含 fontName、数值型只读的 fontWeight、字号、启用的 OpenType 特性标签以及已解析的排版变量绑定。--all-open-type 还会包含值为 false 的特性。结果明确指出了 API 的限制:报告的 fontWeight 不是通用的 wght/wdth/opsz/自定义轴元组,并且 OpenType 特性是只读的。

当从 UI 或其他字体工具知道精确的轴值时,将其作为范围元数据保留在文本节点上:

figma_run ["font", "remember-axes", "12:36", "wght=357,wdth=82", "--start", "0", "--end", "12"]
figma_run ["font", "axes", "12:36"]
figma_run ["font", "forget-axes", "12:36", "--start", "0", "--end", "12"]
figma_run ["font", "forget-axes", "12:36"]  # clear every stored range

remember-axes 仅更改插件元数据——从不更改字体或渲染的字形——因此被能力目录归类为写入操作。figma_spec 将这些记录携带为 axes-meta[start:end](tag=value,…),加上 Figma 报告的 fw… 值和启用的 ot(…) 标签,因此设计到代码的捕获不会静默丢弃已记录的意图。

原生插件 API 事实

两个读取命令暴露了 Figma 自身的表示形式,无需联系 REST API:

figma_run ["node", "css", "12:34"]
figma_run ["node", "css", "12:34", "--json"]
figma_run ["export", "node-json", "12:34"]
figma_run ["export", "node-json", "12:34", "-o", "facts/card.json"]

node css 调用 getCSSAsync() 并返回 Figma 为其检查面板暴露的声明。这特意与 export css 分开,后者导出设计令牌自定义属性。export node-json 使用 exportAsync({format:"JSON_REST_V1"}):其形状类似于 REST 文件模式,但字节来自实时插件文档,既不需要令牌也不需要网络请求。

版本历史与差异

Figma 的插件 API 可以写入版本,但无法读取回版本,因此“从今早开始发生了什么变化”无法仅从桥接层得到答案。history 无需任何凭据即可提供答案:记录子树的某个结构,稍后再次记录,然后对两者进行差异比较。

figma_run ["history", "save", "Before refactor", "--description", "Agent restore point"]
figma_run ["history", "snapshot", "--label", "before refactor"]
# … agent works …
figma_run ["history", "diff", "latest", "live"]

history save 直接通过 saveVersionHistoryAsync() 创建命名条目,属于 Figma 写入操作。snapshotlistdiff 保持为本地/只读的 Figma 操作;读取 Figma 原生的历史版本仍然需要可选的 REST 附加组件。

快照为每个节点存储一条规范化记录——几何、布局、填充、排版、组件键——加上内容哈希和子树哈希,因此差异比较器可以报告未更改的部分而无需遍历。它们存储在 ~/.figma-bridge-mcp/snapshots/<fileKey>/ 目录下,经过 gzip 压缩,保留最新的 20 个。

引用可以是 latestprevious、来自 history list 的索引、文件名,或者 live(表示当前文档)。报告区分了新增移除替换移动更改——最后一个区别在实践中很重要:一个代理删除一个框架并重新渲染它,会保留名称路径但获得新的节点 ID,如果没有替换检测,每次重新渲染都会被视为一百次删除。--changelog 会输出 markdown 格式;diff 在有任何差异时退出码为 1,因此它也可以作为 CI 门控。

通过 MCP,这是一个参数,而不是第十三个工具:

figma_history {diff: {from: "latest", to: "live"}}
figma_history {diff: {from: "version:1234", to: "version:5678"}}   # REST add-on

version: 引用通过 REST 层,并使用相同的差异比较器对设计师保存的版本进行差异比较。两个来源不能混合在一个差异中:REST 文档和插件快照暴露不同的属性,因此每个节点看起来都会发生变化——工具会说明这一点,而不是产生误导性的输出墙。

动效

Figma Motion(Config 2026 Beta)可以通过 figma_run 配合 ["motion", …] 访问:关键帧轨道(add)、来自 JSON 的完整规格(apply)、命名预设(preset)、跨节点的编排偏移(stagger)、Figma 第一方动画样式(stylesstyle)、帧时长(timeline)、回读(inspect)和移除(clear)。

与所有其他命令一样,它通过插件桥接层运行——没有单独的传输层。stylesinspect 是读取操作;其他所有操作,包括 timeline(它根据参数读取设置),在 FIGMA_WRITE_CONFIRM=1 下都算作写入操作。

Motion 正在 Figma Beta 标志后面逐步推出。如果没有访问权限,命令会失败并显示名为 MOTION_DISABLED 的错误,告诉您更新 Figma Desktop,而不是显示通用的 API 失败。

REST 附加组件(可选)

以上所有功能都无需任何 Figma 凭据即可工作。本地插件桥接层在结构上无法访问的三件事位于 Figma REST API 之后,可以通过个人访问令牌解锁:

功能

新增内容

版本历史

figma_history {includeVersions:true}设计师保存的内容(时间、操作者)合并到本地审计+Git时间线中——插件API只能写入版本,无法读取版本。figma_history {diff:{from:"version:…", to:"version:…"}} 更进一步,对文档本身进行差异比较。

评论

figma_comments 读取设计评审反馈(包含节点锚点和线程ID),并可进行回复。发布前始终显示预览,且需要 confirm:true——评论对其他用户可见。

库元数据

map storybook 自动用已发布组件的 description 和文档链接丰富 figma-map.json——这比名称规范化提供了更强的匹配信号。

启用方式——令牌永远不会离开你的机器:

  1. 在 Figma 中创建个人访问令牌(设置 → 安全 → 个人访问令牌),作用域包括:文件内容(读取)文件版本(读取)评论(读取和写入)当前用户(读取) 是可选的——它仅使 figma_status 显示你的用户名。

  2. 在 Figma Desktop 中打开 Figma Bridge 插件,进行连接(插件认证后会出现该字段),展开 "REST token (optional)"。粘贴令牌,点击 Save token

  3. figma_status 会报告令牌已配置,无需发起远程请求。当你需要显式验证时,运行 figma_status {validateRest:true};当缺少可选的 Current user 作用域时,它会报告你的用户名或验证文件访问权限。

令牌通过经过身份验证的 localhost WebSocket 从插件传输到守护进程,守护进程将其存储在 ~/.figma-bridge-mcp/rest-token(权限 0600)中。令牌永远不会在聊天中输入,永远不会存储在你的 MCP 客户端配置中,不会被任何工具回显,也永远不会写入审计日志(REST 调用仅记录为方法+路径)。在插件中点击 Clear token 会删除该文件。

无头/CI 替代方案:设置 FIGMA_REST_TOKEN 环境变量——它会覆盖文件。

作用域: 默认情况下,REST 调用针对 Figma Desktop 中当前打开的文件(插件会推送其文件密钥)。其他文件需要显式的 fileKey 参数(裸密钥或完整的 Figma URL)。请注意,PAT 本身可以读取其账户有权访问的所有文件——请保持作用域最小化。

REST 客户端是一个封闭的内部白名单,而不是通用的 HTTP 逃生口。它允许令牌健康检查、版本列表、版本固定的文档内容、评论以及文件范围的已发布组件元数据。在读取令牌或接触网络之前,裸当前文件获取以及所有节点/CSS/导出/变量/样式/开发资源端点都会被拒绝;这些操作必须使用上述本地插件 API 命令。

安全模型

  • 无需 Figma API 令牌——Figma 通过本地插件驱动,从不使用 api.figma.com。REST 附加功能严格可选:没有令牌时代码路径是无效的,有令牌时令牌存储在 0600 文件(或你自己的环境变量)中,而不是 MCP 客户端配置中。

  • 无需二进制补丁——Yolo/CDP 模式已从供应商引擎中剥离。

  • 能力门控命令——figma_run 仅接受能力目录公开的命令;connect 公开,因此强制使用仅安全模式连接。相同的已解析计划驱动写入确认门控、目标要求和重试策略,防止适配器漂移。

  • 无 shell——引擎使用 execFileshell:false)生成。

  • 双层守护进程认证,无秘密在线上传输——签名的 HTTP 请求(基于方法/路径/体的每次请求 HMAC,使用会话令牌作为密钥,nonce 重放防护)+ 插件套接字上的双向挑战-响应握手(Origin/Host 白名单)。会话令牌和访问密钥都不会在任何方向上传输——请参阅握手

  • 本地主机锁定插件——plugin/manifest.jsonnetworkAccess.allowedDomains 限制为 ws://127.0.0.1:3456–3460

  • 隔离状态——令牌、PID、密钥和审计日志位于 ~/.figma-bridge-mcp/ 下,与任何上游的 figma-ds-cli 安装分开。

  • 审计日志——每个执行的命令都会附加到 ~/.figma-bridge-mcp/audit.log(包含接触的节点 ID、可选标签以及记录成功/失败的完成条目——figma_history 的数据源)。日志在 5 MB 时轮换;保留一个前一代(audit.log.1),figma_history 仍可读取。

端口回退。 守护进程绑定 3456–3460 范围内的第一个空闲端口,并将其发布到 ~/.figma-bridge-mcp/daemon-port 中;CLI/MCP 层每次调用时解析端口(环境变量 DAEMON_PORT > 端口文件 > 3456),插件扫描整个范围,因此外部进程占用 3456 不再阻止连接。占用检查是一个未经身份验证的 /health 探测,而经过身份验证的请求是 HMAC 签名的——范围端口上的占用者既看不到会话令牌,也看不到任何可重放的内容(签名绑定时间戳、nonce、方法、路径和体;守护进程拒绝重复使用的 nonce)。插件套接字在任何范围端口上都是安全的,原因相同:下面的握手不携带任何秘密,并绑定其运行的端口。显式设置 DAEMON_PORT 会禁用回退;3456–3460 之外的值不受支持——插件清单受 Figma 强制执行,无法访问它们。

握手

插件套接字运行双向挑战-响应(协议 2,engine/src/lib/plugin-handshake.js):

daemon → plugin   {type:'challenge', proto:2, nonce:<dNonce>, port:<bound>}
plugin → daemon   {type:'hello', proto:2, nonce:<pNonce>, version, proof}
daemon → plugin   {type:'hello-ack', proof, restTokenConfigured}

其中 proof = HMAC-SHA256(access key, transcript) 覆盖两个 nonce、绑定端口和插件版本——每个方向使用不同的角色标签和 nonce 顺序,因此任何一个证明都不能被重放为另一个。由此得出三个属性:

  • 密钥永远不会在线上传输。 在守护进程之前绑定范围端口并记录整个交换的过程,会学习到一个针对它永远不会再看到的 nonce 的 HMAC。这消除了早期版本文档中记录的残余风险,即原始密钥是插件发送的第一个帧。

  • 守护进程也证明了自己。 在协议 2 之前,插件信任任何响应者,并会运行发送给它的任何 eval——冒充守护进程根本不需要密钥。面板现在拒绝每个命令,直到确认验证通过。

  • 绑定端口在转录中。 占用 3456 并转发到 3457 上真实守护进程的占用者,会使插件签署 3456,而守护进程验证 3457,因此中继失败。

没有协议 1 的回退。figma_connect 在每次运行时刷新已安装的插件文件,因此升级方法是:运行 figma_connect,然后关闭并重新打开插件窗口——过时的面板会收到一个命名错误,明确指出这一点,而不是静默地使用较弱的握手。

面板携带自己的 SHA-256/HMAC 实现:插件 UI 是一个沙盒化的 null-origin iframe,我们无法保证 WebCrypto 的可用性,而对于认证握手来说,静默回退到较弱的实现是最糟糕的结果。tests/plugin-handshake.test.js 针对 Node 的 crypto 运行该已发布代码,因此两个实现不会发生偏离。

已知限制

  • Figma Slides 处于测试阶段且有意限制。 支持网格检查、幻灯片创建/复制/移动/删除、跳过状态和过渡。演讲者备注、交互式投票/嵌入、演示者控件和完整的内容创作工作流不支持。请参阅 Slides 路线图了解可行的候选功能与插件 API 边界。

  • 非 localhost 网络操作很少且明确api setup(一次性克隆 Figma 插件 API 文档镜像,用于 figma_referenceapi gap 则针对已安装的官方 @figma/plugin-typings 包进行测量)、import/map storybook 的 Storybook 索引获取(你传入的 URL/目录),以及——仅当你选择 REST 附加功能时——对 api.figma.com 的调用。没有其他内容与网络通信——上游的 iconify/unsplash/remove.bg/screenshot-url 集成已完全移除;figma_render JSX 中的 <Icon> 渲染为命名占位符(真实图标通过 export assets 从 Figma 文件中获取)。

  • 单一传输,无 CDP 残留。 每个命令都以相同方式到达 Figma:引擎 → 守护进程 → 插件 eval。上游的 Chrome-DevTools 客户端、其 figma-use shell 往返、二进制补丁 init 向导和 figma-use 依赖项都已移除(约 5,600 行代码被删除),因此没有第二条代码路径可以绕过插件桥。

开发

npm run check:contracts       # static JavaScript seam + plugin contracts
npm run check:architecture-latency # warmed latency budget in an idle process
npm run measure:architecture  # context, payload and local latency baselines
npm test                      # all contracts and regression suites

当前领域语言位于 CONTEXT.md,已接受的架构决策位于 docs/adr/,API 覆盖率位于 docs/figma-plugin-api-coverage.md,发布说明位于 docs/releasing.md。公共文档索引位于 docs/README.md

避免同时运行上游的 figma-cli。守护进程现在在 3456 被占用时回退到 3456–3460 范围内的端口,因此两者可以共存,但插件会扫描整个范围,而两个守护进程使用不同的访问密钥——插件先到达哪个是随机的。此构建将其自己的令牌/PID/端口文件隔离在 ~/.figma-bridge-mcp/ 下。

许可证

figma-bridge-mcp 根据 MIT 许可证发布。它按"原样"提供,不提供任何保证;确切的保证和责任条款在许可证本身中。第三方版权和许可声明保留在 NOTICEengine/LICENSE 中。

灵感与归属

两个项目以不同方式塑造了本项目。

figma-cli(Sil Bormüller)是 engine/ 目录的来源:它在 2026 年 7 月以 v2.1.0 版本被供应商化,此后发生了分歧——CDP 传输和二进制补丁安装程序已移除,插件套接字已认证,引擎现在所做的大部分工作都是在此编写的。四个文件与上游保持字节一致。上游 MIT 许可证完整保留在 engine/LICENSE 中,NOTICE 记录了更改内容。

figma-console-mcp 贡献了一个想法而非代码:Figma 桥可以真正本地化——在环回接口上的插件套接字,无需云中继,无需修补二进制文件。此处没有任何内容源自其源代码;工具界面、传输和插件是无关的。本项目不同之处在于,套接字还证明了另一端是谁。

插件身份。 开发清单使用与产品对齐的 ID figma-bridge-mcpfigma-bridge-mcp-dev。Figma 将 clientStorage(配对的访问密钥所在位置)键控到插件 ID。因此,0.5.0 版本之前的安装需要重新导入清单并粘贴一次现有的 Bridge 访问密钥。

Install Server
A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • The Figma MCP server brings Figma design context directly into your AI workflow.

  • A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

View all MCP Connectors

Latest Blog Posts

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/KaiUweHella/figma-bridge-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server