This Skill is responsible for interacting with the Pencil MCP Server, reading/editing encrypted .pen design files, and providing copyable invocation templates and best practices.
Key boundaries and safety rules
.penThe file content is encrypted: it is forbidden to parse.pencontent using ordinary file reading/search methods; it can only be accessed and modified through pencil MCP tools.- Prefer "read before write": before writing, first use
get_editor_state/batch_getto understand the current document structure and selection. batch_designAt most 25 operations per single run; when exceeding this, split into multiple executions following "structure→content→style→acceptance".- Any capability that would cause large-scale changes (
replace_all_matching_properties, large batches ofbatch_design) must first output a change plan, then execute.
MCP Server configuration (reference)
{
"pencil": {
"name": "pencil",
"transport": "stdio",
"command": "/Users/wandl/.trae/extensions/highagency.pencildev-0.6.15-universal/out/mcp-server-darwin-arm64",
"args": ["--ws-port", "61405"],
"env": {}
}
}
Usage flow (recommended)
get_editor_state(include_schema=false): Confirm whether.penis currently open, and the current selection.- If there is no document:
open_document(filePathOrTemplate)open or create one. - Read structure:
batch_get(...)obtain the target node tree, components, variables, etc. - Design/modify:
batch_design(filePath, operations)(≤25 ops per run). - Acceptance:
snapshot_layout(...)check for layout issues; if necessaryget_screenshot(...)take a screenshot for review.
Tool list (Tools) and main parameter purposes
The following are the tools currently supported by pencil MCP (prompts/resources are not supported).
1) get_editor_state
- Purpose: obtain context such as the current editor state, active document, and currently selected nodes.
- Parameters:
include_schema: boolean: whether to include.penschema。
- Invocation template:
{ "name": "get_editor_state", "arguments": { "include_schema": false } }
2) open_document
- Purpose: open or create a
.penfile. - Parameters:
filePathOrTemplate: string:.penfile path or"new"。
- Invocation template:
{ "name": "open_document", "arguments": { "filePathOrTemplate": "new" } }
3) batch_get
- Purpose: batch read/search nodes (read structure, read components, read instances).
- Key parameters:
filePath: string(required)nodeIds?: string[]: read by IDparentId?: string: limit the search to a certain node's subtreepatterns?: object[]: search by pattern (e.g.nameregex,type、reusable)includePathGeometry?: boolean: whether to return full path geometry (by default...is used to abbreviate)readDepth?: number: read expansion depth (recommended ≤3)searchDepth?: number: search depthresolveInstances?: boolean: expand instancesresolveVariables?: boolean: resolve variables to current values
- Invocation template (search reusable components by pattern):
{
"name": "batch_get",
"arguments": {
"filePath": "designs/app.pen",
"patterns": [{ "reusable": true }],
"readDepth": 2,
"searchDepth": 3
}
}
4) batch_design
- Purpose: batch execute operations such as insert/copy/update/replace/move/delete/image.
- Key parameters:
filePath: string(required)operations: string(required): operation script (one op per line, can bind variable names; ≤25 ops per run).
- Invocation template (illustrative):
{
"name": "batch_design",
"arguments": {
"filePath": "designs/app.pen",
"operations": "root=G()\\nframe=I(root,{type:\\\"frame\\\",name:\\\"Home\\\"})\\nU(frame,{width:390,height:844})"
}
}
5) snapshot_layout
- Purpose: check layout structure and common issues (overlap, clipping, etc.), can return only problematic nodes.
- Key parameters:
filePath: string(required)parentId?: string: check only the subtreemaxDepth?: number: check depthproblemsOnly?: boolean: output only problematic nodes
- Invocation template:
{
"name": "snapshot_layout",
"arguments": { "filePath": "designs/app.pen", "maxDepth": 2, "problemsOnly": true }
}
6) get_screenshot
- Purpose: Take a screenshot of the specified node (visual acceptance).
- Parameters:
filePath: string(required)nodeId: string(required)
- Call template:
{
"name": "get_screenshot",
"arguments": { "filePath": "designs/app.pen", "nodeId": "node_123" }
}
7) get_guidelines
- Purpose: Get design guidelines/rules.
- Parameters:
topic: \"code\" | \"table\" | \"tailwind\" | \"landing-page\" | \"design-system\"(required)
- Call template:
{ "name": "get_guidelines", "arguments": { "topic": "design-system" } }
8) get_style_guide_tags
- Purpose: Get the set of available style tags.
- Call template:
{ "name": "get_style_guide_tags", "arguments": {} }
9) get_style_guide
- Purpose: Get style guidelines by tags or id.
- Parameters (optional):
tags?: string[]id?: string
- Call template:
{ "name": "get_style_guide", "arguments": { "tags": ["mobile", "minimal", "fresh"] } }
10) get_variables
- Purpose: Read the variables and themes of the
.penfile (used to generate global styles/code mappings). - Parameters:
filePath: string(required)
- Call template:
{ "name": "get_variables", "arguments": { "filePath": "designs/app.pen" } }
11) set_variables
- Purpose: Update the variables and themes of the
.penfile. - Parameters:
filePath: string(required)variables: object(required)replace?: boolean: Whether to replace in full (default is merge).
- Call template:
{
"name": "set_variables",
"arguments": { "filePath": "designs/app.pen", "replace": false, "variables": {} }
}
12) find_empty_space_on_canvas
- Purpose: Find an empty area of the specified size on the canvas or around a node.
- Parameters:
filePath: string(required)width: number(required)height: number(required)padding: number(required)direction: \"top\" | \"right\" | \"bottom\" | \"left\"(required)nodeId?: string: Use a node as reference (optional)
- Call template:
{
"name": "find_empty_space_on_canvas",
"arguments": {
"filePath": "designs/app.pen",
"width": 390,
"height": 844,
"padding": 24,
"direction": "right"
}
}
13) search_all_unique_properties
- Purpose: Count the set of unique values for several properties (color/font/spacing, etc.) in the specified subtree, used to analyze whether they are consistent.
- Parameters:
filePath: string(required)parents: string[](required)properties: string[](required; enum: fillColor/textColor/strokeColor/strokeThickness/cornerRadius/padding/gap/fontSize/fontFamily/fontWeight)
- Call template:
{
"name": "search_all_unique_properties",
"arguments": {
"filePath": "designs/app.pen",
"parents": ["root_frame"],
"properties": ["fillColor", "fontFamily", "fontSize"]
}
}
14) replace_all_matching_properties
- Purpose: Batch replace matching properties in the specified subtree (change colors/fonts/adjust spacing, etc.).
- Parameters:
filePath: string(required)parents: string[](required)properties: object(required): Provide a list of from/to replacement rules by property name
- Call template:
{
"name": "replace_all_matching_properties",
"arguments": {
"filePath": "designs/app.pen",
"parents": ["root_frame"],
"properties": {
"fontFamily": [{ "from": "Inter", "to": "SF Pro" }],
"fontSize": [{ "from": 14, "to": 15 }]
}
}
}
Common task prompts (execution instruction templates for large models)
A) "Open and analyze the current design structure"
- Call
get_editor_state(include_schema=false)to get activeFilePath and selection - Use
batch_getto read the selected node and its subtree (readDepth=2) - Use
snapshot_layout(problemsOnly=true)to output a list of layout issues - If necessary,
get_screenshottake screenshots of the problematic nodes to confirm
B) "Batch change theme/change font/unify spacing"
search_all_unique_propertiesFirst count the current state (output the set of unique values and their distribution)- Propose a change plan (from→to mapping, scope of impact, rollback strategy)
replace_all_matching_propertiesExecute the replacementsnapshot_layout+get_screenshotacceptance