Restructuring, improving README structure and npm commands

This commit is contained in:
Dominik Jain 2025-10-06 13:24:40 +02:00 committed by Dominik Jain
parent cb5dbcfb06
commit cbac84bab2
18 changed files with 186 additions and 213 deletions

181
README.md
View File

@ -1,122 +1,111 @@
# The Penpot MCP Server # The Penpot MCP Server
This system enables LLMs to interact with Penpot design projects through a Model Context Protocol (MCP) server and plugin architecture. This project enables LLMs to interact directly 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
```
## Architecture ## Architecture
The system consists of three main components: This repository is a monorepo containing four main components:
1. **Common Types** (`common/`): 1. **Common Types** (`common/`):
- Shared TypeScript definitions for request/response protocol - Shared TypeScript definitions for request/response protocol
- Ensures type safety across server and plugin components - 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 - 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 - Implements request/response correlation with unique task IDs
- Handles task timeouts and proper error reporting - Handles task timeouts and proper error reporting
3. **Penpot Plugin** (`penpot-plugin/`): 3. **Penpot MCP Plugin** (`penpot-plugin/`):
- Connects to MCP server via WebSocket - Connects to the MCP server via WebSocket
- Executes tasks in Penpot using the Plugin API - 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)
``` ## Usage
LLM → MCP Server → WebSocket → Penpot Plugin → Penpot API
↓ ↓ ↓ ### Build & Launch the MCP Server and the Plugin Server
Tool Call Task Request Execute Action
↑ ↑ ↑ If it's your first execution, install the required dependencies:
LLM ← MCP Server ← WebSocket ← Penpot Plugin ← Result ```shell
npm install
``` ```
### Request Format Then build all components and start them:
```shell
npm run bootstrap
``` ```
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`)
### Load the Plugin in Penpot and Establish the Connection
1. Open Penpot in your browser
2. Navigate to a design file
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.)
### Connecting an MCP Client
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`
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
{ {
id: string, // Unique UUID for correlation "mcpServers": {
task: string, // Task type (e.g., "printText") "penpot": {
params: object // Task-specific parameters "command": "npx",
} "args": ["-y", "mcp-remote", "http://localhost:4401/sse", "--allow-http"]
``` }
### Response Format
```
{
id: string, // Matching request ID
result: {
success: boolean, // Task completion status
error?: string, // Error message if failed
data?: any // Optional result data
} }
} }
``` ```
## Testing the Connection 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".
For each component, run `npm install` before running other commands After the restart, you should see the MCP server listed when clicking on the "Search and tools" icon at the bottom
if you haven't installed the component in the past. of the prompt input area.
### 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
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`)
5. Open the plugin UI
### Step 4: Test the Connection
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
### Step 5: Use an MCP Client to Interact with the Penpot Project
See [MCP Server README](mcp-server/README.md)

View File

@ -7,10 +7,24 @@
"": { "": {
"name": "@penpot-mcp/common", "name": "@penpot-mcp/common",
"version": "1.0.0", "version": "1.0.0",
"dependencies": {
"penpot-mcp": "file:.."
},
"devDependencies": { "devDependencies": {
"typescript": "^5.0.0" "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": { "node_modules/typescript": {
"version": "5.9.2", "version": "5.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",

View File

@ -13,5 +13,8 @@
}, },
"files": [ "files": [
"dist/**/*" "dist/**/*"
] ],
"dependencies": {
"penpot-mcp": "file:.."
}
} }

View File

@ -1,17 +1,17 @@
# Penpot MCP Server # 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 ## Prerequisites
- Node.js (tested with v20+) - Node.js (tested with v22)
- npm (with npx on the PATH) - npm (with npx on the PATH)
## Installation & Setup ## Setup
1. Install Dependencies 1. Install Dependencies
cd mcp-server
npm install npm install
2. Build the Project 2. Build the Project
@ -20,95 +20,9 @@ A Model Context Protocol (MCP) server that provides Penpot integration capabilit
3. Run the Server 3. Run the Server
- Development Mode (with TypeScript compilation):
npm run dev
- Production Mode (requires build first):
npm start 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 ## Penpot Plugin API REPL
The MCP server includes a REPL interface for testing Penpot Plugin API calls. The MCP server includes a REPL interface for testing Penpot Plugin API calls.

View File

@ -15,6 +15,7 @@
"class-validator": "^0.14.0", "class-validator": "^0.14.0",
"express": "^4.18.0", "express": "^4.18.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"penpot-mcp": "file:..",
"pino": "^9.10.0", "pino": "^9.10.0",
"pino-pretty": "^13.1.1", "pino-pretty": "^13.1.1",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
@ -31,6 +32,13 @@
"typescript": "^5.0.0" "typescript": "^5.0.0"
} }
}, },
"..": {
"version": "1.0.0",
"dependencies": {
"concurrently": "^8.2.2",
"kill-port": "^2.0.1"
}
},
"../common": { "../common": {
"name": "@penpot-mcp/common", "name": "@penpot-mcp/common",
"version": "1.0.0", "version": "1.0.0",
@ -1849,6 +1857,10 @@
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/penpot-mcp": {
"resolved": "..",
"link": true
},
"node_modules/pino": { "node_modules/pino": {
"version": "9.10.0", "version": "9.10.0",
"resolved": "https://registry.npmjs.org/pino/-/pino-9.10.0.tgz", "resolved": "https://registry.npmjs.org/pino/-/pino-9.10.0.tgz",

View File

@ -28,6 +28,7 @@
"class-validator": "^0.14.0", "class-validator": "^0.14.0",
"express": "^4.18.0", "express": "^4.18.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"penpot-mcp": "file:..",
"pino": "^9.10.0", "pino": "^9.10.0",
"pino-pretty": "^13.1.1", "pino-pretty": "^13.1.1",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",

View File

@ -3,10 +3,10 @@
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"scripts": { "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\"", "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\"", "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\"", "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\"",
"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\"" "bootstrap": "npm run install:all && npm run build:all && npm run start:all"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -0,0 +1 @@
*.md

21
penpot-plugin/README.md Normal file
View 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`.

