关于 open-pencil
OpenPencil 提供 CLI 和 MCP 服务,可检查和编辑 `.fig` 文件或编辑器中打开的文档。设计师和自动化工作流可搜索、分析、检查、转换及导出设计,并通过兼容 Figma Plugin API 的运行时执行 JavaScript。
主要功能
- 01检查并搜索设计节点
- 02分析与检查文档
- 03通过兼容 Figma Plugin API 的 JavaScript 编辑
- 04导出和转换设计文件
- 05管理变量、评论与状态
- 06控制正在运行的编辑器
适用场景
- 01查找并检查设计中的组件
- 02检查设计一致性与无障碍性
- 03将设计导出为图像、PDF 或 JSX
- 04自动修改已打开的文档
MCP 相关
MCP 服务向 MCP 客户端提供设计文档和运行中编辑器的自动化工具。支持 stdio 和 Streamable HTTP 连接。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ open-pencil/ open-pencil --skill open-pencil安装后在 Claude Code 中输入/open-pencil确认已加载。
附带文件LICENSE.txtreferences/design-authoring.md
详细介绍
OpenPencil
OpenPencil 为 .fig 设计文件和正在运行的 OpenPencil 编辑器提供 CLI 和 MCP 服务。
有两种模式:
- 应用模式 — 省略文件参数,即可连接正在运行的 OpenPencil 编辑器。
- 无头模式 — 传入文件路径,直接处理
.fig文件。
# App mode — operates on the document open in the editor
openpencil tree
# Headless mode — operates on a .fig file
openpencil tree design.fig
使用 openpencil --help、各命令的帮助信息以及已连接的 MCP 服务工具架构,查看已安装版本的功能。当前文档请参阅 CLI 参考 和 MCP 指南。
变量公式
在 eval 中,使用 openpencil.setVariableFormula('Spacing', 'large', '{base} * 2') 设置数值公式,或使用 openpencil.setVariableFormula('State', 'visible', '{viewport} > 1024 and not {loading}') 设置布尔公式;布尔公式支持 and、or、not 和数字比较。集合和变量必须已存在。可选的第四个参数按名称选择模式;否则会编辑默认模式。调用会在修改前验证,并返回解析后的值。长度公式使用存储的像素值。CSS 样式表会将数值公式写为 calc();设计令牌文件会在 $extensions 中保存公式及其结果。
变量遵循 Figma 的插件 API:figma.variables.getLocalVariables()、createVariable(name, collection, type)、variable.setValueForMode(modeId, value) 和 node.setBoundVariable(field, variable),使用 Figma 的字段名称(characters、width、paddingLeft)和类型;填充颜色通过 figma.variables.setBoundVariableForPaint 绑定。若要像图层面板那样绑定,请使用 openpencil.bindVariable(node, field, variable) 和 openpencil.unbindVariable(node, field),并采用 OpenPencil 的名称(text、visible、opacity、fills/0/color):文本内容使用文本或数值变量,并显示为文本;可见性则使用布尔或文本变量。openpencil 还可设置布局和文本方向(setLayoutDirection、setTextDirection)、设置 OkHCL 填充色(setFillOkHCL)和描边色(setStrokeOkHCL)、公开实例替换项(exposeInstanceSwap),并报告字体可用情况(getFontStatus());布尔运算和扁平化操作分别对应 Figma 的 figma.union、subtract、intersect、exclude 和 figma.flatten。
要求
# CLI
bun add -g @open-pencil/cli
# MCP server used by the desktop app and external MCP clients
bun add -g @open-pencil/mcp
在生产环境的 Tauri 构建中安装了 @open-pencil/mcp 全局包时,桌面应用会自动启动 openpencil-mcp-http,并在以下地址提供自动化功能:
- HTTP/RPC:
http://127.0.0.1:7600 - WebSocket 桥接:
ws://127.0.0.1:7601 - MCP Streamable HTTP:
http://127.0.0.1:7600/mcp
CLI 命令
openpencil --help
常用命令:
info— 文档概览:页面、节点数量、字体tree— 打印包含类型和尺寸的层级结构pages— 列出页面node— 按 ID 查看节点详细属性selection— 获取正在运行的应用中的当前选区find— 按名称或类型查找节点query— 使用 XPath 选择器搜索节点variables— 列出变量和集合tokens— 将变量导出为 CSS 自定义属性样式表、Tailwind v4 主题或 W3C 设计令牌文件(--format dtcg --out <folder>)export— 导出为 PNG/JPG/WEBP/SVG/PDF/JSX/.figconvert— 在支持的文档格式之间转换analyze— 分析颜色、排版、间距和重复簇lint— 检查一致性、结构和无障碍性formats— 列出支持的文档和导出格式eval— 使用 Figma Plugin API 执行 JavaScripttool— 在应用模式或无头模式下,从 shell 列出、描述并调用任意 MCP 工具documents— 在正在运行的应用中列出、打开、创建、保存、关闭和激活文档undo/redo— 在正在运行的应用中撤销 / 重做自己的(自动化)更改settings— 在正在运行的应用中读取和更改编辑器设置
检查
openpencil info design.fig
openpencil tree design.fig
openpencil tree --page "Components" --depth 3 # app mode
openpencil pages design.fig
openpencil node design.fig --id 1:23
openpencil node --id 1:23 # app mode
openpencil selection --json
openpencil variables design.fig
openpencil variables --collection "Colors" --type COLOR
openpencil tokens design.fig --format tailwind > theme.css
openpencil tokens design.fig --format dtcg --out tokens # W3C design tokens; import_design_tokens reads them back
搜索和 XPath 查询
openpencil find design.fig --name "Button"
openpencil find --type FRAME # app mode
openpencil find design.fig --type TEXT --page "Home"
openpencil find design.fig --name "Card" --type COMPONENT --limit 50
openpencil query design.fig "//FRAME"
openpencil query design.fig "//FRAME[@width < 300]"
openpencil query design.fig "//TEXT[contains(@name, 'Button')]"
openpencil query design.fig "//COMPONENT[@stackMode]"
openpencil query design.fig "//COMPONENT//FRAME//TEXT"
openpencil query "//FRAME[@width > 1000]" # app mode
常见节点类型:FRAME、TEXT、RECTANGLE、ELLIPSE、VECTOR、GROUP、COMPONENT、COMPONENT_SET、INSTANCE、SECTION、LINE、STAR、POLYGON、SLICE、BOOLEAN_OPERATION。
导出和转换
openpencil export design.fig -o hero.png
openpencil export -o hero.png # app mode
openpencil export design.fig --node 1:23 -s 2 -o [email protected]
openpencil export design.fig -f jpg -q 85 -o preview.jpg
openpencil export design.fig -f svg --node 1:23 -o icon.svg
openpencil export design.fig -f pdf -o page.pdf
openpencil export design.fig -f fig -o roundtrip.fig
openpencil export design.fig -f jsx -o component.jsx
openpencil export design.fig -f jsx --style tailwind -o component.tsx
openpencil export design.pen -f storybook -o src/stories --watch # stories + design images per component, re-exported on save
openpencil export 'src/**/*.pen' -f storybook --beside # stories next to each design file
openpencil export design.fig --thumbnail --width 1920 --height 1080
openpencil export --page "Components" -o components.png
openpencil convert design.fig -o design.pen
openpencil formats
分析和检查
openpencil analyze colors design.fig
openpencil analyze colors --similar --threshold 10 # app mode
openpencil analyze typography design.fig --group-by size
openpencil analyze spacing design.fig --grid 8
openpencil analyze clusters design.fig --min-count 3
openpencil lint design.fig
openpencil lint design.fig --json
openpencil lint design.fig --fix -o fixed.fig # bind matching color variables, round to whole pixels
在 MCP 和 AI 聊天中,lint 会列出发现的问题及其 fix 和 suggestions;lint_fix 会应用安全的修复,并应用每个问题的第一条建议(当 suggestions: true 时)。
Eval(Figma Plugin API)
使用兼容 Figma Plugin API 的运行时,对文档执行 JavaScript:
openpencil eval design.fig -c 'figma.currentPage.findAll(n => n.type === "TEXT").length'
# App mode — modifies the live document in the editor
openpencil eval -c '
const buttons = figma.currentPage.findAll(n => n.name === "Button");
buttons.forEach(b => { b.cornerRadius = 8 });
buttons.length + " buttons updated"
'
# Modify and save to the same file
openpencil eval design.fig -w -c '
const texts = figma.currentPage.findAll(n => n.type === "TEXT");
texts.forEach(t => { t.fontSize = 16 });
'
# Save to a different file
openpencil eval design.fig -o modified.fig -c '...'
# Read code from stdin
echo 'figma.currentPage.children.map(n => n.name)' | openpencil eval design.fig --stdin
# Style part of a text, and read how it is styled
openpencil eval design.fig -w -c '
const title = figma.currentPage.findOne(n => n.type === "TEXT" && n.name === "Title");
title.setRangeFontName(0, 5, { family: "Inter", style: "Bold" });
title.setRangeFills(0, 5, [{ type: "SOLID", color: { r: 0.9, g: 0.1, b: 0.1 } }]);
title.getStyledTextSegments(["fontName", "fills"]).map(s => [s.characters, s.fontName.style])
'
文本样式遵循 Figma 的逐字符模型:getStyledTextSegments(fields) 可读取文本段;getRange…/setRange… 可读取和设置 [start, end) 范围内的字体、字号、填充、字间距、行高、装饰、文本大小写、超链接、文本和填充样式 ID,以及绑定变量;当字符之间存在差异时,文本的 fontSize、fontName、fills 等属性会读取为 figma.mixed。使用该值前,请先检查是否为此值。所有位置的绘制对象都采用 Figma 的格式:纯色的 color 为 { r, g, b },透明度放在 opacity 中;图像为 { type: "IMAGE", imageHash, scaleMode: "FILL" | "FIT" | "CROP" | "TILE" },并可选包含 rotation 和 scalingFactor。
除 figma 外,脚本还会获取 openpencil:它以自己的风格扩展 Figma API。主组件可以根据自身的属性名和插槽名,表现为 Reka UI 控件:
openpencil eval design.fig -w -c '
const set = figma.currentPage.findOne(n => n.type === "COMPONENT_SET" && n.name === "Switch");
const thumb = set.findOne(n => n.name === "Thumb");
const behaviour = openpencil.setBehaviour(set, "switch")
.bindValue("value", "State") // On/Off guessed from the variant values
.bindPart("thumb", thumb); // the frame becomes a slot
behaviour.states = "Interaction";
behaviour.missing // [] when the control is complete
'
openpencil.behaviourKinds 会列出所有类型及其值和部件;openpencil.getBehaviour(node) 会读取某个类型(变体会读取其组件集的类型);openpencil.createSlot(frame) 会将一个画框设为插槽。MCP 中的 set_behaviour、get_behaviour 和 create_slot 工具执行相同操作;设计 JSX 使用 Reka 的元素名称编写控件(Switch.Root、Switch.Thumb)。
用户留在画布上的评论是可以据此采取行动的评审反馈。读取未处理的评论,修改设计,然后逐条回复并解决评论,并将自己设为作者:
openpencil eval design.fig -w -c '
openpencil.getComments({ resolved: false }).map(c => ({ id: c.id, text: c.text, layer: c.node?.name }))
'
# after the change:
openpencil eval design.fig -w -c 'openpencil.getComment("c_…").reply("Title is 24px now", { author: "Claude" }).resolve()'
openpencil.addComment(text, { node, page, x, y, author }) 会添加一条新评论。MCP 中对应的工具为 get_comments、add_comment、reply_to_comment 和 resolve_comment。评论内容采用 Markdown。
状态用于表示某个区段、画框、组件或实例所处的阶段,状态列表来自文档自身。读取列表,找出已就绪的状态,并在完成某个图层的工作后将其推进到下一状态:
openpencil eval design.fig -c 'openpencil.statuses.map(s => s.name)'
openpencil eval design.fig -w -c 'openpencil.setStatus(figma.currentPage.findOne(n => n.name === "Checkout"), "In review")'
openpencil.getStatus(node) 会读取某个状态。MCP 中对应的工具为 get_statuses 和 set_status。
差异比较
比较节点和文档,并应用补丁:
openpencil diff create design.fig --from 1:23 --to 1:87 # JSX attribute patch
openpencil diff jsx design.fig --from 1:23 --to 1:87 # JSX structure
openpencil diff show 1:24 design.fig --attributes 'rounded={8}' > fix.diff
openpencil diff apply fix.diff design.fig --dry-run # fails on stale values
openpencil diff apply fix.diff design.fig --write
openpencil diff visual design.fig --from 1:23 --to 1:87 -o diff.png
openpencil diff files before.fig after.fig # exit 1 when different
控制正在运行的应用
openpencil documents list --json # tab IDs, paths, pages
openpencil documents open designs/landing.fig # new tab; --json returns target.documentId
openpencil documents new --path designs/draft.fig
openpencil documents activate tab-123 --page-id 0:4 # bring a tab to the front
openpencil documents save --document-id tab-123
openpencil documents close --document-id tab-123 --save # or --discard; fails on unsaved changes otherwise
openpencil undo --document-id tab-123 # also: redo
openpencil settings get --json
openpencil settings set editing.snapping.pixelGrid false
tool 会公开所有 MCP 工具,因此 CLI 不会受其专用命令限制:
openpencil tool list
openpencil tool describe set_fill # JSON Schema for the arguments
openpencil tool call set_fill --document-id tab-123 --args '{"id":"0:5","color":"#2563eb"}'
openpencil tool call create_page design.fig --args '{"name":"Icons"}' --write # headless
所有报告结构化数据的命令都可在适用时使用 --json。
MCP 服务
Stdio MCP 客户端
默认使用 Bun:
{
"mcpServers": {
"open-pencil": {
"command": "bunx",
"args": ["openpencil-mcp"]
}
}
}
如果已全局安装 @open-pencil/mcp,也可以直接使用二进制文件:
{
"mcpServers": {
"open-pencil": {
"command": "openpencil-mcp"
}
}
}
HTTP / Streamable HTTP
export PORT=7600
export OPENPENCIL_MCP_ROOT=/path/to/files # explicitly limit filesystem access
openpencil-mcp-http
# or: bunx openpencil-mcp-http
默认启用身份验证,并自动生成令牌。OPENPENCIL_MCP_AUTH_TOKEN 可提供一个明确的非空令牌;设为空值则会禁用身份验证。如果浏览器访问需要 CORS,请将 OPENPENCIL_MCP_CORS_ORIGIN 设为受信任的来源。切勿同时使用通配符 CORS(*)和禁用身份验证。
在 Windows 上,CLI 默认将文件系统根目录设为主目录;在其他系统上,则设为当前工作目录。请将 OPENPENCIL_MCP_ROOT 设为明确且范围较窄的目录,而不要依赖该默认值。
MCP 工作流
- 查找或打开文档 — 使用
list_documents查看已打开的标签页及其 ID;使用open_file { path }打开有效文件系统根目录内的文件(list_recent_files会列出该目录中最近打开的文件),或使用new_document {}新建文档。请显式传入document_id和page_id,不要依赖当前活动标签页;当需要让用户看到某个标签页时,使用activate_document { document_id }将其置于前台。 - 查询 —
get_page_tree、find_nodes、query_nodes、get_node、list_pages、get_current_page。 - 检查 —
get_jsx、diff_jsx、diff_create、diff_visual、describe、export_image、export_svg、export_pdf。 - 修改 —
render、batch_update、update_node、set_fill、set_layout、create_shape、import_svg等。对于流程图,请用 Mermaid 编写并调用import_mermaid { mermaid }:它会自动排列 FigJam 形状、区块和连接线,避免重叠,并返回每个节点的图层 ID,而无需手动放置形状和连接线。当你创建的图层发生重叠时,调用arrange { ids }:它会将图层分散开,同时让它们保持在原来的位置附近。arrange还可以排列屏幕(mode: "pack"),并沿连接线排列形状(流程使用"flow",层级结构使用"tree",思维导图使用"radial",关系图使用"network")。 - 保存/导出 — 使用
save_file、export_image、export_svg、export_pdf,或 CLIexport。 - 关闭 — 工作流完成后,使用
close_file { document_id, unsaved }关闭文档标签页。存在未保存的更改时,除非unsaved为"save"或"discard",否则关闭会失败;自动化操作不会在应用中弹出提示。
使用 undo / redo { document_id } 撤销或重做你自己的更改。如果最新一步是用户在编辑器中执行的操作,这些工具会拒绝执行;切勿绕过此限制。get_settings 和 update_settings { settings } 用于读取和更改主题、语言、吸附等编辑器偏好设置;它们不会公开凭据、模型或工具访问权限。
浏览器原生 WebMCP(实验性)
WebMCP 默认处于关闭状态。在 Settings → MCP → WebMCP 中,选择 Inspect 以使用只读工具,或选择 Edit 以进行受限更改。这些控制项独立于本地 MCP 设置。支持的浏览器可通过 document.modelContext,直接从 OpenPencil 工作区提供检查功能,以及可撤销的现有图层、属性和变量编辑,无需连接 MCP 服务。请单独探索此浏览器功能:它不支持结构的创建/删除、任意 JS/JSX 执行、外部资源、文件系统操作和凭据。
调用会捕获活动文档/页面。取消操作可阻止编辑开始,但不会撤销已提交的编辑;请改用编辑器的撤销功能。原子编辑涉及的节点和变量总数不得超过 10,000;即使通过应用 AI/MCP 运行这些相同工具,也受此限制。有关适用范围和浏览器要求,请参阅 WebMCP 指南。
工具发现
用户可在 Settings → Tool access → Local MCP 中配置本地服务工具,该设置独立于 Built-in AI 工具偏好设置。更改本地 MCP 设置后,需要重启服务并重新连接 stdio 客户端;更改内置 AI 设置后,会从下一条消息开始生效。ACP 和 Pi Agent 使用 MCP 功能,而不是直接模型 AI 工具选择。工具开关并非沙箱:已启用的脚本工具仍可执行专用工具已禁用的操作。
请从已连接的服务或浏览器中发现可用工具及其参数;工具可用性会因版本和模式而异。每个工具的架构、执行和暴露元数据均为权威信息。数值输入始终接受数字或数字字符串,但会拒绝非有限值。不要依赖固定的工具数量或复制来的工具清单。
工具可用性可能取决于服务模式。
open_file、save_file和写入磁盘的导出路径受有效文件系统根目录限制;请使用OPENPENCIL_MCP_ROOT显式设置该目录。
面向 Agent 的关键工具
query_nodes— 使用 XPath 选择器查找特定节点,无需获取完整树。get_jsx— 以render接受的相同格式,将任意节点检查为 JSX。diff_jsx/diff_create— 以 JSX 行差异或可应用的 JSX 属性补丁形式比较两个节点;diff_show可预览属性设置,diff_apply仅在节点仍与补丁匹配时应用补丁。diff_visual— 比较两个渲染节点的像素差异;用它确认编辑只更改了预期区域。describe— 对角色、视觉样式、布局和设计问题进行语义分析。batch_update— 高效应用多个节点更新。export_image/export_svg/export_pdf— 用于视觉验证和交付。viewport_zoom_to_fit/viewport_set/viewport_get— 仅在用户要求展示内容时移动用户视图。get_codegen_prompt— 获取 OpenPencil 当前的 JSX / 代码生成指南。undo/redo— 撤销或重做最新更改;不会触碰用户的编辑。list_documents/activate_document— 查找已打开的标签页,并显示你处理过的标签页。
JSX 渲染
创建或修改 JSX 设计前,请阅读 设计创作指南。此打包参考资料根据 Core 的创作指南、经过测试的示例和渲染器元数据生成,也是聊天和代码生成提示词使用的同一份参考资料。
对 JSX 字符串使用 render 工具。仅使用已安装的 eval 环境公开的 API;原生库导出不会自动成为脚本全局变量。已连接服务的 get_codegen_prompt 会提供其版本对应的代码生成和创作指南。
提示
- 省略文件路径,即可处理正在运行的 OpenPencil 编辑器中打开的文档。
- 从
info或get_page_tree开始,了解文档。 - 对大型文件使用
tree --depth 2或query_nodes,以避免输出过多内容。 - 使用
--node导出特定节点,以加快视觉检查。 - 更改后使用
export_image验证视觉质量。 - 运行中的编辑器会将每个 MCP 会话显示为一个 Agent,位于其工具触及的图层,并在用户启用“跟随 Agent”后跟随其操作。除非用户要求展示内容,否则不要更改用户的选区和视图。
- 使用
analyze colors --similar查找近似重复的颜色。 - 对于没有专用 CLI 命令的 MCP 工具,使用
openpencil tool call;对于工具未涵盖的 Figma Plugin API 操作,使用eval。 - 通过管道将 CLI 输出传递给脚本时,使用
--json。 - 在应用模式下,
eval和 MCP 修改会实时反映在编辑器中。