open-pencil
CLI 和 MCP 服务器,直接操作 Figma 设计文件,支持 Headless 模式批量处理设计资源,提取设计规范和组件信息
npx skills add open-pencil/skills --skill open-pencilBefore / After 效果对比
1 组手动打开 Figma 逐个查看设计文件,复制粘贴样式代码,容易遗漏细节,批量导出需要数小时操作
命令行直接读取.fig文件,自动提取设计令牌、组件代码和样式规范,批量处理多个文件,几分钟完成
description SKILL.md
open-pencil
OpenPencil
CLI and MCP server for .fig design files. Two modes of operation:
-
App mode — connect to the running OpenPencil editor (omit the file argument)
-
Headless mode — work with .fig files directly (pass a file path)
# App mode — operates on the document open in the editor
bun open-pencil tree
# Headless mode — operates on a .fig file
bun open-pencil tree design.fig
The app exposes an automation bridge on http://127.0.0.1:7600 when running. The CLI auto-connects to it when no file path is provided.
CLI Commands
Inspect
# Document overview — pages, node counts, fonts
bun open-pencil info design.fig
# Node tree — shows hierarchy with types and sizes
bun open-pencil tree design.fig
bun open-pencil tree --page "Components" --depth 3 # app mode, specific page
# List pages
bun open-pencil pages design.fig
# Detailed node properties — fills, strokes, effects, layout, text
bun open-pencil node design.fig --id 1:23
bun open-pencil node --id 1:23 # app mode
# List design variables and collections
bun open-pencil variables design.fig
bun open-pencil variables --collection "Colors" --type COLOR
Search
# Find by name (partial match, case-insensitive)
bun open-pencil find design.fig --name "Button"
# Find by type
bun open-pencil find --type FRAME # app mode
bun open-pencil find design.fig --type TEXT --page "Home"
# Combine filters
bun open-pencil find design.fig --name "Card" --type COMPONENT --limit 50
XPath Query
Find nodes using XPath selectors — filter by type, attributes, and tree structure:
# All frames
bun open-pencil query design.fig "//FRAME"
# Frames narrower than 300px
bun open-pencil query design.fig "//FRAME[@width < 300]"
# Text with "Button" in the name
bun open-pencil query design.fig "//TEXT[contains(@name, 'Button')]"
# Components with auto-layout
bun open-pencil query design.fig "//COMPONENT[@stackMode]"
# Deeply nested — text inside frames inside components
bun open-pencil query design.fig "//COMPONENT//FRAME//TEXT"
# App mode
bun open-pencil query "//FRAME[@width > 1000]"
Node types: FRAME, TEXT, RECTANGLE, ELLIPSE, VECTOR, GROUP, COMPONENT, COMPONENT_SET, INSTANCE, SECTION, LINE, STAR, POLYGON, SLICE, BOOLEAN_OPERATION
Export
# PNG (default)
bun open-pencil export design.fig -o hero.png
bun open-pencil export -o hero.png # app mode — exports from running editor
# Specific node at 2x
bun open-pencil export design.fig --node 1:23 -s 2 -o button@2x.png
# JPG with quality
bun open-pencil export design.fig -f jpg -q 85 -o preview.jpg
# SVG
bun open-pencil export design.fig -f svg --node 1:23 -o icon.svg
# JSX (OpenPencil format — renderable back into .fig)
bun open-pencil export design.fig -f jsx -o component.jsx
# JSX (Tailwind — React component with Tailwind classes)
bun open-pencil export design.fig -f jsx --style tailwind -o component.tsx
# Page thumbnail
bun open-pencil export design.fig --thumbnail --width 1920 --height 1080
# Specific page
bun open-pencil export --page "Components" -o components.png
Analyze
# Color palette — usage frequency, similar colors
bun open-pencil analyze colors design.fig
bun open-pencil analyze colors --similar --threshold 10 # app mode
# Typography — font families, sizes, weights
bun open-pencil analyze typography design.fig --group-by size
# Spacing — gap and padding values, grid compliance
bun open-pencil analyze spacing design.fig --grid 8
# Clusters — repeated patterns that could be components
bun open-pencil analyze clusters design.fig --min-count 3
Eval (Figma Plugin API)
Execute JavaScript against the document using the full Figma Plugin API:
# Read-only — query the document
bun open-pencil eval design.fig -c 'figma.currentPage.findAll(n => n.type === "TEXT").length'
# App mode — modifies the live document in the editor
bun open-pencil 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 file
bun open-pencil 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
bun open-pencil eval design.fig -o modified.fig -c '...'
# Read code from stdin
echo 'figma.currentPage.children.map(n => n.name)' | bun open-pencil eval design.fig --stdin
The eval environment provides figma with the Figma Plugin API: figma.currentPage, figma.createFrame(), figma.createText(), figma.getNodeById(), etc.
JSON Output
Every command supports --json for machine-readable output:
bun open-pencil info design.fig --json
bun open-pencil find --name "Button" --json # app mode
bun open-pencil analyze colors design.fig --json
MCP Server
Stdio (Claude Desktop, Cursor)
Add to your MCP config:
{
"mcpServers": {
"open-pencil": {
"command": "npx",
"args": ["openpencil-mcp"]
}
}
}
HTTP (multi-session, remote)
export PORT=3100
export OPENPENCIL_MCP_AUTH_TOKEN=secret # optional auth
export OPENPENCIL_MCP_CORS_ORIGIN="*" # optional CORS
export OPENPENCIL_MCP_ROOT=/path/to/files # restrict file access
npx openpencil-mcp-http
MCP Workflow
-
Open a file —
open_file { path: "/path/to/design.fig" }ornew_document {} -
Query —
get_page_tree,find_nodes,query_nodes,get_node,list_pages, etc. -
Inspect —
get_jsx(JSX view),diff_jsx(structural diff),describe(semantic analysis),export_image(visual screenshot) -
Modify —
render(JSX),set_fill,set_layout,create_shape, etc. -
Save —
save_file { path: "/path/to/output.fig" }
MCP Tools (94 total)
Read (14): get_selection, get_page_tree, get_node, find_nodes, query_nodes, get_components, list_pages, switch_page, get_current_page, page_bounds, select_nodes, list_fonts, get_jsx, diff_jsx
Create (7): create_shape, render, create_component, create_instance, create_page, create_vector, create_slice
Modify (20): set_fill, set_stroke, set_effects, update_node, set_layout, set_constraints, set_rotation, set_opacity, set_radius, set_min_max, set_text, set_font, set_font_range, set_text_resize, set_visible, set_blend, set_locked, set_stroke_align, set_text_properties, set_layout_child
Structure (17): delete_node, clone_node, rename_node, reparent_node, group_nodes, ungroup_node, flatten_nodes, node_to_component, node_bounds, node_move, node_resize, node_ancestors, node_children, node_tree, node_bindings, node_replace_with, arrange_nodes
Variables (11): list_variables, list_collections, get_variable, find_variables, create_variable, set_variable, delete_variable, bind_variable, get_collection, create_collection, delete_collection
Vector & Export (14): boolean_union, boolean_subtract, boolean_intersect, boolean_exclude, path_get, path_set, path_scale, path_flip, path_move, viewport_get, viewport_set, viewport_zoom_to_fit, export_svg, export_image
Analyze & Inspect (8): analyze_colors, analyze_typography, analyze_spacing, analyze_clusters, diff_create, diff_show, describe, eval
File (3): open_file, save_file, new_document
Key tools for AI agents
-
query_nodes— XPath selectors to find specific nodes without fetching the full tree. Essential for large files. -
get_jsx— see any node as JSX (same format therendertool accepts). Useful for understanding structure before modifying. -
diff_jsx— unified diff between two nodes. Compare before/after, or find differences between similar components. -
describe— semantic analysis: what role a node plays, its visual style, layout properties, and potential design issues. -
export_image— render a node to PNG and return it. Use for visual verification after making changes.
JSX Rendering (via render tool or eval)
Create entire component trees in one call:
<Frame name="Card" w={320} h="hug" flex="col" gap={16} p={24} bg="#FFF" rounded={16}>
<Text size={18} weight="bold">Title</Text>
<Text size={14} color="#666">Description text</Text>
<Frame flex="row" gap={8}>
<Frame w={80} h={36} bg="#3B82F6" rounded={8} justify="center" items="center">
<Text size={14} color="#FFF" weight="600">Action</Text>
</Frame>
</Frame>
</Frame>
Elements: Frame, Text, Rectangle, Ellipse, Line, Star, Polygon, Group, Section, Component
Layout shorthands:
Prop Meaning
w, h
Width, height (number or "hug" / "fill")
flex
"row" or "col"
grid, columns, rows
CSS Grid — e.g. columns="1fr 200px 1fr"
gap, rowGap, columnGap
Item spacing
p, px, py, pt, pr, pb, pl
Padding
justify
"start", "center", "end", "between"
items
"start", "center", "end", "stretch"
grow
Flex grow factor
bg
Fill color (hex)
rounded, roundedTL/TR/BL/BR
Corner radius
stroke, strokeWidth
Stroke color and weight
opacity
0–1
rotate
Degrees
overflow
"hidden" to clip children
shadow
"offsetX offsetY blur #color"
blur
Layer blur
size, weight, font, color, textAlign
Text properties
colStart, rowStart, colSpan, rowSpan
Grid child positioning
Node IDs
Format: session:local (e.g., 1:23). Get IDs from find, tree, query, or node commands.
Tips
-
Omit the file path to work with the document open in the running OpenPencil editor
-
Start with
infoto understand the document structure -
Use
tree --depth 2for a quick overview without overwhelming output -
Use
query "//COMPONENT"to discover reusable components with XPath -
Use
query_nodes(MCP) to find exactly the nodes you need in large files — avoids fetching the whole tree -
Use
get_jsxto see how a node is structured before modifying it -
After modifying designs, use
export_imageto visually verify the result -
Use
analyze colors --similarto find near-duplicate colors to merge -
Export specific nodes with
--nodeinstead of full pages for faster results -
The
evalcommand gives you the full Figma Plugin API for anything the CLI doesn't cover -
Use
--jsonwhen piping output to other tools -
In app mode,
evalmodifications are reflected live in the editor
Weekly Installs254Repositoryopen-pencil/skillsGitHub Stars2First SeenMar 7, 2026Security AuditsGen Agent Trust HubWarnSocketPassSnykPassInstalled oncodex250cursor248github-copilot247gemini-cli247amp247cline247
forum用户评价 (0)
发表评价
暂无评价,来写第一条吧
统计数据
用户评分
为此 Skill 评分