- Update comparison tables: 78 tools (was 75), SVG export no longer a Penpot advantage, renderer LOC updated to ~3,200 after split into 10 files - Update figma-comparison: Rename layers ✅, SVG export ✅, +Copy/Paste as, +Tailwind export, +Stroke align, +per-side stroke weights; coverage 88/152 → 94/158 - Add What's Next roadmap to architecture.md: AI providers, figma-use tool set, CI tooling, prototyping, CSS Grid, PDF export, .fig fidelity - Update user-guide: SVG in export format table, Copy/Paste as submenu, stroke align + per-side weights, layer inline rename, mobile drawer, Code tab format toggle - Fix keyboard shortcuts: ⌘N/⌘T/⌘W ✅, ⌘\ ✅, add ⇧⌘C ✅ - Expand MCP tools reference from ~25 to all 78 tools in full category tables - Add Homebrew tap install to Getting Started - Add new features.md sections: SVG export, Copy/Paste as, stroke align, mobile/PWA, Tailwind JSX export, Google Fonts fallback, auto-save toggle, Homebrew tap, layer rename, renderer profiler - Full locale sync for DE, ES, FR, IT, PL: all 7 files updated in each locale
7.1 KiB
7.1 KiB
MCP Server
OpenPencil includes an MCP (Model Context Protocol) server that lets AI coding tools — Claude Code, Cursor, Windsurf, etc. — read and modify .fig files headlessly.
Two transports: stdio for MCP clients, HTTP for everything else.
Install
bun add -g @open-pencil/mcp
Stdio (Claude Code, Cursor, etc.)
Add to your MCP config (e.g. ~/.claude/settings.json or .cursor/mcp.json):
{
"mcpServers": {
"open-pencil": {
"command": "openpencil-mcp"
}
}
}
Or run from source without installing:
::: code-group
{
"mcpServers": {
"open-pencil": {
"command": "bun",
"args": ["/path/to/open-pencil/packages/mcp/src/index.ts"]
}
}
}
{
"mcpServers": {
"open-pencil": {
"command": "npx",
"args": ["tsx", "/path/to/open-pencil/packages/mcp/src/index.ts"]
}
}
}
:::
HTTP
For browser extensions, scripts, CI, or any HTTP client:
openpencil-mcp-http
Or from source: bun packages/mcp/src/http.ts / npx tsx packages/mcp/src/http.ts
Security defaults (HTTP transport):
- Binds to
127.0.0.1by default (HOSTto override) evaltool is disabled- File operations are limited to
OPENPENCIL_MCP_ROOT(defaults to current working directory) - CORS is disabled by default; set
OPENPENCIL_MCP_CORS_ORIGINto allow one origin - Optional auth token:
OPENPENCIL_MCP_AUTH_TOKEN(client sendsAuthorization: Bearer <token>orx-mcp-token)
Server starts on port 3100 (override with PORT env var). Endpoints:
GET /health— server statusPOST /mcp— MCP Streamable HTTP (SSE). Sessions viamcp-session-idheader.
Workflow
- Open —
open_fileto load an existing.fig, ornew_documentfor a blank canvas - Read —
get_page_tree,find_nodes,get_node,list_pages - Create —
create_shape,render(JSX) - Modify —
set_fill,set_stroke,set_layout,update_node,set_effects - Structure —
reparent_node,group_nodes,clone_node,delete_node - Save —
save_fileto write back to.fig
Tools (78)
Document
| Tool | Description |
|---|---|
open_file |
Open a .fig file for editing |
save_file |
Save the current document to a .fig file |
new_document |
Create a new empty document |
Read
| Tool | Description |
|---|---|
get_selection |
Get currently selected nodes |
get_page_tree |
Get the full node tree of the current page |
get_current_page |
Get the current page name and ID |
get_node |
Get detailed properties of a node by ID |
find_nodes |
Find nodes by name pattern and/or type |
get_components |
List all components in the document |
list_pages |
List all pages |
list_variables |
List design variables |
list_collections |
List variable collections |
node_bounds |
Get bounding box of a node |
node_ancestors |
Get ancestor chain of a node |
node_children |
Get direct children of a node |
node_tree |
Get the subtree rooted at a node |
node_bindings |
Get variable bindings on a node |
Create
| Tool | Description |
|---|---|
create_shape |
Create a shape (FRAME, RECTANGLE, ELLIPSE, TEXT, LINE, STAR, POLYGON, SECTION) |
create_vector |
Create a vector node from a path string |
create_slice |
Create an export slice |
create_page |
Create a new page |
render |
Render JSX to design nodes — create entire component trees in one call |
create_component |
Convert a frame/group into a component |
create_instance |
Create an instance of a component |
node_to_component |
Convert an existing node into a component in-place |
Modify
| Tool | Description |
|---|---|
set_fill |
Set fill color (hex) |
set_stroke |
Set stroke color, weight, alignment |
set_effects |
Add shadow or blur effects |
update_node |
Update position, size, opacity, corner radius, text, font |
set_layout |
Set auto-layout (flexbox) — direction, spacing, padding, alignment |
set_constraints |
Set resize constraints |
set_rotation |
Set rotation angle in degrees |
set_opacity |
Set opacity (0–1) |
set_radius |
Set corner radius (uniform or per-corner) |
set_minmax |
Set min/max width and height constraints |
set_text |
Set text content of a TEXT node |
set_font |
Set font family and weight |
set_font_range |
Set font properties on a character range |
set_text_resize |
Set text auto-resize mode (fixed/auto-width/auto-height) |
set_visible |
Show or hide a node |
set_blend |
Set blend mode |
set_locked |
Lock or unlock a node |
set_stroke_align |
Set stroke alignment (inside/center/outside) |
node_move |
Move a node to a new position |
node_resize |
Resize a node |
node_replace_with |
Replace a node with another node |
arrange |
Align or distribute selected nodes |
Structure
| Tool | Description |
|---|---|
delete_node |
Delete a node |
clone_node |
Duplicate a node |
rename_node |
Rename a node |
reparent_node |
Move a node into a different parent |
select_nodes |
Select nodes by ID |
group_nodes |
Group nodes |
ungroup_node |
Ungroup a group |
boolean_union |
Boolean union of two or more nodes |
boolean_subtract |
Boolean subtraction |
boolean_intersect |
Boolean intersection |
boolean_exclude |
Boolean exclusion |
Vector Path
| Tool | Description |
|---|---|
path_get |
Get the path data of a vector node |
path_set |
Set the path data of a vector node |
path_scale |
Scale a vector path |
path_flip |
Flip a vector path horizontally or vertically |
path_move |
Translate a vector path |
Variables
| Tool | Description |
|---|---|
get_variable |
Get a variable by ID or name |
find_variables |
Find variables by name pattern or type |
create_variable |
Create a new variable in a collection |
set_variable |
Set a variable value in a mode |
delete_variable |
Delete a variable |
bind_variable |
Bind a variable to a node property |
get_collection |
Get a variable collection by ID or name |
create_collection |
Create a new variable collection |
delete_collection |
Delete a variable collection |
Analyze
| Tool | Description |
|---|---|
analyze_colors |
Analyze color palette usage across the document |
analyze_typography |
Analyze font/size/weight distribution |
analyze_spacing |
Analyze gap and padding values |
analyze_clusters |
Detect repeated patterns (potential components) |
Diff
| Tool | Description |
|---|---|
diff_create |
Create a snapshot of the current document state |
diff_show |
Show differences between the current state and a snapshot |
Navigation
| Tool | Description |
|---|---|
switch_page |
Switch to a page by name or ID |
Escape Hatch
| Tool | Description |
|---|---|
eval |
Execute JavaScript with full Figma Plugin API access |
Note: eval is available over stdio, but disabled in HTTP mode for security.