Feature Request: Enable MCP and Access Tokens flags in Penpot (or expose EXTRA_PENPOT_FLAGS)
-
I created a /app/data/env.sh file and tried adding the following line:
export PENPOT_FLAGS="enable-registration enable-login-with-password enable-access-tokens enable-mcp"After saving the file and completely restarting the app via the Cloudron dashboard, the "Integrations" and "Access Tokens" UI elements still do not appear in the Penpot account settings.
My assumption was that the Cloudron deployment's internal startup script dynamically generates or overrides the PENPOT_FLAGS variable (perhaps to ensure SMTP or OIDC settings stay intact) and is ignoring the manual export in env.sh.
If there is a specific syntax I should be using in env.sh to append custom flags without them getting overwritten by the system, please let me know! Otherwise, having a supported way to inject flags like EXTRA_PENPOT_FLAGS would be really helpful.
-
+1 for this.
I’ve just hit the same limitation on a Cloudron-hosted Penpot 2.16.0 instance.
The frontend bundle appears to include the MCP / access-token UI code, but the features are not available because the required flags are not active. In our live app,
/js/config.jsshowspenpotFlagswithoutenable-mcporenable-access-tokens, and/mcp/stream,/mcp/sse, and/mcp/wscurrently route to 404.So I think this is exactly the right package-level fix:
- enable
enable-access-tokens - enable
enable-mcp - ideally expose something like
EXTRA_PENPOT_FLAGSfor future opt-in flags
The flexible
EXTRA_PENPOT_FLAGSoption would be especially useful because Penpot is moving quickly and Cloudron users may need to opt into new official features before the package defaults catch up.Thanks for looking into this happy to test once there’s a package update or workaround.
- enable
-
Hi @james,
Thanks for the super quick response on adding those flags, really appreciate it.
Just wanted to give you a quick update. I actually managed to get things working via a local workaround - running the Penpot MCP server on my own machine and bridging it to the canvas using a browser plugin.
While trying to get the remote connection working earlier, though, I noticed that hitting https://[domain]/mcp/stream returns a standard HTML webpage instead of the expected SSE stream (text/event-stream). From what I can tell, I think Penpot’s MCP server might actually run as a separate standalone service or container, rather than being built directly into the core backend.
If that is the case, I think the Cloudron package might eventually need to bundle that extra container and map the Nginx routing for the /mcp/ paths to get remote connections working properly.
There's no rush since my local setup is doing fine, but I figured I'd pass this along in case it saves you some debugging time.
-
Quick follow-up here in case it helps anyone else debugging this.
We tested the updated Cloudron Penpot package with the new
enable-access-tokensandenable-mcpflags. The flags do appear to be applied correctly — access tokens and the MCP-related UI/config are enabled — but the Penpot app itself does not appear to expose a usable MCP HTTP/SSE endpoint from the core backend.In our checks:
/api/rpc/command/get-access-tokensexists and is auth-gated, so access-token support is working./mcp,/mcp/sse,/api/mcp,/api/mcp/sse,/mcp/streametc. did not resolve to a working MCP transport from the Penpot app itself.- The official Penpot MCP implementation appears to be a separate Node service/plugin bridge rather than just a backend route inside the main Penpot container.
- That service exposes, roughly:
- MCP HTTP endpoint on
/mcp - legacy SSE endpoint on
/sse - plugin WebSocket bridge on
/ws - static plugin assets such as
/manifest.jsonand/plugin.js
- MCP HTTP endpoint on
We got remote MCP working by deploying the official
penpot-mcpservice separately and proxying those routes through nginx. A few practical gotchas we hit:- Build the plugin assets at image-build time, not runtime, because Cloudron app code is read-only at runtime.
- The plugin manifest/assets need CORS headers so the Penpot UI can install/fetch the plugin from another origin.
/mcpand/sseshould be auth-gated withuserToken./wsneeds proper WebSocket upgrade proxying.- The internal REPL/debug service should not be exposed publicly.
So I think the Cloudron Penpot package flags are useful and necessary, but full remote MCP support likely needs either:
- bundling/running the official
penpot-mcpservice alongside Penpot, or - documenting it as a companion app/service with nginx routes for
/mcp,/sse,/messages,/ws, and the plugin static assets.
Hope that saves someone else some digging.
-
Following up on this thread with the state on the current package (1.18.3 / Penpot 2.16.2). The flags @james added are working, and
/mcpnow resolves. However, the in-app MCP plugin still can't load, which blocksFile → MCP Server → Connect. This is exactly the missing piece @Operator described (the frontendplugins/static assets aren't served).Current state on 1.18.3:
- [v]
enable-mcp+enable-access-tokensare in/app/pkg/start.shand served in/js/config.js(penpotFlags). - [v]
/mcpnow returns 200 (progress vs the earlier 404s in this thread). - In a design file,
File → MCP Server → Connectfails. Browser console:
Plugin Error: Failed to load plugin code GET https://penpot.inno3.eu/plugins/mcp/plugin.js 404 (Not Found)Root cause (confirmed): the frontend loads the bundled MCP plugin from
${PENPOT_PUBLIC_URI}/plugins/mcp/…, but the nginx root/app/code/frontendhas noplugins/directory -- the files don't exist anywhere in the container. The upstream image already ships them:$ docker export $(docker create penpotapp/frontend:2.16.2) | tar -tf - | grep plugins/mcp var/www/app/plugins/mcp/ var/www/app/plugins/mcp/assets/index-JunN9mS-.css var/www/app/plugins/mcp/icon.jpg var/www/app/plugins/mcp/index.html var/www/app/plugins/mcp/index.js var/www/app/plugins/mcp/manifest.json var/www/app/plugins/mcp/plugin.jsFor reference
https://design.penpot.app/plugins/mcp/plugin.jsreturns 200; ours returns 404. Related: ourconfig.jsexposes none of thepenpotPlugins*vars (penpotPluginsWhitelist,penpotPluginsListUri, …), so the Plugins manager panel is unavailable too for same root cause.As @Operator noted,
/app/codeis read-only at runtime, so this needs to be handled at image-build time. It looks like copying the upstream frontendplugins/directory into the served root (and exposing thePENPOT_PLUGINS_*config inconfig.js) would light up both the native MCP plugin and the Plugins manager, without needing to bundle the separate penpot-mcp Node service. Happy to test a patched package on our instance. - [v]
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login