MCP server wrapping the Penpot REST API for headless design automation
Project description
penpot-api-mcp
MCP server wrapping the Penpot REST API for headless design automation. Provides read, search, and export access to Penpot projects, files, and design objects — without requiring a browser session.
Part of the Bodai Ecosystem alongside Mahavishnu, Akosha, Dhara, Session-Buddy, and Crackerjack.
Why this exists
The official @penpot/mcp (TypeScript) requires a live browser plugin to operate — it is the right tool for interactive canvas manipulation. This server targets the complementary use case: background automation, asset export pipelines, and AI-driven design queries that run without a browser.
Tools
| Tool | Description |
|---|---|
list_projects |
List all projects for the authenticated user |
get_project_files |
List design files in a project |
get_file |
Fetch the full content of a design file |
get_object_tree |
Return the design object hierarchy for a file |
search_objects |
Search objects by name or type |
export_object |
Export a design object as PNG/SVG (base64-encoded) |
Setup
uv sync
cp .env.example .env # fill in credentials
Configuration
Environment variables (prefix PENPOT_):
| Variable | Description | Default |
|---|---|---|
PENPOT_ACCESS_TOKEN |
API access token (preferred) | — |
PENPOT_EMAIL |
Email for password auth (fallback) | — |
PENPOT_PASSWORD |
Password for password auth (fallback) | — |
PENPOT_BASE_URL |
API base URL for self-hosted instances | https://design.penpot.app/api |
Either PENPOT_ACCESS_TOKEN or PENPOT_EMAIL + PENPOT_PASSWORD must be set.
Running
# HTTP mode (default — Claude Code compatible)
uv run python -m penpot_api_mcp start --force
# stdio mode
uv run python -m penpot_api_mcp
Server listens on http://localhost:3051/mcp.
MCP configuration
{
"mcpServers": {
"penpot-api": {
"type": "http",
"url": "http://localhost:3051/mcp"
}
}
}
Development
uv run pytest # Run tests
uv run crackerjack # Full quality suite (ruff + mypy + pytest + bandit)
uv run ruff check --fix # Lint
uv run mypy . # Type check
Architecture
penpot_api_mcp/
├── utils/transit.py # Transit+JSON encode/decode (Penpot's wire format)
├── config/settings.py # Pydantic settings (PENPOT_* env vars)
├── clients/ # httpx async client with dual auth
├── models/ # Pydantic models: Project, File, Object, ObjectTree
├── tools/ # FastMCP tool registrations
├── server.py # FastMCP app + health endpoints
└── __main__.py # MCPServerCLIFactory entrypoint (Oneiric)
Transit+JSON
Penpot's RPC layer uses Transit+JSON — a Clojure serialization format where map keys are ~:keyword and UUIDs are ~uUUID. The utils/transit.py module handles encode/decode at the API boundary, keeping all Python models clean.
Authentication
Two modes are supported:
- API token (
PENPOT_ACCESS_TOKEN): sent asAuthorization: Token <token>header - Email + password: authenticates via
/rpc/command/login-with-password, then relies on the httpx cookie jar (auth-tokencookie) for all subsequent requests
License
BSD 3-Clause. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file penpot_api_mcp-0.1.1.tar.gz.
File metadata
- Download URL: penpot_api_mcp-0.1.1.tar.gz
- Upload date:
- Size: 17.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90ca828bad9a47bb57150abe9132e10ef9d321ace73a37a889e26d823a9ba285
|
|
| MD5 |
cdbd6a98a9b8347509aa001810587781
|
|
| BLAKE2b-256 |
24cfa0d9b9deb604921197f87aa7b119461e068f5c26e68eb947225667543c68
|
File details
Details for the file penpot_api_mcp-0.1.1-py3-none-any.whl.
File metadata
- Download URL: penpot_api_mcp-0.1.1-py3-none-any.whl
- Upload date:
- Size: 16.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bda313df5d6c8d37a718f7fe2e92ba14b992c876fc0a92a00020b4b945f194b8
|
|
| MD5 |
584157ad68ff00e005a4527ed83e6e7e
|
|
| BLAKE2b-256 |
c8fc0883c58177eb09462eeff017e96b293ffbaf5d3b8bfe2d4a3358d38c91c8
|