mirror of
https://github.com/penpot/penpot-mcp.git
synced 2026-04-25 03:08:19 +00:00
Restructuring, improving README structure and npm commands
This commit is contained in:
parent
cb5dbcfb06
commit
cbac84bab2
171
README.md
171
README.md
@ -1,122 +1,111 @@
|
||||
# The Penpot MCP Server
|
||||
|
||||
This system enables LLMs to interact with Penpot design projects through a Model Context Protocol (MCP) server and plugin architecture.
|
||||
|
||||
## Quick Start
|
||||
|
||||
If it's your first execution, install and build all components before starting:
|
||||
```shell
|
||||
npm install
|
||||
npm run install-all-and-start
|
||||
```
|
||||
|
||||
Otherwise, just start all components:
|
||||
```shell
|
||||
npm run start
|
||||
```
|
||||
|
||||
Then proceed with loading the plugin and connecting to the MCP server as described in [steps 3-4](#step-3-load-plugin-in-penpot)
|
||||
|
||||
You can also install and build the components without starting them:
|
||||
```shell
|
||||
npm run install-all
|
||||
npm run build-all
|
||||
```
|
||||
This project enables LLMs to interact directly with Penpot design projects
|
||||
through a Model Context Protocol (MCP) server and plugin architecture.
|
||||
|
||||
## Architecture
|
||||
|
||||
The system consists of three main components:
|
||||
This repository is a monorepo containing four main components:
|
||||
|
||||
1. **Common Types** (`common/`):
|
||||
- Shared TypeScript definitions for request/response protocol
|
||||
- Ensures type safety across server and plugin components
|
||||
- Defines `PluginTaskResult`, request/response interfaces, and task parameters
|
||||
|
||||
2. **MCP Server** (`mcp-server/`):
|
||||
2. **Penpot MCP Server** (`mcp-server/`):
|
||||
- Provides MCP tools to LLMs for Penpot interaction
|
||||
- Runs WebSocket server accepting connections from Penpot plugins
|
||||
- Runs a WebSocket server accepting connections from the Penpot MCP plugin
|
||||
- Implements request/response correlation with unique task IDs
|
||||
- Handles task timeouts and proper error reporting
|
||||
|
||||
3. **Penpot Plugin** (`penpot-plugin/`):
|
||||
- Connects to MCP server via WebSocket
|
||||
3. **Penpot MCP Plugin** (`penpot-plugin/`):
|
||||
- Connects to the MCP server via WebSocket
|
||||
- Executes tasks in Penpot using the Plugin API
|
||||
- Sends structured responses back to server with success/failure status
|
||||
- Sends structured responses back to the server#
|
||||
|
||||
## Protocol Flow
|
||||
4. **Helper Scripts** (`helper/`):
|
||||
- Python scripts that prepare data for the MCP server (development use)
|
||||
|
||||
```
|
||||
LLM → MCP Server → WebSocket → Penpot Plugin → Penpot API
|
||||
↓ ↓ ↓
|
||||
Tool Call Task Request Execute Action
|
||||
↑ ↑ ↑
|
||||
LLM ← MCP Server ← WebSocket ← Penpot Plugin ← Result
|
||||
## Usage
|
||||
|
||||
### Build & Launch the MCP Server and the Plugin Server
|
||||
|
||||
If it's your first execution, install the required dependencies:
|
||||
```shell
|
||||
npm install
|
||||
```
|
||||
|
||||
### Request Format
|
||||
```
|
||||
{
|
||||
id: string, // Unique UUID for correlation
|
||||
task: string, // Task type (e.g., "printText")
|
||||
params: object // Task-specific parameters
|
||||
}
|
||||
Then build all components and start them:
|
||||
```shell
|
||||
npm run bootstrap
|
||||
```
|
||||
|
||||
### Response Format
|
||||
```
|
||||
{
|
||||
id: string, // Matching request ID
|
||||
result: {
|
||||
success: boolean, // Task completion status
|
||||
error?: string, // Error message if failed
|
||||
data?: any // Optional result data
|
||||
}
|
||||
}
|
||||
```
|
||||
This bootstrap command will:
|
||||
* install dependencies for all components (`npm run install:all`)
|
||||
* build all components (`npm run build:all`)
|
||||
* start all components (`npm run start:all`)
|
||||
|
||||
## Testing the Connection
|
||||
|
||||
For each component, run `npm install` before running other commands
|
||||
if you haven't installed the component in the past.
|
||||
|
||||
### Step 0: Build the common components
|
||||
|
||||
```bash
|
||||
cd common
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Step 1: Start the MCP Server
|
||||
|
||||
```bash
|
||||
cd mcp-server
|
||||
npm run build
|
||||
npm start
|
||||
```
|
||||
|
||||
### Step 2: Build and Run the Plugin
|
||||
|
||||
```bash
|
||||
cd penpot-plugin
|
||||
npm run build
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Step 3: Load Plugin in Penpot
|
||||
### Load the Plugin in Penpot and Establish the Connection
|
||||
|
||||
1. Open Penpot in your browser
|
||||
2. Navigate to a design file
|
||||
3. Go to Plugins menu
|
||||
4. Load the plugin using the development URL (typically `http://localhost:4400/manifest.json`)
|
||||
3. Open the Plugins menu
|
||||
4. Load the plugin using the development URL (`http://localhost:4400/manifest.json` by default)
|
||||
5. Open the plugin UI
|
||||
6. In the plugin UI, click "Connect to MCP server".
|
||||
The connection status should change from "Not connected" to "Connected to MCP server".
|
||||
(Check the browser's developer console for WebSocket connection logs.
|
||||
Check the MCP server terminal for WebSocket connection messages.)
|
||||
|
||||
### Step 4: Test the Connection
|
||||
### Connecting an MCP Client
|
||||
|
||||
1. In the plugin UI, click "Connect to MCP server"
|
||||
2. The connection status should change from "Not connected" to "Connected to MCP server"
|
||||
3. Check the browser's developer console for WebSocket connection logs
|
||||
4. Check the MCP server terminal for WebSocket connection messages
|
||||
By default, the server runs on port 4401 and provides:
|
||||
|
||||
### Step 5: Use an MCP Client to Interact with the Penpot Project
|
||||
- **Modern Streamable HTTP endpoint**: `http://localhost:4401/mcp`
|
||||
- **Legacy SSE endpoint**: `http://localhost:4401/sse`
|
||||
|
||||
See [MCP Server README](mcp-server/README.md)
|
||||
These endpoints can be used directly by MCP clients that support them.
|
||||
Simply configure the client to the MCP server by providing the respective URL.
|
||||
|
||||
When using a client that only supports stdio transport,
|
||||
a proxy like `mcp-remote` is required.
|
||||
|
||||
#### Using a Proxy for stdio Transport
|
||||
|
||||
The `mcp-remote` package can proxy stdio transport to HTTP/SSE,
|
||||
allowing clients that support only stdio to connect to the MCP server indirectly.
|
||||
|
||||
1. Install `mcp-remote` globally if you haven't already:
|
||||
|
||||
npm install -g mcp-remote
|
||||
|
||||
2. Use `mcp-remote` to provide the launch command for your MCP client:
|
||||
|
||||
npx -y mcp-remote http://localhost:4401/sse --allow-http
|
||||
|
||||
#### Example: Claude Desktop
|
||||
|
||||
For Claude Desktop integration, you will need to use a proxy like `mcp-remote` since it only supports stdio transport.
|
||||
So install it as described above.
|
||||
|
||||
To add the server to Claude Desktop's configuration, locate the configuration file:
|
||||
|
||||
- **Windows**: `%APPDATA%/Claude/claude_desktop_config.json`
|
||||
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"penpot": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "mcp-remote", "http://localhost:4401/sse", "--allow-http"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After updating the configuration file, restart Claude Desktop completely for the changes to take effect.
|
||||
Be sure to fully quit the app! On Windows, right-click the tray icon and select "Quit".
|
||||
|
||||
After the restart, you should see the MCP server listed when clicking on the "Search and tools" icon at the bottom
|
||||
of the prompt input area.
|
||||
|
||||
14
common/package-lock.json
generated
14
common/package-lock.json
generated
@ -7,10 +7,24 @@
|
||||
"": {
|
||||
"name": "@penpot-mcp/common",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"penpot-mcp": "file:.."
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"..": {
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"concurrently": "^8.2.2",
|
||||
"kill-port": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/penpot-mcp": {
|
||||
"resolved": "..",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
|
||||
|
||||
@ -13,5 +13,8 @@
|
||||
},
|
||||
"files": [
|
||||
"dist/**/*"
|
||||
]
|
||||
],
|
||||
"dependencies": {
|
||||
"penpot-mcp": "file:.."
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
# Penpot MCP Server
|
||||
|
||||
A Model Context Protocol (MCP) server that provides Penpot integration capabilities for Claude Desktop and other MCP-compatible clients.
|
||||
A Model Context Protocol (MCP) server that provides Penpot integration
|
||||
capabilities for AI clients supporting the model context protocol (MCP).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js (tested with v20+)
|
||||
- Node.js (tested with v22)
|
||||
- npm (with npx on the PATH)
|
||||
|
||||
## Installation & Setup
|
||||
## Setup
|
||||
|
||||
1. Install Dependencies
|
||||
|
||||
cd mcp-server
|
||||
npm install
|
||||
|
||||
2. Build the Project
|
||||
@ -20,94 +20,8 @@ A Model Context Protocol (MCP) server that provides Penpot integration capabilit
|
||||
|
||||
3. Run the Server
|
||||
|
||||
- Development Mode (with TypeScript compilation):
|
||||
npm start
|
||||
|
||||
npm run dev
|
||||
|
||||
- Production Mode (requires build first):
|
||||
|
||||
npm start
|
||||
|
||||
|
||||
### Summary of Commands
|
||||
|
||||
| Command | Description |
|
||||
| ---------------------- | -------------------------------------- |
|
||||
| `npm install` | Install all dependencies |
|
||||
| `npm run build` | Compile TypeScript to JavaScript |
|
||||
| `npm run start` | Start the built server |
|
||||
| `npm run dev` | Start in development mode with ts-node |
|
||||
| `npm run format` | Format all files with Prettier |
|
||||
| `npm run format:check` | Check if files are properly formatted |
|
||||
|
||||
|
||||
## Client Integration
|
||||
|
||||
The MCP server supports both Streamable HTTP and legacy SSE transports, providing compatibility with various MCP clients.
|
||||
|
||||
Note that we do not support stdio transport directly, as clients tend to spawn multiple instances of the MCP server,
|
||||
and since the MCP server is also a WebSocket server, this would lead to port conflicts.
|
||||
Therefore, we recommend using a proxy like `mcp-remote` for clients that support stdio transport only (e.g., Claude Desktop).
|
||||
|
||||
### Starting the Server
|
||||
|
||||
First, build and start the MCP server:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
npm start
|
||||
```
|
||||
|
||||
By default, the server runs on port 4401 and provides:
|
||||
|
||||
- **Modern Streamable HTTP endpoint**: `http://localhost:4401/mcp`
|
||||
- **Legacy SSE endpoint**: `http://localhost:4401/sse`
|
||||
|
||||
### Using a Proxy for stdio Transport
|
||||
|
||||
The `mcp-remote` package can proxy stdio transport to HTTP/SSE.
|
||||
|
||||
1. Install `mcp-remote` globally if you haven't already:
|
||||
|
||||
npm install -g mcp-remote
|
||||
|
||||
2. Use `mcp-remote` to provide the launch command for your MCP client:
|
||||
|
||||
npx -y mcp-remote http://localhost:4401/sse --allow-http
|
||||
|
||||
### Claude Desktop
|
||||
|
||||
For Claude Desktop integration, you will need to use a proxy like `mcp-remote` since it only supports stdio transport.
|
||||
So install it as described above.
|
||||
|
||||
To add the server to Claude Desktop's configuration, locate the configuration file:
|
||||
|
||||
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
||||
- **Windows**: `%APPDATA%/Claude/claude_desktop_config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"penpot": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "mcp-remote", "http://localhost:4401/sse", "--allow-http"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After updating the configuration file, restart Claude Desktop completely for the changes to take effect.
|
||||
Be sure to fully quit the app! On Windows, right-click the tray icon and select "Quit".
|
||||
|
||||
After the restart, you should see the MCP server listed when clicking on the "Search and tools" icon at the bottom
|
||||
of the prompt input area.
|
||||
|
||||
### Other MCP Clients
|
||||
|
||||
For MCP clients that support HTTP transport directly, use:
|
||||
|
||||
- Streamable HTTP for modern clients: `http://localhost:4401/mcp`
|
||||
- SSE for legacy clients: `http://localhost:4401/sse`
|
||||
|
||||
## Penpot Plugin API REPL
|
||||
|
||||
|
||||
12
mcp-server/package-lock.json
generated
12
mcp-server/package-lock.json
generated
@ -15,6 +15,7 @@
|
||||
"class-validator": "^0.14.0",
|
||||
"express": "^4.18.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"penpot-mcp": "file:..",
|
||||
"pino": "^9.10.0",
|
||||
"pino-pretty": "^13.1.1",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
@ -31,6 +32,13 @@
|
||||
"typescript": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"..": {
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"concurrently": "^8.2.2",
|
||||
"kill-port": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"../common": {
|
||||
"name": "@penpot-mcp/common",
|
||||
"version": "1.0.0",
|
||||
@ -1849,6 +1857,10 @@
|
||||
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/penpot-mcp": {
|
||||
"resolved": "..",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/pino": {
|
||||
"version": "9.10.0",
|
||||
"resolved": "https://registry.npmjs.org/pino/-/pino-9.10.0.tgz",
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
"class-validator": "^0.14.0",
|
||||
"express": "^4.18.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"penpot-mcp": "file:..",
|
||||
"pino": "^9.10.0",
|
||||
"pino-pretty": "^13.1.1",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
|
||||
@ -3,10 +3,10 @@
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"install-all": "concurrently --names \"COMMON,MCP-SERVER,PLUGIN\" --prefix-colors \"green,cyan,magenta\" \"npm --prefix common install\" \"npm --prefix mcp-server install\" \"npm --prefix penpot-plugin install\"",
|
||||
"build-all": "concurrently --names \"COMMON,MCP-SERVER,PLUGIN\" --prefix-colors \"green,cyan,magenta\" --success first \"npm --prefix common install && npm --prefix common run build\" \"npm --prefix mcp-server run build\" \"npm --prefix penpot-plugin run build\"",
|
||||
"start": "concurrently --names \"MCP-SERVER,PLUGIN-SERVER\" --prefix-colors \"cyan,magenta\" --kill-others-on-fail \"npm --prefix mcp-server start\" \"npm --prefix penpot-plugin run dev\"",
|
||||
"install-all-and-start": "npm run install-all && npm run build-all && concurrently --names \"MCP-SERVER,PLUGIN-SERVER\" --prefix-colors \"cyan,magenta\" --kill-others-on-fail \"npm --prefix mcp-server start\" \"npm --prefix penpot-plugin run dev\""
|
||||
"install:all": "concurrently --names \"COMMON,MCP-SERVER,PLUGIN\" --prefix-colors \"green,cyan,magenta\" \"npm --prefix common install\" \"npm --prefix mcp-server install\" \"npm --prefix penpot-plugin install\"",
|
||||
"build:all": "concurrently --names \"COMMON,MCP-SERVER,PLUGIN\" --prefix-colors \"green,cyan,magenta\" --success first \"npm --prefix common install && npm --prefix common run build\" \"npm --prefix mcp-server run build\" \"npm --prefix penpot-plugin run build\"",
|
||||
"start:all": "concurrently --names \"MCP-SERVER,PLUGIN-SERVER\" --prefix-colors \"cyan,magenta\" --kill-others-on-fail \"npm --prefix mcp-server start\" \"npm --prefix penpot-plugin run dev\"",
|
||||
"bootstrap": "npm run install:all && npm run build:all && npm run start:all"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
1
penpot-plugin/.prettierignore
Normal file
1
penpot-plugin/.prettierignore
Normal file
@ -0,0 +1 @@
|
||||
*.md
|
||||
21
penpot-plugin/README.md
Normal file
21
penpot-plugin/README.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Penpot MCP Plugin
|
||||
|
||||
This project contains a Penpot plugin that accompanies the Penpot MCP server.
|
||||
It connects to the MCP server via WebSocket, subsequently allowing the MCP
|
||||
server to execute tasks in Penpot using the Plugin API.
|
||||
|
||||
## Setup
|
||||
|
||||
1. Install Dependencies
|
||||
|
||||
npm install
|
||||
|
||||
2. Build the Project
|
||||
|
||||
npm run build
|
||||
|
||||
3. Start a Local Development Server
|
||||
|
||||
npm run dev start
|
||||
|
||||
This will start a local development server at `http://localhost:4400`.
|
||||
14
penpot-plugin/package-lock.json
generated
14
penpot-plugin/package-lock.json
generated
@ -10,7 +10,8 @@
|
||||
"dependencies": {
|
||||
"@penpot-mcp/common": "file:../common",
|
||||
"@penpot/plugin-styles": "1.3.2",
|
||||
"@penpot/plugin-types": "1.3.2"
|
||||
"@penpot/plugin-types": "1.3.2",
|
||||
"penpot-mcp": "file:.."
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.0.0",
|
||||
@ -19,6 +20,13 @@
|
||||
"vite-live-preview": "^0.3.2"
|
||||
}
|
||||
},
|
||||
"..": {
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"concurrently": "^8.2.2",
|
||||
"kill-port": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"../common": {
|
||||
"name": "@penpot-mcp/common",
|
||||
"version": "1.0.0",
|
||||
@ -937,6 +945,10 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/penpot-mcp": {
|
||||
"resolved": "..",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
|
||||
@ -10,9 +10,10 @@
|
||||
"format:check": "prettier --check ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@penpot-mcp/common": "file:../common",
|
||||
"@penpot/plugin-styles": "1.3.2",
|
||||
"@penpot/plugin-types": "1.3.2",
|
||||
"@penpot-mcp/common": "file:../common"
|
||||
"penpot-mcp": "file:.."
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.0.0",
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
# Preparation of API Documentation for the MCP Server
|
||||
|
||||
The script `prepare_api_docs.py` read API documentation from the Web
|
||||
and collects it in a single yaml file, which is then used by an MCP
|
||||
tool to provide API documentation to an LLM on demand.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Pixi is used for environment management.
|
||||
|
||||
Install the environment via:
|
||||
|
||||
pixi install
|
||||
|
||||
## Running the Script
|
||||
|
||||
To run the script, use:
|
||||
|
||||
pixi run python prepare_api_docs.py
|
||||
|
||||
This will generate `../mcp-server/data/api_types.yml`.
|
||||
26
python-scripts/README.md
Normal file
26
python-scripts/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Helper Scripts for the Penpot MCP Server
|
||||
|
||||
This subproject contains helper scripts used in the development of the
|
||||
Penpot MCP server.
|
||||
|
||||
## Setup
|
||||
|
||||
This project uses [pixi](https://pixi.sh) for environment management.
|
||||
|
||||
Install the environment via
|
||||
|
||||
pixi install
|
||||
|
||||
## Scripts
|
||||
|
||||
### Preparation of API Documentation for the MCP Server
|
||||
|
||||
The script `prepare_api_docs.py` reads API documentation from the Web
|
||||
and collects it in a single yaml file, which is then used by an MCP
|
||||
tool to provide API documentation to an LLM on demand.
|
||||
|
||||
Running the script:
|
||||
|
||||
pixi run python prepare_api_docs.py
|
||||
|
||||
This will generate `../mcp-server/data/api_types.yml`.
|
||||
@ -1,8 +1,8 @@
|
||||
[project]
|
||||
authors = ["Dominik Jain <dominik.jain@outlook.com>"]
|
||||
authors = ["Oraios AI <info@oraios-ai.de>"]
|
||||
channels = ["conda-forge"]
|
||||
description = "Add a short description here"
|
||||
name = "prepare-api-docs"
|
||||
description = "Scripts supporting the development of the Penpot MCP server"
|
||||
name = "penpot-mcp-scripts"
|
||||
platforms = ["win-64"]
|
||||
version = "0.1.0"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user