Public leaderboard

Public assessment

attalla1/photopea-mcp-server (photopea-mcp-server)

photopea-mcp-server · v0.1.0 · scanned

What changed in the harness

Selection accuracy 100→98, token cost up 5%, unconfirmed writes 0%→0%.

Category breakdown

Where the score comes from.

Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.

01Safety

0.0 / 30

0.0 out of 30
02Legibility

20.3 / 30

20.3 out of 30
03Economics

15.7 / 20

15.7 out of 20
04Discoverability

12.8 / 20

12.8 out of 20

Highest-impact fix

Estimated gain +30 points

Add explicit identity and permission preflight tools

Expose machine-readable principal/tenant confirmation and a non-mutating permission check so agents can verify both before destructive actions.

Description evidence

Defects and rewrites.

31 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.

Tool Defect types Suggested rewrite
photopea_create_document
no_return_description
Create a new blank document and make it the active document. This is typically the first step in a workflow. The document opens with a Background layer. Use open_file instead to edit an existing image. Returns a JSON result with the new document's ID and name, which can be referenced in subsequent operations.
photopea_open_file
no_return_description
Open an existing image file in Photopea as a new document. Supports PSD, PNG, JPG, WebP, SVG, and other common formats. The opened file becomes the active document. Use create_document instead to start with a blank canvas. Returns a JSON result with the opened document's ID and name, which can be referenced in subsequent operations.
photopea_resize_document
no_return_description
Resize the active document canvas to new pixel dimensions, resampling all layer content to fit. This is a destructive operation — all layers are scaled proportionally. Use undo to revert if needed. Returns a JSON result confirming the new document width and height.
photopea_close_document
no_return_description
Close the active document. Set save to true to save changes before closing. Unsaved changes are discarded if save is false. The next open document becomes active, if any. Returns a JSON result confirming that the document was closed, or an error if no document was open.
photopea_add_layer
no_return_description
Add a new empty layer to the active document. The new layer becomes the active layer. Use this before operations that draw onto a layer, such as fill_selection or add_gradient. Returns a JSON result with the new layer's name and index for use in subsequent operations.
photopea_add_fill_layer
no_return_description
Add a non-destructive solid color fill layer that covers the entire canvas. Unlike fill_selection, this creates a separate adjustment-style layer that can be toggled, recolored, or deleted without affecting other layers. Use set_layer_properties to change its opacity or blend mode. Returns a JSON result with the fill layer's name and index.
photopea_delete_layer
no_return_description
Permanently remove a layer from the active document by name or index. The next layer in the stack becomes active after deletion. Use get_layers to see available layers before deleting. Returns a JSON result confirming the layer was deleted, or an error if the target layer was not found.
photopea_select_layer
no_return_description
Set a layer as the active layer by name or index. Many tools (apply_filter, apply_adjustment, fill_selection) operate on the active layer — use this to target a specific layer first. Use get_layers to find layer names and indices. Returns a JSON result confirming the newly active layer's name and index.
photopea_set_layer_properties
no_return_description
Update one or more properties on a layer. Only specified properties are changed; others remain at their current values. Use get_layers to inspect current property values before modifying. Returns a JSON result with the target layer's updated property values.
photopea_move_layer
no_return_description
Translate a layer by a relative x/y offset in pixels from its current position. Positive x moves right, positive y moves down. Use get_layers to check current layer bounds, or transform_layer for scaling and rotation. Returns a JSON result confirming the layer's new position.
photopea_duplicate_layer
no_return_description
Create a copy of a layer in the active document. The duplicate becomes the active layer and is placed above the original. Use newName to distinguish the copy from the original. Returns a JSON result with the duplicate layer's name and index.
photopea_reorder_layer
no_return_description
Move a layer to a new position in the layer stack. Use 'top' or 'bottom' to move to the ends of the stack, or 'above'/'below' to shift one position relative to the current index. Use get_layers to see the current layer order. Returns a JSON result with the layer's new position and index.
photopea_group_layers
no_return_description
Group multiple layers into a layer group (folder). Layers are specified by name — use get_layers to find layer names. Grouped layers can be ungrouped later with ungroup_layers. Returns a JSON result with the group's name and the list of layers it contains.
photopea_ungroup_layers
no_return_description
Dissolve a layer group, moving all child layers to the document root. The group folder is removed but its contents are preserved. Use get_layers to find group names. Returns a JSON result confirming the group was dissolved and listing the layers moved to the document root.
photopea_add_text
no_return_description
Add a new text layer to the active document at the specified position. The text layer becomes the active layer. Use paragraphBounds to create a text box with word wrapping, or omit for point text. Use load_font to add custom fonts, and list_fonts to find available font names. Returns a JSON result with the text layer's name and index.
photopea_edit_text
no_return_description
Modify the content or style of an existing text layer. Only specified properties are changed — omit parameters to keep their current values. Use get_layers to find text layer names if needed. Returns a JSON result confirming the updated properties of the target text layer.
photopea_add_shape
no_return_description
Add a vector shape layer (rectangle or ellipse) to the active document. The shape layer becomes the active layer. Shapes are non-destructive and can be resized with transform_layer without quality loss. Returns a JSON result with the shape layer's name and index.
photopea_place_image
no_return_description
Place an image into the active document from a URL or local file path. Creates a new layer with the placed image as the active layer. Use width/height to resize while preserving aspect ratio, or x/y to position the layer. Returns a JSON result with the placed layer's name and index.
photopea_apply_adjustment
no_return_description
Apply a destructive image adjustment to the active layer's pixel data. Use select_layer to target a specific layer first. Modifies pixels directly — use undo to revert if needed. Returns a JSON result confirming the adjustment was applied to the active layer, or an error if no layer is active.
photopea_apply_filter
no_return_description
Apply a destructive filter effect to the active layer's pixel data. Use select_layer to target a specific layer first. Modifies pixels directly — use undo to revert if needed. Returns a JSON result confirming the filter was applied to the active layer, or an error if no layer is active.
photopea_transform_layer
no_return_description
Scale, rotate, or flip a layer in-place. Modifies the layer's pixel data destructively. Use get_layers to check current layer bounds before transforming, and undo to revert if needed. Returns a JSON result confirming the transformed layer's new bounds.
photopea_add_gradient
no_return_description
Apply a linear gradient fill to a layer, replacing its current pixel content. The target layer must already exist — use add_layer to create one first. Colors are distributed evenly across the gradient. Returns a JSON result confirming the gradient was applied to the target layer.
photopea_make_selection
no_return_description
Create a pixel selection region in the active document. After creating a selection, use fill_selection to fill it with color, or clear_selection to deselect. Use type 'all' to select the entire canvas, or 'rect'/'ellipse' with bounds for a specific region. Returns a JSON result describing the created selection (its type and bounds).
photopea_modify_selection
no_return_description
Modify the current active selection and return a status confirming the selection was updated. Requires an existing selection created by make_selection. For expand, contract, and feather, the amount parameter specifies pixels in the modification. Invert swaps selected and unselected areas.
photopea_fill_selection
no_return_description
Fill the current selection with a solid color on the active layer using the given opacity and blend mode, and return a status confirming the fill was applied. Requires an active selection — use make_selection to create one first. Modifies pixel data on the active layer directly. Use clear_selection afterward to deselect.
photopea_clear_selection
no_return_description
Deselect the current selection in the active document, removing the marching ants, and return a status confirming the selection was cleared. Does not modify any pixel data. Use after fill_selection or other selection-based operations are complete.
photopea_export_image
no_return_description
Export the active document to the specified local file path in the chosen format with the given quality, and return a status confirming the export succeeded. The entire document is flattened and exported in the chosen format. Use create_document or open_file to set up the document before exporting.
photopea_load_font
no_return_description
Load a custom font from a URL (TTF, OTF, or WOFF2) into Photopea and return a status confirming the font was loaded. The font becomes available for add_text and edit_text. Use list_fonts to find the PostScript name after loading.
photopea_run_script
no_return_description
Execute arbitrary Photopea/ExtendScript JavaScript in the Photopea environment and return the data passed to app.echoToOE(result). Use this for advanced operations not covered by other tools. Has full access to the Photopea DOM (app, activeDocument, layers). Use with caution — scripts can modify or delete any document data.
photopea_undo
no_return_description
Undo one or more recent actions in the active document and return a status confirming how many steps were undone. Each step reverses one operation from the history. Use after destructive operations (apply_filter, apply_adjustment, fill_selection) to revert changes.
photopea_redo
no_return_description
Redo one or more previously undone actions in the active document and return a status confirming how many steps were redone. Only available after using undo — the redo history is cleared when new actions are performed.

