penpot-mcp

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Penpot MCP Skill

Penpot MCP 技能

AI-agent workflows for creating, auditing, and maintaining production-grade design projects and design systems — including flows, interactions, animations, tokens, and visual effects — in Penpot via the official MCP Server.
通过官方MCP Server在Penpot中创建、审计和维护生产级设计项目与设计系统的AI Agent工作流——包括流程、交互、动画、令牌和视觉效果。

Compatible AI Agents

兼容的AI Agent

Works with any MCP-compatible client: Claude Code, Cursor, VS Code / Copilot, Codex / OpenCode, Amp, Cline, Windsurf, Claude Desktop (via
mcp-remote
), and any agent supporting HTTP or SSE MCP transport.

兼容所有支持MCP的客户端:Claude CodeCursorVS Code / CopilotCodex / OpenCodeAmpClineWindsurfClaude Desktop(通过
mcp-remote
),以及任何支持HTTP或SSE MCP传输的Agent。

Architecture Overview

架构概述

MCP Client (any MCP-compatible agent / IDE)
      ↕  HTTP  (or stdio via mcp-remote proxy)
MCP Server (hosted remote OR local npx)
      ↕  WebSocket / plugin bridge
Penpot Plugin (running inside the open design file)
MCP always acts on the currently focused page in the active Penpot browser tab. Only one tab can own MCP at a time.
MCP runs through the Penpot MCP plugin. It does not provide a documented way to enumerate, install, launch, or drive arbitrary installed community plugins. Coordinate with other plugins only when the user explicitly asks or when file-visible evidence makes a plugin relevant.

MCP Client (any MCP-compatible agent / IDE)
      ↕  HTTP  (or stdio via mcp-remote proxy)
MCP Server (hosted remote OR local npx)
      ↕  WebSocket / plugin bridge
Penpot Plugin (running inside the open design file)
MCP 始终作用于Penpot浏览器当前激活标签页中聚焦的页面。同一时间只能有一个标签页占用MCP。
MCP通过Penpot MCP插件运行。它没有提供文档化的方法来枚举、安装、启动或驱动任意已安装的社区插件。仅当用户明确要求,或文件中有可见证据表明某插件相关时,才与其他插件配合使用。

1. Connection Setup

1. 连接设置

Remote MCP (recommended for most users)

远程MCP(推荐大多数用户使用)

  1. Penpot → Your account → Integrations → MCP Server → enable
  2. Generate MCP key (shown once — store safely; only one key per user at a time)
  3. Copy server URL:
    https://<your-penpot-domain>/mcp/stream?userToken=YOUR_MCP_KEY
  4. Add to your MCP client config (see snippets below)
  5. Open a design file → File → MCP Server → Connect
  1. 打开Penpot → 你的账户 → 集成 → MCP Server → 启用
  2. 生成MCP密钥(仅显示一次——请妥善保存;每个用户同一时间只能拥有一个密钥)
  3. 复制服务器URL:
    https://<your-penpot-domain>/mcp/stream?userToken=YOUR_MCP_KEY
  4. 添加到你的MCP客户端配置中(见下方代码片段)
  5. 打开一个设计文件 → 文件 → MCP Server → 连接

Local MCP (advanced; extra file-system access)

本地MCP(高级用户;支持额外文件系统访问)

bash
npx @penpot/mcp@stable   # keep running; matches current Penpot release
npx @penpot/mcp@beta     # for beta/test environments
  • Load plugin: Plugins → Load from URL
    http://localhost:4400/manifest.json
  • Click Connect to MCP server in plugin UI → keep plugin window open at all times
  • Client URL:
    http://localhost:4401/mcp
    (no auth; preferred for single-client setups)
  • SSE fallback:
    http://localhost:4401/sse
    (use when
    /mcp
    transport conflicts occur, or with
    mcp-remote
    for stdio-only clients)
bash
npx @penpot/mcp@stable   # 保持运行;匹配当前Penpot正式版本
npx @penpot/mcp@beta     # 用于测试/预览环境
  • 加载插件:插件 → 从URL加载
    http://localhost:4400/manifest.json
  • 在插件界面点击连接到MCP服务器 → 始终保持插件窗口打开
  • 客户端URL:
    http://localhost:4401/mcp
    (无需认证;适合单客户端设置)
  • SSE备用地址:
    http://localhost:4401/sse
    (当
    /mcp
    传输发生冲突时使用,或用于仅支持标准输入输出的客户端配合
    mcp-remote
    使用)

