关于 mokido
mokido 是面向编码 Agent 的零依赖 MCP 服务,可直接在实时 Figma 画布上进行设计。它支持沙箱中的任意 JavaScript 写入、返回渲染截图供视觉检查,并可回滚修改。
主要功能
- 01读取和写入实时 Figma 画布
- 02画布修改后返回 PNG 截图
- 03回滚 Agent 的写入检查点
- 04以紧凑形式检查实时文档结构
- 05在文档中运行持久化代码模块
- 06通过状态等待处理长时间任务
适用场景
- 01让 Agent 创建并视觉检查 Figma 布局
- 02检查生成的设计是否溢出或对比度过低
- 03撤销意外的画布编辑
- 04无需云端令牌即可检查打开的文档
MCP 相关
mokido 通过 stdio 使用 MCP 与 Agent 通信,并通过 WebSocket 连接 Figma 插件。提供未打开文件的云端 REST 工具需要配置 Figma personal access token。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
⚡ Mokido
用于 Figma 设计的 MCP 服务。让 AI Agent 在 Figma 中设计,并实际查看它绘制的内容。
原名为 figma-mcp-bridge(npm 上的 @kolganovr/figma-mcp-bridge)。旧链接会重定向到此处。
零依赖的 MCP 服务,为编码 Agent 提供对实时 Figma 画布的读写权限,然后将渲染后的 PNG 返回给模型进行视觉自我审查,形成闭环。