Selection evidence

Confusable tool pairs.

10 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.

Tool A Tool B Confidence Why they collide
photopea_move_layer photopea_reorder_layer medium A task like 'move the layer up' or 'bring the layer to the front' is ambiguous: move_layer does spatial x/y translation while reorder_layer changes z-order, and users rarely specify which dimension they mean.
photopea_add_fill_layer photopea_fill_selection medium A task like 'fill the whole image/background red' could target the non-destructive solid fill layer or a destructive selection fill; the descriptions even cross-reference each other, so an agent may pick the wrong one.
photopea_apply_adjustment photopea_apply_filter medium Both are destructive pixel ops on the active layer with nearly identical descriptions; a task like 'apply a blur/brightness effect to the photo' or a generic 'apply an effect' could be routed to either depending on whether the agent maps 'effect' to filter or adjustment.
photopea_make_selection photopea_modify_selection medium Tasks like 'make the selection bigger/smaller/softer' map to modify_selection (expand/contract/feather), but a user phrasing 'select a larger/rounded region' might trigger make_selection with new bounds instead of modifying the existing selection.
photopea_add_text photopea_edit_text medium 'Put the text "Hello" in the image' is ambiguous between creating a new text layer and editing an existing one; an agent must infer from the tool descriptions whether add or edit applies, and may pick wrongly when a text layer already exists.
photopea_add_layer photopea_add_fill_layer medium A task like 'add a red filled layer' or 'create a layer of solid color' is ambiguous between an empty layer plus fill steps and the dedicated solid fill layer, especially since both are 'add a layer' in name.
photopea_add_fill_layer photopea_add_gradient medium 'Fill the canvas with a gradient from red to blue' is ambiguous: add_fill_layer only supports solid colors while add_gradient requires an existing layer, so an agent may call the wrong one and fail or produce the wrong result.
photopea_load_font photopea_list_fonts low A task like 'get/use the Arial font' could be read as finding the font name (list_fonts) versus importing a font file (load_font), since both descriptions reference fonts and cross-reference each other.
photopea_fill_selection photopea_clear_selection low 'Clear the selection' is usually deselect (clear_selection), but a user saying 'clear/empty the selected region' could mean filling or erasing pixels (fill_selection), making the intent ambiguous at the margin.
photopea_add_layer photopea_add_text low A task like 'add a layer with some text in it' or 'add a text block' could be routed to the generic add_layer instead of add_text, since add_text is the more specific 'add a layer' variant.

Compare the field

One score is useful.
The evidence makes it actionable.

Back to the leaderboard