Penpot MCP Server
by devstroop
README.md
# Penpot MCP Server
A comprehensive Model Context Protocol (MCP) server for [Penpot](https://penpot.app/), the open-source design platform. This server provides full access to Penpot's capabilities through 14 powerful tools covering projects, files, components, design tokens, exports, comments, teams, and more.
## Features
- **šļø Project Management**: Full CRUD operations for projects with file organization
- **š File Operations**: Create, edit, duplicate, move files with version history
- **š§© Component Library**: Manage reusable components with instances, annotations, and stats
- **šØ Design Tokens**: Colors, typography with export to CSS/JSON/SCSS/Tailwind
- **š¤ Asset Export**: PNG, SVG, PDF, JPEG, WebP with multi-scale and batch support
- **š¬ Comments & Reviews**: Thread-based commenting with resolution tracking
- **š„ Team Collaboration**: Team management, invitations, roles, and permissions
- **š¤ Profile Management**: User settings, notifications, recent files
- **š Library Sharing**: Shared libraries, linking, publishing, and sync
- **š Global Search**: Search across files, objects, components, tokens
- **š Design Analysis**: Design system audits, accessibility, duplicates detection
## Architecture
```
penpot-mcp/
āāā src/
ā āāā index.ts # Entry point
ā āāā server-core.ts # MCP server implementation
ā āāā config.ts # Configuration management
ā āāā logger.ts # Logging utility
ā āāā api/
ā ā āāā client-factory.ts # API client factory (9 domain clients)
ā ā āāā base/ # Base API client & utilities
ā ā ā āāā base-client.ts
ā ā ā āāā error-handler.ts
ā ā ā āāā response-formatter.ts
ā ā ā āāā index.ts
ā ā āāā domains/ # Domain-specific API clients
ā ā āāā projects-api.ts # Project CRUD, files, stats
ā ā āāā files-api.ts # File operations, pages, objects
ā ā āāā components-api.ts # Components, instances, annotations
ā ā āāā tokens-api.ts # Colors, typography, export
ā ā āāā exports-api.ts # Asset export (PNG/SVG/PDF/etc)
ā ā āāā comments-api.ts # Threads, comments, resolution
ā ā āāā team-api.ts # Team management, invitations
ā ā āāā profile-api.ts # User profile, settings
ā ā āāā library-api.ts # Shared libraries, linking
ā ā āāā index.ts
ā āāā tools/
ā āāā tool-definitions.ts # MCP tool schemas (14 tools)
ā āāā index.ts
ā āāā orchestration/ # High-level orchestration tools
ā āāā projects.ts # penpot_projects
ā āāā files.ts # penpot_files
ā āāā components.ts # penpot_components
ā āāā tokens.ts # penpot_tokens
ā āāā exports.ts # penpot_exports
ā āāā comments.ts # penpot_comments
ā āāā team.ts # penpot_team
ā āāā profile.ts # penpot_profile
ā āāā library.ts # penpot_library
ā āāā search.ts # penpot_search
ā āāā analyze.ts # penpot_analyze
ā āāā navigate.ts # penpot_navigate (legacy)
ā āāā inspect.ts # penpot_inspect (legacy)
ā āāā assets.ts # penpot_assets (legacy)
ā āāā types.ts
ā āāā index.ts
āāā package.json
āāā tsconfig.json
āāā README.md
```
## Installation
```bash
npm install
npm run build
```
## Configuration
Create a `.env` file:
```env
# Required: Penpot credentials
PENPOT_USERNAME=your-email@example.com
PENPOT_PASSWORD=your-password
# Optional: Custom Penpot instance URL (defaults to design.penpot.app)
PENPOT_API_URL=https://design.penpot.app/api
# Optional: Default project scope
PENPOT_PROJECT_ID=your-project-id
# Optional: Logging level
LOG_LEVEL=info
```
## Usage with Claude Desktop
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"penpot": {
"command": "node",
"args": ["/path/to/penpot-mcp/dist/index.js"],
"env": {
"PENPOT_USERNAME": "your-email@example.com",
"PENPOT_PASSWORD": "your-password"
}
}
}
}
```
## Available Tools (14 Total)
### Core Tools
| Tool | Description |
|------|-------------|
| `penpot_projects` | Project management: list, create, rename, delete, duplicate, move |
| `penpot_files` | File operations: CRUD, pages, objects, tree, search, history |
| `penpot_components` | Component library: list, search, instances, create, delete, annotations |
| `penpot_tokens` | Design tokens: colors, typography, CRUD, export to CSS/JSON/SCSS/Tailwind |
| `penpot_exports` | Asset export: PNG, SVG, PDF, JPEG, WebP with batch and multi-scale |
| `penpot_comments` | Comment management: threads, replies, resolve, reopen |
| `penpot_team` | Team management: members, invitations, roles, permissions |
| `penpot_profile` | User profile: settings, notifications, recent files |
| `penpot_library` | Shared libraries: link, unlink, publish, sync |
| `penpot_search` | Global search: files, objects, components, tokens |
| `penpot_analyze` | Design analysis: design system, accessibility, duplicates |
### Legacy Tools (Backward Compatibility)
| Tool | Description |
|------|-------------|
| `penpot_navigate` | Navigate projects, files, pages |
| `penpot_inspect` | Deep inspection of file structure |
| `penpot_assets` | Basic asset export |
## Tool Actions Reference
### penpot_projects
| Action | Description | Required Params |
|--------|-------------|-----------------|
| `list` | List all projects | - |
| `get` | Get project details | `projectId` |
| `create` | Create new project | `name` |
| `rename` | Rename project | `projectId`, `name` |
| `delete` | Delete project | `projectId` |
| `duplicate` | Duplicate project | `projectId` |
| `move` | Move to team | `projectId`, `targetTeamId` |
| `files` | List project files | `projectId` |
| `stats` | Project statistics | `projectId` |
### penpot_files
| Action | Description | Required Params |
|--------|-------------|-----------------|
| `get` | Get file details | `fileId` |
| `create` | Create new file | `projectId`, `name` |
| `rename` | Rename file | `fileId`, `name` |
| `delete` | Delete file | `fileId` |
| `duplicate` | Duplicate file | `fileId` |
| `move` | Move to project | `fileId`, `projectId` |
| `pages` | List file pages | `fileId` |
| `page` | Get page objects | `fileId`, `pageId` |
| `objects` | Get page objects | `fileId`, `pageId` |
| `object` | Get specific object | `fileId`, `pageId`, `objectId` |
| `tree` | Get object tree | `fileId`, `objectId` |
| `search` | Search objects | `fileId`, `query` |
| `analyze` | Analyze structure | `fileId` |
| `history` | Version history | `fileId` |
| `snapshot` | Create/restore | `fileId` |
### penpot_components
| Action | Description | Required Params |
|--------|-------------|-----------------|
| `list` | List components | `fileId` |
| `get` | Get component | `fileId`, `componentId` |
| `search` | Search components | `fileId`, `query` |
| `instances` | Get instances | `fileId`, `componentId` |
| `structure` | Get structure | `fileId`, `componentId` |
| `create` | Create component | `fileId`, `objectId`, `name` |
| `delete` | Delete component | `fileId`, `componentId` |
| `rename` | Rename component | `fileId`, `componentId`, `name` |
| `annotate` | Add annotation | `fileId`, `componentId`, `annotation` |
| `stats` | Component stats | `fileId` |
| `detach` | Detach instance | `fileId`, `instanceId` |
| `reset` | Reset instance | `fileId`, `instanceId` |
### penpot_tokens
| Action | Description | Required Params |
|--------|-------------|-----------------|
| `colors` | List colors | `fileId` |
| `color` | Get color | `fileId`, `colorId` |
| `create_color` | Create color | `fileId`, `name`, `color` |
| `update_color` | Update color | `fileId`, `colorId` |
| `delete_color` | Delete color | `fileId`, `colorId` |
| `typography` | List typography | `fileId` |
| `typography_style` | Get style | `fileId`, `styleId` |
| `create_typography` | Create style | `fileId`, `name` |
| `update_typography` | Update style | `fileId`, `styleId` |
| `delete_typography` | Delete style | `fileId`, `styleId` |
| `all` | Get all tokens | `fileId` |
| `search` | Search tokens | `fileId`, `query` |
| `export_css` | Export as CSS | `fileId` |
| `export_json` | Export as JSON | `fileId` |
| `export_scss` | Export as SCSS | `fileId` |
| `export_tailwind` | Export Tailwind | `fileId` |
| `stats` | Token statistics | `fileId` |
### penpot_exports
| Action | Description | Required Params |
|--------|-------------|-----------------|
| `export` | Export object | `fileId`, `objectId`, `format` |
| `batch` | Batch export | `fileId`, `objectIds` |
| `page` | Export page | `fileId`, `pageId` |
| `file_pdf` | Export as PDF | `fileId` |
| `multi_scale` | Multi-scale export | `fileId`, `objectId`, `scales` |
| `multi_format` | Multi-format export | `fileId`, `objectId`, `formats` |
| `list` | List exportable | `fileId` |
| `settings` | Export settings | `fileId`, `objectId` |
| `download` | Download export | `exportId` |
| `formats` | Supported formats | - |
### penpot_comments
| Action | Description | Required Params |
|--------|-------------|-----------------|
| `list` | List threads | `fileId` |
| `thread` | Get thread | `threadId` |
| `create_thread` | Create thread | `fileId`, `pageId`, `content` |
| `add` | Add comment | `threadId`, `content` |
| `update` | Update comment | `commentId`, `content` |
| `delete` | Delete comment | `commentId` |
| `delete_thread` | Delete thread | `threadId` |
| `resolve` | Resolve thread | `threadId` |
| `reopen` | Reopen thread | `threadId` |
| `unread` | Unread count | `fileId` |
### penpot_team
| Action | Description | Required Params |
|--------|-------------|-----------------|
| `list` | List teams | - |
| `get` | Get team | `teamId` |
| `create` | Create team | `name` |
| `rename` | Rename team | `teamId`, `name` |
| `delete` | Delete team | `teamId` |
| `members` | List members | `teamId` |
| `invite` | Invite member | `teamId`, `email`, `role` |
| `remove_member` | Remove member | `teamId`, `memberId` |
| `update_role` | Update role | `teamId`, `memberId`, `role` |
| `invitations` | Pending invites | `teamId` |
| `cancel_invite` | Cancel invite | `invitationId` |
| `leave` | Leave team | `teamId` |
| `stats` | Team statistics | `teamId` |
### penpot_profile
| Action | Description | Required Params |
|--------|-------------|-----------------|
| `get` | Get profile | - |
| `update` | Update profile | - |
| `password` | Change password | `oldPassword`, `newPassword` |
| `props` | Get properties | - |
| `update_props` | Update props | `props` |
| `email` | Request email change | `newEmail` |
| `delete` | Delete account | - |
| `recent` | Recent files | - |
| `notifications` | Notifications | - |
| `mark_read` | Mark as read | `notificationId` |
### penpot_library
| Action | Description | Required Params |
|--------|-------------|-----------------|
| `shared` | List shared | `teamId` |
| `link` | Link library | `fileId`, `libraryId` |
| `unlink` | Unlink library | `fileId`, `libraryId` |
| `linked` | List linked | `fileId` |
| `publish` | Publish library | `fileId` |
| `unpublish` | Unpublish | `fileId` |
| `summary` | Library summary | `fileId` |
| `sync` | Sync library | `fileId`, `libraryId` |
| `colors` | Library colors | `libraryId` |
| `typography` | Library typography | `libraryId` |
| `components` | Library components | `libraryId` |
| `search` | Search libraries | `teamId`, `query` |
### penpot_search
| Action | Description | Required Params |
|--------|-------------|-----------------|
| `files` | Search files | `query` |
| `objects` | Search objects | `fileId`, `query` |
| `components` | Search components | `fileId` |
| `colors` | Search colors | `fileId` |
| `typography` | Search typography | `fileId` |
| `recent` | Recent files | - |
| `global` | Global search | `query` |
### penpot_analyze
| Action | Description | Required Params |
|--------|-------------|-----------------|
| `design_system` | Design system audit | `fileId` |
| `accessibility` | Accessibility check | `fileId` |
| `naming` | Naming conventions | `fileId` |
| `structure` | File structure | `fileId` |
| `colors` | Color analysis | `fileId` |
| `typography` | Typography analysis | `fileId` |
| `components` | Component usage | `fileId` |
| `duplicates` | Find duplicates | `fileId` |
## Example Usage
### List all projects
```json
{
"tool": "penpot_projects",
"arguments": {
"action": "list"
}
}
```
### Search for files
```json
{
"tool": "penpot_search",
"arguments": {
"action": "files",
"query": "dashboard"
}
}
```
### Export component as PNG
```json
{
"tool": "penpot_exports",
"arguments": {
"action": "export",
"fileId": "file-uuid",
"objectId": "object-uuid",
"format": "png",
"scale": 2
}
}
```
### Get design tokens as CSS
```json
{
"tool": "penpot_tokens",
"arguments": {
"action": "export_css",
"fileId": "file-uuid"
}
}
```
### Analyze design system
```json
{
"tool": "penpot_analyze",
"arguments": {
"action": "design_system",
"fileId": "file-uuid"
}
}
```
## Development
```bash
# Development mode with hot reload
npm run dev
# Build
npm run build
# Run tests
npm test
```
## API Reference
This MCP server uses Penpot's RPC API with Transit+JSON encoding:
- UUIDs are encoded with `~u` prefix
- Keywords are encoded with `~:` prefix
- All requests go through `/rpc/command/{command-name}`
## License
MIT