mcpField
O
open-pencil

open-pencil

github.com/open-pencil设计与 UI9.4k489 次安装今天更新
代码仓库

关于 open-pencil

OpenPencil 提供 CLI 和 MCP 服务,可检查和编辑 `.fig` 文件或编辑器中打开的文档。设计师和自动化工作流可搜索、分析、检查、转换及导出设计,并通过兼容 Figma Plugin API 的运行时执行 JavaScript。

主要功能

  1. 01检查并搜索设计节点
  2. 02分析与检查文档
  3. 03通过兼容 Figma Plugin API 的 JavaScript 编辑
  4. 04导出和转换设计文件
  5. 05管理变量、评论与状态
  6. 06控制正在运行的编辑器

适用场景

  1. 01查找并检查设计中的组件
  2. 02检查设计一致性与无障碍性
  3. 03将设计导出为图像、PDF 或 JSX
  4. 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/.fig
  • convert — 在支持的文档格式之间转换
  • analyze — 分析颜色、排版、间距和重复簇
  • lint — 检查一致性、结构和无障碍性
  • formats — 列出支持的文档和导出格式
  • eval — 使用 Figma Plugin API 执行 JavaScript
  • tool — 在应用模式或无头模式下,从 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 工作流
  1. 查找或打开文档 — 使用 list_documents 查看已打开的标签页及其 ID;使用 open_file { path } 打开有效文件系统根目录内的文件(list_recent_files 会列出该目录中最近打开的文件),或使用 new_document {} 新建文档。请显式传入 document_id 和 page_id,不要依赖当前活动标签页;当需要让用户看到某个标签页时,使用 activate_document { document_id } 将其置于前台。
  2. 查询 — get_page_tree、find_nodes、query_nodes、get_node、list_pages、get_current_page。
  3. 检查 — get_jsx、diff_jsx、diff_create、diff_visual、describe、export_image、export_svg、export_pdf。
  4. 修改 — 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")。
  5. 保存/导出 — 使用 save_file、export_image、export_svg、export_pdf,或 CLI export。
  6. 关闭 — 工作流完成后,使用 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 修改会实时反映在编辑器中。

评论

支持 Markdown