Client Config Snippets

客户端配置代码片段

Claude Code (
.claude/settings.json
):
json
{
  "mcpServers": {
    "penpot": { "transport": "http", "url": "REMOTE_OR_LOCAL_URL" }
  }
}
Cursor:
json
{ "mcpServers": { "penpot": { "url": "REMOTE_OR_LOCAL_URL", "type": "http" } } }
VS Code / Copilot (
settings.json
):
json
{
  "mcp.servers": {
    "penpot": { "transport": "http", "url": "REMOTE_OR_LOCAL_URL" }
  }
}
Codex / OpenCode:
json
{
  "servers": {
    "penpot": { "url": "REMOTE_OR_LOCAL_URL", "transport": { "type": "http" } }
  }
}
Claude Desktop (stdio-only — requires proxy):
bash
npx -y mcp-remote http://localhost:4401/sse --allow-http
Claude Code
.claude/settings.json
):
json
{
  "mcpServers": {
    "penpot": { "transport": "http", "url": "REMOTE_OR_LOCAL_URL" }
  }
}
Cursor
json
{ "mcpServers": { "penpot": { "url": "REMOTE_OR_LOCAL_URL", "type": "http" } } }
VS Code / Copilot
settings.json
):
json
{
  "mcp.servers": {
    "penpot": { "transport": "http", "url": "REMOTE_OR_LOCAL_URL" }
  }
}
Codex / OpenCode
json
{
  "servers": {
    "penpot": { "url": "REMOTE_OR_LOCAL_URL", "transport": { "type": "http" } }
  }
}
Claude Desktop(仅支持标准输入输出——需要代理):
bash
npx -y mcp-remote http://localhost:4401/sse --allow-http

Troubleshooting Checklist

