关于 localfig
localfig 是一个 MCP 服务,让 AI Agent 通过 Figma 桌面应用的 Plugin API 读取和编辑当前文件。它在本机运行,不需要 Figma 云 API 令牌或配额。
主要功能
- 01通过 Plugin API 读取和写入
- 02运行任意 Plugin API JavaScript
- 03检查元数据、样式和令牌
- 04搜索页面并跟踪更改
- 05导出设计并放置图像
- 06撤销编辑并保存快照
适用场景
- 01通过 AI Agent 编辑设计文件
- 02检查设计系统令牌和组件
- 03查看调用间在 Figma 中所做的更改
- 04导出画框或添加本地图像
MCP 相关
它通过 stdio 向 MCP 客户端提供 Figma Plugin API 工具,并通过回环 HTTP 桥接连接正在运行的桌面插件。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
10收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
localfig
将 Figma 桌面应用用作 MCP 服务。 localfig 通过一个小型开发插件和本地回环 HTTP 桥接,让 AI Agent 能够使用你当前打开的文件中的完整 Figma Plugin API,所有操作均在你的设备上完成。
- 读取和写入。 帧、文本、自动布局、变量、组件、图像填充、导出、撤销——Plugin API 能做的任何操作,Agent 都能做。
- 不需要 Figma 云 API、个人访问令牌,也没有账号配额。
- 零依赖。 仅使用 Node 内置功能。任何内容都不会离开你的设备。
- 适用于任何能够启动 stdio 服务的 MCP 客户端:Claude Code、Cursor、Windsurf、Cline、Claude Desktop 等。
MCP client --stdio JSON-RPC--> localfig --http localhost:8765--> Figma plugin --> Plugin API
为什么选择 localfig
| localfig | 官方 Figma MCP | REST API 服务 | 固定命令插件桥接 | |
|---|---|---|---|---|
| 写入文件 | Plugin API 能做的任何操作 | 有限 | 不支持——REST API 无法写入节点 | 固定的命令菜单 |
| 任意 Plugin API JavaScript | 支持(figma_eval) | 不支持 | 不支持 | 不支持 |
| 配额 / 登录 | 无 | 取决于套餐 | 令牌 + 速率限制 | 无 |
| 读回令牌、样式、组件 | figma_tokens、figma_metadata | 支持,包括 Code Connect | 部分支持 | 很少支持 |
| Agent 能否以图像形式查看设计 | 支持,直接显示在响应中 | 支持 | 提供文件或链接,不直接显示 | 不定 |
| 每个 Agent 步骤均可撤销、跟踪更改 | 支持 | 不支持 | 不支持 | 不支持 |
要求
- Node.js 18 或更高版本
- Figma 桌面应用——无法在浏览器中导入开发插件
- MCP 客户端:Claude Code、Cursor、Windsurf、Cline、Claude Desktop 等
安装(一次性)
npx -y localfig --setup
这会生成本地密钥,将插件写入 ~/.localfig/plugin/,在你计算机上找到的每个 MCP 客户端中注册 localfig,并打印下一步所需的清单路径。--dry-run 会显示将执行的操作,但不会进行任何更改;--clients=cursor,vscode 则只会处理你指定的客户端。想要克隆仓库?git clone https://github.com/LucasGorgal/localfig.git && cd localfig && node server.mjs --setup 执行相同操作。
| 客户端 | 安装程序注册 localfig 的位置 |
|---|---|
| Claude Code | claude mcp add --scope user |
| Claude Desktop | claude_desktop_config.json |
| Cursor | ~/.cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code(Copilot Agent 模式) | 用户级 mcp.json |
| Cline(扩展和 CLI) | ~/.cline/data/settings/cline_mcp_settings.json,或旧版本中的 VS Code 扩展存储 |
| Gemini CLI | ~/.gemini/settings.json |
| Codex | ~/.codex/config.toml |
| opencode | ~/.config/opencode/opencode.json |
| Zed | settings.json 中的 context_servers |
| LM Studio | ~/.lmstudio/mcp.json |
只要客户端的配置文件夹存在,就会被视为已安装。安装程序会合并到现有文件中,而非替换它们:其他服务和设置会保留,现有 localfig 条目中的 env 也会保留,并且在任何更改前都会创建 .localfig.bak 副本。对于无法安全重写的文件(例如带有注释的 settings.json),安装程序不会修改,而是报告需要粘贴的条目。重启所有已打开的客户端。
对于列表中没有的客户端,请将以下内容添加到其 MCP 配置中:
{ "mcpServers": { "localfig": { "command": "npx", "args": ["-y", "localfig"] } } }
在 Windows 上,请改用 "command": "cmd", "args": ["/c", "npx", "-y", "localfig"]:大多数客户端会在不使用 shell 的情况下启动服务,而 npx 在 Windows 上是一个 .cmd 脚本。
然后将插件导入 Figma(一次性):
- 在桌面应用中打开任意一个设计文件。Plugins 菜单只会在文件内显示,主屏幕上没有。
- 打开 Figma 菜单(左上角的徽标)→ Plugins → Development → Import plugin from manifest…,或按
Ctrl/(Cmd/)并输入 import plugin from manifest。 - 选择
~/.localfig/plugin/manifest.json(安装程序会输出完整路径)。
清单会请求两项权限——teamlibrary(库组件和令牌)和 currentuser(正在操作的用户)——并注册一个重新启动按钮。
使用(每次会话)
- 打开你要处理的文件。
- 运行插件:
Ctrl/→ localfig;也可以按CtrlAltP(CmdOptP)重新运行上一个插件,或点击已运行过该插件的文件属性面板中的 Reconnect localfig 按钮。MCP 服务启动后,会出现一个小面板并显示 Connected to localfig。请保持面板打开。 - 让你的 Agent 执行 Figma 相关工作。每个工具都会作用于插件运行所在的文件——这里没有文件键,因此不会触及云端。
关闭面板(或文件)会断开连接;重新运行插件即可重新连接。这是唯一需要手动执行的步骤:Figma 不提供从外部启动插件的方式。
工具
| 工具 | 功能 |
|---|---|
figma_status | 插件是否已连接?文件、页面、选区、顶层框架、当前操作者,以及是否支持动态代码执行 |
figma_eval | 在文件中运行任意 Plugin API JavaScript——核心工具 |
figma_metadata | 子树的结构转储:ID、名称、类型、几何信息和文本。styles: true 会为每个节点添加填充(十六进制值)、渐变色标、字体、效果、自动布局、绑定的变量、命名样式和组件信息;css: true 会为每个节点添加由 Figma 计算的 CSS |
figma_tokens | 所有本地变量集合及其模式和各模式的值,以及绘画 / 文本 / 效果样式 |
figma_find | 按类型、图层名称正则表达式和文本正则表达式搜索当前页面或所有页面 |
figma_changes | 自上次调用以来的更改——创建、删除、属性变更,以及逐节点摘要;工具调用所做的编辑默认会被标记并隐藏,因此这里显示的是用户在此期间在 Figma 中所做的操作 |
figma_history | snapshot:保存命名版本(还原点)。undo:撤销上次工具调用——每次修改操作都会作为一个撤销步骤创建检查点 |
figma_library | 团队库:列出变量集合及其变量,按键导入组件 / 样式 / 变量,并放置实例 |
figma_export | 将节点导出为磁盘上的 PNG/JPG/SVG/PDF/JSON。PNG/JPG 会以内嵌图片的形式返回;JSON(采用 Figma REST API 结构的子树)和 SVG 会以内嵌文本的形式返回 |
figma_place_image | 将本地图像放入节点的填充中。支持浏览器可解码的任意格式——PNG、JPG、WebP、GIF、BMP、AVIF。超过 4096px 的图像会自动缩小(maxSide) |
figma_eval 环境
代码在插件沙盒中运行,并包装在异步函数内:顶层 await 和 return 都可使用。
const n = await figma.getNodeByIdAsync('10:59'); // sync getNodeById is unavailable (dynamic-page access)
await helpers.setText(n.findOne(x => x.type === 'TEXT'), 'new copy');
helpers.reveal(n); // put it on the person's screen
return { id: n.id, w: n.width }; // JSON-serialized back to the agent
全局变量:figma 和 helpers。
helpers.createText({characters, font: {family, style}, fontSize, color: '#hex', width, lineHeight, letterSpacing, textCase, textAlign, name, parent, x, y})——加载字体,并确保先调用resize(),再设置textAutoResize。helpers.setText(node, chars)——先加载节点实际使用的字体,再设置字符。helpers.loadNodeFonts(node)。helpers.set(node, props)——批量赋值;先设置layoutMode,通过resize设置width/height,最后设置尺寸模式。helpers.rgb('#rrggbb')、helpers.rgba('#rrggbbaa')——将十六进制值转换为填充所需的{r, g, b[, a]}。helpers.reveal(nodes)——滚动并缩放视口,以显示刚创建的内容。helpers.notify(msg)——显示通知。helpers.collection(name, [modes])、helpers.token(collection, name, type, value | {mode: value})、helpers.bind(node, 'fills' | 'strokes' | prop, variable)——创建设计令牌并将属性绑定到令牌,每项各用一行代码。helpers.importComponent(key)、helpers.instance(key, parent, props)——使用团队库组件。helpers.query(root, sel)——支持最简选择器:TEXT、[name=X]、[name*=X]、A B、a, b。helpers.createAutoLayout(dir, props)。helpers.command(kind, payload)——在脚本中运行任意带类型的命令(tokens、metadata、find、changes、export……):(await helpers.command('tokens', { collection: 'Brand' })).result。
辅助工具会帮你避开的 Plugin API 陷阱
- 对 TEXT 节点调用
resize()会将textAutoResize重置为NONE;对自动布局框架调用时,会将两种尺寸模式都设为FIXED。先调整尺寸,再设置尺寸模式。 - 从
figma_eval返回普通数据。真实的 Figma 节点会折叠为{id, name, type},避免意外的节点引用导致结果过多——使用figma_metadata检查子树。 - 修改任何文本前都要先加载字体。
- 此处可以使用
figma.notify()(云端 MCP 会阻止此操作)。
设计系统感知
figma_tokens 会以设计系统的视角返回文件中的变量:
{ "collections": [{ "name": "Brand", "modes": ["Light", "Dark"], "defaultMode": "Light",
"variables": [{ "name": "color/bg", "type": "COLOR", "values": { "Light": "#ffffff", "Dark": "#04060c" } },
{ "name": "space/md", "type": "FLOAT", "values": { "Light": 16, "Dark": 16 } },
{ "name": "color/accent", "type": "COLOR", "values": { "Light": "{color/blue-500}", "Dark": "{color/blue-300}" } }] }],
"styles": { "paint": [...], "text": [...], "effect": [...] } }
figma_metadata 设置 styles: true 后,会针对每个节点报告 boundVariables(驱动各属性的令牌)、fillStyle / textStyle / effectStyle 名称,以及实例的主 component 和其 componentProperties;设置 css: true 则会添加 Figma 为每个节点计算出的 CSS。两者结合后,Agent 就能基于设计系统构建,而不是将值硬编码——并能从真实文件中交接代码。
图片
- 输入:
figma_place_image会将文件的字节数据发送到插件 UI;该 UI 是一个完整的 Chromium iframe。它会解码任何浏览器支持的格式,使用高质量平滑算法将图像缩小到maxSide(默认值为 4096,即 Figma 的硬性上限),将非原生格式转换为 PNG,然后将结果交给主线程。工具结果会报告处理情况(prepared)。 - 输出:
figma_export会将文件写入~/.localfig/exports/,并将 PNG/JPG(每个不超过 2 MB)作为图片附加到结果中,这样 Agent 无需再次调用就能看到渲染效果。JSON会以 Figma REST API 的格式导出子树。
撤销、版本和更改跟踪
每次修改工具调用都会通过 figma.commitUndo 创建检查点,因此它会在文件的撤销历史中成为一个步骤,用户可以按 Ctrl+Z 撤销(最近一次调用会在完成 60 秒后提交,或在下一次调用时提交)。在此时间窗口内,figma_history {action: "undo"} 会从 Agent 端撤销上一次调用——triggerUndo 会恢复到上一个检查点;{action: "snapshot"} 则会在进行有风险的编辑前保存一个命名版本。插件还会记录其访问过的每个页面上的节点更改(Figma 会在事后批量发送这些更改):figma_changes 会返回自某个 seq 以来发生的更改,通过时间窗口启发式方法判定由工具调用导致的编辑会标记为 byPlugin,且默认隐藏。这样,Agent 就能发现用户在两次调用之间对 Figma 所做的更改,而不是将其覆盖。
多个会话
第一个 localfig 进程会占用桥接端口;后续进程会通过 /health 检测到它,以客户端身份运行并通过它转发请求——两者使用的工具相同。如果所有者进程退出,客户端上的下一次工具调用会重新绑定端口并接管(日志中称为“re-election”);插件重新连接时会重新注册。
文件和配置
~/.localfig/
token local secret (generated on first run)
plugin/ manifest.json + code.js + ui.html — import THIS manifest into Figma
exports/ where figma_export writes
| 变量 | 默认值 | 说明 |
|---|---|---|
LOCALFIG_HOME | ~/.localfig | 令牌、插件和导出文件的存放位置 |
LOCALFIG_PORT | 8765 | 还需更改清单中的 networkAccess 并重新导入插件 |
LOCALFIG_OUT | ~/.localfig/exports | figma_export 写入文件的位置 |
node server.mjs --help 会列出所有标志。
安全性
桥接服务仅绑定到回环地址(127.0.0.1 和 ::1)。除 /health 外,每个端点都需要一个 32 位十六进制密钥;该密钥会在首次运行时生成到 ~/.localfig/token 中,并写入 ~/.localfig/plugin/ui.html。请编辑程序包中的 plugin/ui.template.html,切勿编辑生成的 ui.html。不会向任何服务器发送数据。
设计说明
- 为什么使用插件? 它是唯一一个能够完整读写已打开 Figma 文档的本地接口。REST API 在云端,需要令牌,而且无法写入节点。
- 为什么使用 HTTP 长轮询,而不是 WebSocket? 插件的主线程完全没有网络访问权限;只有 UI iframe 可以访问网络。长轮询无需依赖,也无需编写帧处理代码,而且
http://localhost不受混合内容拦截。Figma 的清单验证器会拒绝networkAccess中的原始 IP,因此使用localhost——以及 IPv6 镜像监听器,因为 Windows 会优先将localhost解析为::1。 - 二进制数据在插件通道中始终保持二进制格式。 导出数据通过
POST /blob发出;图像通过GET /asset以Uint8Array的形式传入。只有 JSON 会通过命令通道传输。(渲染结果只在 MCP 结果中进行一次 base64 编码,这是协议要求的。) - 为什么使用主目录? 软件包可能位于 npx 缓存中,也可能全局安装在只读位置;导入的插件文件夹在软件包更新时不能移动,而且每个用户的状态不应存放在软件包中。
平台说明
在 Windows 11 和 Figma 桌面应用上开发并测试。macOS 和 Linux 应该也能直接运行——仅使用 Node 内置模块,不含原生代码——但尚未实际测试。欢迎提交报告和修复。
测试
node test-e2e.mjs
在隔离的主目录中启动服务,通过 stdio 进行 MCP 通信,并通过 HTTP 模拟插件——覆盖握手、全部十个工具、文件往返、内联图像、所有者重新选举,以及针对沙盒化 MCP 客户端配置的设置过程,无需运行 Figma。共 55 项断言。
目录结构
server.mjs MCP (stdio) + bridge (http), single process; --setup, --help
plugin/manifest.json copied to ~/.localfig/plugin on start
plugin/code.js main thread: executes commands against the Plugin API
plugin/ui.template.html UI source; token/port get baked into ~/.localfig/plugin/ui.html
test-e2e.mjs end-to-end test without Figma
许可证
MIT — 详见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。