View File

@ -10,7 +10,8 @@
"dependencies": { "dependencies": {
"@penpot-mcp/common": "file:../common", "@penpot-mcp/common": "file:../common",
"@penpot/plugin-styles": "1.3.2", "@penpot/plugin-styles": "1.3.2",
"@penpot/plugin-types": "1.3.2" "@penpot/plugin-types": "1.3.2",
"penpot-mcp": "file:.."
}, },
"devDependencies": { "devDependencies": {
"prettier": "^3.0.0", "prettier": "^3.0.0",
@ -19,6 +20,13 @@
"vite-live-preview": "^0.3.2" "vite-live-preview": "^0.3.2"
} }
}, },
"..": {
"version": "1.0.0",
"dependencies": {
"concurrently": "^8.2.2",
"kill-port": "^2.0.1"
}
},
"../common": { "../common": {
"name": "@penpot-mcp/common", "name": "@penpot-mcp/common",
"version": "1.0.0", "version": "1.0.0",
@ -937,6 +945,10 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/penpot-mcp": {
"resolved": "..",
"link": true
},
"node_modules/picocolors": { "node_modules/picocolors": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",

View File

@ -10,9 +10,10 @@
"format:check": "prettier --check ." "format:check": "prettier --check ."
}, },
"dependencies": { "dependencies": {
"@penpot-mcp/common": "file:../common",
"@penpot/plugin-styles": "1.3.2", "@penpot/plugin-styles": "1.3.2",
"@penpot/plugin-types": "1.3.2", "@penpot/plugin-types": "1.3.2",
"@penpot-mcp/common": "file:../common" "penpot-mcp": "file:.."
}, },
"devDependencies": { "devDependencies": {
"prettier": "^3.0.0", "prettier": "^3.0.0",

View File

@ -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
View 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`.

View File

@ -1,8 +1,8 @@
[project] [project]
authors = ["Dominik Jain <dominik.jain@outlook.com>"] authors = ["Oraios AI <info@oraios-ai.de>"]
channels = ["conda-forge"] channels = ["conda-forge"]
description = "Add a short description here" description = "Scripts supporting the development of the Penpot MCP server"
name = "prepare-api-docs" name = "penpot-mcp-scripts"
platforms = ["win-64"] platforms = ["win-64"]
version = "0.1.0" version = "0.1.0"