故障排查清单

  • Restart MCP server process
  • Reconnect plugin (File → MCP Server → Connect)
  • Restart MCP client / reload tools
  • Error: Already connected to a transport
    → close other MCP clients; use
    /sse
    fallback if
    /mcp
    conflicts
  • Keep plugin window open while agents run at all times
  • Firefox preferred if Chromium blocks
    localhost
    from
    https://design.penpot.app
  • Expired MCP key → regenerate in Penpot → Integrations; update all client configs

  • 重启MCP服务器进程
  • 重新连接插件(文件 → MCP Server → 连接
  • 重启MCP客户端/重新加载工具
  • 出现
    Error: Already connected to a transport
    错误 → 关闭其他MCP客户端;若
    /mcp
    传输冲突,使用
    /sse
    备用地址
  • 运行Agent时始终保持插件窗口打开
  • 如果Chromium阻止
    https://design.penpot.app
    访问
    localhost
    ,建议使用Firefox
  • MCP密钥过期 → 在Penpot的集成中重新生成;更新所有客户端配置

2. Available MCP Tools

2. 可用的MCP工具

ToolModeDescription
high_level_overview
BothRead overall file structure, pages, layers, components
penpot_api_info
BothQuery Penpot plugin API documentation
execute_code
BothRun JavaScript in Penpot plugin context — primary read/write tool
export_shape
BothExport shape as PNG/SVG (remote: limited; may fail with HTTP error)
import_image
Local onlyImport image from local file path into design
Remote MCP cannot import images from local paths.
export_shape
may fail with HTTP errors — always verify structurally via API rather than relying on export success.
工具名称运行模式描述
high_level_overview
两种模式均支持读取文件整体结构、页面、图层、组件
penpot_api_info
两种模式均支持查询Penpot插件API文档
execute_code
两种模式均支持在Penpot插件上下文运行JavaScript —— 主要的读写工具
export_shape
两种模式均支持将形状导出为PNG/SVG(远程模式受限;可能因HTTP错误失败)
import_image
仅本地模式从本地文件路径导入图片到设计中
远程MCP无法从本地路径导入图片。
export_shape
可能因HTTP错误失败 —— 请始终通过API进行结构验证,而非依赖导出成功。

Check connection first (always)

始终先检查连接

Before any setup steps, call
penpot_api_info
or
high_level_overview
first
. If it succeeds, skip setup entirely.
在执行任何设置步骤之前,先调用
penpot_api_info
high_level_overview
。如果调用成功,则完全跳过设置步骤。

Community plugin guardrails

社区插件使用规范

  • Do not assume MCP can read the user's installed plugin list or invoke another plugin's UI/API.
  • Prefer MCP-native reads/writes for normal design, prototyping, token, and export tasks.
  • If a community plugin could materially help, first look for file-visible evidence: generated layers, library assets, comments, or namespaced shared plugin data.
  • If the user provides an installed-plugin inventory, treat it as user-provided context and select a plugin only when the task clearly maps to that plugin's stated capability.
  • Ask for user confirmation before using or relying on any community plugin. If it has its own UI, ask the user to run it manually, then re-inspect the file.
  • Never use a plugin marketplace/browser plugin such as Plugins list unless the user explicitly asks to browse, search, discover, or install plugins. Do not search/install plugins automatically for routine tasks.
  • 不要假设MCP可以读取用户已安装的插件列表或调用其他插件的UI/API。
  • 对于常规设计、原型制作、令牌和导出任务,优先使用MCP原生的读写功能。
  • 如果某个社区插件可能提供实质性帮助,首先查找文件中的可见证据:生成的图层、库资源、注释或带命名空间的共享插件数据。
  • 如果用户提供了已安装插件清单,将其视为用户提供的上下文,仅当任务明确匹配该插件声明的功能时才选择使用它。
  • 在使用或依赖任何社区插件之前,请征得用户确认。如果插件有自己的界面,请让用户手动运行它,然后重新检查文件。
  • 除非用户明确要求浏览、搜索、发现或安装插件,否则不要使用插件市场/浏览器插件(如插件列表)。不要为常规任务自动搜索/安装插件。

JavaScript API

JavaScript API

execute_code
runs JS against the Penpot plugin API. Read
references/penpot-api-patterns.md
before any
execute_code
calls.
It covers the full API including tokens, library creation, page management, visual effects, storage, and idempotency helpers.

execute_code
针对Penpot插件API运行JavaScript。在调用任何
execute_code
之前,请阅读
references/penpot-api-patterns.md
。该文档涵盖了完整的API,包括令牌、库创建、页面管理、视觉效果、存储和幂等性辅助工具。

3. Safety-First Workflow (ALWAYS follow this order)

3. 安全优先工作流(务必遵循此顺序)

1. READ   → Inspect, list, analyze (never skip)
2. PLAN   → Describe intended changes BEFORE applying
3. WRITE  → Small atomic batches; one logical unit per call
4. VERIFY → Structural read after each write batch (not export-based)
Write call limits — enforce strictly:
  • Max ~5–10 shape operations per
    execute_code
    call
  • Pause and verify between batches
  • Never "build everything" in one call — MCP writes time out on large batches, leaving partial updates with no error indication
Page switching — two-call pattern (mandatory on Penpot ≤ 2.16.x, defensive habit on 2.17+):
text
Call N:   penpot.openPage(page)    ← switch page (currentPage still reports OLD page on ≤ 2.16)
Call N+1: any operation            ← now on new page; currentPage updated
⚠️ Penpot ≤ 2.16.x only — fixed upstream in 2.17.0 (#10078):
penpot.currentPage
does NOT update until the next tool call after
openPage()
. Writing shapes in the same call as
openPage()
silently applies them to the previously active page. This is a plugin-bridge bug, not a permanent API contract. On Penpot ≥ 2.17.0,
currentPage
updates immediately after
openPage()
and the two-call pattern is unnecessary — keep it anyway as a harmless defensive habit.
remove()
is unreliable across calls
— Boards deleted via
shape.remove()
may reappear in subsequent structural queries (
getPages()
shapeStructure()
). The remove appears to succeed in the current call, but stale boards from previous sessions can reappear when the page structure is re-read. (No upstream fix published through 2.18.0 — treat cleanup as best-effort and always verify structurally in a later call.)
Always verify the page before writing: after
openPage()
, always make a lightweight read-only call first (e.g. return
penpot.currentPage?.name
) before creating any shapes.
Use
storage
for large workflows:
javascript
// Call 1: compute and store your design token data
storage.tokenData = { colors: { primary: '#HEX' }, spacing: 8, ... };
// Call 2+: retrieve from storage instead of recomputing
const fallback = { colors: {}, spacing: 8 }; // safe default if session reset
const DS = storage.tokenData || fallback;
Starter prompts (always run first after connecting):
"List all pages in this file."
"Show all components on this page."
"Analyze the design structure and summarize the token system."

1. 读取   → 检查、列出、分析(绝不能跳过)
2. 规划   → 应用前先描述预期的更改
3. 写入   → 小批量原子操作;每次调用处理一个逻辑单元
4. 验证   → 每次写入批次后进行结构读取(不依赖导出)
写入调用限制 —— 严格执行:
  • 每次
    execute_code
    调用最多执行约5-10个形状操作
  • 在批次之间暂停并验证
  • 不要在一次调用中“构建所有内容”——MCP在处理大批次写入时会超时,导致部分更新且无错误提示
页面切换 —— 两次调用模式(Penpot ≤2.16.x版本强制要求,2.17+版本建议作为防御性习惯):
text
调用N:   penpot.openPage(page)    ← 切换页面(≤2.16版本中currentPage仍会返回旧页面)
调用N+1: 任意操作            ← 现在已在新页面;currentPage已更新
⚠️ 仅适用于Penpot ≤2.16.x版本 —— 上游已在2.17.0版本修复(#10078):
penpot.currentPage
openPage()
之后的下一次工具调用前不会更新。在与
openPage()
相同的调用中写入形状会静默地将其应用到之前激活的页面。这是一个插件桥接bug,并非永久的API约定。在Penpot ≥2.17.0版本中,
currentPage
会在
openPage()
后立即更新,两次调用模式不再必要——但仍建议保留作为无害的防御性习惯。
跨调用时
remove()
不可靠
—— 通过
shape.remove()
删除的画板可能会在后续的结构查询(
getPages()
shapeStructure()
)中重新出现。删除操作在当前调用中看似成功,但当重新读取页面结构时,之前会话中的陈旧画板可能会重新出现。(截至2.18.0版本尚未发布上游修复——清理操作仅作最大努力尝试,且务必在后续调用中进行结构验证。)
写入前始终验证页面:
openPage()
之后,创建任何形状之前,务必先进行一次轻量的只读调用(例如返回
penpot.currentPage?.name
)。
大型工作流使用
storage
javascript
// 调用1:计算并存储设计令牌数据
storage.tokenData = { colors: { primary: '#HEX' }, spacing: 8, ... };
// 调用2+:从storage中获取,而非重新计算
const fallback = { colors: {}, spacing: 8 }; // 会话重置时的安全默认值
const DS = storage.tokenData || fallback;
初始提示词(连接后始终先运行):
"列出此文件中的所有页面。"
"显示此页面上的所有组件。"
"分析设计结构并总结令牌系统。"

4. Role & Prompt Engineering

4. 角色与提示词工程

Define the agent role precisely

精确定义Agent角色

BAD:  "You are a creative designer."
GOOD: "You are a Senior Product Designer expert in design systems, WCAG accessibility,
       Penpot plugin API constraints, and Penpot-to-code workflows. You do not make
       product decisions without data. You never invent tokens, colors, or components
       not present in the file. You always work in small reversible batches."
错误示例:"你是一名创意设计师。" 正确示例:"你是一名资深产品设计师,精通设计系统、WCAG无障碍标准、Penpot插件API约束以及Penpot转代码工作流。没有数据支持时你不会做出产品决策。你绝不会发明文件中不存在的令牌、颜色或组件。你始终以可回滚的小批次方式工作。"

Structured Brief Template

结构化简报模板

CONTEXT: [product name, target user, current state of file]
GOAL: [specific problem — e.g., "build design token system and foundations page"]
INPUTS: [page names, board names, component names, token paths, brand colors]
CONSTRAINTS:
  - Max ~10 shape operations per execute_code call
  - Always use idempotency helpers (ensureColor, ensureTypography, etc.)
  - Never switch page and write in the same call
  - Never invent font weights not confirmed installed for this family
  - Verify structurally after each batch — do not rely on export_shape
  - Store shared data in storage global for cross-call access
QUALITY CRITERIA: [how you'll know it's done]
上下文: [产品名称、目标用户、文件当前状态]
目标: [具体问题 —— 例如,"构建设计令牌系统和基础页面"]
输入: [页面名称、画板名称、组件名称、令牌路径、品牌颜色]
约束条件:
  - 每次execute_code调用最多执行约10个形状操作
  - 始终使用幂等性辅助工具(ensureColor、ensureTypography等)
  - 不要在同一个调用中切换页面并写入内容
  - 不要使用未确认已安装的字重
  - 每次批次后进行结构验证 —— 不要依赖export_shape
  - 使用storage全局变量存储跨调用的共享数据
质量标准: [如何判断任务完成]

Negatives (always include)

禁止事项(务必包含)

  • "Do not invent colors not in the token set."
  • "Do not use font weights not confirmed installed for this font family."
  • "Do not switch page and write in the same execute_code call."
  • "Do not rely on export_shape for verification — use structural API checks."
  • "Do not create duplicate colors/typographies — always check before creating."
  • "不要使用令牌集中没有的颜色。"
  • "不要使用未确认已安装的字重。"
  • "不要在同一个execute_code调用中切换页面并写入内容。"
  • "不要依赖export_shape进行验证——使用API进行结构检查。"
  • "不要创建重复的颜色/排版样式——创建前务必检查。"

Iteration pattern

迭代模式

1. Discovery  → read all pages, library assets, tokens, existing components
2. Proposal   → describe planned structure, wait for approval
3. Foundation → build token sets + themes + colors + typographies (batched)
4. Structure  → create pages (all in one call), then build boards per page (separate calls)
5. Components → register library components from source boards
6. Verify     → structural checklist — count colors, typographies, components, token sets

1. 发现  → 读取所有页面、库资源、令牌、现有组件
2. 提案  → 描述计划的结构,等待批准
3. 基础  → 分批构建令牌集 + 主题 + 颜色 + 排版样式
4. 结构  → 一次性创建所有页面,然后为每个页面单独构建画板
5. 组件  → 从源画板注册库组件
6. 验证  → 结构检查清单 —— 统计颜色、排版样式、组件、令牌集的数量

5. Token-Aware Prompting

5. 令牌感知提示词

Global RULESET block (prepend to every design-system prompt)

全局规则集块(添加到每个设计系统提示词开头)

GLOBAL RULESET
- SOURCE: Penpot MCP only
- NO_GUESSING: true
- IF_MISSING: mark as TODO
- PREFER: structured data > prose
- OUTPUT: deterministic, stable ordering
- BATCH_LIMIT: ~10 ops per execute_code call
- PAGE_SWITCH: separate call from writes
- IDEMPOTENCY: always check-before-create
- STORAGE: use storage global for cross-call data
SIZE CONSTRAINTS
- design-system.json: tokens + mappings only
- components.catalog.json: real components only
- layout-and-rules.md: max ~300 lines
STYLE
- Use schemas, key:value, compact bullets
- No narrative explanations
全局规则集
- 数据源: 仅Penpot MCP
- 禁止猜测: true
- 缺失内容: 标记为TODO
- 优先选择: 结构化数据 > 散文
- 输出: 确定、稳定的排序
- 批次限制: 每次execute_code调用约10个操作
- 页面切换: 与写入操作分开调用
- 幂等性: 创建前始终检查
- 存储: 使用storage全局变量存储跨调用数据
大小限制
- design-system.json: 仅包含令牌和映射
- components.catalog.json: 仅包含真实组件
- layout-and-rules.md: 最多约300行
风格
- 使用模式、键值对、紧凑项目符号
- 不要使用叙述性解释

Token hierarchy

令牌层级

text
Tier 1 (Global):    color.base.neutral.100, spacing.base.8
Tier 2 (Semantic):  color.bg.default, color.text.primary
Tier 3 (Component): color.button.primary.bg
Reference tokens can be other tokens:
'{color.base.neutral.100}'
— use curly brace syntax.

text
第一层(全局):    color.base.neutral.100, spacing.base.8
第二层(语义):  color.bg.default, color.text.primary
第三层(组件): color.button.primary.bg
引用令牌可以是其他令牌:
'{color.base.neutral.100}'
—— 使用大括号语法。

6. Workflow Recipes

6. 工作流参考

Read the relevant reference before starting:
  • Full API, tokens, page management, storage, visual effects
    references/penpot-api-patterns.md
    (mandatory before any
    execute_code
    calls)
  • Design system creation/audit
    references/design-system-workflows.md
  • Design-to-code generation
    references/design-to-code-workflows.md
  • Prototyping: flows, interactions, animations
    references/prototyping-workflows.md
开始前请阅读相关参考文档:
  • 完整API、令牌、页面管理、存储、视觉效果
    references/penpot-api-patterns.md
    (调用任何
    execute_code
    前必读)
  • 设计系统创建/审计
    references/design-system-workflows.md
  • 设计转代码生成
    references/design-to-code-workflows.md
  • 原型制作:流程、交互、动画
    references/prototyping-workflows.md

Quick reference: Common task prompts

快速参考:常见任务提示词

Design system from scratch:
"Read all existing pages, colors, typographies, and token sets in this file."

"Build the token system: create token sets [base, theme-light, theme-dark],
populate with [color palette] + spacing (8px grid) + border radii + motion tokens.
Use addToken idempotency. Store DS object in storage. Max 15 tokens per call."

"Create library colors from the base token set.
Use ensureColor pattern. 5 colors per call, pause after each batch."

"Create typographies for the scale: [paste scale].
Use ensureTypography. Check installed font variants first."
Multi-page design system:
"Create pages: [Page1], [Page2], [Page3] — all in one call (list all pages to create).
Then report the current page list before doing anything else."

"Switch to page [PageName]. Confirm currentPage before writing."

"Build the [BoardName] board on the current [PageName] page.
Max 8 shapes per call. Pause after."
Prototyping tasks:
"List all boards on this page and their existing interactions."

"Create a prototype flow entry for '/flows/onboarding-start' using Page.createFlow."

"Add click→navigate interactions from [BoardA] to [BoardB] with Dissolve 300ms."

"Audit all interactions: list broken destinations and prototype coverage percentage."
Visual effects:
"Apply a backdrop blur effect to the [BoardName] overlay:
[N]px layer-blur, [N]px borderRadius, semi-transparent surface fill,
and a drop shadow. Describe the values you'll use before applying."

"Add linear gradient fill to [ShapeName]: brand primary → transparent, top to bottom."

从零开始构建设计系统:
"读取此文件中所有现有页面、颜色、排版样式和令牌集。"

"构建令牌系统:创建令牌集[base、theme-light、theme-dark],
填充[调色板] + 间距(8px网格) + 圆角 + 动效令牌。
使用addToken幂等方法。将DS对象存储在storage中。每次调用最多15个令牌。"

"从基础令牌集创建库颜色。
使用ensureColor模式。每次调用5个颜色,每批次后暂停。"

"为以下比例创建排版样式:[粘贴比例]。
使用ensureTypography。先检查已安装的字体变体。"
多页面设计系统:
"创建页面:[页面1]、[页面2]、[页面3] —— 一次性创建所有页面(列出所有要创建的页面)。
然后在进行其他操作前报告当前页面列表。"

"切换到页面[页面名称]。写入前确认currentPage。"

"在当前[页面名称]页面上构建[画板名称]画板。
每次调用最多8个形状。完成后暂停。"
原型制作任务:
"列出此页面上的所有画板及其现有交互。"

"使用Page.createFlow为'/flows/onboarding-start'创建原型流程入口。"

"添加从[画板A]到[画板B]的点击→导航交互,使用300ms溶解过渡效果。"

"审计所有交互:列出无效目标和原型覆盖百分比。"
视觉效果:
"为[画板名称]遮罩应用背景模糊效果:
[N]px图层模糊、[N]px圆角、半透明表面填充,
以及投影。应用前描述你将使用的值。"

"为[形状名称]添加线性渐变填充:品牌主色→透明,从上到下。"

7. Design File Best Practices

7. 设计文件最佳实践

File & page structure

文件与页面结构

  • Choose one page organisation strategy:
    • Domain-based: e.g.
      Foundations
      ,
      Mobile
      ,
      Desktop
    • Atomic-level: e.g.
      Tokens
      ,
      Primitives
      ,
      Components
      ,
      Patterns
  • Canvas: wireframes left → final design right
  • Every board has a clear purpose and visual entry point
  • 选择一种页面组织策略:
    • 基于领域:例如
      Foundations
      (基础)、
      Mobile
      (移动端)、
      Desktop
      (桌面端)
    • 基于原子级:例如
      Tokens
      (令牌)、
      Primitives
      (基础元素)、
      Components
      (组件)、
      Patterns
      (模式)
  • 画布:左侧放置线框图 → 右侧放置最终设计
  • 每个画板都有明确的用途和视觉入口点

Layer naming

图层命名

  • Function-based:
    background
    ,
    icon-close
    ,
    label-primary
  • Not appearance-based:
    rectangle-23
    ,
    blue-box
  • Hierarchy with
    /
    :
    component/card/default
    ,
    overlay/confirm-delete
  • 基于功能命名:
    background
    (背景)、
    icon-close
    (关闭图标)、
    label-primary
    (主标签) ✅
  • 避免基于外观命名:
    rectangle-23
    (矩形23)、
    blue-box
    (蓝色盒子) ❌
  • 使用
    /
    表示层级:
    component/card/default
    (组件/卡片/默认样式)、
    overlay/confirm-delete
    (遮罩/确认删除)

Components

组件

  • Naming:
    mobile/card/default
    ,
    mobile/nav-bar
  • Register from source shapes via
    createComponent([shapes])
  • Clone source shape first if it's already placed on a page
  • 命名:
    mobile/card/default
    (移动端/卡片/默认样式)、
    mobile/nav-bar
    (移动端/导航栏)
  • 通过
    createComponent([shapes])
    从源形状注册组件
  • 如果源形状已放置在页面上,请先克隆它

Spacing & layout

间距与布局

  • Base unit: 8px. All margins/paddings derived from it.
  • No invisible rectangles for spacing — use Flex/Grid layout
  • 基础单位:8px。所有边距/内边距均基于此单位。
  • 不要使用不可见矩形来设置间距——使用Flex/Grid布局

Visual effects & glassmorphism

视觉效果与毛玻璃效果

  • Glass recipe:
    blurs: [{ type: 'layer-blur', value: 20 }]
    +
    borderRadius: 20
    + shadow
  • Shadow color:
    { color: '#hex', opacity: 0.06 }
    (not r/g/b/a)
  • Ghost border only when accessibility explicitly requires it
  • 毛玻璃配方:
    blurs: [{ type: 'layer-blur', value: 20 }]
    +
    borderRadius: 20
    + 阴影
  • 阴影颜色:
    { color: '#hex', opacity: 0.06 }
    (不要使用r/g/b/a格式)
  • 仅当无障碍标准明确要求时才使用幽灵边框

Prototyping

原型制作

  • Flow entry boards: prefix
    /flows/[journey]-start
  • Overlay boards: prefix
    overlay/
  • Create flows via
    page.createFlow('name', entryBoard)
    or Prototype panel
  • 流程入口画板:前缀为
    /flows/[journey]-start
    (/流程/[旅程]-开始)
  • 遮罩画板:前缀为
    overlay/
    (遮罩/)
  • 通过
    page.createFlow('name', entryBoard)
    或原型面板创建流程

Accessibility

无障碍设计

  • WCAG AA contrast minimum for all text
  • 44px min touch target (iOS) / 48dp (Android)
  • Never use color alone to communicate status
  • 所有文本需满足WCAG AA对比度最低要求
  • 最小触摸目标尺寸:44px(iOS)/48dp(Android)
  • 不要仅使用颜色来传达状态

Handoff readiness

交付准备

  • Component/variable names developer-readable
  • No duplicates — single source of truth

  • 组件/变量名称需便于开发者阅读
  • 无重复内容——保持单一数据源

8. Model Selection

8. 模型选择

  • Always use frontier models (Claude Sonnet/Opus, GPT-4o, Gemini Pro)
  • VLM required for image-based tasks
  • More complex tasks → stronger model
  • Token-constrained workflows → apply RULESET block from §5

  • 始终使用前沿模型(Claude Sonnet/Opus、GPT-4o、Gemini Pro)
  • 基于图像的任务需要使用VLM(视觉语言模型)
  • 任务越复杂,使用的模型越强
  • 令牌受限的工作流 → 应用第5节中的规则集块

9. Key Gotchas

9. 关键注意事项

MCP/infrastructure:
GotchaMitigation
MCP acts on focused page onlyConfirm page focus before each write batch
Write ops immediate — no undo via MCPPlan + describe before applying
Large batches time out silentlyMax ~10 ops per call; verify after each
Page switch is asyncNever switch page and write in same call
export_shape
may fail with HTTP error
Verify structurally via API; export is best-effort
Remote MCP can't read local file systemUse local MCP for
import_image
Only one active MCP tabClose other Penpot tabs before running agents
Error: Already connected to a transport
Close other MCP clients; use
/sse
fallback if
/mcp
conflicts
MCP key shown only onceCopy immediately; regenerate if lost
Expired key blocks all connectionsRegenerate in Integrations; update all configs
Chromium ≥142 blocks localhostUse Firefox, or allow local network explicitly
Penpot plugin API (full detail →
references/penpot-api-patterns.md
):
GotchaMitigation
shape.width
/
shape.height
READ-ONLY
Use
shape.resize(w, h)
shape.x
/
shape.y
READ-ONLY for parented shapes
Use
penpotUtils.setParentXY(shape, x, y)
shape.x
/
shape.y
for root-level boards
✅ Direct assignment works
appendChild
ignores z-order
Use
insertChild(index, shape)
Flex children reversed for column dirsLast inserted = top visually
penpot.createText(...)
may return null
Guard before resize/style calls; return a clear error if unavailable
Text clips after
resize()
Always reset
growType
after every
text.resize()
Font weight rejectionOnly use weights explicitly installed for the font family
Library
fontSize
must be string
"16"
not
16
; library typographies use
fontFamilies
not
fontFamily
LibraryColor.color
for hex
.color = '#hex'
not
.fillColor
shape.blurs
is an array
shape.blurs = [{ type: 'layer-blur', value: 20 }]
Shadow color format
{ color: '#hex', opacity: 0.15 }
not
{r,g,b,a}
Typography
fontId
stays stale
Known API limitation; rendered layers use correct ID
storage
resets on server restart
Always use a fallback value when reading
Page.findShapes()
takes criteria object
page.findShapes({ type: 'board' })
not a predicate
createComponent
wraps an array
createComponent([shape])
not
createComponent(shape)
MCP/基础设施:
问题点解决方法
MCP仅作用于聚焦页面每次写入批次前确认页面聚焦状态
写入操作立即生效——无法通过MCP撤销应用前先规划并描述操作内容
大批次写入会静默超时每次调用最多执行约10个操作;每次批次后进行验证
页面切换是异步操作不要在同一个调用中切换页面并写入内容
export_shape
可能因HTTP错误失败
通过API进行结构验证;导出仅作最大努力尝试
远程MCP无法读取本地文件系统使用本地MCP进行
import_image
操作
同一时间只能有一个激活的MCP标签页运行Agent前关闭其他Penpot标签页
出现
Error: Already connected to a transport
错误
关闭其他MCP客户端;若
/mcp
传输冲突,使用
/sse
备用地址
MCP密钥仅显示一次立即复制;丢失后重新生成
密钥过期会阻止所有连接在集成中重新生成密钥;更新所有配置
Chromium ≥142版本阻止localhost访问使用Firefox,或显式允许本地网络访问
Penpot插件API(详细内容 →
references/penpot-api-patterns.md
):
问题点解决方法
shape.width
/
shape.height
为只读属性
使用
shape.resize(w, h)
父级形状的
shape.x
/
shape.y
为只读属性
使用
penpotUtils.setParentXY(shape, x, y)
根层级画板的
shape.x
/
shape.y
✅ 直接赋值有效
appendChild
忽略z轴顺序
使用
insertChild(index, shape)
列方向的Flex子元素顺序反转最后插入的元素在视觉上位于顶部
penpot.createText(...)
可能返回null
在调整大小/样式调用前进行判断;若不可用则返回清晰的错误信息
文本在
resize()
后会被裁剪
每次
text.resize()
后务必重置
growType
属性
字重被拒绝仅使用该字体家族明确已安装的字重
库中的
fontSize
必须为字符串类型
使用
"16"
而非
16
;库排版样式使用
fontFamilies
而非
fontFamily
十六进制颜色的
LibraryColor.color
属性
使用
.color = '#hex'
而非
.fillColor
shape.blurs
是一个数组
使用
shape.blurs = [{ type: 'layer-blur', value: 20 }]
阴影颜色格式使用
{ color: '#hex', opacity: 0.15 }
而非
{r,g,b,a}
排版样式的
fontId
保持陈旧值
已知API限制;渲染后的图层会使用正确的ID
服务器重启时
storage
会重置
读取时始终使用回退值
Page.findShapes()
接受条件对象
使用
page.findShapes({ type: 'board' })
而非谓词函数
createComponent
需要包裹数组
使用
createComponent([shape])
而非
createComponent(shape)