Patch Penpot MCP: add create_file(project_id, name) #73

Closed
opened 2026-04-19 00:04:13 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As the designer agent, I want a create_file MCP tool so that I
can bootstrap a fresh Penpot file from scratch instead of requiring
the operator to pre-seed one in the Penpot UI.

Carved out of #69 as a follow-up; PR #71 lands every other canvas
primitive but explicitly defers this because Penpot's create-file
RPC has a richer param surface than the other writes (data migrations
list, feature flags) that needs a dedicated pass to get right.

Current state

  • PR #71 ships create_page, create_frame, create_text
    these all require a file_id to exist already.
  • Operator currently creates files via the Penpot UI and pastes the
    UUID into the issue body / skill prompt.
  • The design-implement.md skill's "find-or-create the Penpot file"
    rule cannot be satisfied without this tool; designer always takes
    the "reuse existing" branch.

Acceptance criteria

MCP — new tool

  • create_file(project_id, name, features?) in
    penpot-mcp-server/src/penpot_mcp/tools/canvas.py
    wraps the create-file RPC. Returns {file_id, name, revn}.
  • features defaults to Penpot's current baseline feature set:
    ["components/v2", "layout/grid", "styles/v2", "design-tokens/v1", "fdata/path-data", "fdata/objects-map", "fdata/shape-data-type", "variants/v1", "plugins/runtime"].
    Pulled from get-file response of an existing well-formed
    file (the claude-hooks — dashboard file's features field
    is the reference).
  • Unit test patches api.command and asserts the emitted RPC
    payload shape (camelCase projectId, name, features).
  • Live test (pytest -m live): create a temp file in the
    existing Drafts project, assert get_file_info roundtrips
    the name, delete via delete-file RPC in finally.

Documentation

  • penpot-mcp-server/README.md: add create_file to the canvas
    tools table.
  • CHANGELOG.md: bump to 0.6.0.

Out of scope

  • Data migrations list. The data field Penpot emits when
    creating a file includes a migrations array of applied schema
    migration ids. This is internal Penpot housekeeping — create-file
    fills it with sensible defaults server-side; we don't pass it.
  • Template-based creation. Penpot supports creating a file from
    a template via a different RPC (duplicate-file with a template
    source). Separate tool, separate issue.
  • File renaming / moving between projects. Out of scope;
    rename-file / move-files are different RPCs.

References

  • Parent: #69 (canvas primitives) — PR #71 landing.
  • RPC: https://design.jacquin.app/api/rpc/command/create-file
    probe response schema before coding.
  • Reference features list: run
    curl … /api/rpc/command/get-file -d '{"id":"689d7fa4-…"}' and
    copy the features array.
  • Milestone: Agent pool + customization (#16).

Dependencies

  • Blocked by: nothing — PR #71 is the prerequisite and
    it's ready to merge.
  • Blocks: the designer's "find-or-create" skill branch (today
    only "reuse existing" works).
  • Branch off: main after #71 lands.
## User story As the **designer agent**, I want a `create_file` MCP tool so that I can bootstrap a fresh Penpot file from scratch instead of requiring the operator to pre-seed one in the Penpot UI. Carved out of #69 as a follow-up; PR #71 lands every other canvas primitive but explicitly defers this because Penpot's `create-file` RPC has a richer param surface than the other writes (data migrations list, feature flags) that needs a dedicated pass to get right. ## Current state - PR #71 ships `create_page`, `create_frame`, `create_text` — these all require a `file_id` to exist already. - Operator currently creates files via the Penpot UI and pastes the UUID into the issue body / skill prompt. - The `design-implement.md` skill's "find-or-create the Penpot file" rule cannot be satisfied without this tool; designer always takes the "reuse existing" branch. ## Acceptance criteria ### MCP — new tool - [ ] `create_file(project_id, name, features?)` in `penpot-mcp-server/src/penpot_mcp/tools/canvas.py` — wraps the `create-file` RPC. Returns `{file_id, name, revn}`. - [ ] `features` defaults to Penpot's current baseline feature set: `["components/v2", "layout/grid", "styles/v2", "design-tokens/v1", "fdata/path-data", "fdata/objects-map", "fdata/shape-data-type", "variants/v1", "plugins/runtime"]`. Pulled from `get-file` response of an existing well-formed file (the `claude-hooks — dashboard` file's `features` field is the reference). - [ ] Unit test patches `api.command` and asserts the emitted RPC payload shape (camelCase `projectId`, `name`, `features`). - [ ] Live test (`pytest -m live`): create a temp file in the existing `Drafts` project, assert `get_file_info` roundtrips the name, delete via `delete-file` RPC in `finally`. ### Documentation - [ ] `penpot-mcp-server/README.md`: add `create_file` to the canvas tools table. - [ ] `CHANGELOG.md`: bump to 0.6.0. ## Out of scope - **Data migrations list.** The `data` field Penpot emits when creating a file includes a `migrations` array of applied schema migration ids. This is internal Penpot housekeeping — `create-file` fills it with sensible defaults server-side; we don't pass it. - **Template-based creation.** Penpot supports creating a file from a template via a different RPC (`duplicate-file` with a template source). Separate tool, separate issue. - **File renaming / moving between projects.** Out of scope; `rename-file` / `move-files` are different RPCs. ## References - Parent: #69 (canvas primitives) — PR #71 landing. - RPC: `https://design.jacquin.app/api/rpc/command/create-file` — probe response schema before coding. - Reference features list: run `curl … /api/rpc/command/get-file -d '{"id":"689d7fa4-…"}'` and copy the `features` array. - Milestone: **Agent pool + customization** (#16). ## Dependencies - **Blocked by:** nothing — PR #71 is the prerequisite and it's ready to merge. - **Blocks:** the designer's "find-or-create" skill branch (today only "reuse existing" works). - **Branch off:** `main` after #71 lands.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#73
No description provided.