Model or dataset
penpot/penpot-mcp avatar
penpot/penpot-mcp

penpot-mcp drives a live Penpot file through a plugin WebSocket, and needs three processes running

Penpot's official MCP Server

535 stars73 forksTypeScriptMPL-2.0

At a glance

What is it?
The official Model Context Protocol server for Penpot, exposing tools that read and modify a design file by executing code inside a Penpot plugin. The repository says it was folded into the main Penpot tree in February 2026, the setup depends on three running processes, and Chromium's private network access rules sit squarely in the middle of it.
Who is it for?
penpot-mcp is for someone who wants an agent editing a real design file rather than describing a design in prose, and the plugin bridge is what makes that possible rather than a thin API wrapper. The cost is operational: a Node server, a plugin web server and a browser tab that must stay open, plus a browser permission prompt you will meet again after every Chromium upgrade.
Can I use it commercially?
Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
No. The owners have archived the repository on GitHub, so it is read-only and no longer receives changes.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • penpot/penpot-mcp535 ★ · +38
Star history
Repository2026-09-122026-11-14
penpot/penpot-mcp497535

38 Stars in the last 63 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The file says archived, the metadata says otherwise

The first element in the documentation is an important notice, and it changes what this repository is for. It states that the repository was archived on 2026-02-03 and that its contents have been fully integrated into the main Penpot repository, with a link to the `mcp` directory on the `develop` branch there. GitHub now marks this repository as archived and read-only. The README points to the main Penpot repository for the integrated code. Practically, that means fixes and new capabilities arrive in the Penpot repository, and anyone reading this file for setup instructions should check the newer location before assuming a problem is unfixed.

Three processes, and closing the plugin UI drops the socket

Using the server needs three things alive at once, and they are given as separate requirements rather than buried in a script. You run the MCP server and point an AI client at it. You run the web server that serves the Penpot MCP plugin. And you open that plugin inside Penpot and connect it to the server. The connection runs over a WebSocket, which is why the third item is a browser tab rather than a background process. The plugin is loaded the usual developer way: open Penpot, navigate to a design file, open the Plugins menu, and load it from its development URL, which is `http://localhost:4400/manifest.json` by default. Inside the plugin UI you click Connect to MCP server and the status moves from Not connected to Connected. There is an explicit warning not to close that plugin window while the server is in use, because closing it closes the connection, and both the browser console and the server terminal print WebSocket messages when something goes wrong.

npm run bootstrap installs, builds and starts three components

The setup is one command once dependencies are present:

shell
npm install
shell
npm run bootstrap

Bootstrap chains three scripts, `install:all` then `build:all` then `start:all`, and each of those fans out with `concurrently` across the monorepo's packages rather than building one thing. The names are passed explicitly as COMMON, MCP-SERVER and PLUGIN with green, cyan and magenta prefixes, which is more helpful than it sounds when three installs are streaming past at once. `start:all` adds `--kill-others-on-fail`, so if the MCP server dies the plugin server is taken down with it instead of leaving a half-working pair. The root dependency list is two packages, `concurrently` and `kill-port`, which tells you the port conflict handling is deliberate. Prerequisite is Node.js, tested with v22, with `npm` and `npx` on the path. A parallel `bootstrap:multi-user` variant exists, differing only in building and starting the plugin in its multi-user mode.

Port 4401 speaks Streamable HTTP and legacy SSE

By default the server listens on port 4401 and offers two endpoints: a modern Streamable HTTP one at `http://localhost:4401/mcp`, and a legacy SSE endpoint at `http://localhost:4401/sse`. Clients that support either can be pointed straight at the URL. Clients that speak only stdio need a bridge, and the one named is `mcp-remote`, installed with `npm install -g mcp-remote` and invoked per connection:

shell
npx -y mcp-remote http://localhost:4401/sse --allow-http

The `--allow-http` flag is what permits a plain HTTP endpoint, so leaving it out tends to produce a connection that refuses to start. Claude Desktop is the worked example: its configuration file lives at `%APPDATA%/Claude/claude_desktop_config.json` on Windows, `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS and `~/.config/Claude/claude_desktop_config.json` on Linux, and it takes a `penpot` entry whose command is `npx` with the proxy arguments. The restart instruction is unusually emphatic, because closing the window does not reload the config and you have to quit the app from the menu. Claude Code skips all of this with a single add command.

Chromium 142 private network access sits in the critical path

The longest troubleshooting note in the documentation is about the browser, not the server. Starting with Chromium version 142, private network access restrictions were tightened, so a web application served from one origin, `https://design.penpot.app` for example, has to be granted explicit permission before it can reach `localhost`. Most Chromium browsers such as Chrome and Vivaldi show a popup asking for local network access, and the instruction is to approve it. Other browsers apply their own controls on top, and the named example is turning off Shield in Brave for the Penpot site. The escape hatch is to use a browser that does not enforce this, with Firefox given as the alternative. The reason this belongs in a setup guide rather than a troubleshooting appendix is that a denied prompt looks exactly like a broken server, so the browser is the first thing to check when nothing connects.

