| name | open-pencil |
| description | Work with Figma .fig design files and the running OpenPencil editor — inspect structure, query nodes, analyze design tokens, export images/SVG/JSX, and modify designs programmatically. Use when asked to open, inspect, export, analyze, or edit .fig files, or to control the running OpenPencil app. |
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)
bun open-pencil tree
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
bun open-pencil info design.fig
bun open-pencil tree design.fig
bun open-pencil tree --page "Components" --depth 3
bun open-pencil pages design.fig
bun open-pencil node design.fig --id 1:23
bun open-pencil node --id 1:23
bun open-pencil variables design.fig
bun open-pencil variables --collection "Colors" --type COLOR
Search
bun open-pencil find design.fig --name "Button"
bun open-pencil find --type FRAME
bun open-pencil find design.fig --type TEXT --page "Home"
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:
bun open-pencil query design.fig "//FRAME"
bun open-pencil query design.fig "//FRAME[@width < 300]"
bun open-pencil query design.fig "//TEXT[contains(@name, 'Button')]"
bun open-pencil query design.fig "//COMPONENT[@stackMode]"
bun open-pencil query design.fig "//COMPONENT//FRAME//TEXT"
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
bun open-pencil export design.fig -o hero.png
bun open-pencil export -o hero.png
bun open-pencil export design.fig --node 1:23 -s 2 -o button@2x.png
bun open-pencil export design.fig -f jpg -q 85 -o preview.jpg
bun open-pencil export design.fig -f svg --node 1:23 -o icon.svg
bun open-pencil export design.fig -f jsx -o component.jsx
bun open-pencil export design.fig -f jsx --style tailwind -o component.tsx
bun open-pencil export design.fig --thumbnail --width 1920 --height 1080
bun open-pencil export --page "Components" -o components.png
Analyze
bun open-pencil analyze colors design.fig
bun open-pencil analyze colors --similar --threshold 10
bun open-pencil analyze typography design.fig --group-by size
bun open-pencil analyze spacing design.fig --grid 8
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:
bun open-pencil eval design.fig -c 'figma.currentPage.findAll(n => n.type === "TEXT").length'
bun open-pencil eval -c '
const buttons = figma.currentPage.findAll(n => n.name === "Button");
buttons.forEach(b => { b.cornerRadius = 8 });
buttons.length + " buttons updated"
'
bun open-pencil eval design.fig -w -c '
const texts = figma.currentPage.findAll(n => n.type === "TEXT");
texts.forEach(t => { t.fontSize = 16 });
'
bun open-pencil eval design.fig -o modified.fig -c '...'
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
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
export OPENPENCIL_MCP_CORS_ORIGIN="*"
export OPENPENCIL_MCP_ROOT=/path/to/files
npx openpencil-mcp-http
MCP Workflow
- Open a file —
open_file { path: "/path/to/design.fig" } or new_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 the render tool 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
info to understand the document structure
- Use
tree --depth 2 for 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_jsx to see how a node is structured before modifying it
- After modifying designs, use
export_image to visually verify the result
- Use
analyze colors --similar to find near-duplicate colors to merge
- Export specific nodes with
--node instead of full pages for faster results
- The
eval command gives you the full Figma Plugin API for anything the CLI doesn't cover
- Use
--json when piping output to other tools
- In app mode,
eval modifications are reflected live in the editor