Agent 生成设计、目视检查渲染结果、检测布局缺陷,并实时自我修正——整个过程无需人工介入。
问题所在
编码 Agent 在 Figma 中基本上是盲目的。大多数 Figma MCP 服务都是只读的——它们会将设计转换为文本,供模型据此编写代码,然后交互就此结束。能够写入的服务,要么需要付费 Figma 席位并受每月工具调用配额限制,要么只提供固定的命令集合(create_rectangle、set_fill),一旦任务稍微具体一些就无法满足需求。
而且,没有任何一种服务能回答写入之后真正重要的问题:效果看起来对吗? 一个绘制卡片后收到 {"ok": true} 就继续执行的 Agent,无法发现文本溢出、对比度不合格,或画框覆盖了其他人的作品。
这个桥接服务不仅能闭合这一反馈环路,还加入了自主 Agent 要安全操作真实设计文件所需的防护措施。
有何不同
| 此桥接服务 | Figma Dev Mode MCP(官方) | Framelink | Talk to Figma | |
|---|---|---|---|---|
| 写入画布 | ✅ 沙箱中可运行任意 JS | ✅ 代码转画布 | ❌ 只读 | ✅ 固定命令集 |
| 视觉反馈环路 | ✅ 写入后自动生成适配画面的 PNG(capture: true) | ⚠️ 需要单独调用截图 | ❌ | ❌ |
| 撤销 Agent 的操作 | ✅ figma_rollback | ❌ | 不适用 | ❌ |
| 支持 Figma Free 计划 | ✅ | ❌ 需要 Dev/Full 席位和付费计划¹ | ✅ | ✅ |
| 工具调用配额 | 无——在本地运行 | Starter 席位每月 6 次¹ | 遵循 REST 速率限制 | 无 |
| 对实时文档进行令牌优化读取 | ✅ 减少 86–91%² | ⚠️ 部分支持 | ❌ 仅支持 REST | ❌ |
| 沙箱内持久化代码模块 | ✅ bridge.define/require | ❌ | ❌ | ❌ |
| 长任务可在自身超时后继续运行 | ✅ 异步 job_id,等待时仅阻塞一次 | ❌ | 不适用 | ❌ |
| 每次调用的令牌预算 | ✅ 限制文本、调整图像大小、精简 JSON | ❌ | ⚠️ 仅适用于读取端 | ❌ |
| 安装占用 | 0 个 npm 依赖,可用 npx 或 git clone,仅需 Node | Figma 桌面应用 + 付费席位 | npx + 访问令牌 | Bun + 第二个服务进程 |
简而言之: 如果你只想将现有设计转换为代码,Framelink 是最佳选择。如果你已经订阅了付费 Figma 计划并需要 Code Connect,官方服务是最稳妥的选择。如果设计工作由 Agent 负责,那么此桥接服务就是为这种场景打造的——它需要自由写入、检查自己的成果,并在出错时能够撤销操作。
工作原理
flowchart LR
subgraph AI ["🤖 Coding Agent"]
LLM["Claude Code · Cursor<br/>Antigravity · Windsurf"]
end
subgraph Bridge ["⚡ MCP Server — Node.js, 0 deps"]
Router["Tool Router<br/>+ Job Ledger<br/>+ Target Router"]
Opt["Token Optimizer<br/>REST + LIVE"]
end
subgraph Figma ["🎨 Figma Desktop"]
Plugin["Bridge Plugin<br/>Checkpoint Journal<br/>Component Index"]
Canvas["Live Canvas"]
end
LLM -->|"stdio JSON-RPC"| Router
Router <-->|"WebSocket :8765"| Plugin
Plugin -->|"execute in sandbox"| Canvas
Canvas -->|"export PNG"| Plugin
Plugin -->|"raw node tree"| Opt
Opt -.->|"86% smaller"| LLM
Plugin ==>|"screenshot + warnings"| LLM
Agent 通过 stdio 使用纯 MCP 通信。服务通过手写的 RFC 6455 WebSocket 监听
:8765,Figma 插件会连接到这里——因此命令可以直接到达画布,无需承受轮询延迟,
结果(包括数 MB 的 base64 PNG)也会直接流式传回。
快速开始
npx mokido
或者,如果你想先查看安装脚本,再让它接触你的机器——脚本本身相同,只是获取方式 不同:
git clone https://github.com/kolganovr/mokido.git
cd mokido
node install.mjs
两种方式都会安装服务和插件,并在找到的每个 AI 客户端配置中注册 MCP 服务——Claude Desktop、Claude Code、Cursor、Windsurf、Antigravity。npm 包的存在纯粹是为了让第一条命令更短;它不会增加任何运行时依赖——它的 package.json 中 dependencies 也为空,也不需要 Python。node 是此项目唯一需要的运行时,安装程序和服务都如此。
然后,在 Figma Desktop 中:
- Plugins → Development → Import plugin from manifest… → 选择
figma-plugin/manifest.json - 按
Ctrl + Alt + P(macOS:Cmd + Option + P)启动 Mokido - 状态变为绿色——
CONNECTED
重启 AI 客户端,让它加载新工具。随时可以用以下命令验证:
npx mokido --doctor # or: node install.mjs --doctor
可选:Figma Cloud REST 访问
实时画布工具无需令牌。如果你还想读取未打开的云端文件
(get_file、get_node、get_styles 等),请提供个人访问令牌:
npx mokido --token "your_figma_personal_access_token"
# or: node install.mjs --token "your_figma_personal_access_token"
没有令牌时,这 7 个工具不会注册——参见工具参考。
它能为 Agent 做什么
1. 自由编写,然后查看结果
capture: true 会返回一张 PNG,显示本次调用刚创建或修改的内容——自动将视图框定到
已更改的节点,而不是整个页面,也绝不会劫持用户的选区。
// agent calls figma_execute_code
{ "code": "const f = figma.createFrame(); /* ... */ return f.id;", "capture": true }
// agent gets back — text + image in one response
{
"ok": true,
"created": ["12:34"],
"warnings": ["Text \"Total\" has ~3.1:1 contrast against its parent fill (WCAG AA wants 4.5:1)."],
"checkpoint_id": "cp_mfk3p2a_7",
"duration_ms": 840
}
warnings 数组会对已触及的子树进行快速自动检查——文本溢出、对比度过低、节点尺寸为零。它能无需额外往返获取截图,就捕捉到明显错误。
2. 撤销 Agent 执行的任何操作
每次写入都会自动创建检查点。一次调用即可撤销——不会用 Ctrl+Z 撤销到人类自己所做的无关修改。
// agent calls figma_rollback
{ "checkpoint_id": "last" }
// gets back
{
"ok": true,
"checkpoint_id": "cp_mfk3p2a_7",
"label": "Generate checkout flow",
"removed": ["12:34", "12:35"], // nodes the call created — deleted
"restored": ["9:11"], // nodes it modified — properties put back
"missing": [] // ids that no longer exist
}
创建的节点会通过 figma.create*() 外层的 Proxy 自动跟踪。属性编辑会在快照时跟踪。删除操作会如实报告为不可恢复,而不是悄悄丢失。
3. 读取实时画布只需约 700 个 token,而非约 5,000 个
云端工具所用的精简 + Pseudo-JSX 流水线也可用于读取当前打开的内容。在一个符合实际情况的 6 卡片布局上测得:20 KB 原始 API JSON → 2.7 KB(缩小 86%)。
<Frame id="1:1" name="Landing" w="1440" h="900" row gap="20">
<Frame id="2:0" name="Card" w="300" h="200" col gap="12" pad="20" bg="#FFFFFF" radius="16">
<Icon id="3:0" name="ic_check" size="24" strokeWidth="2" />
<Text id="4:0" color="#1A1A1F" font="Inter 18px">Feature 0</Text>
</Frame>
</Frame>
budget_tokens 会限制响应大小:如果请求的深度超出限制,服务会将已获取的树重新序列化为更浅的结构——无需第二次往返——并附加注释,说明执行了什么操作,以及要获取更多内容时应使用的 id。
4. 为沙盒添加重启后仍能保留的新本领
每次 figma_execute_code 调用都会创建一个全新的函数作用域,因此辅助函数通常会立即消失。
bridge.define 会在 .fig 文档内部编译并存储模块:
// once
bridge.define("kit", `
async function label(parent, text) { /* ... */ }
module.exports = { label };
`);
// in any later call — including next week, after a Figma restart
const { label } = bridge.require("kit");
5. 超时后仍可继续运行的长任务
如果生成任务在 45s 后仍在运行,系统会返回 job_id,而不是报错;插件会继续工作。随后,figma_job_status 会阻塞,直到任务完成(最长等待 wait_ms,默认 45s)——一次调用即可,无需轮询循环。任务运行期间会附带 progress(step, of, note) 提供的进度;静默 2 分钟的任务会标记为 stalled,插件断开连接的任务则会立即以 PLUGIN_DISCONNECTED 失败,而不是一直等到超时。如果调用在仍有任务运行时超时,系统会说明这一情况(PLUGIN_BUSY,并注明任务),而不是让你盲目重试。
6. 为 Token 账单而打造
在 Agent 循环中,一次工具调用要付两次成本:一次是在它返回时,另一次是在之后的每一轮,因为它的输出会保留在每轮都要重新读取的上下文中。因此,这个桥接工具优先考虑减少轮数和缩小残留内容:
| 默认值 | 原因 | |
|---|---|---|
| 截图 | scale: 1,最长边为 max_px: 1024,每次调用最多 4 张图片 | 图片 Token 数随像素面积增长(约为 w·h/750);每张图片都会描述为 800x600 ~640tok |
插入/模式工具上的 capture | 关闭 | 自动 lint 的 warnings 能捕获机械性缺陷,无需图片 |
| 文本结果 | 紧凑 JSON;每个响应都通过结构化缩减控制在 max_output_bytes(3500 个 UTF-8 字节,整个信封)以内;请求值超过 3900 字节上限时会被截到该上限,0 = 无限制 | 某些客户端(Antigravity)会将超过约 4 KB 的输出写入文件,模型必须额外调用才能打开;完整值仍保留在 bridge.state.lastResult 中 |
| 低成本读取 | figma_inspect(每次调用可传多个 ID),以及代码中的 bridge.summarize / inspect / find / check | 使用逐节点一行的概要和通过/失败列表,而不是每次调用都手动编写转储 |
| 插件重新加载 | 调用会等待插件重新连接,最长 8 秒 | 一次失败会耗费一轮来读取错误,再耗费一轮重试 |
| 服务指令 | 约 1.9k 个字符,优先放置节省用量的规则 | 某些客户端会在约 2000 个字符处截断指令 |
每个默认值都可按调用覆盖,也可通过环境变量按安装覆盖:FIGMA_MCP_SCALE、
FIGMA_MCP_MAX_PX、FIGMA_MCP_MAX_IMAGES、FIGMA_MCP_MAX_OUTPUT_BYTES、FIGMA_MCP_MAX_OUTPUT_CEILING(0 = 无上限)、FIGMA_MCP_JOB_WAIT_MS、
FIGMA_MCP_ESCALATE_MS、FIGMA_MCP_RECONNECT_GRACE_MS。
更新内容
4.2.7:compare / like 的差异结果以一行 REF 结尾,其中包含精确的参考值,让 Agent 无需额外读取 props 就能修复副本;find 会返回找到内容的子树;view: "flow" 无需 node_ids 即可使用;bridge.setText 会保留混合字体。在内部基准测试中(Gemini Flash,使用种子任务),每个系列的模型轮数从 112 降至 83,写入后的验证轮数从 11 降至 1。更新后请重新加载 Figma 插件。
历史记录:CHANGELOG.md。
工具参考
工具分为多个层级提供,因此每轮发送给模型的架构列表大小会与实际可用工具的数量相称:
| 层级 | 数量 | 注册条件 |
|---|---|---|
| Core | 8 | 始终 |
| Extended | 5 | 始终 |
| REST | 7 | 仅在设置了 FIGMA_PERSONAL_ACCESS_TOKEN 时 |
| Legacy | 3 | 仅在设置了 FIGMA_MCP_LEGACY_TOOLS=1 时 |
没有 REST Token 时,Agent 看到的是 13 个工具,而不是 23 个,也不会浪费调用去尝试只会返回 REST_TOKEN_MISSING 的工具。
全部 23 个工具
#### 核心 — 实时画布| 工具 | 描述 |
|---|---|
figma_execute_code | 在 Figma 沙盒中运行 JS。注入 figma、ensureFont、getFreePosition、progress、bridge。支持 capture、capture_node_ids、diff、max_px、max_output_bytes、async、target。 |
figma_inspect | 一次读取多个实时节点:紧凑大纲(或使用 view: "map" 查看画布地图)、精确的 props(包括 reactions、connector)、按名称 find / 按文本 find_text、context(祖先区段、断点、组件变体)、offset 分页,或检查 check 预期值(仅显示不匹配项)。不会更改任何内容。 |
figma_read_canvas | 以优化 token 的方式读取实时文档(jsx / tree / json),可设置 budget_tokens(默认值:服务端的字节预算)。 |
figma_screenshot | 将指定的 node_ids 或当前选区导出为 PNG,尺寸由 max_px 控制。 |
figma_find_components | 在缓存中搜索组件,支持 token 化和模糊搜索,包括变体、属性和键。 |
figma_insert_component_instance | 插入组件/变体实例、应用文本覆盖,并将其放入 AutoLayout。 |
figma_insert_svg | 插入原始 SVG,支持等比缩放、重新着色和可选的组件封装。 |
figma_get_variables | 变量集合、模式和 token 值。 |
figma_rollback | 撤销先前写入调用的检查点。 |
扩展 — 实时画布
| 工具 | 描述 |
|---|---|
figma_get_selection | 获取选区的几何信息、紧凑的十六进制填充色、父级/页面和 AutoLayout 上下文。 |
figma_get_canvas_layout | 画板边界和安全的 suggestedNextPosition。layout:"grid" 会以货架式布局排列。 |
figma_set_variables_mode | 在某个画框或页面上切换主题模式(Dark/Light/Brand)。 |
figma_job_status | 等待已升级的后台任务完成(阻塞式,使用 wait_ms)。 |
figma_list_targets | 列出已连接的 Figma 文档,以便进行多文件目标选择。 |
REST — Figma Cloud(需要 token)
| 工具 | 描述 |
|---|---|
get_file / get_node | 以优化 token 的方式获取云端文件/子树。支持 budget_tokens。 |
get_image | 使用 Figma 的渲染器将节点渲染为 PNG/SVG/PDF。 |
get_styles / get_components | 已发布的样式和设计系统组件。 |
get_comments / post_comment | 读取和发布文件评论。 |
旧版 — 通过 FIGMA_MCP_LEGACY_TOOLS=1 启用
figma_create_ui_card · get_me · get_image_fills
工程说明
那些看起来简单、实际却更难的部分,以及代码为何采用这种设计。
Figma 沙盒中的 `eval` 是个陷阱
在调用之间保留辅助函数,最直接的做法是“暂存源码,下次再用 eval 执行”。但这种方式会静默失败:eval 在 Figma 的沙盒中是一个绑定函数,按规范,每次调用都是一次间接 eval — 其中的声明既不会进入调用方作用域,也不会进入 globalThis。什么都不会定义,也不会抛出异常。
bridge.define 则基于 new Function 实现,其函数体拥有普通的函数作用域。运行时的 bridge.info() 会按需向 Agent 说明这一约定,因此 Agent 可以主动询问,而不必猜测。
有意手写 RFC 6455 WebSocket
这里零 npm 依赖并非为了好看 — 这意味着在没有 registry 访问权限的受限机器上,git clone && node install.mjs 也能正常运行,而且无需审核那些会在设计文件中执行任意 JS 的依赖链。
代价是必须自行处理帧:掩码、分片延续帧(一张 4 MB 的截图会拆成多个片段;如果把每个片段都当作完整消息处理,数据就会被静默丢弃,直到 40s 后工具调用超时)、ping/pong 保活,以及 64 MB 上限,防止单个帧耗尽内存。
按 UTF-8 字节而非字符串长度对 `pluginData` 分块
Figma 将 `pluginData` 条目的上限设为约 100 KB——按**字节**计算。原来的分块器按 JS 字符串长度切分,因此用西里尔字母写的模块(约 2 字节/字符)会生成“60,000 字符”的分块,实际大小却是 120 KB,导致 `setPluginData` 抛出错误。现在,拆分器会按实际 UTF-8 大小预算遍历,且不会拆开代理对。端口所有权必须可以重新取得
每个 Agent 都会启动一份独立的服务;最先绑定 :8765 的实例拥有插件套接字,其余实例则通过它进行代理。所有者退出后,代理必须能够接管,否则所有仍在运行的 Agent 都会一直无法使用,直到重启。5 秒看门狗会重试绑定,代理调用失败时则会立即尝试接管。
让放置复杂度从 O(邻近节点数) 而非 O(n)
原来的碰撞引擎会针对最多 200 个候选位置中的每一个,重新扫描所有顶层节点;同一个时间片内还会在另一个函数中再做一次——而且它始终只沿一个轴移动,因此生成的 20 个屏幕会排成一条长带,根本无法缩放到足以看清全貌。
现在,边界只计算一次并由各处共享;碰撞检测通过 500px 网格哈希进行;layout:"grid" 会以货架式布局将内容紧凑地排列成矩形。
错误信息能告诉 Agent 接下来该怎么做
原始 Plugin API 错误一向难以理解。系统会将失败与已知模式进行匹配,并重写错误信息,添加一行 HINT:,指出实际可用的 API;同时附上稳定、机器可读的 code(FONT_NOT_LOADED、INSTANCE_TRANSFORM_LOCKED、STALE_NODE_ID、AUTOLAYOUT_HUG_RESIZE、AMBIGUOUS_TARGET 等),让 Agent 和工具无需解析文本即可根据失败类型执行不同处理。
安全:此端点会在你的设计文件中运行任意 JS
:8765 仅监听回环地址,但用户恰好打开的任何网页都能访问回环地址。我们设置了两道独立的防线:Origin 允许列表(浏览器无法伪造 Origin,因此来自 evil.com 的网页会在握手阶段被拒绝),以及共享令牌。install.mjs 会生成该令牌,并将其写入 MCP 配置和已安装的插件中——这也能覆盖沙盒 iframe 的情况,因为恶意网页同样可以发送 Origin: "null"。
如果直接从克隆的代码库运行且没有令牌,Origin 检查仍然生效,服务会打印警告,因此安全性会有所降低,但不会在无提示的情况下开放访问。
此服务唯一主动发起的网络请求:检查更新
启动时,服务会将安装时所用的提交(由 install.mjs 记录在复制后的代码旁边的 version.json 中)与 main 分支上的最新提交进行比较。它通过一次 GitHub API 请求完成检查;如果提交不同,就会向 stderr 打印一行提示。服务绝不会自行应用任何更新——node install.mjs --update 仍然是一个需要手动、有意执行的步骤。
这是本项目中唯一假定可以访问网络的功能,因此设计上会在网络不可用时妥善停用:检查会在不等待结果的情况下发起(不会延迟 initialize 或首次工具调用),请求失败、耗时过长或离线时都会被捕获并静默跳过;结果会缓存 24 小时,避免触及 GitHub 未认证请求的速率限制,也避免服务的每个副本启动时都请求一次。设置 FIGMA_MCP_NO_UPDATE_CHECK=1 即可彻底关闭此功能——在上一条提到的受限机器上,这么做很有必要。
测试
七个无需依赖的测试套件,均可直接使用 node 运行:
node tests/bridge-runtime.test.js # sandbox runtime, module persistence, checkpoint/rollback
node tests/layout-packer.test.js # row/grid packing, collision grid
node tests/optimizer.test.js # jsx/tree/json serialization, budget truncation
node tests/mcp-protocol.test.js # real server over stdio: initialize, tools/list, tiering
node tests/install.test.js # config merge/reuse, token persistence, stale-file cleanup
node tests/token-economy.test.js # fake plugin over a real WebSocket: budgets, long-poll, proxy
node tests/output-shrink.test.js # line-wise shrinking, offset paging, output ceiling, syntax pre-check
mcp-protocol.test.js 会将实际服务作为子进程启动,并通过 NDJSON 与之通信——这与真正的 MCP 客户端使用的传输方式相同,而不是导入内部实现。
仓库结构
mokido/
├── figma/ # MCP server (Node.js, stdio + WebSocket)
│ ├── index.js # protocol, tool router, job ledger, target router
│ ├── optimizer/ # AST pruner, style collapser, JSX/tree serializers
├── figma-plugin/ # Figma Desktop plugin
│ ├── code.js # sandbox executor, bridge runtime, checkpoints, capture
│ └── ui.html # HUD — stream, settings, control (pause / undo)
├── docs/GUIDE.md # long-form agent guide (server instructions are inline in index.js)
├── tests/ # 7 suites, 0 dependencies
├── install.mjs # cross-platform installer, updater, doctor (Node only)
└── AGENTS.md # onboarding protocol for AI agents
来源
- 官方服务的席位和配额要求 — Figma:Figma MCP 服务指南,Figma 开发者文档:速率限制与访问
- 在一个模拟真实 REST 输出的 6 卡片布局测试样例上测得的令牌减少量:20,587 B 原始数据 → 2,862 B Pseudo-JSX(86.1%)/ 1,912 B 树结构(90.7%)。该测试样例已纳入代码库并有断言 — 运行
node tests/optimizer.test.js即可复现准确数据。
对比反映了截至 2026 年 8 月公开记录的行为。替代方案仍在积极开发中 — 请先核实当前功能,再仅依据此表做出决定。
许可证
MIT · 由 Roman Kolganov 构建
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。