Version 1.0.0, private true, and a repository URL that points elsewhere

The package manifest is short and has a few details worth noticing. The name is `penpot-mcp` at version 1.0.0 with an empty description field, and the package is marked `private`, so it is not published to a registry and is meant to be run from a clone. The `repository` field points at `github.com/oraios/penpot-mcp`, not the `penpot` organisation path the code actually lives under, which is the kind of leftover that makes `git remote` archaeology necessary. Formatting is handled by prettier with both a write and a check script. The monorepo holds the shared TypeScript definitions in `common/`, the server in `mcp-server/`, and the plugin alongside them, with the server doing three specific jobs: exposing the MCP tools, running the WebSocket server the plugin connects into, and correlating request and response pairs with unique task IDs while handling timeouts and error reporting. Alongside the code sit `docs/`, `resources/`, a `python-scripts/` directory and a `.serena/` folder.

The model writes and runs code inside the Penpot plugin

What sits under the tool list is execution rather than a fixed set of verbs. The architecture is described as the MCP server exposing tools to AI clients for retrieving design data and for modifying and creating design elements, but the mechanism is that the LLM carries out its tasks in the context of a design file by executing code that uses the Penpot Plugin API. The text is direct about the consequence: the LLM is free to write and execute arbitrary code snippets within the plugin environment to accomplish whatever the task requires. That is a different trust model from a server that validates a payload against a schema, and the boundary is the plugin runtime rather than a per-tool permission list, which is worth understanding before pointing a model at a design file that matters. It also explains why the repository ships the plugin alongside the server, since the two halves only make sense together. The claimed payoff is bidirectional work, described as design-to-design, code-to-design and design-to-code workflows rather than a single direction of translation.

Editorial conclusion

penpot-mcp is for someone who wants an agent editing a real design file rather than describing a design in prose, and the plugin bridge is what makes that possible rather than a thin API wrapper. The cost is operational: a Node server, a plugin web server and a browser tab that must stay open, plus a browser permission prompt you will meet again after every Chromium upgrade. Before you invest in it, read the archive notice at the top of the file, because the work has moved into the main Penpot repository under `mcp/` and the default branch here is `develop`, so this copy is a snapshot rather than the place new fixes land. Then confirm your browser will allow a page on design.penpot.app to reach localhost, check that your MCP client speaks Streamable HTTP or SSE rather than stdio only, and verify that whoever runs the setup understands the plugin window must stay open.

Frequently asked questions

Is penpot-mcp still maintained or has it moved?

The documentation opens by stating the repository was archived on 2026-02-03 and that its contents were fully integrated into the main Penpot repository under the mcp directory on the develop branch. The repository metadata still reports it as not archived, with a last push dated 2026-03-19, and there are no GitHub releases.

What does the penpot-mcp server need running?

Three things. The MCP server itself with an AI client connected to it, the web server that serves the Penpot MCP plugin, and the plugin open inside Penpot on a design file, connected to the server. The plugin is loaded from a development URL, http://localhost:4400/manifest.json by default, and its window must stay open or the WebSocket closes.

How do I connect an MCP client that only supports stdio?

Use a proxy. Install mcp-remote with npm install -g mcp-remote, then point your client at npx -y mcp-remote http://localhost:4401/sse --allow-http. The flag is required to permit a plain HTTP endpoint. Clients that speak Streamable HTTP can skip the proxy and connect to http://localhost:4401/mcp directly.

Why can the browser not reach the penpot-mcp plugin server?

Since Chromium 142, private network access restrictions require explicit permission for a page served from another origin, such as https://design.penpot.app, to reach localhost. Chrome and Vivaldi show a popup asking for local network access and it has to be approved, Brave additionally needs Shield disabled for the Penpot site, and Firefox is suggested as a browser that does not enforce the restriction.

Official sources

  1. Issues
  2. License: MPL-2.0
  3. penpot/penpot-mcp on GitHub
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/penpot-penpot-mcp.svg)](https://hysenlabs.com/projects/penpot-penpot-mcp)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/penpot-penpot-mcp.svg)](https://hysenlabs.com/projects/penpot-penpot-mcp)

Was this useful?