mirror of
https://github.com/penpot/penpot.git
synced 2026-08-06 12:58:55 +00:00
Merge pull request #8416 from penpot/luis-revert-mcp-changes
Revert "✨ MCP changes to improve handling of use cases 2 & 3…
This commit is contained in:
commit
3f277b7daf
@ -50,45 +50,31 @@ Follow the steps below to enable the integration.
|
|||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
The project requires [Node.js](https://nodejs.org/) (tested with v22.x).
|
The project requires [Node.js](https://nodejs.org/) (tested with v22.x
|
||||||
Following the installation of Node.js, the tools `corepack` and `npx`
|
with corepack).
|
||||||
should be available in your terminal.
|
|
||||||
|
|
||||||
On Windows, use the Git Bash terminal to ensure compatibility with the provided scripts.
|
Following the installation of Node.js, the tools `pnpm` and `npx`
|
||||||
|
should be available in your terminal. For ensure corepack installed
|
||||||
|
and enabled correctly, just execute the `./scripts/setup`.
|
||||||
|
|
||||||
### 0. Clone the Appropriate Branch of the Repository
|
It is also required to have `caddy` executeable in the path, it is
|
||||||
|
used for start a local server for generate types documentation from
|
||||||
|
the current branch. If you want to run it outside devenv where all
|
||||||
|
dependencies are already provided, please download caddy from
|
||||||
|
[here](https://caddyserver.com/download).
|
||||||
|
|
||||||
> [!IMPORTANT]
|
You should probably be using penpot devenv, where all this
|
||||||
> The branches are subject to change in the future.
|
dependencies are already present and correctly setup. But nothing
|
||||||
> Be sure to check the instructions for the latest information on which branch to use.
|
prevents you execute this outside of devenv if you satisfy the
|
||||||
|
specified dependencies.
|
||||||
|
|
||||||
Clone the Penpot repository, using the proper branch depending on the
|
|
||||||
version of Penpot you want to use the MCP server with.
|
|
||||||
|
|
||||||
* For released versions of Penpot, use the `mcp-prod` branch:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
git clone https://github.com/penpot/penpot.git --branch mcp-prod --depth 1
|
|
||||||
```
|
|
||||||
|
|
||||||
* For the latest development version of Penpot, use the `develop` branch:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
git clone https://github.com/penpot/penpot.git --branch develop --depth 1
|
|
||||||
```
|
|
||||||
|
|
||||||
Then change into the `mcp` directory:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
cd penpot/mcp
|
|
||||||
```
|
|
||||||
|
|
||||||
### 1. Build & Launch the MCP Server and the Plugin Server
|
### 1. Build & Launch the MCP Server and the Plugin Server
|
||||||
|
|
||||||
If it's your first execution, install the required dependencies.
|
If it's your first execution, install the required dependencies:
|
||||||
(If you are using the Penpot devenv, this step is not necessary, as dependencies are already installed.)
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
cd mcp/
|
||||||
./scripts/setup
|
./scripts/setup
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -100,9 +86,9 @@ pnpm run bootstrap
|
|||||||
|
|
||||||
This bootstrap command will:
|
This bootstrap command will:
|
||||||
|
|
||||||
* install dependencies for all components
|
* install dependencies for all components (`pnpm -r run install`)
|
||||||
* build all components
|
* build all components (`pnpm -r run build`)
|
||||||
* start all components
|
* start all components (`pnpm -r --parallel run start`)
|
||||||
|
|
||||||
### 2. Load the Plugin in Penpot and Establish the Connection
|
### 2. Load the Plugin in Penpot and Establish the Connection
|
||||||
|
|
||||||
@ -209,30 +195,31 @@ To add the Penpot MCP server to a Claude Code project, issue the command
|
|||||||
|
|
||||||
This repository is a monorepo containing four main components:
|
This repository is a monorepo containing four main components:
|
||||||
|
|
||||||
1. **Common Types** (`packages/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
|
||||||
|
|
||||||
2. **Penpot MCP Server** (`packages/server/`):
|
2. **Penpot MCP Server** (`mcp-server/`):
|
||||||
- Provides MCP tools to LLMs for Penpot interaction
|
- Provides MCP tools to LLMs for Penpot interaction
|
||||||
- Runs a WebSocket server accepting connections from the Penpot MCP plugin
|
- 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 MCP Plugin** (`packages/plugin/`):
|
3. **Penpot MCP Plugin** (`penpot-plugin/`):
|
||||||
- Connects to the 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 the server#
|
- Sends structured responses back to the server#
|
||||||
|
|
||||||
4. **Types Generator** (`types-generator/`):
|
4. **Helper Scripts** (`python-scripts/`):
|
||||||
- Generates data on API types for the MCP server (development use)
|
- Python scripts that prepare data for the MCP server (development use)
|
||||||
|
|
||||||
The core components are written in TypeScript, rendering interactions with the
|
The core components are written in TypeScript, rendering interactions with the
|
||||||
Penpot Plugin API both natural and type-safe.
|
Penpot Plugin API both natural and type-safe.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The Penpot MCP server can be configured using environment variables.
|
The Penpot MCP server can be configured using environment variables. All configuration
|
||||||
|
options use the `PENPOT_MCP_` prefix for consistency.
|
||||||
|
|
||||||
### Server Configuration
|
### Server Configuration
|
||||||
|
|
||||||
@ -276,9 +263,3 @@ you may set the following environment variables to configure the two servers
|
|||||||
* `PENPOT_MCP_SERVER_ADDRESS=<your-address>`: This sets the hostname or IP address
|
* `PENPOT_MCP_SERVER_ADDRESS=<your-address>`: This sets the hostname or IP address
|
||||||
where the MCP server can be reached. The Penpot MCP Plugin uses this to construct
|
where the MCP server can be reached. The Penpot MCP Plugin uses this to construct
|
||||||
the WebSocket URL as `ws://<your-address>:<port>` (default port: `4402`).
|
the WebSocket URL as `ws://<your-address>:<port>` (default port: `4402`).
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
* The [contribution guidelines for Penpot](../CONTRIBUTING.md) apply
|
|
||||||
* Auto-formatting: Use `pnpm run fmt`
|
|
||||||
* Generating API type data: See [types-generator/README.md](types-generator/README.md)
|
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
You have access to Penpot tools in order to interact with a Penpot design project directly.
|
You have access to Penpot tools in order to interact with a Penpot design project directly.
|
||||||
As a precondition, the user must connect the Penpot design project to the MCP server using the Penpot MCP Plugin.
|
As a precondition, the user must connect the Penpot design project to the MCP server using the Penpot MCP Plugin.
|
||||||
|
|
||||||
|
IMPORTANT: When transferring styles from a Penpot design to code, make sure that you strictly adhere to the design.
|
||||||
|
NEVER make assumptions about missing values and don't get overly creative (e.g. don't pick your own colours and stick to
|
||||||
|
non-creative defaults such as white/black if you are lacking information).
|
||||||
|
|
||||||
# Executing Code
|
# Executing Code
|
||||||
|
|
||||||
One of your key tools is the `execute_code` tool, which allows you to run JavaScript code using the Penpot Plugin API
|
One of your key tools is the `execute_code` tool, which allows you to run JavaScript code using the Penpot Plugin API
|
||||||
@ -44,8 +48,6 @@ Actual low-level shape types are `Rectangle`, `Path`, `Text`, `Ellipse`, `Image`
|
|||||||
**Other Writable Properties**:
|
**Other Writable Properties**:
|
||||||
* `name` - Shape name
|
* `name` - Shape name
|
||||||
* `fills`, `strokes` - Styling properties
|
* `fills`, `strokes` - Styling properties
|
||||||
IMPORTANT: The contents of the arrays are read-only. You cannot modify individual fills/strokes; you need to replace the entire array to change them, e.g.
|
|
||||||
`shape.fills = [{ fillColor: "#FF0000", fillOpacity: 1 }]` to set a single red fill.
|
|
||||||
* `rotation`, `opacity`, `blocked`, `hidden`, `visible`
|
* `rotation`, `opacity`, `blocked`, `hidden`, `visible`
|
||||||
|
|
||||||
**Z-Order**:
|
**Z-Order**:
|
||||||
@ -97,12 +99,11 @@ Boards can have layout systems that automatically control the positioning and sp
|
|||||||
- `dir`: "row" | "column" | "row-reverse" | "column-reverse"
|
- `dir`: "row" | "column" | "row-reverse" | "column-reverse"
|
||||||
- Padding: `topPadding`, `rightPadding`, `bottomPadding`, `leftPadding`, or combined `verticalPadding`, `horizontalPadding`
|
- Padding: `topPadding`, `rightPadding`, `bottomPadding`, `leftPadding`, or combined `verticalPadding`, `horizontalPadding`
|
||||||
- To modify spacing: adjust `rowGap` and `columnGap` properties, not individual child positions.
|
- To modify spacing: adjust `rowGap` and `columnGap` properties, not individual child positions.
|
||||||
Optionally, adjust individual child margins via `child.layoutChild`.
|
Optionally, adjust indivudual child margins via `child.layoutChild`.
|
||||||
- Sizing: `verticalSizing` and `horizontalSizing` are NOT functional. You need to size manually for the time being.
|
|
||||||
- When a board has flex layout,
|
- When a board has flex layout,
|
||||||
- child positions are controlled by the layout system, not by individual x/y coordinates (unless `child.layoutChild.absolute` is true);
|
- child positions are controlled by the layout system, not by individual x/y coordinates (unless `child.layoutChild.absolute` is true);
|
||||||
appending or inserting children automatically positions them according to the layout rules.
|
appending or inserting children automatically positions them according to the layout rules.
|
||||||
- CRITICAL: For dir="column" or dir="row", the order of the `children` array is reversed relative to the visual order!
|
- CRITICAL: For for dir="column" or dir="row", the order of the `children` array is reversed relative to the visual order!
|
||||||
Therefore, the element that appears first in the array, appears visually at the end (bottom/right) and vice versa.
|
Therefore, the element that appears first in the array, appears visually at the end (bottom/right) and vice versa.
|
||||||
ALWAYS BEAR IN MIND THAT THE CHILDREN ARRAY ORDER IS REVERSED FOR dir="column" OR dir="row"!
|
ALWAYS BEAR IN MIND THAT THE CHILDREN ARRAY ORDER IS REVERSED FOR dir="column" OR dir="row"!
|
||||||
- CRITICAL: The FlexLayout method `board.flex.appendChild` is BROKEN. To append children to a flex layout board such that
|
- CRITICAL: The FlexLayout method `board.flex.appendChild` is BROKEN. To append children to a flex layout board such that
|
||||||
@ -209,6 +210,19 @@ Common tasks - Quick Reference (ALWAYS use penpotUtils for these):
|
|||||||
});
|
});
|
||||||
Always validate against the root container that is supposed to contain the shapes.
|
Always validate against the root container that is supposed to contain the shapes.
|
||||||
|
|
||||||
|
# Visual Inspection of Designs
|
||||||
|
|
||||||
|
For many tasks, it can be critical to visually inspect the design. Remember to use the `export_shape` tool for this purpose!
|
||||||
|
|
||||||
|
# Revising Designs
|
||||||
|
|
||||||
|
* Before applying design changes, ask: "Would a designer consider this appropriate?"
|
||||||
|
* When dealing with containment issues, ask: Is the parent too small OR is the child too large?
|
||||||
|
Container sizes are usually intentional, check content first.
|
||||||
|
* Check for reasonable font sizes and typefaces
|
||||||
|
* The use of flex layouts is encouraged for cases where elements are arranged in rows or columns with consistent spacing/positioning.
|
||||||
|
Consider converting boards to flex layout when appropriate.
|
||||||
|
|
||||||
# Asset Libraries
|
# Asset Libraries
|
||||||
|
|
||||||
Libraries in Penpot are collections of reusable design assets (components, colors, and typographies) that can be shared across files.
|
Libraries in Penpot are collections of reusable design assets (components, colors, and typographies) that can be shared across files.
|
||||||
@ -268,15 +282,14 @@ The token library: `penpot.library.local.tokens` (type: `TokenCatalog`)
|
|||||||
* `tokens: Token[]` - All tokens in set
|
* `tokens: Token[]` - All tokens in set
|
||||||
* `addToken(type: TokenType, name: string, value: TokenValueString): Token` - Creates a token, adding it to the set.
|
* `addToken(type: TokenType, name: string, value: TokenValueString): Token` - Creates a token, adding it to the set.
|
||||||
- `TokenType`: "color" | "dimension" | "spacing" | "typography" | "shadow" | "opacity" | "borderRadius" | "borderWidth" | "fontWeights" | "fontSizes" | "fontFamilies" | "letterSpacing" | "textDecoration" | "textCase"
|
- `TokenType`: "color" | "dimension" | "spacing" | "typography" | "shadow" | "opacity" | "borderRadius" | "borderWidth" | "fontWeights" | "fontSizes" | "fontFamilies" | "letterSpacing" | "textDecoration" | "textCase"
|
||||||
- `value`: depends on the type of token (inspect `Token` and related types)
|
|
||||||
- Examples:
|
- Examples:
|
||||||
const token = set.addToken("color", "color.primary", "#0066FF"); // direct value
|
const token = set.addToken("color", "color.primary", "#0066FF"); // direct value
|
||||||
const token2 = set.addToken("color", "color.accent", "{color.primary}"); // reference to another token
|
const token2 = set.addToken("color", "color.accent", "{color.primary}"); // reference to another token
|
||||||
|
|
||||||
`Token`: union type encompassing various token types, with common properties:
|
`Token`:
|
||||||
* `name: string` - Token name (typically structured, e.g. "color.base.white")
|
* `name: string` - Token name (may include group path like "color.base.white")
|
||||||
* `value` - Raw value (direct value or reference to another token like "{color.primary}")
|
* `value: string | TokenValueString` - Raw value (may be direct value or reference to another token like "{color.primary}")
|
||||||
* `resolvedValue` - Computed final value (follows references) - currently NOT working, do not use!
|
* `resolvedValue` - Computed final value (follows references)
|
||||||
* `type: TokenType`
|
* `type: TokenType`
|
||||||
|
|
||||||
Discovering tokens:
|
Discovering tokens:
|
||||||
@ -316,24 +329,5 @@ Removing tokens:
|
|||||||
Simply set the respective property directly - token binding is automatically removed, e.g.
|
Simply set the respective property directly - token binding is automatically removed, e.g.
|
||||||
shape.fills = [{ fillColor: "#000000", fillOpacity: 1 }]; // Removes fill token
|
shape.fills = [{ fillColor: "#000000", fillOpacity: 1 }]; // Removes fill token
|
||||||
|
|
||||||
# Visual Inspection of Designs
|
|
||||||
|
|
||||||
For many tasks, it can be critical to visually inspect the design. Remember to use the `export_shape` tool for this purpose!
|
|
||||||
|
|
||||||
# Creating and Translating Designs
|
|
||||||
|
|
||||||
* When transferring styles from a Penpot design to code, make sure that you strictly adhere to the design.
|
|
||||||
NEVER make assumptions about missing values and don't get overly creative (e.g. don't pick your own colours and stick to
|
|
||||||
non-creative defaults such as white/black if you are lacking information).
|
|
||||||
|
|
||||||
# Revising Designs
|
|
||||||
|
|
||||||
* Before applying design changes, ask: "Would a designer consider this appropriate?"
|
|
||||||
* When dealing with containment issues, ask: Is the parent too small OR is the child too large?
|
|
||||||
Container sizes are usually intentional, check content first.
|
|
||||||
* Check for reasonable font sizes and typefaces
|
|
||||||
* The use of flex layouts is encouraged for cases where elements are arranged in rows or columns with consistent spacing/positioning.
|
|
||||||
Consider converting boards to flex layout when appropriate.
|
|
||||||
|
|
||||||
--
|
--
|
||||||
You have hereby read the 'Penpot High-Level Overview' and need not use a tool to read it again.
|
You have hereby read the 'Penpot High-Level Overview' and need not use a tool to read it again.
|
||||||
|
|||||||
@ -53,10 +53,9 @@ export class ExecuteCodeTool extends Tool<ExecuteCodeArgs> {
|
|||||||
"could come in handy later should be stored in `storage` instead of just a fleeting variable; " +
|
"could come in handy later should be stored in `storage` instead of just a fleeting variable; " +
|
||||||
"you can also store functions and thus build up a library).\n" +
|
"you can also store functions and thus build up a library).\n" +
|
||||||
"Think of the code being executed as the body of a function: " +
|
"Think of the code being executed as the body of a function: " +
|
||||||
"The tool call returns whatever you return in the applicable `return` statement, if any. " +
|
"The tool call returns whatever you return in the applicable `return` statement, if any.\n" +
|
||||||
"You can return arbitrary JS objects; no need to apply JSON.stringify.\n" +
|
|
||||||
"If an exception occurs, the exception's message will be returned to you.\n" +
|
"If an exception occurs, the exception's message will be returned to you.\n" +
|
||||||
"Any output that you generate via the `console` object will be returned to you separately; so you may use it " +
|
"Any output that you generate via the `console` object will be returned to you separately; so you may use it" +
|
||||||
"to track what your code is doing, but you should *only* do so only if there is an ACTUAL NEED for this! " +
|
"to track what your code is doing, but you should *only* do so only if there is an ACTUAL NEED for this! " +
|
||||||
"VERY IMPORTANT: Don't use logging prematurely! NEVER log the data you are returning, as you will otherwise receive it twice!\n" +
|
"VERY IMPORTANT: Don't use logging prematurely! NEVER log the data you are returning, as you will otherwise receive it twice!\n" +
|
||||||
"VERY IMPORTANT: In general, try a simple approach first, and only if it fails, try more complex code that involves " +
|
"VERY IMPORTANT: In general, try a simple approach first, and only if it fails, try more complex code that involves " +
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user