Editmamei
Editmamei is an MCP server that lets an AI assistant drive desktop Adobe Photoshop through natural-language tool calls — creating, editing, verifying, and exporting documents without uploading images.
Orient and inspect: ping Photoshop, get workflow overview, list capabilities, inspect document metadata/layer tree/history, and render annotated previews.
Documents and canvas: create, open, close, save PSD copies, export JPEG/PNG, resize, crop, convert color mode, transform canvas, and manage guides.
Layers and compositing: create, delete, duplicate, select, reorder, merge, bake, group, convert to smart objects, apply layer styles, clipping masks, vector masks, and shape layers.
Non-destructive adjustments: adjustment layers for curves, levels, hue/saturation, color balance, photo filter, vibrance, exposure, LUTs, and more; fill layers and gradient fills.
Selections: rectangle/ellipse/polygon/color/luminance/magic wand, feather/refine/expand/contract, selection channels, and AI Select Subject / Select Sky.
Filters and retouch: blur, sharpen, noise, high-pass, distort, oil paint, smart filter management, content-aware fill/patch/move, and brush-family retouching/painting tools.
Perception: on-device face/object/scene detection, scene model with regions, named-region selection (sky, ground, skin, face features), and grounded placement resolution.
Verification: histograms, region comparisons, layer-bounds diffs, and selection stats/previews for numeric checks.
Automation: run ordered tool sequences in one round trip; Pro adds Photoshop actions, batch processing, custom scripts, templates, Camera Raw develop, warp, face mesh, and precision grounding.
Safe by design: destructive operations usually auto-duplicate the active layer, adjustments stay editable, and edits are reversible.
Editmamei
Unlock Photoshop with natural-language photo editing. AI orchestration, not generation.
Independent project, not affiliated with or endorsed by Adobe Inc.
Editmamei is a Model Context Protocol (MCP) server that drives desktop Adobe Photoshop. You describe the edit in plain words, your AI assistant plans the steps, and Photoshop carries them out with its standard adjustment layers, masks, selections, and filters. The AI directs and Photoshop edits. No generative model touches your pixels, and no image is uploaded to perform an edit.
It serves photographers and retouchers who want to edit by conversation just as much as developers wiring Photoshop into an AI pipeline. To learn more or get started, visit editmamei.com.
editmamei.com · Docs · Report a bug
How it works
Editmamei is a pure MCP stdio server written in Node. Your AI client launches it as a subprocess and calls its tools over stdio. Each tool builds a small Photoshop script and runs it in your local Photoshop over the platform's native automation channel:
AI client ──stdio──▶ Editmamei (Node MCP server)
│ builds a Photoshop script per tool call
▼
COM (Windows) / AppleScript (macOS)
│
▼
Your local Adobe PhotoshopWindows drives Photoshop through COM (the
Photoshop.Applicationobject).macOS drives it through AppleScript / OSA.
Perception (face, object, and scene detection) runs on-device with local ONNX computer vision, so the model gets real document coordinates without your image leaving the machine.
Photoshop does the pixel work with its own engine. Editmamei is the conductor, not a renderer.
Related MCP server: photoshop-mcp-pro
Install
npm install -g editmamei
editmamei install # registers with Claude Desktop, Cursor, Claude Code
editmamei status # confirms install state + Photoshop detectionThen restart your AI client and ask it: "Is Photoshop connected?"
Prefer not to use a terminal? Claude Desktop users can install the one-click .mcpb extension directly (no system Node required, Claude Desktop ships its own runtime). Full walkthrough in the install guide.
Requirements: Adobe Photoshop 2026 (v27.x), Windows 10/11 or macOS 13+, Node.js 22+ (for the npm path), and an MCP-compatible AI client (Claude Desktop, Cursor, Claude Code). Editmamei ships no model of its own and runs on whichever client you connect, so every edit spends that client's tokens.
A session, end to end
The discovery chain is ps_ping (liveness), then ps_overview (the working method and capability map), then tools/list (the full schema-typed inventory). After that you just talk to your assistant:
"Open my vacation photo." "Make the sky more dramatic but keep the foreground natural." "Sharpen the eyes, soften the skin, leave everything else alone." "Isolate the subject onto its own layer with a clean mask." "Export a 2048px web JPEG."
Your assistant composes those into tool calls, checks the result with previews and measurements, and iterates.
Design principles
These are the choices that shape the surface, and the reason an AI assistant can drive it reliably rather than hopefully.
Structured results, not prose. Every tool declares an
outputSchemaand returns a typed JSON payload. Any tool that changes what is active reports the current document and layer back, so the model keeps an accurate picture of Photoshop's state between calls instead of re-deriving it.Guidance lives in the surface.
ps_overviewreturns the working method (assess, plan, enact, check, iterate) andps_list_capabilitiesreturns a live map of what exists. The model orients itself from the server rather than from guesswork or a stale prompt.Measure, don't eyeball. A dedicated set of verification tools (histogram, region compare, layer-bounds diff, selection preview) lets the model check its own work numerically instead of trusting a thumbnail.
On-device perception. Local computer vision (ONNX) detects faces, objects, and scene regions and returns real document coordinates. The image stays on your machine for this step and is never sent to a cloud vision model.
Non-destructive by default. Adjustments are adjustment layers, and destructive pixel operations run on an auto-created duplicate. An edit is reversible by construction.
Verified against real Photoshop. Every tool is built on Photoshop's own native scripting functions and verified in live Photoshop sessions before it ships. A new tool stays disabled until it has passed live verification, so the shipped surface is the verified surface.
Built for modern Photoshop. Editmamei targets Photoshop 2026 (v27.x) so it can rely on current, stable scripting descriptors rather than carrying a decade of drifted behavior.
Tool surface
83 tools across 16 capability groups (62 Community, 21 Pro). Every tool is namespaced ps_* and discoverable at runtime via tools/list. Community tools ship in both editions; Pro tools unlock with a license.
Group | Edition | Tools |
Core | Community |
|
Inspect | Community |
|
Verify | Community |
|
Document & canvas | Community |
|
Selection | Community |
|
Adjustments | Community |
|
Filters | Community |
|
Retouch | Community |
|
Layers | Community |
|
Masks & paths | Community |
|
Type | Community |
|
Perception | Community |
|
AI selection | Community |
|
Automation | Community |
|
AI selection | Pro |
|
Filters | Pro |
|
Layers (warp) | Pro |
|
Perception | Pro |
|
Face mesh | Pro |
|
Templates | Pro |
|
Automation | Pro |
|
Editions
Community is free and covers the everyday editing surface: documents, layers, selections (including AI Select Subject and Select Sky), non-destructive adjustments, filters, masks, type, retouching, on-device perception, and the inspect/verify primitives.
Pro adds Camera Raw develop, the grounded precision tools (warp, named-object masks, precision placement), subject-instance targeting, face-mesh perception, the reproducible-template system, and Photoshop Actions plus the scripting escape hatch.
The split is detailed in pro-features.md. Pricing is at editmamei.com.
This repository holds the Community source. Pro is a separately licensed module and its source is not published here; Community never imports it, so this tree builds and runs on its own.
Build from source
git clone https://github.com/editmamei/editmamei.git
cd editmamei
npm install
npm run build
npm testYou need Node.js 22+ and Go 1.21+ (the build compiles the editmamei-core binary that generates Photoshop scripts; it needs Go 1.27, which Go fetches for you from 1.21 on). The build warns instead of failing when Go is missing, so you can still run the test suite; set EDITMAMEI_CORE_BIN to a prebuilt binary if you would rather not install Go.
The test suite runs without Photoshop. It verifies the ExtendScript Editmamei generates, never that Photoshop accepted it, so live verification against a real Photoshop is a separate step.
Contributions are welcome. Start with CONTRIBUTING.md, which covers the CLA, the branch and pull-request flow, and what to include in a bug report.
Configuration
Settings live in ~/.editmamei/settings.json, managed by the editmamei config CLI:
editmamei config list
editmamei config set telemetry.usage false # turn off usage telemetry
editmamei config set ps_path "/path/to/Photoshop"PHOTOSHOP_PATH (env var) overrides Photoshop auto-detection for a single run.
Privacy
Editmamei runs on your computer and edits in desktop Photoshop. No image content, document data, or file paths are sent to Editmamei's servers. It reports content-free usage telemetry (on by default, turn it off with editmamei config set telemetry.usage false). When your AI assistant needs to see a result, Editmamei sends it a downscaled preview, the same as dropping a photo into a chat with that assistant. Every field is documented in privacy.md, including your rights, and the legal basis.
The source in this repository is the same code published to npm, so none of the above has to be taken on trust.
Docs and support
Features and pricing: editmamei.com
Install: docs/installation.md
Getting started: docs/getting-started.md
FAQ: docs/faq.md
Pro features: docs/pro-features.md
Roadmap: docs/roadmap.md
Bugs and feature requests: the issue tracker. If something's broken, ask your assistant to "report a problem" (or run
editmamei report) to drop an anonymized diagnostic bundle in your Downloads folder, then attach it to the issue.Security: see SECURITY.md (don't file security issues publicly)
License
Editmamei CE is Fair Source software under the Functional Source License, v1.1, MIT Future License (FSL-1.1-MIT).
You can read, run, modify, and redistribute the code for almost anything: commercial photo editing, internal tools, education, research, security review. The one thing the license holds back, for two years per release, is offering the code to others in a commercial product or service that competes with Editmamei CE or Pro. If you redistribute the code, keep the license and copyright notices with it. Two years after each version ships, that version automatically becomes available under plain MIT.
This section is a plain-English summary. The LICENSE file is the license; where they differ, the LICENSE file controls.
Editmamei is not open source under the OSI definition, and we don't call it that. It is source-available, with the full CE stack developed in the open.
Editmamei Pro is a separate, commercially licensed module; its source is not published.
Third-party dependencies keep their own licenses, listed in NOTICES.md.
Available Tools
64 toolsps_add_adjustment_layerAIdempotent
Create a non-destructive adjustment layer above the active layer — hoisted out of the active layer's group by default even though Photoshop's own Mk-AdjL placement rule would otherwise nest it INSIDE that group (pass into_active_group:true to keep that native nesting). Supports the full real-Photoshop tonal/color surface: Curves (with S-curve presets), Levels, Hue/Saturation, Brightness/Contrast, Black & White (with optional tint), Color Balance, Photo Filter (preset or custom color), Vibrance, Channel Mixer, Selective Color, Gradient Map (preset), Exposure (stops + offset + gamma), Color Lookup (3DLUT presets or custom file path), and Invert. Values are editable, maskable, and removable. This is the canonical entry point for tonal/color adjustments — EXCEPT global tone/color on raw-sourced documents, which starts with a Camera Raw develop pass when a camera-raw develop tool is registered (see ps_open_document's is_raw_source); the old destructive bake tools (auto_levels / auto_contrast / desaturate / invert) were removed on 2026-05-31 — if you genuinely need a pixel bake, follow this call with ps_merge (mode=visible). Optionally clips the adjustment to only affect the layer directly below it. If a selection is active at call time, the new layer is automatically masked by it (toggle with mask_from_selection / mask_inverted). For destructive ops that don't have an adjustment-layer equivalent in Photoshop (Shadows/Highlights — single-pass shadow/highlight recovery), use ps_apply_adjustment (type=shadows_highlights) which auto-duplicates the active layer to keep the original intact. Returns context (the new adjustment layer becomes active) plus parent_path — the actual containing-group chain, so placement is never silent.
| Name | Required | Description | Default |
|---|---|---|---|
| hue | No | For type=hue_saturation. Hue shift in degrees (-180 to 180). | |
| name | No | Optional name for the new adjustment layer. | |
| type | Yes | Adjustment kind. | |
| gamma | No | For type=levels. Midpoint gamma. | |
| bw_reds | No | For type=black_and_white. Red-channel lightness mapping (-200 to 300). PS default 40. | |
| bw_tint | No | For type=black_and_white. If true, applies a single-color tint over the grayscale conversion (split-toning effect). Pair with bw_tint_hue + bw_tint_saturation. | |
| bw_blues | No | For type=black_and_white. Blue-channel mapping (-200 to 300). PS default 20. | |
| bw_cyans | No | For type=black_and_white. Cyan-channel mapping (-200 to 300). PS default 60. | |
| contrast | No | For type=brightness_contrast. Contrast (-100 to 100). | |
| gm_stops | No | For type=gradient_map. Custom color stops overriding gm_preset — each {red,green,blue (0-255), location (0-100 shadows→highlights), midpoint (5-95, default 50)}. At least 2; sorted by location. E.g. a blue→orange stylized grade: [{red:20,green:40,blue:120,location:0},{red:250,green:150,blue:50,location:100}]. | |
| bw_greens | No | For type=black_and_white. Green-channel mapping (-200 to 300). PS default 40. | |
| exp_gamma | No | For type=exposure. Gamma correction (0.01 to 9.99). PS default 1.0 (identity). Values <1 brighten midtones; >1 darken them. | |
| gm_dither | No | For type=gradient_map. Apply dithering to reduce banding. | |
| gm_preset | No | For type=gradient_map. Preset gradient. "black_to_white" is the canonical tonal B&W via gradient. "sepia" is a warm vintage tone. "tint" maps black→tint_color→white using gm_tint_color_hex. For arbitrary color mappings pass gm_stops instead (overrides the preset). | black_to_white |
| lightness | No | For type=hue_saturation. Lightness (-100 to 100). | |
| pf_preset | No | For type=photo_filter. Named filter preset. If set, takes precedence over pf_color_hex. Common picks: warming_85 (warm portraits), cooling_80 (cool down skies), sepia (vintage), warming_lba / cooling_lbb (subtle classic film), underwater. | |
| sc_colors | No | For type=selective_color. Nested per-color-family CMYK shifts. Each family is an object {cyan, magenta, yellow, black} with values -100 to 100. Omitted families default to zero. Families: reds, yellows, greens, cyans, blues, magentas, whites, neutrals, blacks. | |
| sc_method | No | For type=selective_color. "relative" scales adjustments by the existing color amount (subtle, the PS default). "absolute" applies fixed CMYK shifts (more aggressive). | relative |
| thr_level | No | For type=threshold. Threshold luminance (1-255). PS default 128. Pixels brighter than the threshold become white; darker become black. | |
| brightness | No | For type=brightness_contrast. Brightness (-100 to 100). | |
| bw_yellows | No | For type=black_and_white. Yellow-channel mapping (-200 to 300). PS default 60. | |
| exp_offset | No | For type=exposure. Offset shift (-0.5 to +0.5). PS default 0. Shifts the black point — most useful for paired with negative exposure for moody/crushed-shadow looks. | |
| gm_reverse | No | For type=gradient_map. Reverse the gradient direction. | |
| pf_density | No | For type=photo_filter. Filter strength (1-100). PS default 25. | |
| pos_levels | No | For type=posterize. Number of tonal levels per channel (2-255). PS default 4. Lower values yield a more graphic / illustration look (2-4); higher values are gentler. | |
| saturation | No | For type=hue_saturation. Master saturation (-100 to 100). Note: vibrance has its own vib_saturation param. | |
| black_point | No | For type=levels. Input black (0-255). | |
| bw_magentas | No | For type=black_and_white. Magenta-channel mapping (-200 to 300). PS default 80. | |
| bw_tint_hue | No | For type=black_and_white when bw_tint=true. Tint hue in degrees (-180 to 180). Default 220 (cool blue). | |
| cl_lut_name | No | For type=color_lookup. The LUT file name as Photoshop sees it. Common built-in 3DLUT presets: "3Strip.look", "Bleach Bypass.look", "Candlelight.CUBE", "Crisp_Warm.look", "Crisp_Winter.look", "DropBlues.3DL", "EdgyAmber.3DL", "FoggyNight.3DL", "FuturisticBleak.3DL", "Horror Blue.3DL", "LateSunset.3DL", "Moonlight.3DL", "NightFromDay.CUBE", "Soft_Warming.look", "TealMagentaGold.look", "TealOrangePlusContrast.3DL". For custom files, pass the absolute path. | |
| cl_lut_type | No | For type=color_lookup. Which LUT slot to load into. Default 3dlut covers .cube / .3dl / .look files (the photographer-typical case). abstract and device_link are for color-management workflows. | 3dlut |
| cm_b_from_b | No | For type=channel_mixer. Blue-from-Blue weight. PS default 100. | |
| cm_b_from_g | No | For type=channel_mixer. Blue-from-Green weight. | |
| cm_b_from_r | No | For type=channel_mixer. Blue-from-Red weight. | |
| cm_g_from_b | No | For type=channel_mixer. Green-from-Blue weight. | |
| cm_g_from_g | No | For type=channel_mixer. Green-from-Green weight. PS default 100. | |
| cm_g_from_r | No | For type=channel_mixer. Green-from-Red weight. | |
| cm_r_from_b | No | For type=channel_mixer. Red-from-Blue weight. Default 0. | |
| cm_r_from_g | No | For type=channel_mixer. Red-from-Green weight. Default 0. | |
| cm_r_from_r | No | For type=channel_mixer with cm_monochrome=false. Red-from-Red weight. PS default 100 (identity). | |
| white_point | No | For type=levels. Input white (0-255). | |
| exp_exposure | No | For type=exposure. Exposure shift in STOPS (-20 to +20). PS default 0. Photographer-feeling tonal control — 1 stop ≈ 2× linear brightness. | |
| pf_color_hex | No | For type=photo_filter. Custom filter color as a hex string like "#EC8A00". Only used when pf_preset is not set. | |
| vib_vibrance | No | For type=vibrance. Vibrance (-100 to 100). Saturation boost that protects skin tones and already-saturated colors. Gentler than hue_saturation.saturation. | |
| clip_to_below | No | If true, the adjustment only affects the layer directly below. | |
| cm_b_constant | No | For type=channel_mixer. Constant added to Blue output. | |
| cm_g_constant | No | For type=channel_mixer. Constant added to Green output. | |
| cm_monochrome | No | For type=channel_mixer. If true, output is single gray channel and only cm_gray_* params apply. If false, the per-output cm_{r,g,b}_from_* and cm_{r,g,b}_constant params apply for RGB→RGB remix. | |
| cm_r_constant | No | For type=channel_mixer. Constant added to Red output. | |
| curves_preset | No | For type=curves only. Default sCurveMedium. | sCurveMedium |
| mask_inverted | No | Only meaningful when mask_from_selection is true AND there is an active selection. If true, the resulting mask is inverted — so the adjustment affects EVERYTHING OUTSIDE the selection rather than inside. Common idiom: "I selected the sky but want to adjust everything else." Defaults to false. | |
| cm_gray_from_b | No | For type=channel_mixer with cm_monochrome=true. Blue contribution to gray. PS default 20. | |
| cm_gray_from_g | No | For type=channel_mixer with cm_monochrome=true. Green contribution to gray. PS default 40. | |
| cm_gray_from_r | No | For type=channel_mixer with cm_monochrome=true. Red contribution to gray (-200 to 200). PS default 40. | |
| vib_saturation | No | For type=vibrance. Master saturation override (-100 to 100). Affects all colors equally. | |
| cm_gray_constant | No | For type=channel_mixer with cm_monochrome=true. Constant added to gray output. | |
| gm_tint_color_hex | No | For type=gradient_map with gm_preset=tint. Mid-tone tint color as a hex string like "#5588CC". Only used when gm_preset=tint. | #5588CC |
| into_active_group | No | Photoshop's Mk-AdjL descriptor carries no placement target, so with a GROUP active it would natively nest the new layer INSIDE that group. Default false hoists the new layer back out so it lands above the active layer/group as a sibling, matching this tool's documented placement. Pass true to keep the new layer nested inside the active group instead. | |
| bw_tint_saturation | No | For type=black_and_white when bw_tint=true. Tint saturation (0 to 100). Default 25. | |
| cb_shadows_cyan_red | No | For type=color_balance. Shadows: cyan↔red shift (-100 cyan to +100 red). Default 0. | |
| mask_from_selection | No | If true (default) and there is an active selection at the time of this call, the new adjustment layer is automatically masked by that selection. If false, any existing selection is dropped first and the new layer is unmasked (full canvas). Photoshop's native Mk-with-active-selection behavior does the masking; this flag makes it explicit and toggleable. | |
| cb_midtones_cyan_red | No | For type=color_balance. Midtones: cyan↔red shift. | |
| cb_highlights_cyan_red | No | For type=color_balance. Highlights: cyan↔red shift. | |
| cb_preserve_luminosity | No | For type=color_balance. Preserve luminosity while shifting color. Default true (matches the PS dialog default). | |
| cb_shadows_yellow_blue | No | For type=color_balance. Shadows: yellow↔blue shift (-100 yellow to +100 blue). | |
| pf_preserve_luminosity | No | For type=photo_filter. Preserve luminosity. Default true. | |
| cb_midtones_yellow_blue | No | For type=color_balance. Midtones: yellow↔blue shift. | |
| cb_shadows_magenta_green | No | For type=color_balance. Shadows: magenta↔green shift (-100 magenta to +100 green). | |
| cb_highlights_yellow_blue | No | For type=color_balance. Highlights: yellow↔blue shift. | |
| cb_midtones_magenta_green | No | For type=color_balance. Midtones: magenta↔green shift. | |
| cb_highlights_magenta_green | No | For type=color_balance. Highlights: magenta↔green shift. |
Output Schema
| Name | Required | Description |
|---|---|---|
| type | No | |
| clipped | No | |
| context | No | |
| created | No | |
| hoisted | No | True when the new layer had to be moved back out of the previously-active group to honor into_active_group:false (the default). False when it landed correctly on its own, or when the move-back itself failed — check the layer tree if this matters and hoisted is false. |
| clipError | No | |
| layerKind | No | |
| layerName | No | |
| kindMatches | No | |
| parent_path | No | The containing-group name chain (outermost first), empty array at the document root. |
| mask_applied | No | |
| had_selection | No | |
| mask_inverted | No | |
| customValuesApplied | No | |
| raw_develop_pending | No | Advisory, present only when the active document was opened from a raw source this session and no Camera Raw develop pass has run yet. Nothing failed — the layer was created. Global tone/color on raw sources normally starts with the camera-raw develop pass; ignore if the user prescribed this exact layer or the file was already developed elsewhere. |
| mask_inversion_error | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotation Contradiction: The annotation idempotentHint=true claims the operation is idempotent, but the description says 'Create a non-destructive adjustment layer' — each call would create a new layer, which is not idempotent. While the description adds rich behavioral details (placement hoisting, masking, return context), the direct contradiction with the annotation forces a score of 1.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very long, but each section serves a purpose: purpose, placement nuance, supported types, alternatives, masking, and return value. It is front-loaded with the core purpose. A small deduction for listing all adjustment types that are already in the schema enum, making it slightly redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 71 parameters and an output schema, the description is exceptionally complete. It explains non-obvious placement behavior (hoisting vs into_active_group), selection-based masking, return of parent_path, and explicitly differentiates from sibling tools in key scenarios. The output schema exists, and the description adds context beyond structured fields without needing to re-explain return values in detail.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each of the 71 parameters is already documented in the schema. The description adds a high-level summary of the supported types but largely repeats the enum values already present. It does add some context (e.g., 'Exposure (stops + offset + gamma)'), but the baseline of 3 is appropriate because the schema already carries the parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Create a non-destructive adjustment layer above the active layer.' It clearly distinguishes this from siblings by explicitly naming the canonical entry point for tonal/color adjustments, contrasting with ps_apply_adjustment for destructive ops and ps_merge for pixel baking.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance: 'This is the canonical entry point for tonal/color adjustments' plus an EXCEPT clause for raw-sourced documents. It gives alternatives: ps_merge for pixel bake, ps_apply_adjustment for Shadows/Highlights, and notes the removal of old destructive bake tools. Very clear when-to-use vs alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_add_fill_layerA
Add a non-destructive SOLID COLOR or GRADIENT fill layer (an editable content layer — distinct from ps_fill_layer, which bakes color into the active pixel layer). fill_type=gradient is the go-to for sky fades, color washes, and vignettes (radial + reverse + multiply blend); combine with opacity_stops 100→0 for fade-to-transparent, or ps_bake_layer to rasterize. For fading a layer out via its MASK use ps_layer_mask op=gradient instead. Hoisted out of the active layer's group by default (pass into_active_group:true to keep Photoshop's native nesting). The new fill layer becomes active.
| Name | Required | Description | Default |
|---|---|---|---|
| red | No | fill_type=solid_color: red (0-255). Required for solid_color. | |
| blue | No | fill_type=solid_color: blue (0-255). Required for solid_color. | |
| angle | No | fill_type=gradient: gradient angle in degrees (Photoshop convention: 90 runs the first stop from the bottom up; 0 runs it left to right). | |
| green | No | fill_type=solid_color: green (0-255). Required for solid_color. | |
| scale | No | fill_type=gradient: gradient scale percent (compress/stretch the ramp). | |
| stops | No | fill_type=gradient: color stops, each {red,green,blue (0-255), location (0-100 along the ramp), midpoint (5-95, default 50)}. At least 2 when supplied; sorted by location. Default: black at 0 → white at 100. | |
| dither | No | fill_type=gradient: dither to reduce banding. | |
| reverse | No | fill_type=gradient: reverse the stop order. | |
| offset_x | No | fill_type=gradient: horizontal center offset percent. | |
| offset_y | No | fill_type=gradient: vertical center offset percent. | |
| fill_type | No | Fill-layer type. solid_color takes red/green/blue (required for that type); gradient takes the gradient_* params + stops (pattern fills still planned). | solid_color |
| gradient_type | No | fill_type=gradient: gradient geometry. linear for skies/fades, radial for vignettes/glows. | linear |
| opacity_stops | No | fill_type=gradient: opacity stops, each {opacity (0-100), location (0-100), midpoint (5-95, default 50)}. Use e.g. 100→0 for a fade-to-transparent wash. Default: fully opaque. | |
| into_active_group | No | Photoshop's Mk-contentLayer descriptor carries no placement target, so with a GROUP active it would natively nest the new fill layer INSIDE that group. Default false hoists the new layer back out so it lands above the active layer/group as a sibling. Pass true to keep it nested inside the active group instead. |
Output Schema
| Name | Required | Description |
|---|---|---|
| angle | No | |
| color | No | |
| scale | No | |
| context | No | |
| created | No | |
| hoisted | No | True when the new layer had to be moved back out of the previously-active group to honor into_active_group:false (the default). False when it landed correctly on its own, or when the move-back itself failed — check the layer tree if this matters and hoisted is false. |
| reverse | No | |
| fill_type | No | |
| layer_name | No | |
| stop_count | No | |
| parent_path | No | The containing-group name chain (outermost first), empty array at the document root. |
| gradient_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the minimal annotation (idempotentHint=false), the description discloses key behavioral traits: the fill layer is 'non-destructive', 'becomes active', and is 'hoisted out of the active layer's group by default' unless into_active_group:true is passed. It also explains the distinction from ps_fill_layer, which bakes color into the pixel layer, and explicitly mentions the layer's editable content nature.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is 6 sentences and each sentence earns its place, front-loading the core purpose and then adding differentiation, use cases, alternatives, and placement behavior. It is detailed enough for a 14-parameter tool without being verbose or redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (14 params, multiple modes, placement nuance), the description is fully complete: it covers purpose, alternatives, parameter semantics, default behavior, and side-effects (layer becomes active). The presence of an output schema means return values are covered elsewhere, and no further context is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema description coverage is 100%, the description enriches parameter understanding by explaining conditional usage: 'fill_type=gradient is the go-to for sky fades, color washes, and vignettes', 'combine with opacity_stops 100→0 for fade-to-transparent', and 'gradient_type linear for skies/fades, radial for vignettes/glows'. It also clarifies the placement default and override via into_active_group.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Add a non-destructive SOLID COLOR or GRADIENT fill layer (an editable content layer)', clearly distinguishing ps_add_fill_layer from ps_fill_layer, which 'bakes color into the active pixel layer'. This immediately clarifies the tool's unique role among sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance with alternatives: 'fill_type=gradient is the go-to for sky fades, color washes, and vignettes (radial + reverse + multiply blend)' and 'For fading a layer out via its MASK use ps_layer_mask op=gradient instead'. It also suggests combining with ps_bake_layer to rasterize, giving clear when-to-use and when-not-to-use scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_add_layer_styleAIdempotent
Apply a layer style (drop shadow, stroke, outer glow, inner shadow, inner glow, or color overlay) to the active layer. Non-destructive and editable. For PHOTO workflows: stroke = print-style border around the image (apply to the flattened photo on a transparent canvas, or to a duplicated background); outer_glow = atmospheric lift on highlights (halo around the sun, glow around a window or lamp); drop_shadow = depth on text overlays and layered composites. Drop shadow uses Multiply blend; outer glow uses Screen; stroke uses Normal. Cannot be applied to a background layer (duplicate or convert it first). Returns context — applying a style changes what exists on the layer (the Lefx descriptor).
| Name | Required | Description | Default |
|---|---|---|---|
| size | No | drop_shadow/inner_shadow: shadow blur size in pixels. | |
| angle | No | drop_shadow/inner_shadow: light angle in degrees. 90 = top-down (standard product shadow). | |
| color | No | Effect color RGB (0-255). Default black for drop shadow, white for glow, black for stroke. | |
| style | Yes | Which layer style to apply. drop_shadow/inner_shadow share angle/distance/spread/size; outer_glow/inner_glow share glow_size/glow_spread; color_overlay uses only color + opacity. inner_shadow = recessed shadow inside the layer edges (Multiply); inner_glow = glow inset from the edges (Screen); color_overlay = flat solid-color fill (Normal). | |
| spread | No | drop_shadow/inner_shadow: shadow choke/spread (0-100%). | |
| opacity | No | Effect opacity (0-100). | |
| distance | No | drop_shadow/inner_shadow: shadow offset in pixels. | |
| glow_size | No | outer_glow/inner_glow: glow blur size in pixels. | |
| glow_spread | No | outer_glow/inner_glow: glow choke/spread (0-100%). | |
| stroke_size | No | stroke only: stroke width in pixels. | |
| stroke_position | No | stroke only: where the stroke sits relative to the layer edge. | outside |
Output Schema
| Name | Required | Description |
|---|---|---|
| style | No | |
| applied | No | |
| context | No | |
| layerName | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that the style is non-destructive and editable, complementing the idempotentHint annotation. It also reveals blend modes for specific styles, the background layer restriction, and that applying a style modifies the Lefx descriptor, all of which add behavioral context beyond what annotations alone provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is approximately 100 words, yet every sentence earns its place: purpose, non-destructive nature, photo workflow examples, blend modes, background restriction, and return behavior. It is front-loaded with the core verb/resource, then organized hierarchically from general to specific use cases.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (11 parameters, nested color object, and an output schema), the description covers all essential operational facts: what it does, when to use each style, the background limitation, and the return context (Lefx descriptor). A minor gap is that it doesn't state whether applying a style replaces an existing style or stacks, but overall it is sufficiently complete for an agent to confidently select and invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All 11 parameters are thoroughly documented in the input schema with style-specific coverage, so the description does not need to repeat them. The text adds only marginal context (e.g., blend modes for drop_shadow/outer_glow/stroke) that overlaps with the schema's style parameter description, resulting in limited additional value beyond the structured data.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Apply a layer style' and lists all six supported styles, making it unmistakable that this tool adds layer effects, not filters or fill layers. It also specifies 'to the active layer,' which clearly distinguishes it from sibling tools like ps_add_fill_layer or ps_apply_adjustment that create new layers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit photo workflow scenarios—stroke as a print-style border, outer_glow for atmospheric lift, drop_shadow for depth on text overlays—telling the agent exactly when each style is appropriate. It also gives a clear exclusion (cannot apply to a background layer, duplicate/convert first), though it does not explicitly name alternative sibling tools for other use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_apply_adjustmentADestructive
Apply a DESTRUCTIVE tonal adjustment that Photoshop does NOT offer as an adjustment layer — chosen via type. Runs on a DUPLICATE of the active layer by default (auto-duplicate-first — the original is preserved; revert by deleting the copy); pass apply_to_active_layer: true to bake in place. Auto-rasterizes text/smart-object layers. shadows_highlights recovers blown highlights + crushed shadows in one pass (defaults match Adobe's dialog: 35 shadow amount, +20 color correction); equalize stretches/flattens the histogram (parameter-free); color_lookup bakes a 3DLUT grade (cl_lut_name required — leaf name of a file in Presets/3DLUTs/ or an absolute .cube/.3dl/.look path). For EDITABLE tonal/color work, prefer ps_add_adjustment_layer.
| Name | Required | Description | Default |
|---|---|---|---|
| type | Yes | Which destructive adjustment to bake (none exist as adjustment layers in PS). shadows_highlights: one-pass shadow/highlight recovery (shadow_amount, highlight_amount, …). equalize: parameter-free histogram equalization. color_lookup: bake a 3DLUT grade — cl_lut_name REQUIRED. All auto-duplicate the active layer by default (apply_to_active_layer:true to bake in place). | |
| black_clip | No | Percent of the darkest shadow pixels to clip to pure black (0-50). PS default 0.01 — minimal clipping. Higher values increase contrast but lose shadow detail. | |
| white_clip | No | Percent of the brightest highlight pixels to clip to pure white (0-50). PS default 0.01. Higher values increase contrast but lose highlight detail. | |
| cl_lut_name | No | Leaf name of a 3DLUT file in PS's Presets/3DLUTs/ folder (e.g. "TealOrangePlusContrast.3DL", "FallColors.look", "Kodak 5205 Fuji 3510 (by Adobe).cube") OR an absolute path to a .3DL / .look / .cube file. Extension-agnostic leaf-name resolution (the same base name with a different extension still matches). | |
| shadow_width | No | Tonal width of shadows (0-100). Wider = more midtones treated as shadow. PS default 50. | |
| shadow_amount | No | Shadow recovery amount (0-100). PS default 35. | |
| shadow_radius | No | Local-contrast radius for shadow recovery in pixels (0-2500). PS default 30. | |
| highlight_width | No | Tonal width of highlights (0-100). PS default 50. | |
| color_correction | No | Color saturation compensation for recovered shadows (-100 to +100). PS default +20 — counteracts the desaturation that shadow recovery tends to produce. | |
| highlight_amount | No | Highlight recovery amount (0-100). PS default 0. | |
| highlight_radius | No | Local-contrast radius for highlight recovery in pixels (0-2500). PS default 30. | |
| midtone_contrast | No | Midtone contrast (-100 to +100). PS default 0. | |
| apply_to_active_layer | No | If false (default), the color lookup is applied to a duplicate of the active layer named "<OpName> (<Original Name>)" — the original is preserved and the LLM can undo simply by deleting the copy. If true, the color lookup bakes directly into the active layer (the historical destructive behavior). |
Output Schema
| Name | Required | Description |
|---|---|---|
| filter | No | |
| context | No | |
| lut_path | No | |
| lut_format | No | |
| shadow_width | No | |
| shadow_amount | No | |
| shadow_radius | No | |
| highlight_width | No | |
| target_was_copy | No | |
| color_correction | No | |
| highlight_amount | No | |
| highlight_radius | No | |
| midtone_contrast | No | |
| target_layer_name | No | |
| original_layer_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial context beyond the destructiveHint annotation: it discloses auto-duplication, original preservation, revert-by-deleting-copy, auto-rasterization of text/smart-object layers, and per-type parameter defaults (e.g., shadow amount 35, +20 color correction). No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-structured: it front-loads the core purpose with DESTRUCTIVE emphasized, then covers behavior (auto-duplicate/rasterize) and type-specific semantics in a logical flow. Despite the length, each clause earns its place given the 13-parameter complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 13 parameters, an output schema, and annotations, the description covers purpose, safety, alternatives, per-type behavior, defaults, and parameter requirements. It provides complete guidance without needing to explain return values because an output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed per-parameter descriptions, so the baseline is 3. The description adds valuable extra semantics: how `type` drives parameter relevance, that `equalize` is parameter-free, and that `cl_lut_name` is required for color_lookup. However, it does not describe every parameter's role beyond what the schema already provides, so the value is strong but not exhaustive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Apply') and resource ('tonal adjustment'), enumerates the three concrete types, and explicitly distinguishes itself from the editable alternative by name (ps_add_adjustment_layer). This clearly differentiates it from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states exactly when to use the tool (for destructive adjustments not available as adjustment layers) and explicitly recommends the editable alternative: 'For EDITABLE tonal/color work, prefer ps_add_adjustment_layer.' It also clarifies the default auto-duplicate behavior and the apply_to_active_layer opt-in, so usage context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_apply_brush_strokeADestructive
Paint along a path with one of PS's 16 brush-family tools — supply the path EITHER as an anchor-relational placement (preferred: a path relation → the stroke traces a resolved, gate-verified curve along a traced edge / landmark / between two anchors, no pixel-guessing) OR as an explicit path list of anchor points — the retouch tools (healing_brush, clone_stamp, burn, dodge, blur, sharpen, smudge), the paint family (brush, pencil, eraser), and the specialty tools (pattern_stamp, art_history_brush, history_brush, color_replacement, background_eraser, sponge). The path parameter takes a list of anchor points with optional bezier handles, so the same tool handles straight-line strokes, freeform curves, and closed shapes — all by varying the path geometry. Reach for this when: (a) cloning out a distraction along a specific shape (clone_stamp with a source_point + a path tracing the unwanted edge); (b) healing a scratch or seam (healing_brush with source_point); (c) dodging / burning to redirect tonal balance along a contour; (d) painting a freehand line into the canvas (brush + foreground_color). Active layer must be a normal pixel layer (background auto-promotes); rasterize adjustment/shape/text/smart-object layers first. Auto-duplicates — the original is preserved and a "Brush Stroke ()" copy receives the paint. Brush dynamics: hardness, opacity, and flow are independently settable via hardness_pct / opacity_pct / flow_pct (the live tool options are mutated before stroking and restored to the user's prior state in finally). Sampled brushes (custom shape-stamp presets) silently ignore hardness/diameter mutations — vary their character via brush_preset instead.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Ordered list of anchor points the stroke traces. **Minimum 2 anchors.** Each anchor is `{x, y}` for a sharp corner OR `{x, y, in: [hx, hy], out: [hx, hy]}` for a smooth bezier point. The `in` and `out` handles MUST be positioned **tangent** to the curve at the anchor — `in` placed in the direction of the PREVIOUS anchor in the array, `out` placed in the direction of the NEXT anchor. Handles placed RADIALLY (toward/away from the shape's center) produce loops + concave curves instead of smooth convex ones. Mix corner + smooth points freely. Coordinates are document pixels; (0, 0) is top-left. Partial handles (only `in` OR only `out`) degrade to a sharp corner. **Recipes for common natural-stroke shapes** (compute these client-side and emit the resulting `[{x, y}, ...]` array): (1) **Hand-drawn straight line A→B with sketchy feel**: sample 8-30 evenly-spaced corner anchors along the line, then perturb each interior anchor by ±2-5px on the perpendicular axis — OR pass clean anchors and use `jitter_px` to apply the perturbation server-side (preferred — cheaper, deterministic). (2) **Sine wave A→B, amplitude a, periods n**: for i in 0..N, x_i = A.x + (i/N)*(B.x - A.x), y_i = A.y + a * sin((i/N) * 2π * n). Use 20-40 anchors for a smooth wave. (3) **Parabolic arc A→B peaking height h above midline**: for i in 0..N, t = i/N, x_i = lerp(A.x, B.x, t), y_i = lerp(A.y, B.y, t) - 4*h*t*(1-t). (4) **Canonical clockwise circle of radius r around (cx, cy)** with k = r * 0.5523: TOP `{x: cx, y: cy-r, in: [cx-k, cy-r], out: [cx+k, cy-r]}`, RIGHT `{x: cx+r, y: cy, in: [cx+r, cy-k], out: [cx+r, cy+k]}`, BOTTOM `{x: cx, y: cy+r, in: [cx+k, cy+r], out: [cx-k, cy+r]}`, LEFT `{x: cx-r, y: cy, in: [cx-r, cy+k], out: [cx-r, cy-k]}` — close with `closed: true`. (5) **Many short overlapping strokes for ink-on-paper texture**: chain multiple `apply_brush_stroke` calls along the same trajectory with small position offsets and varying `brush_size`; reads more natural than one long stroke. | |
| tool | Yes | Which brush-family tool to dispatch. Headline retouch options: `healing_brush` and `clone_stamp` (both REQUIRE `source_point` — set the sample location, then stroke the path); `burn` darkens; `dodge` lightens; `blur` smooths; `sharpen` enhances local contrast; `smudge` pushes pixels in the stroke direction. Paint family: `brush` (the standard paintbrush — honors `foreground_color`), `pencil` (hard-edge), `eraser`. Specialty: `pattern_stamp`, `art_history_brush`, `history_brush`, `color_replacement`, `background_eraser`, `sponge`. | |
| closed | No | When true, the path is closed (last anchor connects back to first) so the stroke forms a loop. Default false. | |
| flow_pct | No | Optional brush flow override (percent, 0-100). Routed through `currentToolOptions.flow` (top-level integer key). Flow controls how much paint each stroke step deposits — for paint-family tools (`brush`, `pencil`, `pattern_stamp`), low flow means the stroke needs multiple overlapping passes to reach full opacity; high flow saturates immediately. Restored to the user's original value in `finally`. | |
| jitter_px | No | Server-side hand-drawn perturbation. When > 0, the handler shifts every INTERIOR anchor (not the first, not the last — those stay exactly where you placed them) by a deterministic pseudo-random offset in `[-jitter_px, +jitter_px]` on each axis BEFORE stroking. Bezier handles ride along with their anchor so curve tangents are preserved. Same inputs produce the same emitted shape every call. **Reach for this when** you want a clean intent (mathematically perfect line, sine wave, arc) to read as hand-drawn ink without writing the jitter math yourself. Typical values: 2-5 for subtle ink texture, 5-10 for visibly sketchy, 10-20 for cartoonish/scratchy. Default 0 (no jitter). | |
| placement | No | ANCHOR-RELATIONAL stroke path (preferred over supplying pixels): a PATH relation — `along` a traced edge or a Pro face-mesh landmark curve, `offset-curve`, or `segment` between two anchors — so the stroke traces the resolved, gate-verified curve (the FULL polyline, not just endpoints: paint along the jaw / horizon / under-eye). Strokes ONLY if the gate PASSES. When set, `path` is ignored; tool/brush_size/source_point/colors/dynamics/jitter still apply. See ps_resolve_placement for the anchors + relation vocabulary. | |
| brush_size | Yes | Brush tip diameter in pixels. Typical retouch values: 12-30 for fine work, 50-100 for filling, 150+ for broad strokes. Verified scriptable via `setd Brsh.Trgt masterDiameter` in the 2026-06-09 spike. | |
| opacity_pct | No | Optional brush opacity override (percent, 0-100). Routed through `currentToolOptions.opacity` (a top-level integer key on the tool options descriptor, not nested inside the brush sub-descriptor). Applies to the WHOLE stroke uniformly — varying-opacity strokes require chaining multiple `apply_brush_stroke` calls. Restored to the user's original value in `finally`. | |
| brush_preset | No | Optional brush-preset name to select before stroking (e.g. "Soft Round", "Hard Round", or any custom preset the user has loaded). The preset's saved hardness, opacity, flow, and shape dynamics load with the slct dispatch — set the preset for a coherent character (soft vs hard, calligraphic vs round), then optionally override individual values via `hardness_pct` / `opacity_pct` / `flow_pct`. If the named preset is not installed, the tool falls back to "Soft Round" then "Hard Round" (both ship on every install) and reports which one landed via `preset_applied` in the result. | |
| hardness_pct | No | Optional brush hardness override (percent, 0-100). When set, mutates the live tool's hardness via the `currentToolOptions.brush.hardness` get-mutate-set pattern AFTER any brush_preset has loaded — so the preset's hardness is what you start from and this overrides it. **Computed brushes only**: Soft Round / Hard Round / Calligraphic / etc. accept the mutation; **sampled brushes** (custom shape-stamp presets loaded from .abr files) silently ignore it because their shape isn't parametric. The user's original tool options are restored in `finally` so this doesn't leak to their next non-LLM brush action. | |
| source_point | No | Sample point for `clone_stamp` / `healing_brush` — the pixel location PS samples from while the stroke progresses. REQUIRED for those two tools (unless `source_placement` names it instead). Ignored for all others. `layer_name` defaults to the active layer at call time when omitted. | |
| foreground_color | No | RGB foreground color for paint-family tools (`brush`, `pencil`). The retouch family (`burn`/`dodge`/`blur`/`sharpen`/`smudge`/`clone_stamp`/`healing_brush`) ignores foreground color — setting it on those tools is harmless but pointless. The user's previous foreground color is restored after the stroke completes. | |
| source_placement | No | Grounded alternative to `source_point` for `clone_stamp` / `healing_brush`: NAME the sample location (resolves to a POINT via the grounding resolver + objective gate — e.g. an `extremum` for the cleanest/smoothest nearby skin, a `grid` intersection, or a landmark point) instead of guessing pixels. Resolves to a POINT relation (centroid / midpoint / offset / extremum / grid / landmark point); the resolved point supplies `source_point` and WINS over an explicit `source_point`. Strokes only if the source gate PASSES. | |
| apply_to_active_layer | No | If false (default), the stroke is applied to a duplicate of the active layer named "<OpName> (<Original Name>)" — the original is preserved and the LLM can undo simply by deleting the copy. If true, the stroke bakes directly into the active layer (the historical destructive behavior). |
Output Schema
| Name | Required | Description |
|---|---|---|
| tool | No | |
| closed | No | |
| anchors | No | |
| context | No | |
| stroked | No | |
| placement | No | Present when the stroke path came from anchor-relational placement: the resolved curve + gate verdict. |
| tool_type | No | |
| brush_size | No | |
| flow_applied | No | |
| path_removed | No | |
| size_applied | No | |
| preset_applied | No | Name of the brush preset that actually landed — equal to `brush_preset` if installed, "Soft Round" / "Hard Round" if a fallback fired, null when no preset was requested. |
| opacity_applied | No | |
| stroke_envelope | No | The doc-pixel bbox the stroke should occupy (path bbox + brush radius) — the objective target to verify stroke occupancy against. |
| target_was_copy | No | |
| clone_source_set | No | |
| hardness_applied | No | |
| source_placement | No | Present when the clone/heal sample point came from a source_placement: the resolved point + gate verdict. |
| target_layer_name | No | |
| background_promoted | No | |
| original_layer_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only sparse annotations (idempotentHint=false, destructiveHint=true), the description carries the burden and delivers richly: auto-duplication preserving the original with a 'Brush Stroke (<name>)' copy, tool-option mutation restored in `finally`, sampled brushes silently ignoring hardness/diameter mutations, background auto-promotion, and gate-verified placement that strokes only on pass. The destructive `apply_to_active_layer=true` path is explicitly disclosed, so there is no contradiction with destructiveHint — the annotation is merely conservative.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but for a 14-parameter, 16-tool surface every section earns its place: family inventory, when-to-use block, layer prerequisite, auto-duplication, and the sampled-brush caveat. Structure is logical — capability → input modes → tool list → use cases → prerequisites → side effects → dynamics — and the key 'Reach for this when' guidance is bolded and prominent. The only mild redundancy is echoing the tool enum, but the family-grouping angle justifies it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value explanation is unnecessary, and the description covers the major behavioral contracts: dual input modes (placement vs path), gate-failure semantics for placement, layer prerequisites, auto-duplication default, and user-state restoration. All nested objects (placement, source_placement, source_point, foreground_color) are addressed. Minor gaps such as exact error behavior on gate failure are left to schema/output, which is acceptable at this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds cross-cutting semantics the schema lacks: which tools REQUIRE source_point, which families honor foreground_color vs ignore it, and the brush-dynamics interaction order (preset loads first, then hardness_pct overrides). The family grouping (retouch/paint/specialty) enriches the flat enum meaningfully. Per-parameter detail rightly lives in the schema, so this is a solid 4 rather than a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: 'Paint along a path with one of PS's 16 brush-family tools,' and enumerates the full tool families (retouch, paint, specialty). The four 'Reach for this when' scenarios pin down concrete use cases, making it unambiguous how this differs from siblings like ps_filter, ps_apply_adjustment, or ps_fill_layer. No ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The bolded '**Reach for this when**' block lists four concrete scenarios (clone-out a distraction, heal a scratch/seam, dodge/burn a contour, paint a freehand line), and the placement-vs-path guidance states which input mode is preferred and why. It also gives a clear prerequisite: rasterize adjustment/shape/text/smart-object layers first. It does not explicitly name sibling tools it is NOT for, so exclusions remain implicit rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_apply_imageADestructive
Composite a source layer + channel onto the ACTIVE layer using a calculation blend mode (Image ▸ Apply Image). Reach for this for luminosity blends, frequency-separation re-blends, texture overlays, or pulling one channel into another. Source = a layer (merged or named) and a channel (rgb/red/green/blue/alpha). Bakes into pixels, so by default it runs on a DUPLICATE of the active layer (set apply_to_active_layer=true to bake in place). The active layer must be a normal pixel layer. (AM-only; verified live on PS 27.2.0.)
| Name | Required | Description | Default |
|---|---|---|---|
| blend | Yes | Calculation blend mode: how the source combines with the target. multiply (darken/texture), screen (lighten), overlay/soft_light/hard_light (contrast), difference/exclusion/subtract/add (channel math for masks). | |
| opacity | No | Blend opacity 0-100. Default 100 (full strength). | |
| source_layer | No | Which layer to pull the source from: 'merged' (the flattened composite, default) or an exact layer name. | merged |
| source_channel | No | Source channel: 'rgb' (the composite, default), a single 'red'/'green'/'blue' channel, or 'alpha' (then set source_alpha_name). | rgb |
| source_alpha_name | No | Required when source_channel='alpha': the name of the alpha channel to read. | |
| apply_to_active_layer | No | If false (default), the composite is applied to a duplicate of the active layer named "<OpName> (<Original Name>)" — the original is preserved and the LLM can undo simply by deleting the copy. If true, the composite bakes directly into the active layer (the historical destructive behavior). |
Output Schema
| Name | Required | Description |
|---|---|---|
| blend | No | |
| applied | No | |
| context | No | |
| opacity | No | |
| source_layer | No | |
| source_channel | No | |
| target_was_copy | No | |
| target_layer_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the destructiveHint annotation by explaining that the tool defaults to running on a duplicate of the active layer, preserving the original, with an opt-in flag to bake in place. It also discloses the 'AM-only' environment and version verification, adding useful behavioral context without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is succinct, with six sentences each serving a purpose: main action, use cases, source explanation, safety behavior, prerequisite, and environment note. It is front-loaded with the primary operation and uses bold for 'Reach for this' to draw attention to usage guidance without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, multiple channels, blend modes) and the presence of a detailed input schema and output schema, the description adds the necessary context: purpose, use cases, default safety behavior, and prerequisites. It is complete enough for an agent to decide when to use it and what to expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with detailed descriptions for all six parameters, including the blend mode enum and apply_to_active_layer behavior. The main description adds only a high-level summary of source and channel, which is already well-covered in the schema, so it provides minimal additional semantic value beyond the structured fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool composites a source layer and channel onto the active layer using a calculation blend mode, explicitly naming 'Image ▸ Apply Image'. It also lists specific use cases like luminosity blends and channel pulling, which distinguishes it from the sibling tool ps_calculations by focusing on the active layer target.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit 'Reach for this' use cases (luminosity blends, frequency-separation, texture overlays, channel pulling) and mentions prerequisites like the active layer must be a normal pixel layer. However, it does not explicitly mention alternatives such as ps_calculations or scenarios where this tool should not be used, so it lacks a crisp when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_bake_layerA
Flatten the active layer's CURRENT APPEARANCE — the layer plus any adjustment layers clipped to it plus its layer styles — into a NEW pixel layer named " (baked)". Non-destructive: the originals are left intact. This is how you get real baked pixels out of a non-destructive stack: clip a Hue/Saturation (saturation -100) or an Invert adjustment to a layer, then bake to get a desaturated / inverted PIXEL layer for techniques that need actual pixels (line art, blurred-layer blends). Also works on a lone layer with nothing clipped to it — it rasterizes that layer's own appearance (layer styles, smart-object or text content) into a flat pixel copy. The active layer must be top-level (not inside a group).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| baked | No | |
| context | No | |
| baked_layer_name | No | |
| source_layer_name | No | |
| clipped_layers_baked | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description provides rich behavioral detail beyond annotations: it explicitly states the operation is non-destructive, creates a new pixel layer with a specific naming pattern, includes clipping and styles, and works for lone layers. It also discloses the requirement that the active layer be top-level. This goes well beyond the minimal idempotentHint annotation and gives the agent a full understanding of side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a bit lengthy but every sentence earns its place: it explains the core action, the non-destructive nature, an explicit usage recipe, and a key constraint. It is front-loaded with the main purpose, and while it could be trimmed slightly, the extra detail aids usability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there are no parameters and an output schema exists, the description covers all essential context: what the tool does, why to use it, how it works in common scenarios, and its constraints. There is no missing information that would prevent an agent from selecting and invoking it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so schema coverage is trivially 100%. The description adds no parameter-specific info because none exists, but it explains the tool's behavior in a way that makes the lack of parameters clear. Baseline 4 for 0 params is appropriate; the description doesn't leave any ambiguity about inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Flatten' and the exact resource: the active layer's current appearance, including clipped adjustment layers and layer styles, into a new pixel layer. It distinguishes from sibling tools (like ps_rasterize_layer) by emphasizing non-destructive creation of a new layer, and provides concrete examples that clarify its unique role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly explains when to use this tool: 'This is how you get real baked pixels out of a non-destructive stack' with a specific example (desaturating via Hue/Saturation or Invert). It also states it works on a lone layer. However, it does not explicitly name alternative tools or say 'use this instead of X,' though the context implies the distinction. The constraint that the active layer must be top-level is clearly stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_calculationsA
Blend TWO sources (each a layer + single channel) into a NEW alpha channel via a calculation blend mode (Image ▸ Calculations). Reach for this to build advanced selections/masks from channel math — e.g. difference of two channels to isolate edges, or multiply two channels for a luminosity mask. Non-destructive: adds a new channel (delete it to revert); the result is loadable as a selection via ps_selection_channel op=load. (AM-only; verified live on PS 27.2.0.)
| Name | Required | Description | Default |
|---|---|---|---|
| blend | Yes | Calculation blend mode: how the source combines with the target. multiply (darken/texture), screen (lighten), overlay/soft_light/hard_light (contrast), difference/exclusion/subtract/add (channel math for masks). | |
| opacity | No | Blend opacity 0-100. Default 100. | |
| source1_layer | No | Source 1 layer: 'merged' (default) or an exact layer name. | merged |
| source2_layer | No | Source 2 layer: 'merged' (default) or an exact layer name. | merged |
| source1_channel | No | Source 1 channel: a single 'red'/'green'/'blue' channel, or 'alpha' (+ name). | red |
| source2_channel | No | Source 2 channel: a single 'red'/'green'/'blue' channel, or 'alpha' (+ name). | red |
| source1_alpha_name | No | Required when source1_channel='alpha'. | |
| source2_alpha_name | No | Required when source2_channel='alpha'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| blend | No | |
| context | No | |
| opacity | No | |
| calculated | No | |
| channel_count | No | |
| new_channel_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (which only mark non-idempotent and non-destructive), the description adds rich behavioral detail: it states the operation is 'Non-destructive: adds a new channel (delete it to revert)' and explains the result can be loaded as a selection. It also discloses the environment constraint 'AM-only; verified live on PS 27.2.0', which annotations do not cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is only three sentences, front-loaded with the core function, then use cases, then behavior. Every sentence adds value: the function, the practical examples, and the non-destructive/revert behavior. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists, the description need not explain returns, and it covers all necessary context: what the tool does, when to use it, how it behaves (non-destructive, new channel), and how to follow up. It also mentions the AM-only environment. The tool's complexity is well-supported by the rich schema and this description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already has 100% descriptive coverage for all 8 parameters, including enum explanations of blend modes and channel options. The description provides conceptual guidance (e.g., 'multiply two channels for a luminosity mask') but does not add details beyond what the schema already states, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: 'Blend TWO sources... into a NEW alpha channel via a calculation blend mode' and differentiates from siblings by focusing on channel math for masks ('difference of two channels to isolate edges'). It names the actual Photoshop menu (Image ▸ Calculations), making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use context: '**Reach for this** to build advanced selections/masks from channel math' and provides concrete examples. It also references the follow-up operation (ps_selection_channel op=load) but does not explicitly state alternatives to avoid for simpler operations, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_clipping_maskAIdempotent
Clip or un-clip the active layer against the layer directly below it — choose with op. create: use the layer below as the alpha source; PS paints the active layer only where the layer below has pixels. Non-destructive — the upper layer is unchanged. Common for constraining a texture/photo to a shape, or masking an effect to a single underlying layer (the add_adjustment_layer tool already accepts clip_to_below for the adjustment-layer-specific case). Equivalent to Layer > Create Clipping Mask (Ctrl+Alt+G). release: the inverse — the layer returns to compositing against the whole canvas. Both ops are idempotent: create no-ops (already_clipped:true) on an already-clipped layer; release no-ops (released:false) on a non-clipped layer.
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | create: clip the active layer to the layer directly below it (that layer becomes the alpha source); no-ops (already_clipped:true) when the layer is already clipped. release: release the active layer from its clipping mask; no-ops (released:false) when the layer is not clipped. |
Output Schema
| Name | Required | Description |
|---|---|---|
| clipped | No | |
| context | No | |
| released | No | |
| layerName | No | |
| already_clipped | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the idempotentHint annotation, revealing that the operation is non-destructive, that create no-ops with already_clipped:true and release no-ops with released:false, and that the active layer is unchanged. This behavior is not evident from the annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise yet thorough, front-loading the core operation and then supporting details in a logical order: action, create, release, idempotency note. Every sentence contributes meaning, with no filler or repetition of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a single parameter fully documented in the schema and an output schema that can convey return details, the description covers everything needed for correct selection and invocation: operands, effect, no-op behavior, and alternative tools. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already rules the single op parameter with a 100%-coverage enum description. The tool description enriches this by explaining the mechanics (layer below becomes alpha source), the inverse behavior, and the practical consequence, adding value beyond the schema's dry definition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific operation ('Clip or un-clip the active layer against the layer directly below it') and explicitly names the two modes, create and release. It clearly distinguishes this tool from siblings like ps_layer_mask and ps_add_adjustment_layer, so an agent can identify its unique role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives contexts for use (constraining a texture/photo to a shape, masking an effect to a single underlying layer) and explicitly directs the agent away from this tool when an adjustment-layer-specific case exists, naming the add_adjustment_layer tool as the alternative. This is explicit when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_close_documentADestructiveIdempotent
Close a Photoshop document — the active one by default, or a specific one by name or id. Destructive if save=false and the document has unsaved changes. If two open documents share the requested name the call fails rather than guessing. Returns the closed document name plus a fresh context block (which document, if any, is active afterwards).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Target an open document by its Photoshop document id. Unambiguous — prefer this when names collide. | |
| name | No | Target an open document by its exact Photoshop name, INCLUDING the extension as shown in the tab (e.g. 'portrait.jpg', not 'portrait'). If two open documents share a name the call fails rather than guessing — target by id instead. | |
| save | No | Whether to save changes before closing |
Output Schema
| Name | Required | Description |
|---|---|---|
| saved | No | |
| closed | No | |
| context | No | |
| closedName | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the destructiveHint annotation by specifying the exact condition under which closing is destructive (save=false with unsaved changes), and it discloses the duplicate-name failure mode and the returned context block. This is valuable behavioral detail an agent needs before calling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences cover purpose, targeting options, destructive risk, ambiguity handling, and return value without redundancy. The most important content is front-loaded and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the default behavior, all targeting modes, failure on ambiguous names, destructive conditions, and the post-close context update. Combined with full parameter schema coverage, the output schema, and annotations, nothing important is missing for an agent to invoke this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter is already well described. The description adds meaningful context beyond the schema, especially the active-by-default targeting and the guidance to prefer id over name when names collide, which helps an agent choose parameters correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Close a Photoshop document'), immediately distinguishes the active-by-default behavior from targeting by name or id, and makes the tool's scope clear relative to document-focused siblings. It fully answers what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context for choosing the active document versus a specific one, and explicitly advises using id when names collide. It does not name alternative sibling tools or state when not to use this tool, but the guidance provided is sufficient for correct invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_compare_regionsARead-onlyIdempotent
Quantitative region comparison — the NUMERIC verification answer when "does it look right?" via get_preview is too subjective. Captures the histogram of two rectangular regions on the same document and reports per-channel mean / stdev / median for each region plus the deltas. Reach for this when: (a) "did the placed image match the room's lighting?" — sample a region of the placed image vs a region of the surrounding wall; (b) "did this adjustment do anything visible in the shadows?" — sample the same dark region before and after; (c) "is region A noticeably warmer/cooler than region B?" — read the channel means directly. Single-pixel sampling via a 1×1 rect is supported. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| label_a | No | Optional label for region A in the response. | |
| label_b | No | Optional label for region B in the response. | |
| region_a_top | Yes | Region A top edge. | |
| region_b_top | Yes | Region B top edge. | |
| region_a_left | Yes | Region A left edge. | |
| region_b_left | Yes | Region B left edge. | |
| region_a_right | Yes | Region A right edge. | |
| region_b_right | Yes | Region B right edge. | |
| region_a_bottom | Yes | Region A bottom edge. | |
| region_b_bottom | Yes | Region B bottom edge. |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| region_a | No | |
| region_b | No | |
| differences | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the description adds value by explaining the output structure (per-channel mean/stdev/median, deltas) and the supported single-pixel sampling. It does not contradict annotations and provides useful behavioral context beyond the hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: the first sentence states the core purpose, the next gives technical detail, then a bolded 'Reach for this when' section with three examples, plus a final note on single-pixel support. Every sentence earns its place and information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema and strong annotations, the description is complete. It explains the purpose, usage scenarios, and key constraints (same document, 1x1 sampling). Missing details like error handling are not essential for a read-only comparison tool with output schema defined.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter is already documented. The description adds overall context about what the regions represent and the comparison nature, but does not elaborate on individual coordinate semantics, units, or edge cases. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description has a specific verb and resource: it captures histograms of two regions and reports per-channel statistics with deltas. It clearly distinguishes itself from get_preview by framing itself as the numeric verification counterpart for subjective visual checks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Reach for this when' section lists three concrete use cases with examples, and directly contrasts with get_preview. This gives the agent clear actionable guidance on when to select this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_convert_image_modeADestructiveIdempotent
Convert the document color mode (grayscale / rgb / cmyk / lab). Destructive and document-wide: the image is FLATTENED and, for grayscale, color is discarded (the confirmation prompt is auto-accepted). Use grayscale as the base for halftone / line-art workflows, or rgb to bring a CMYK/Lab doc back for normal editing. Returns updated document context.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | Target document color mode. grayscale discards color (the "Discard color information?" prompt is auto-confirmed); the document is FLATTENED as part of the conversion. `bitmap` produces a 1-bit halftone-screen image (auto-converts to grayscale first) — use frequency/angle/shape. | |
| angle | No | bitmap only: halftone screen angle in degrees (-180 to 180). PS default 45. | |
| shape | No | bitmap only: halftone dot shape. | round |
| frequency | No | bitmap only: halftone screen frequency in lines/inch (1-999). PS default 53. |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| converted | No | |
| mode_after | No | |
| mode_before | No | |
| requested_mode | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint/idempotentHint, and the description adds critical behavioral details: document-wide flattening, auto-accepting the confirmation prompt, and color discard for grayscale. This goes well beyond the annotations and is consistent with them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three purposeful sentences, front-loaded with the action and destructiveness warning, followed by usage guidance and return value. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has a rich input schema and an output schema. The description covers the destructive scope, when to use which mode, and what is returned ('updated document context'). Any omitted details like bitmap are fully handled by the schema, making this complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with detailed parameter descriptions, including bitmap-specific parameters and defaults. The description's prose covers mode at a high level but omits bitmap and the angle/shape/frequency parameters; however, the schema already provides full semantics, so a baseline score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description explicitly states 'Convert the document color mode' and lists specific target modes. This clearly distinguishes it from sibling tools like resize/crop by focusing on color mode conversion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides concrete usage context: 'Use grayscale as the base for halftone / line-art workflows, or rgb to bring a CMYK/Lab doc back for normal editing.' It doesn't state when not to use or name alternatives, but the use cases are clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_convert_to_smart_objectA
Convert the active layer to a Smart Object, or (mode=new_via_copy) copy an existing Smart Object to an independent new one. convert (default) wraps the layer content so every subsequent filter becomes a Smart Filter — fully editable and non-destructive. PREREQUISITE for Camera Raw Filter, non-destructive frequency separation, and any workflow where filter parameters need to stay adjustable after the fact. Works on pixel, text, shape, and adjustment layers. Auto-promotes the background layer if needed. Wrapping an already-Smart-Object layer creates a nested Smart Object (valid in Photoshop — the inner SO is preserved as-is). new_via_copy requires the active layer to already be a Smart Object and yields a copy with its OWN source (unlinked). Use ps_rasterize_layer to go the other direction.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | convert (default): wrap the active layer into a Smart Object in place. new_via_copy: the active layer must ALREADY be a Smart Object — make a NEW Smart Object that is an INDEPENDENT copy (its own embedded source), unlinked from the original's shared source, so editing the copy's contents does not propagate back. (Differs from ps_duplicate_layer of a Smart Object, which keeps the shared source.) | convert |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| layer_name | No | |
| original_kind | No | |
| is_smart_object | No | |
| source_unlinked | No | |
| background_promoted | No | |
| was_already_smart_object | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the minimal annotations by explaining key behavioral traits: wrapping is non-destructive, background auto-promotion, creation of nested Smart Objects when wrapping an existing SO, and the unlinked nature of new_via_copy. It also clarifies that new_via_copy requires the active layer to already be a Smart Object.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is relatively long but every sentence contributes meaning—covering modes, use cases, supported layers, background promotion, edge cases, and alternatives. It is well-structured with `convert` and `new_via_copy` separated, though slightly dense for a quick read.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having only one optional parameter, the tool's behavior is nuanced and depends on current layer state. The description covers prerequisites, side effects (nested SO, background promotion), and both modes comprehensively. Since an output schema exists, the lack of return-value explanation is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the mode parameter has a detailed description in the schema, providing a baseline of 3. The main description adds extra semantic nuance beyond the schema, such as the nested Smart Object behavior and explicit contrast with ps_duplicate_layer, elevating it to 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Convert') and resource ('active layer to a Smart Object'), and distinguishes between the default 'convert' mode and 'new_via_copy'. It also explicitly differentiates from sibling tools by mentioning 'Use ps_rasterize_layer to go the other direction' and contrasts with ps_duplicate_layer in the schema description.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance: 'PREREQUISITE for Camera Raw Filter, non-destructive frequency separation, and any workflow where filter parameters need to stay adjustable after the fact.' Also specifies supported layer types, auto-promotion of background, and an alternative tool (ps_rasterize_layer) for the reverse operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_copy_to_new_layerA
Copy the current selection into a NEW layer above the active one — Photoshop's "Layer via Copy" (Ctrl+J) — hoisted out of the active layer's group by default even though the underlying CpTL event carries no placement target and would otherwise nest the new layer INSIDE that group (pass into_active_group:true to keep that native nesting). The source layer is left untouched and the new copied layer becomes active. With an active selection only the selected pixels are lifted; with no selection it copies the whole active layer (a plain duplicate). Reach for this to isolate a region for independent transforms or filters (stretch, light rays, a local grade) without altering the source. Returns context so the caller sees the new active layer.
| Name | Required | Description | Default |
|---|---|---|---|
| into_active_group | No | Photoshop's CpTL (Layer via Copy) event carries no placement target, so with a GROUP active it would natively nest the new layer INSIDE that group. Default false hoists the new layer back out so it lands above the active layer/group as a sibling. Pass true to keep it nested inside the active group instead. |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| hoisted | No | True when the new layer had to be moved back out of the previously-active group to honor into_active_group:false (the default). False when it landed correctly on its own, or when the move-back itself failed — check the layer tree if this matters and hoisted is false. |
| parent_path | No | The containing-group name chain (outermost first), empty array at the document root. |
| new_layer_name | No | |
| layer_count_after | No | |
| layer_count_before | No | |
| copied_to_new_layer | No | |
| original_active_layer_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No readOnly/destructive annotations are present, so the description carries the full burden. It thoroughly discloses the default hoisting behavior, the underlying CpTL event's lack of placement target, the effect of into_active_group, that the source is left untouched, that the new layer becomes active, and the selection edge cases. This is exemplary transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place, progressing from the core action to edge cases to usage. It is front-loaded with 'Copy the current selection...' and contains no redundant or filler content, making it appropriately sized for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one optional parameter, an output schema, and only idempotentHint annotation, the description fully covers selection behavior, group placement, return context, and intended use cases. It leaves no significant ambiguity for an agent trying to decide whether and how to call it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description goes beyond the schema by explaining the 'why' behind the parameter: the CpTL event carries no placement target and would otherwise nest the new layer inside the active group. This rationale is not in the schema, adding genuine meaning for correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource+behavior: 'Copy the current selection into a NEW layer above the active one — Photoshop's "Layer via Copy" (Ctrl+J)'. It clearly distinguishes this from sibling tools by explaining the selection semantics and the group-nesting nuance, which makes the tool's unique purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives direct usage guidance: 'Reach for this to isolate a region for independent transforms or filters' and explains behavior with and without a selection. It does not explicitly name alternative sibling tools or state when not to use this tool, but the context is clear enough for an agent to decide.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_create_documentA
Create a new empty Photoshop document with given dimensions, resolution, and color mode. Returns the new document id and name plus active context. Use this when starting from scratch; prefer ps_open_document to load an existing file.
| Name | Required | Description | Default |
|---|---|---|---|
| width | Yes | Document width in pixels | |
| height | Yes | Document height in pixels | |
| color_mode | No | Color mode (RGB, CMYK, Grayscale) | RGB |
| resolution | No | Document resolution in DPI (default: 72) |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| name | No | |
| context | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide title and idempotentHint=false, so the description carries most of the behavioral disclosure burden. It adds value by noting the return value ('Returns the new document id and name plus active context'), which hints at side effect of becoming active. It does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: first states purpose and returns, second gives usage guidance and alternative. No wasted words, front-loaded with the core action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return value details are already covered. The description fully covers the tool's purpose, when to use it, and how it differs from siblings. It is complete for a straightforward create operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with well-described parameters (width, height, color_mode, resolution). The description merely lists parameter categories ('dimensions, resolution, and color mode') without adding new meaning beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Create') and resource ('new empty Photoshop document') with explicit parameters (dimensions, resolution, color mode). It clearly distinguishes from sibling ps_open_document by stating 'prefer ps_open_document to load an existing file.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use this tool: 'Use this when starting from scratch' and provides an alternative: 'prefer ps_open_document to load an existing file.' This gives clear context and exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_create_layerA
Create a new empty raster layer above the currently active layer. Non-destructive. Use ps_text (op=create) for text, ps_add_adjustment_layer for adjustments.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Name for the new layer (optional) |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| created | No | |
| layerName | No | |
| parent_path | No | The containing-group name chain (outermost first), empty array at the document root. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds meaningful behavioral context by stating 'Non-destructive' and specifying the created layer's position relative to the currently active layer. Annotations only provide idempotentHint: false, so the description carries the burden of safety disclosure and handles it well, though it does not explain what happens if no document/active layer exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences provide the core action, positioning, safety behavior, and alternative routing with no filler. The most important information is front-loaded and every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple operation with one optional parameter and no required fields, the description fully covers what the agent needs to know: what is created, where it is created, that it is non-destructive, and what to use instead for text or adjustment layers. The existing output schema covers return behavior, so the description does not need to duplicate it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already contains a complete description of the only parameter: 'Name for the new layer (optional),' giving 100% schema description coverage. The description does not need to restate this, and it adds no meaning beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Create a new empty raster layer above the currently active layer.' It clearly distinguishes itself from sibling creation tools like ps_text and ps_add_adjustment_layer, and the phrase 'empty raster layer' removes ambiguity about what kind of layer is created.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to use this tool and when to choose an alternative: 'Use ps_text (op=create) for text, ps_add_adjustment_layer for adjustments.' This gives direct routing guidance without requiring the agent to infer it from the schema or sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_crop_documentADestructiveIdempotent
Crop the document to a region — EITHER anchor-relational placement (preferred: a region relation like inside/gap → the crop is the resolved, gate-verified region bbox, no pixel-guessing) OR absolute pixel bounds (left/top/right/bottom in document space). Destructive: pixels outside the bounds are permanently lost. Idempotent for the same bounds. Returns updated document context.
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | Top edge position in pixels (raw mode; ignored when placement is set). | |
| left | No | Left edge position in pixels (raw mode; ignored when placement is set). | |
| right | No | Right edge position in pixels (raw mode; ignored when placement is set). | |
| bottom | No | Bottom edge position in pixels (raw mode; ignored when placement is set). | |
| placement | No | ANCHOR-RELATIONAL crop (preferred over guessing pixels): a REGION relation (inside/gap) → the crop is the resolved region bounding box, verified by the gate. Crops ONLY if the gate PASSES. When set, left/top/right/bottom are ignored. See the placement-resolver tool, when this build has one, for the anchors + relation vocabulary. |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| cropped | No | |
| newWidth | No | |
| newHeight | No | |
| placement | No | Present when anchor-relational placement was used: the resolved region + gate verdict. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint and idempotentHint, and the description adds operational detail: pixels outside the crop are permanently lost, placement-based crops are gate-verified and only executed when the gate passes, and the operation returns updated document context. This goes beyond the bare hints without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured: one front-loaded sentence covers the two modes, and the next covers consequences and return value. There is no filler, and every clause contributes operational or safety context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For five parameters including a nested placement object, the description plus schema covers modes, coordinate space, gate behavior, destructive impact, idempotency, and result. The only minor weakness is the repeated 'when this build has one' caveat, but it does not prevent correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds useful meaning by framing placement as the preferred approach and clarifying that raw bounds are expressed in document space, helping the agent choose between the two parameter groups.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the operation: 'Crop the document to a region' and enumerates the two supported modes. It is unambiguous about the resource and action, but it does not explicitly contrast with sibling tools like ps_transform_canvas or ps_resize_image.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete mode-selection guidance, saying anchor-relational placement is 'preferred' over raw pixel bounds and noting that raw bounds are ignored when placement is set. It does not name alternative sibling tools to use instead, but the in-tool guidance is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_delete_layerADestructive
DESTRUCTIVE: Delete a layer. With no arg, deletes the currently active layer (backward-compatible). With name, recurses into groups and deletes the first LAYER matching that name — useful for cleanup workflows where the dead layer is not currently active. A name that matches a group is refused rather than deleted; use ps_group(op=delete) to delete a group and all its contents. Recoverable only via Edit > Undo.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Optional layer name. If supplied, recurses into groups and deletes the first layer matching this name. If omitted, deletes the currently active layer (backward-compatible). |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| deleted | No | |
| layerName | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds valuable behavior beyond the destructiveHint annotation: it warns that deletion is recoverable only via Edit > Undo, explains recursion into groups, and discloses that group-name matches are refused. This level of detail is especially useful for a destructive operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the critical destructive warning. Every sentence carries useful information: the two behavior modes, the group-match exception, the alternative tool, and the recovery path. There is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive tool, the description is complete: it covers both parameter states, the recursion behavior, refusal semantics, recovery expectations, and the correct alternative for groups. The output schema exists, so return-value explanation is not needed from the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the input schema already documents the `name` parameter well. The description adds extra meaning by emphasizing that matching is first-match, happens recursively through groups, and that group names will not be deleted. This goes beyond the schema's baseline and helps the agent understand edge behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the verb and resource precisely ('Delete a layer') and distinguishes the two invocation modes: no-argument deletes the active layer, while `name` deletes the first matching layer in groups. It also explicitly differentiates from `ps_group` by stating that groups are refused rather than deleted.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear when-to-use guidance: use no-arg for backward-compatible active-layer deletion, and use `name` for cleanup when the target layer is not active. It also provides an explicit alternative — `ps_group(op=delete)` — for deleting groups, which prevents misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_detectARead-onlyIdempotent
The cheap, narrow read: labeled bounding boxes only — faces and/or COCO-80 objects (person, dog, car, chair, sofa, …) in DOCUMENT-pixel space. LOCAL on-device computer vision; the image is never sent anywhere. Use this for real coordinates before a spatially-targeted edit when boxes are all you need — far more reliable than estimating positions from a preview. For the full scene model (regions, horizon, tonal zones, composition, and a menu of selectable named regions), use ps_read_scene instead. target selects faces / objects / both. Read-only: renders a throwaway duplicate, never modifies the working document. Boxes are [x1, y1, x2, y2]. Pass annotate:true for an annotated preview JPEG (faces cyan, objects magenta) when you need to visually confirm a surprising result.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | What to detect: 'faces' (forward-facing faces), 'objects' (COCO-80 classes: person, dog, car, chair, …), or 'both'. | both |
| annotate | No | Also return an annotated preview JPEG with the detected boxes drawn (faces cyan, objects magenta). Default false: the labeled boxes returned by this call are already complete on their own — ask for the image only when you actually need to visually confirm a detection. | |
| max_objects | No | Cap on returned objects, highest-confidence first. | |
| max_dimension | No | Long-edge pixels of the JPEG the detectors run on. Smaller is faster; the models downscale internally so 1024 is plenty. Returned coordinates are always in full document pixels regardless. | |
| face_threshold | No | Minimum face confidence (0–1). | |
| object_threshold | No | Minimum object confidence (0–1). |
Output Schema
| Name | Required | Description |
|---|---|---|
| faces | No | |
| image | No | |
| context | No | |
| objects | No | |
| backends | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and idempotentHint annotations, the description adds valuable behavioral context: it is local on-device vision, the image is never sent anywhere, it renders a throwaway duplicate and never modifies the working document, and coordinates are always in full document pixels. This goes well beyond the annotations and helps the agent predict side effects and trust boundaries.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: scope, privacy, use case, sibling alternative, target selection, read-only behavior, coordinate format, and annotate guidance are all packed in without redundancy. The key differentiators are front-loaded with 'cheap, narrow read' and 'labeled bounding boxes only.'
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with six parameters and an output schema, the description covers all needed context: what it returns, coordinate space, privacy, side effects, when to use it, and how to visually verify results. The output schema handles return-value details, so no critical guidance is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers all six parameters with 100% description coverage, so the baseline is 3. The description adds extra meaning by explaining the relationship between max_dimension and speed/coordinate accuracy, by framing annotate as a visual-confirmation aid, and by noting that target selects faces/objects/both. This enriches, rather than merely restates, the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: detecting faces and/or COCO-80 objects and returning labeled bounding boxes in document-pixel space. It clearly distinguishes this tool from ps_read_scene by calling it 'the cheap, narrow read' and contrasting it with the 'full scene model.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use this tool: 'Use this for real coordinates before a spatially-targeted edit when boxes are all you need.' It also names the alternative, ps_read_scene, and explains when that sibling should be used instead, providing clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_documentAIdempotent
See and steer WHICH documents are open, without touching their content. op=list answers 'what is open, which one is active, and does it have unsaved changes' — and it is the one document tool that works when nothing is open at all, so it is the recovery read after a 'No document is open' failure. op=activate switches the active document by name or id, which is how you fix having edited the wrong one. Read-only with respect to pixels; use ps_open_document to load a file and ps_close_document to close one.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Target an open document by its Photoshop document id. Unambiguous — prefer this when names collide. | |
| op | Yes | list: every open document (index, id, name, path, saved, active, dimensions) — safe to call when NOTHING is open, which is the point. activate: make one of them the active document, by name or id. | |
| name | No | Target an open document by its exact Photoshop name, INCLUDING the extension as shown in the tab (e.g. 'portrait.jpg', not 'portrait'). If two open documents share a name the call fails rather than guessing — target by id instead. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| op | Yes | |
| name | No | |
| count | No | |
| context | No | |
| activated | No | |
| documents | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states 'Read-only with respect to pixels,' clarifying that even the activate operation does not modify image content, and highlights that op=list works when nothing is open. It also notes the duplicate-name failure behavior via the parameter description. While the idempotentHint annotation covers repeat-safety, the description adds meaningful context about scope and pixel-read-only behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficiently organized, front-loading the core purpose before explaining the two operations and sibling alternatives. A few phrases like 'which is the point' add flavor but do not bloat the content; every substantive point earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers both operations, their failure/recovery contexts, the pixel-read-only guarantee, and explicitly points to sibling tools for load and close. With an output schema present, return-value details are not required. The only minor gap is that op=activate implicitly requires at least one open document, though this is reasonably inferable from the list/activate contrast.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real value beyond the schema: it explains what op=list returns conceptually ('what is open, which one is active, and does it have unsaved changes'), frames op=activate as the fix for editing the wrong document, and reinforces the id-vs-name disambiguation. This goes beyond repeating schema property names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair — 'See and steer WHICH documents are open' — and immediately distinguishes itself from content-mutating tools by saying it is 'without touching their content.' It also names the two operations, op=list and op=activate, making the tool's purpose concrete and distinguishable from ps_open_document and ps_close_document.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly gives usage context: op=list answers 'what is open, which one is active, and does it have unsaved changes,' and is called the 'recovery read' after a 'No document is open' failure. It also names alternatives explicitly — 'use ps_open_document to load a file and ps_close_document to close one' — so an agent knows exactly when to choose this tool over siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_duplicate_layerA
Duplicate the active layer. The new layer becomes active. Returns context so the caller sees the new active layer. Not idempotent (each call creates another copy).
| Name | Required | Description | Default |
|---|---|---|---|
| new_name | No | Optional name for the duplicated layer. If omitted, Photoshop assigns "<name> copy". |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| newName | No | |
| parent_path | No | The containing-group name chain (outermost first), empty array at the document root. layer.duplicate() is parent-preserving by DOM semantics, so this always matches the original layer's placement. |
| originalName | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the idempotentHint annotation by explicitly stating 'Not idempotent (each call creates another copy).' It also discloses behavioral side effects: 'The new layer becomes active' and that it returns context. This adds valuable context beyond the structured annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with each sentence serving a purpose: action, side effect, return behavior, and idempotency. It is front-loaded with the primary action and contains no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one optional parameter and an output schema, the description covers all essential behavioral aspects: what it does, the resulting active layer change, return context, and non-idempotency. The presence of an output schema means return values need not be detailed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single parameter new_name, so the description does not need to add parameter details. The schema already explains the naming behavior. The description adds no extra parameter semantics but also does not need to.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: 'Duplicate the active layer.' It is specific with a verb and resource, and distinguishes itself from similar tools like ps_create_layer or ps_copy_to_new_layer by focusing on duplicating the existing active layer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage context is implied: use this tool to duplicate the active layer. However, it does not explicitly compare with alternatives or state when not to use it. No direct mention of sibling tools or exclusions, so it earns a baseline implied usage score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_exportADestructiveIdempotent
Export the active document to a flattened image file — JPEG or PNG, chosen via format. Operates on a duplicate, so the working document is unchanged. Optionally downscales so the long edge equals long_edge_px. JPEG: quality 0-100 (Save-As scale), optional sRGB convert + profile embed. PNG: transparent background (alpha preserved) or flattened onto white, compression 0-9.
| Name | Required | Description | Default |
|---|---|---|---|
| format | Yes | Output image format. jpeg: quality 0-100, optional convert_to_srgb + embed_color_profile. png: transparent_background (alpha) or flattened-on-white, compression 0-9. Both take output_path (required) and optional long_edge_px (downscale only). | |
| quality | No | JPEG quality 0-100 (the Photoshop 'Save As' / JPEG-dialog scale humans and the UI use). 100 = maximum. Mapped internally to Photoshop's 0-12 JPEGSaveOptions scripting scale (e.g. 90→11, 100→12). | |
| compression | No | PNG compression level 0-9. Lower = larger file, faster. Default 6. | |
| output_path | Yes | Absolute output path including filename. | |
| long_edge_px | No | Resize so the longest edge equals this value. Omit for full resolution. Downscale only. | |
| convert_to_srgb | No | Convert to sRGB before export. Default true. | |
| embed_color_profile | No | Embed color profile in the exported file. Default true. | |
| transparent_background | No | If true, preserves transparency. If false, flattens onto white. Default false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| quality | No | |
| success | Yes | |
| width_px | No | |
| height_px | No | |
| exported_to | No | |
| transparent | No | |
| quality_ps_scale | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states 'Operates on a duplicate, so the working document is unchanged,' which directly contradicts the annotation destructiveHint: true. This is a fundamental inconsistency: the annotation implies the tool may be destructive, while the description explicitly claims non-destructive behavior for the document. No other behavioral details can compensate for this conflict.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured, starting with the core purpose, then the duplicate behavior, downscaling, and format-specific details. Every sentence adds value, and there is no redundancy or unnecessary elaboration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (8 parameters) and the presence of an output schema, the description is largely complete. It covers the main export logic, duplicate operation, downscaling, and all format-specific parameters. It omits overwrite behavior and error handling, but these are not necessarily required, especially with the output schema present. The contradiction with the annotation lowers completeness slightly, but overall it is sufficiently complete for a well-documented schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with very detailed descriptions for all 8 parameters, including specifics like quality mapping and compression levels. The description adds a concise high-level summary of the format options and the long_edge_px behavior, but largely restates the schema. Since the schema carries the heavy lifting, a baseline of 3 is appropriate, with the description providing only marginal additive value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool exports the active document to a flattened image file (JPEG or PNG), using a specific verb and resource. It distinguishes itself from siblings like ps_save_psd and ps_get_preview by focusing on raster export, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context about when to use the tool (when exporting to JPEG/PNG) and notes it operates on a duplicate, implying safe use. However, it does not explicitly mention alternative tools or exclusions, such as 'for PSD use ps_save_psd', so it lacks explicit when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_fill_layerAIdempotent
Fill the active layer (or the current selection within it) with a solid RGB color. Idempotent for the same color. Throws on fully-locked or text layers — rasterize text first if needed.
| Name | Required | Description | Default |
|---|---|---|---|
| red | Yes | Red component (0-255) | |
| blue | Yes | Blue component (0-255) | |
| green | Yes | Green component (0-255) |
Output Schema
| Name | Required | Description |
|---|---|---|
| color | No | |
| filled | No | |
| layerName | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the idempotentHint annotation, the description discloses important error behavior (throws on locked/text layers) and a remediation (rasterize text first). It also clarifies scope (active layer or selection). These are valuable details not present in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences front-load the primary action, then add important qualifications. No waste; every clause serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with three well-documented parameters and an output schema, the description provides the essential scope and error handling. The note about text layers and locked layers covers the main edge cases an agent would encounter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage with each color component defined in its own property ('Red component (0-255)', etc.). The description adds no extra parameter context, but the schema is self-sufficient, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Fill'), a clear resource ('the active layer or the current selection within it'), and the action (with a solid RGB color). It clearly distinguishes from sibling tool ps_add_fill_layer, which creates a new fill layer rather than filling an existing one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a practical precondition: 'Throws on fully-locked or text layers — rasterize text first if needed.' This tells the agent when the tool cannot be used and what to do before use. However, it does not explicitly mention alternatives like ps_add_fill_layer, though the difference is implied by 'active layer.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_filterADestructive
Apply a Photoshop filter (op=apply, the default) to a DUPLICATE of the active layer by default — the original is preserved, undo by deleting the copy. Pass apply_to_active_layer:true to bake into the original instead. Choose the filter with type (see the type field for its params); pass as_smart_filter:true on a Smart Object to apply it as a re-editable SMART FILTER instead of rasterizing. This same tool also reads and manages that re-editable Smart Filter stack: op=list (every filter's index/name/type/enabled/opacity/blend), op=set_visibility (toggle one off/on), op=set_blend (restyle opacity/blend_mode), op=remove (delete one). Management ops need a 1-based index from op=list first — index 1 is the first-applied filter, at the bottom of the stack. Covers blur, sharpen, noise, high_pass, pixelate, distort, displace, and oil_paint.
| Name | Required | Description | Default |
|---|---|---|---|
| op | No | apply (default): apply a NEW filter — set `type` (+ its own params). list: read every re-editable Smart Filter on the active Smart Object (index, name, type, enabled, opacity, blend mode). set_visibility: turn one Smart Filter on/off without losing its settings (needs `index` + `enabled`). set_blend: restyle one Smart Filter's `opacity` and/or `blend_mode` (needs `index` + at least one of them). remove: delete one Smart Filter from the stack (needs `index`). The four management ops act on the Smart Filter stack that apply as_smart_filter=true creates; indices are 1-based and come from op=list, where 1 is the first-applied filter (bottom of the stack). | apply |
| edge | No | trace_contour only: trace the lower or upper edge of the level. PS default lower. | lower |
| mode | No | surface_blur = blur while preserving edges above a threshold (skin-smoothing; radius + threshold); box_blur = fast square-kernel blur (radius); average = fill the layer with its single average color (parameterless). | |
| seed | No | fibers only: randomize seed — change for a different fiber pattern. PS default 12345. | |
| size | No | ripple only: ripple wavelength size. | medium |
| type | No | Which filter to apply. Required when op=apply (the default); ignored otherwise. Each type uses its own parameters: gaussian_blur(radius); motion_blur(angle, radius); lens_blur(radius, iris_shape, …); radial_blur(amount, method spin|zoom, quality, center_x, center_y); sharpen=Unsharp Mask(amount, radius, threshold); smart_sharpen(amount, radius, remove_mode, …); noise=Add Noise(amount, distribution, monochromatic); reduce_noise(strength, preserve_details, color_noise, …); high_pass(radius); pixelate(mode color_halftone|mosaic|crystallize|pointillize|facet|fragment, …); distort(mode twirl|ripple|polar|wave|pinch|spherize|zigzag, …); stylize(mode emboss|find_edges|solarize|wind|trace_contour|tiles, …); render(mode clouds|difference_clouds|fibers, …); other(mode maximum|minimum|offset, …); denoise(mode median|dust_and_scratches|despeckle, …); blur(mode surface_blur|box_blur|average, …); displace(map_path, horizontal_scale, vertical_scale, …); oil_paint(stylization, cleanliness, …). | |
| angle | No | Angle in degrees. Used by motion_blur (−360–360) and distort/twirl (−999–999). | |
| index | No | 1-based index of the filter to act on, as reported by op=list. 1 is the FIRST-APPLIED filter (bottom of the Smart Filters stack in the Layers panel). Required for every op except 'list'. | |
| level | No | trace_contour only: brightness level the contour traces (0-255). PS default 128. | |
| shine | No | Specular shine (0-10). | |
| amount | No | Filter strength. Range depends on type — sharpen 1–500, noise 0.1–400, radial_blur 1–100, distort/ripple −999–999. | |
| height | No | emboss only: relief height in pixels (1-100). PS default 3. | |
| method | No | spin = rotational blur around the center (turntable motion); zoom = radial streaks toward/from the center (the classic "god rays" / speed-zoom look). | spin |
| number | No | tiles only: number of tiles across (1-99). PS default 10. | |
| offset | No | tiles only: maximum tile offset percent (1-99). PS default 10. | |
| radius | No | Radius/distance in px. Range depends on type — gaussian_blur 0.1–250, motion_blur 1–999, lens_blur 0–100, smart_sharpen 0.1–64, high_pass 0.1–1000. | |
| ridges | No | zigzag only: number of concentric ridges (0-20). PS default 5. | |
| angle_1 | No | color_halftone only: screen angle for channel 1 in degrees. PS default 108. | |
| angle_2 | No | color_halftone only: screen angle for channel 2. PS default 162. | |
| angle_3 | No | color_halftone only: screen angle for channel 3. PS default 90. | |
| angle_4 | No | color_halftone only: screen angle for channel 4. PS default 45. | |
| enabled | No | set_visibility only: true shows the filter, false hides it. The filter stays in the stack either way and keeps all its settings. | |
| opacity | No | set_blend only: filter opacity 0-100. Omit to leave the current opacity untouched. | |
| quality | No | Render quality. best is smoothest but slowest. | good |
| center_x | No | Horizontal blur center, normalized 0-1 (0.5 = middle). Resolution-independent. | |
| center_y | No | Vertical blur center, normalized 0-1 (0.5 = middle). Resolution-independent. | |
| map_path | No | Absolute path to the displacement-map .psd file (required). The map's brightness drives the per-pixel warp — mid-gray = no shift, lighter/darker push in opposite directions. | |
| preserve | No | maximum/minimum only: edge-preservation shape. PS default roundness. | roundness |
| strength | No | Luminance noise reduction strength (0-10). PS default 5. Higher = more aggressive noise reduction but more detail loss. | |
| variance | No | fibers only: color variance / streak length (1-64). PS default 16. | |
| vertical | No | offset only: vertical shift in pixels (positive = down). | |
| cell_size | No | Cell size in pixels — used by mosaic (2-300, PS default 10), crystallize (3-300), and pointillize (3-300, PS default 5). Ignored by color_halftone/facet/fragment. | |
| threshold | No | surface_blur only: tonal threshold (0-255) — edges differing by more than this are preserved. PS default 20. | |
| wave_type | No | wave only: waveform shape. | sine |
| blend_mode | No | set_blend only: how the filter result composites against the unfiltered layer. Same names as ps_set_layer. Omit to leave the current mode untouched. | |
| conversion | No | polar only: rect_to_polar wraps the image into a circle; polar_to_rect unwraps it. | rect_to_polar |
| generators | No | wave only: number of wave generators (1-999). | |
| horizontal | No | offset only: horizontal shift in pixels (positive = right). | |
| iris_shape | No | Aperture iris shape — affects the look of out-of-focus highlights (bokeh). PS default hexagon. Triangle = 3 blades, octagon = 8 blades. Real lenses with fewer blades produce more polygonal bokeh. | hexagon |
| max_radius | No | color_halftone only: maximum dot radius in pixels (4-127). PS default 8. | |
| brush_scale | No | Brush scale (0.1-2). | |
| cleanliness | No | Stroke cleanliness / smoothness (0-10). | |
| color_noise | No | Color (chroma) noise reduction (0-100). PS default 45. Hits the colorful speckle noise typical of high-ISO photos. | |
| lighting_on | No | Whether the lighting/shine relief is applied. | |
| per_channel | No | Enable per-channel advanced mode. If true, the per-channel strength/preserve_details params (red_*, green_*, blue_*) override the global strength/preserve_details for each RGB channel — useful when noise is concentrated in one channel (typically blue for low-light shots). PS default false. | |
| random_seed | No | wave only: random seed for the wave pattern (change for a different pattern). | |
| remove_mode | No | Blur model to remove. gaussianBlur (default) is the general-purpose modern Unsharp Mask replacement. lensBlur removes lens-style softness with better edge handling. motionBlur removes directional motion blur — pair with motion_angle. | lensBlur |
| shadow_fade | No | Shadows tab: amount of sharpening to fade in shadow regions (0-100). 0 = sharpen shadows fully, 100 = no shadow sharpening. Useful for preventing shadow-noise amplification. PS default 0. | |
| stylization | No | Brush-stroke stylization (0.1-10). | |
| wind_method | No | wind only: streak intensity/style. PS default wind. | wind |
| depth_source | No | Depth map source for selective focus. "none" = uniform blur across the whole layer. "transparency" = use the layer alpha channel as depth (foreground sharper). "layerMask" = use the layer mask. PS default none. | none |
| distribution | No | Noise distribution type. Default: UNIFORM. | UNIFORM |
| invert_depth | No | Invert the depth map. PS default false. | |
| motion_angle | No | Motion blur angle in degrees (-360 to 360). Only meaningful when remove_mode=motionBlur. | |
| noise_amount | No | Noise added to the blurred result (0-100). PS default 0. Lens Blur can produce un-naturally clean blur regions; a small noise amount (5-15) keeps the texture believable. | |
| red_strength | No | Per-channel: red channel noise-reduction strength (0-10). Only used when per_channel=true. | |
| amplitude_max | No | wave only: maximum amplitude (1-999). | |
| amplitude_min | No | wave only: minimum amplitude (1-998; must be <= amplitude_max). | |
| blue_strength | No | Per-channel: blue channel noise-reduction strength. Usually the noisiest channel in low-light photos. | |
| iris_rotation | No | Iris rotation in degrees (0-360). Rotates the iris-shape pattern. PS default 0. | |
| monochromatic | No | Apply monochromatic noise. Default: false. | |
| shadow_radius | No | Shadows tab: local-contrast radius in pixels (1-100). PS default 30. Defines the neighborhood used to classify pixels as shadows. | |
| bristle_detail | No | Bristle detail (0-10). | |
| fiber_strength | No | fibers only: fiber strength / definition (1-64). PS default 4. | |
| focal_distance | No | Focal-plane depth value (0-255), only meaningful when depth_source != none. Pixels at this depth stay sharp; pixels farther from it blur progressively. | |
| green_strength | No | Per-channel: green channel noise-reduction strength. | |
| highlight_fade | No | Highlights tab: amount of sharpening to fade in highlight regions (0-100). PS default 0. | |
| scale_vertical | No | wave only: vertical scale percent (1-100). | |
| vertical_scale | No | Vertical displacement scale (-999 to 999). PS default 10. | |
| wavelength_max | No | wave only: maximum wavelength (1-999). | |
| wavelength_min | No | wave only: minimum wavelength (1-998; must be <= wavelength_max). | |
| wind_direction | No | wind only: streak direction. PS default left. | left |
| as_smart_filter | No | If true, apply the filter as a re-editable SMART FILTER riding the Smart Object instead of baking it into pixels — nothing is rasterized, and the filter can later be toggled, re-blended or removed instead of being permanent. Requires the target to be a Smart Object (convert first with ps_convert_to_smart_object); errors rather than converting silently. If false (default), the filter is baked and a smart-object layer is rasterized first. | |
| light_direction | No | Lighting angle in degrees (-180 to 180). | |
| noise_reduction | No | Noise reduction during sharpening (0-100). PS default 10. Prevents sharpening from amplifying existing noise. For low-light photos, raise this (25-50). | |
| sharpen_details | No | Sharpening to apply after noise reduction (0-100). PS default 25. Compensates for the softening that noise reduction causes. | |
| undefined_areas | No | How to fill areas pushed outside the layer. | repeat_edge |
| center_placement | No | Grounded alternative to center_x/center_y: NAME the blur center (a `placement` resolving to a POINT — an object centroid, an extremum, a grid intersection). The resolved document-pixel point is normalized to the 0-1 center for you and WINS over center_x/center_y. The blur runs ONLY if the objective gate PASSES. | |
| displacement_map | No | How the map fits the layer: stretch_to_fit (resize the map) or tile (repeat it). | stretch_to_fit |
| highlight_radius | No | Highlights tab: local-contrast radius in pixels (1-100). PS default 30. | |
| horizontal_scale | No | Horizontal displacement scale (-999 to 999). PS default 10. | |
| preserve_details | No | Preserve details percentage (0-100). PS default 50. Higher protects edges; lower lets the smoother kick in further. | |
| scale_horizontal | No | wave only: horizontal scale percent (1-100). | |
| noise_distribution | No | Noise distribution type. PS default uniform. | uniform |
| shadow_tonal_width | No | Shadows tab: tonal width — how broadly "shadows" is defined (0-100). PS default 50. | |
| specular_threshold | No | Specular highlight threshold (0-255). PS default 255 (no specular boost applies). Lower the threshold to let more pixels be treated as specular highlights for the brightness boost. Typical photographic use: 240-250. | |
| noise_monochromatic | No | Monochromatic noise (luminance-only). PS default true. | |
| specular_brightness | No | Specular highlight brightness boost (0-255). PS default 0. Lift highlights to enhance bokeh "balls" — values around 50-100 produce visible specular highlights, higher = more dramatic. | |
| iris_blade_curvature | No | Iris blade curvature (0-100). 0 = polygonal bokeh, 100 = perfectly circular. PS default 0. | |
| red_preserve_details | No | Per-channel: red channel preserve-details percentage (0-100). Only used when per_channel=true. | |
| remove_jpeg_artifact | No | Remove JPEG compression artifacts (the 8x8 block boundaries and ringing). PS default false. | |
| apply_to_active_layer | No | If false (default), the filter is applied to a duplicate of the active layer named "<OpName> (<Original Name>)" — the original is preserved and the LLM can undo simply by deleting the copy. If true, the filter bakes directly into the active layer (the historical destructive behavior). | |
| blue_preserve_details | No | Per-channel: blue channel preserve-details percentage. | |
| highlight_tonal_width | No | Highlights tab: tonal width (0-100). PS default 50. | |
| green_preserve_details | No | Per-channel: green channel preserve-details percentage. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | |
| index | No | |
| filter | No | |
| applied | No | |
| context | No | |
| enabled | No | |
| filters | No | |
| opacity | No | |
| removed | No | |
| blend_mode | No | |
| layer_name | No | |
| filter_name | No | |
| filter_type | No | |
| visibility_set | No | |
| is_smart_object | No | |
| remaining_count | No | |
| target_was_copy | No | |
| requested_enabled | No | |
| target_layer_name | No | |
| original_layer_name | No | |
| removed_filter_name | No | |
| removed_filter_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal destructiveHint=true and idempotentHint=false, and the description substantially enriches the safety picture: it discloses the non-destructive duplicate-by-default behavior, the reversal path (delete the copy), the destructive bake-in path via apply_to_active_layer:true, and the non-rasterizing smart-filter path. This is exactly the kind of behavioral nuance agents need beyond the annotation flags.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but earned: it front-loads the critical safety/destructive behavior first, then the op dispatch, then the index convention, then the coverage scope. Given 95 parameters and 5 operations, the density is justified, though a lighter touch around the filter-coverage list would have been possible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 95 params, 5 dispatch modes, and an output schema, the description covers everything needed to call it correctly: op semantics, index sourcing, smart-object prerequisites, the duplicate-vs-bake-in decision, and the supported filter repertoire. Nothing an agent needs to decide between apply/list/remove or duplicate vs. destructive is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds narrative meaning beyond the schema: it explains what each op does in prose, codifies the index convention (index 1 = bottom/first-applied), and maps type values to their parameter families. This reduces the cognitive load of parsing 95 schema entries.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb+resource: apply Photoshop filters and manage the re-editable Smart Filter stack (list/set_visibility/set_blend/remove). It also enumerates the exact filter families covered (blur, sharpen, noise, high_pass, pixelate, distort, displace, oil_paint), so an agent knows precisely what this tool does and does not do relative to siblings like ps_apply_adjustment or ps_retouch.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit operational guidance: op=apply is the default for new filters, management ops require a 1-based index obtained from op=list first, and as_smart_filter requires a prior Smart Object conversion. It does not explicitly contrast against sibling tools, but the internal op-routing conditions are unambiguous and enough to prevent misselection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_get_histogramARead-onlyIdempotent
Whole-image (or per-channel) histogram — the quantitative answer to questions get_preview can't reliably answer by eye. Returns 256 bin counts plus mean / stdev / median. Cheap (~50ms), read-only. Reach for this when: (a) clipping detection — bins 0 and 255 carry the count of crushed shadows / blown highlights; you can't see clipping reliably in a downsampled JPEG preview; (b) exposure verification after a levels/curves/exposure adjustment — confirm the histogram actually shifted; (c) "is this image neutral-gray?" — compare R / G / B channel means; (d) confirming a destructive op did anything (two identical histograms = no-op regardless of the tool's success message). Composite reads the visible flattened image (any color mode). Per-channel reads require the document have that channel.
| Name | Required | Description | Default |
|---|---|---|---|
| channel | No | Which channel to read. "composite" (default) is the visible flattened image; if the active layer is an adjustment/fill/shape layer the tool transparently switches to a pixel layer to read it. "red"/"green"/"blue" require an RGB doc; "gray" a grayscale doc. "luminosity" dispatches per doc mode — Lab uses the Lightness channel (exact), Grayscale uses Gray (exact), and RGB reads the per-pixel luminance Photoshop reports, weighted 0.30/0.59/0.11, so its shape and any clipping or percentile read taken from it are sound. Note that weighting is not Rec.709, so a luminosity mean will not match one computed as 0.2126/0.7152/0.0722. A channel value naming a marginal mixture means the document histogram was unavailable and the read fell back to combining the channel histograms: that mean is still sound, its shape is not. The result's `channel` field annotates which path landed when a fallback was used. | composite |
Output Schema
| Name | Required | Description |
|---|---|---|
| bins | No | |
| mean | No | |
| stdev | No | |
| median | No | |
| channel | No | |
| context | No | |
| bin_count | No | |
| total_pixels | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and idempotentHint annotations, the description discloses latency, composite-vs-per-channel reading behavior, required document mode, transparent layer fallback behavior, and the exact luminosity weighting with its non-Rec.709 caveat. It also explains what a marginal fallback value means and how the result's channel field annotates it. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-structured and front-loaded: one-sentence purpose, cost/read-only note, bolded use-case list, then channel-specific edge cases. Every clause carries operational value for a tool with non-obvious fallback behavior, so the length is justified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one optional parameter, full schema coverage, an output schema, and read-only/idempotent annotations, the description covers selection criteria, return values, channel constraints, fallback paths, and interpretation caveats. Nothing an agent needs to call or interpret the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already fully documents the channel enum at 100% coverage, and the description adds substantial meaning beyond the schema: how composite reads fall back to a pixel layer, when red/green/blue/gray are valid, the exact luminosity weighting formula, and the fallback semantics. This far exceeds the baseline expectation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('get histogram') and defines it as the quantitative complement to get_preview, listing the concrete return values (256 bin counts plus mean/stdev/median). This clearly distinguishes it from sibling inspection/read tools like ps_get_preview and ps_inspect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Reach for this when' section explicitly enumerates four concrete use cases: clipping detection, exposure verification, neutral-gray checking, and confirming a destructive op had an effect. It also contrasts directly with get_preview, saying it answers questions get_preview can't reliably answer by eye. This gives an agent explicit selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_get_layer_bounds_diffARead-onlyIdempotent
Numeric verification: compute the per-edge pixel deltas between a layer's actual bounds and a target rectangle. Returns left/top/right/bottom deltas (actual − target), scale ratio (actual_size / target_size), centroid offset, and a one-word verdict ("aligned", "shifted right", "layer too small", etc.). Use this AFTER place_image / scale_layer / move_layer to confirm the operation produced the intended result — far more reliable than eyeballing a preview for fine alignment. Read-only. Layers nested in groups are found by name recursively.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | Yes | Name of the layer to measure. Reads boundsNoEffects (raw pixel bounds without layer-style expansion). The active doc's layer tree is searched recursively (so layers nested in groups are findable by name alone). | |
| target_top | Yes | Target rectangle top edge. | |
| target_left | Yes | Target rectangle left edge in document pixels. | |
| target_right | Yes | Target rectangle right edge. | |
| tolerance_px | No | Tolerance in pixels for the verdict — within this delta on every edge, the verdict is "aligned". Default 10. | |
| target_bottom | Yes | Target rectangle bottom edge. |
Output Schema
| Name | Required | Description |
|---|---|---|
| deltas | No | |
| context | No | |
| verdict | No | |
| actual_bounds | No | |
| scale_ratio_x | No | |
| scale_ratio_y | No | |
| target_bounds | No | |
| within_tolerance | No | |
| centroid_offset_x | No | |
| centroid_offset_y | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and idempotentHint annotations, the description adds meaningful behavioral context: it computes 'actual − target' deltas, uses boundsNoEffects for measurement, and searches layers recursively in groups. It also explains the verdict mechanism and reinforces read-only behavior. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, starting with the category 'Numeric verification' before stating the verb and resource. It packs outputs, usage guidance, and behavioral notes into a tight paragraph with no wasted words. Every sentence contributes unique value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the full input schema, read-only/idempotent annotations, and presence of an output schema, the description covers purpose, outputs, timing, and search behavior very well. Minor omissions like error handling for missing layers or explicit unit confirmation are not critical because the schema and output schema fill most gaps. It is nearly complete for an AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage with clear descriptions for all six parameters, including the tolerance threshold for the verdict. The description adds the overall computation formula and the role of tolerance, but does not clarify individual parameters beyond the schema. This aligns with the baseline expectation for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Numeric verification: compute the per-edge pixel deltas between a layer's actual bounds and a target rectangle,' which names a specific verb and resource. It lists exact outputs (left/top/right/bottom deltas, scale ratio, centroid offset, verdict) and frames it as a verification tool distinct from visual previews. This clearly distinguishes it from siblings like ps_get_preview and ps_compare_regions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use it: 'AFTER place_image / scale_layer / move_layer to confirm the operation produced the intended result.' It also contrasts with 'eyeballing a preview,' implying a better alternative for numeric checks. However, it does not name an alternative tool or provide explicit when-not-to-use conditions, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_get_previewARead-onlyIdempotent
Render the active Photoshop document as a flattened, downscaled image and return it inline so the calling AI can see the current visual state. Use this to verify edits visually, judge whether adjustments went too far or not far enough, and decide what to do next. Read-only with respect to the working document (renders a duplicate that is closed immediately). The optional annotations array draws overlays in document-space coordinates: rectangle / guide / point / selection for spatial verification, and grid / composition for coordinate readout and compositional evaluation (added 2026-06-09 — grid styles every / thirds / quarters / phi, composition styles diagonals / triangles / fibonacci_grid / golden_spiral). Use spatial annotations to verify ("did the placed image land inside the frame interior?") — pass both target and actual bounds in different colors. Use grid / composition annotations to EVALUATE composition (balance, thirds, leading lines, focal-point placement) — not to read a coordinate for a tool call. To place or select precisely, do NOT read a pixel off a grid (unreliable) — NAME the intent to the on-device perception tools instead: ps_detect (COCO objects → real document-pixel boxes), ps_select_by_reference (a named target → a real selection, not a guessed rectangle), plus any spatial-grounding locator / selection tools present in tools/list. Without annotations, behaves identically to a plain preview.
| Name | Required | Description | Default |
|---|---|---|---|
| quality | No | JPEG quality 1-12. Default: 6 (visibly clean for verification at the default 1024px max-dim; halves payload vs the older quality=8 default). Bump to 8-10 only when the preview is the deliverable, not the verification primitive. | |
| annotations | No | Optional list of visual annotations to draw onto the preview before rendering — rectangles (by explicit bounds OR by layer name), guides (horizontal / vertical reference lines), point markers, and the current document selection. Use this to verify SPATIAL work (placement, alignment, scaling) — pass both your TARGET rect and the ACTUAL placement (e.g. the layer's bounds) in different colors, then visually compare in the returned image. Skips the spatial-self-evaluation trap where the LLM tries to estimate alignment from a plain preview. | |
| max_dimension | No | Cap on the long edge in pixels. Defaults to 1024, which is plenty for tone/color/composition judgment and roughly halves the base64 payload vs the older 1500 default. Bump higher only when reading fine detail (e.g. text legibility or fur texture). |
Output Schema
| Name | Required | Description |
|---|---|---|
| bytes | No | |
| format | No | |
| context | No | |
| mime_type | No | |
| dimensions | No | |
| annotation_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true. The description adds the mechanism: 'renders a duplicate that is closed immediately,' and confirms no side effects on the working document. It also notes the fallback behavior without annotations. This is useful context beyond the structured hints, though it doesn't address rate limits or payload details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph but front-loads the core purpose and usage. Every segment earns its place, covering annotation types, intended use, and alternatives. It is long but matches the tool's complexity; minor structural improvements (e.g., paragraph breaks) would enhance scannability but are not essential.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (three parameters, one highly flexible annotations array), the description is complete: it explains what the preview shows, how to use overlays, how to avoid misusing grid annotations, and what happens with no annotations. Since an output schema exists, the description need not explain return values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed per-parameter descriptions, so the baseline is 3. The description goes further by explaining the strategic use of the annotations parameter: spatial verification vs compositional evaluation, and explicitly warns against using grid overlays for coordinate reading. This adds meaning beyond the JSON schema alone, especially for the complex annotations array.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource+outcome: 'Render the active Photoshop document as a flattened, downscaled image and return it inline so the calling AI can see the current visual state.' It clearly differentiates from sibling preview tools by emphasizing the current visual state and read-only nature, and the closing note about a plain preview clarifies its default behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use guidance: 'Use this to verify edits visually, judge whether adjustments went too far or not far enough, and decide what to do next.' It also provides exclusions and alternatives: 'To place or select precisely, do NOT read a pixel off a grid (unreliable) — NAME the intent to the on-device perception tools instead: ps_detect, ps_select_by_reference.' This is textbook when/when-not plus named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_get_selection_previewARead-onlyIdempotent
Render an inline JPEG so the agent can visually verify what is currently selected: by default a red-wash OVERLAY (50% red over the selected area, Quick Mask-style — most intuitive); pass image:'mask' for a B/W MASK (black = selected, white = not) instead, or image:'both' for both. selection_info is always returned regardless of image. Heavier than the selection_info bundle alone (~2-4s) — call this when the stats look off or before committing a mask. Does NOT modify the source document.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | Which rendered image(s) to return inline. 'overlay' (default): a 50% red wash over the selected area (Quick Mask-style — most intuitive). 'mask': a B/W mask (black=selected, white=not) instead. 'both': the overlay followed by the mask, for when you need to compare them side by side. selection_info is returned regardless of this choice. | overlay |
| max_dimension | No | Long-edge pixel cap for the returned images. Default 800. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rendered | No | |
| mask_bytes | No | |
| max_dimension | No | |
| overlay_bytes | No | |
| selection_info | No | Rich post-op stats. Use these to verify the selection actually grabbed what was intended before committing it to a mask. `has_selection:false` short-circuits the rest of the fields (they will be absent). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/idempotentHint annotations, the description adds meaningful behavioral context: the operation is heavy (~2-4s), selection_info is always returned regardless of the image parameter, the rendering is inline JPEG, and it explicitly reassures 'Does NOT modify the source document.' It could add details like output encoding, but the additive context is substantial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded: purpose and default behavior first, then alternates, then cost/when-to-call guidance, then a safety reassurance. Every sentence earns its place; it could be marginally tightened (e.g., the parenthetical enum explanations slightly overlap the schema), but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter, read-only preview tool with a fully documented schema, an output schema, and safety annotations, the description covers everything needed to decide and invoke: rendering modes, latency tradeoff, invocation conditions, always-returned selection_info, and non-destructive behavior. There is no meaningful gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents image and max_dimension, including the enum meanings and defaults. The description reinforces the key enum behavior in prose ('pass `image:'mask'` for a B/W MASK') but adds no genuinely new parameter semantics beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Render an inline JPEG so the agent can visually verify what is currently selected') and immediately explains the default rendering mode and two alternates. The focus on selection preview with overlay/mask options clearly differentiates it from the sibling ps_get_preview, which presumably covers general document preview.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit when-to-call directive: 'call this when the stats look off or before committing a mask.' It also implies the alternative — the lighter 'selection_info bundle alone' — by contrasting latency (~2-4s). It stops short of naming the exact sibling tool to use when the lightweight stats suffice, but the context is clear enough for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_groupADestructive
Layer group (LayerSet) lifecycle and membership — choose the operation with op. create/delete/ungroup/add_layer/set_blend_mode. See the op enum for per-operation params. delete and ungroup are DESTRUCTIVE and require confirm:true — delete removes the group AND everything inside it; ungroup dissolves the group but promotes its contents to the parent level (use ungroup, not delete, to keep the layers).
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | create: make a new group above the active layer named `name` (hoisted out of an active group by default; into_active_group:true keeps Photoshop's native nesting), optionally moving `layers` into it. delete: DESTRUCTIVE — delete group `name` and everything inside it (nested groups and their layers); requires confirm:true. To dissolve a group while keeping its contents, use ungroup instead. ungroup: DESTRUCTIVE structural change — dissolve group `name`, promoting its contents to the parent level in their existing stack order; requires confirm:true. add_layer: move `layer_name` into `group_name` (top of its stack). set_blend_mode: set group `name`'s blend mode to `blend_mode` — PASSTHROUGH (default for new groups) lets adjustments inside affect layers below the group; NORMAL treats the group as a single composite. | |
| name | No | Group name. create: name for the NEW group. delete/ungroup/set_blend_mode: the EXISTING group to act on (recursive search). | |
| layers | No | Optional list of existing layer names to move into the new group. The first listed name ends up on top of the group stack. Layers not found are returned in `not_found`. | |
| confirm | No | REQUIRED for op=delete and op=ungroup, ignored by the other ops. Must be true — guards against accidental loss of a group and (for delete) everything it contains. | |
| blend_mode | No | Blend mode (Photoshop ExtendScript BlendMode enum). PASSTHROUGH (default for new groups) lets adjustments inside the group affect the layers below the group; NORMAL treats the group as a single composite (use this when applying one mask to a stack of adjustments). Use COLORBLEND for the "Color" blend mode. | |
| group_name | No | Name of the destination group (recursive search). | |
| layer_name | No | Name of the layer to move (recursive search). A layer is preferred over a group of the same name; a group is moved only when no layer matches, which is how one group is nested inside another. | |
| into_active_group | No | Photoshop's Mk-layerSection descriptor carries no placement target, so with a GROUP active it would natively nest the new group INSIDE that group. Default false hoists the new group back out so it lands above the active layer/group as a sibling, matching this tool's documented placement. Pass true to keep it nested inside the active group instead. |
Output Schema
| Name | Required | Description |
|---|---|---|
| set | No | op=set_blend_mode: true on success. |
| moved | No | op=add_layer: true on success. |
| context | No | |
| created | No | op=create: true on success. |
| deleted | No | op=delete: true on success. |
| hoisted | No | op=create: true when the new group had to be moved back out of the previously-active group to honor into_active_group:false. |
| blendMode | No | op=set_blend_mode: the mode applied. |
| groupName | No | |
| layerName | No | op=add_layer: the moved layer. |
| not_found | No | op=create: requested layer names that were not found. |
| ungrouped | No | op=ungroup: true on success. |
| child_names | No | op=ungroup: names of the promoted children. |
| moved_count | No | op=create: layers moved into it. |
| parent_path | No | op=create: the containing-group name chain (outermost first), empty array at the document root. |
| children_promoted | No | op=ungroup: children promoted to the parent level. |
| descendants_deleted | No | op=delete: total layers removed with the group. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint annotation, the description discloses exactly what each destructive operation does: delete removes the group AND everything inside it, while ungroup dissolves the group but promotes contents to the parent level. It also clearly states the confirm:true requirement, giving agents the information needed to avoid catastrophic mistakes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and routes the agent immediately to the `op` enum for lower-level details. It is slightly longer than needed because it repeats some destructive behavior that is also present in the `op` field description, but the redundancy is purposeful and conflict-worthy for a destructive group tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a multi-operation tool with 8 parameters, an output schema, and rich per-field descriptions, the description is complete enough for an agent to select the correct operation and understand the major risks. The main missing piece is explicit routing advice for related sibling tools, but the schema and annotations carry the remaining burden well.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the input schema already documents every parameter in rich detail, so the description itself does not need to carry much parameter meaning. The free-text summary restates important behavioral semantics for delete/ungroup but does not materially extend what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly defines the tool as "Layer group (LayerSet) lifecycle and membership" and explicitly lists the five `op` dispatch values: create/delete/ungroup/add_layer/set_blend_mode. This gives a specific resource, a clear operation set, and enough signal to distinguish it from sibling single-layer tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description directly explains when to use ungroup versus delete: "use ungroup, not delete, to keep the layers," and it tells the agent to "See the `op` enum for per-operation params." It does not explicitly contrast this tool against sibling tools like ps_create_layer or ps_delete_layer, so it stops short of a perfect usage guide.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_guidesA
Manage document guides — non-printing layout aids for a HUMAN working in Photoshop. Guides are editor-only chrome: they do NOT render into ps_get_preview (the exported/flattened image), so they are a user authoring aid, not a model-perception tool — place them when a person will open the PSD and wants alignment/composition marks. Choose with op. add places one guide (orientation horizontal|vertical) at a position in px. layout creates an evenly-spaced grid (columns and/or rows — great for rule-of-thirds at 3×3). clear removes all guides.
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | Guide operation. add: one guide at position (orientation + position px). layout: an evenly-spaced grid (columns and/or rows). clear: remove ALL guides from the document. | |
| rows | No | Number of evenly-spaced rows (horizontal guides). 0 = none. | |
| columns | No | Number of evenly-spaced columns (vertical guides). 0 = none. | |
| position | No | Guide position in document pixels (the x for a vertical guide, the y for a horizontal guide). | |
| orientation | No | 'vertical' adds a top-to-bottom guide positioned by its x coordinate; 'horizontal' adds a left-to-right guide positioned by its y coordinate. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | No | |
| columns | No | |
| position | No | |
| guide_added | No | |
| orientation | No | |
| guides_cleared | No | |
| guide_layout_created | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (idempotentHint: false), the description discloses key behaviors: guides are 'non-printing layout aids', 'editor-only chrome', and 'do NOT render into ps_get_preview'. It also warns that 'clear removes all guides', which is important destructive behavior. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the core purpose, then each sentence adds distinct value: rendering behavior, op selection, add/layout syntax, and clear semantics. No wasted words, perfectly structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully covers all three operations, parameter semantics, use cases, and exclusions. Output schema is present, so return value details are unnecessary. Complete for a tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, providing baseline 3. The description goes further by reinforcing parameter meaning ('position in px', orientation horizontal|vertical) and adding usage semantics like 'evenly-spaced grid' and the concrete 'rule-of-thirds at 3×3' example. This adds value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Manage document guides' with specific operations (add, layout, clear), and distinguishes from sibling ps_get_preview by explicitly noting guides do not render into the exported preview. The description is a specific verb+resource with clear scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly explains when to use the tool: 'place them when a person will open the PSD and wants alignment/composition marks', and when not to: 'not a model-perception tool'. It also names the direct alternative ps_get_preview and clarifies the non-effect on it, fully addressing usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_inspectARead-onlyIdempotent
Read-only document inspection — choose with what (metadata / layer_tree / history / selection_info / smart_object). This is the assess/orientation surface: call it at the start of a workflow and whenever you need fresh state. For metadata, pass sections to subset (e.g. ["context"] for a cheap probe). For an IMAGE-based check use ps_get_preview; for NUMERIC verification use ps_get_histogram / ps_compare_regions / ps_get_layer_bounds_diff (these stay separate, named tools on purpose). Read-only and idempotent.
| Name | Required | Description | Default |
|---|---|---|---|
| what | Yes | Which read-only state to return. metadata: document/IPTC/camera-EXIF/GPS/ACR develop settings + active context (optionally subset with `sections`; sections=["context"] is the cheap orientation probe). layer_tree: the full recursive layer tree (name/kind/visibility/opacity/blend/clipping/bounds) — use whenever you need what is inside a group. history: all history states + the current cursor, for deciding how far to undo. selection_info: current selection bounds/coverage/edge-complexity without modifying anything. smart_object: whether the ACTIVE layer is a Smart Object and, if so, whether its source is embedded or linked to a file on disk, plus how many Smart Filters it carries. | |
| sections | No | Optional subset of sections to return. Omit for all sections. The context block (active doc + layer + selection state) is always returned regardless. Use ["context"] for a cheap orientation call that skips the IPTC traversal and the source-file read. |
Output Schema
| Name | Required | Description |
|---|---|---|
| acr | No | |
| gps | No | |
| iptc | No | |
| tree | No | |
| bounds | No | |
| camera | No | |
| linked | No | |
| placed | No | |
| states | No | |
| canRedo | No | |
| canUndo | No | |
| context | No | |
| document | No | |
| layer_kind | No | |
| layer_name | No | |
| activeLayer | No | |
| document_id | No | |
| totalStates | No | |
| currentIndex | No | |
| currentState | No | |
| documentName | No | |
| topLevelCount | No | |
| file_reference | No | |
| selection_info | No | |
| is_smart_object | No | |
| source_metadata | No | |
| smart_filter_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, and the description reinforces those. It adds valuable behavioral/cost context: the `context` block is always returned, and using sections=["context"] skips IPTC traversal and source-file reads, which helps the agent reason about probe cost and freshness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, starting with the core purpose and then quickly adding usage rules, alternatives, and behavioral caveats. A bit dense in places, but everything earns its place for a multi-mode inspection tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, the input schema is complete, and sibling tools are explicitly named with their expected use, the description covers orientation and behavior thoroughly. It even explains fresh-state, cheap-probe, and read-only properties, so an agent can invoke it correctly with minimal ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both `what` and `sections` are thoroughly described in the schema with per-enum behavior. The main description adds higher-level routing and a cheap-probe strategy, but doesn't need to re-document parameter semantics; the schema handles that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific verb + resource (inspect document state) and differentiates itself from image-based or numeric sibling tools by enumerating exactly what `what` can return. It is immediately clear this is the general read-only orientation/assessment tool, not a preview or histogram tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to call at the start of a workflow and whenever fresh state is needed, and gives concrete alternative routing: use ps_get_preview for image checks, and ps_get_histogram / ps_compare_regions / ps_get_layer_bounds_diff for numeric checks. This gives the agent both when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_layer_maskADestructive
Manage the active layer's mask — choose with op. create: add a layer mask; if a selection is active it reveals the selection and hides the rest (the one-call "mask the placed image to the frame opening" — make the selection first, then create); with no selection, a reveal-all mask; adjustment layers load the current selection into their built-in mask. delete: remove the mask (layer pixels preserved). apply: DESTRUCTIVE — permanently bake the mask into the pixels (outside-mask pixels lost). gradient: draw a linear fade into the mask (fade_to names the side that ends hidden; start/end place the fade; auto-creates the mask; replaces existing mask content and clears any active selection first) — the standard fade for reflections, sky blends, and soft edge falloff. Verify with ps_get_preview. Prefer keeping masks non-destructive unless flattening for export. Don't write Mk Chnl At=Msk or Grdn AM scripts in execute_script — this tool already does both.
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | create: add a layer mask on the active layer (if a selection is active it reveals the selection — the "mask to the frame opening" answer; adjustment layers load the selection into their built-in mask). delete: remove the mask (layer pixels preserved). apply: DESTRUCTIVE — bake the mask into pixels (pixels outside the mask are lost). gradient: draw a linear white→black fade INTO the mask (auto-creates a reveal-all mask if none) — the universal fade-out primitive (reflections, sky blends, edge feathering). REPLACES existing mask content. | |
| end | No | op=gradient: 0-1 fraction where the fade completes — fully hidden from here on. Must be greater than start. | |
| start | No | op=gradient: 0-1 fraction along the fade direction where the fade begins — the layer stays fully visible up to here. | |
| extent | No | op=gradient: measure start/end over the active layer's pixel bounds (default) or the whole canvas. A layer with no pixel bounds falls back to canvas. | layer |
| fade_to | No | op=gradient: the side that ends fully HIDDEN (mask black). The opposite side stays fully visible. E.g. a water reflection fades with fade_to=bottom. | bottom |
Output Schema
| Name | Required | Description |
|---|---|---|
| to | No | op=gradient: fully-hidden end of the drawn fade, doc pixels. |
| from | No | op=gradient: fully-visible end of the drawn fade, doc pixels. |
| extent | No | op=gradient: 'layer' or 'canvas' — reports the extent actually used. |
| context | No | |
| fade_to | No | |
| layer_name | No | |
| bounds_used | No | |
| maskApplied | No | |
| maskCreated | No | |
| maskDeleted | No | |
| created_mask | No | op=gradient: true when the reveal-all mask had to be created first. |
| hadSelection | No | |
| mask_gradient | No | |
| activeLayerKind | No | |
| modifiedExistingMask | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide destructiveHint: true, and the description goes further by detailing side effects: apply is DESTRUCTIVE and permanently bakes the mask with outside pixels lost; gradient replaces existing mask content and clears any active selection first; delete preserves layer pixels. This adds behavioral context beyond the annotation and is consistent with it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized, starting with a summary line and then breaking out each `op` with relevant details and a strong closing note about avoiding manual AM scripts. Every sentence serves a purpose, and the structure aids quick comprehension without unnecessary fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (4 operations, 5 parameters), the description is remarkably complete. It covers all operations, side effects, prerequisites (selection needed for create), the relationship to preview verification, and best-practice guidance. The presence of an output schema means return values don't need explanation, so nothing is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description adds meaningful context beyond field names and types. It explains the semantics of `op` operations (e.g., 'create' reveals selection, adjustment layers load selection into built-in mask), and for gradient it clarifies that the tool auto-creates the mask, replaces existing content, and clears the active selection—details not fully captured in schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: managing the active layer's mask via the `op` parameter, with specific sub-operations (create, delete, apply, gradient). It distinguishes itself from sibling tools by focusing on masks and explicitly cross-references ps_get_preview and execute_script, making its role unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides rich usage guidance: when to use each op (e.g., gradient for reflections, sky blends, edge falloff), preference for non-destructive masks unless flattening for export, and an explicit warning not to write `Mk Chnl At=Msk` or `Grdn` scripts in execute_script because the tool already handles them. This clearly frames when to use the tool and when not to.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_list_capabilitiesARead-onlyIdempotent
Live map of every tool this MCP exposes, grouped by capability — each group is a one-line purpose plus the tool names in it. Read-only and cheap. Reach for it to re-orient mid-session (what exists, what to reach for) when the overview brief has scrolled out of context, or to learn which tool names to look up. ps_overview tells you HOW to combine tools; this tells you WHAT exists, currently; tools/list has the full schema for any one you pick.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| groups | No | |
| tool_count | No | |
| group_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint. The description adds 'cheap' (lightweight/efficient) and 'live' (shows current state of exposed tools), which are useful behavioral traits beyond the annotations. No contradiction or hidden side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: first defines the tool's output and format, second gives usage context, third differentiates from two similar tools. It is front-loaded with the core purpose and avoids any filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, zero-parameter listing tool, the description fully covers what it does, how to use it, and how it differs from related tools. The existence of an output schema means return-value details don't need to be in the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema has full coverage, so there is nothing to explain. The baseline for 0 params is 4, and the description doesn't need to compensate for any missing parameter information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it provides a live map of all exposed tools grouped by capability, with each group showing one-line purpose and tool names. It explicitly differentiates from sibling tools ps_overview (HOW to combine) and tools/list (full schema), making its unique purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit guidance on when to use it: to re-orient mid-session or learn tool names, with the caveat about when the overview brief has scrolled out of context. It also names alternatives and their distinct purposes, so the agent knows exactly when NOT to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_mergeADestructive
Merge layers — choose with mode. visible: collapse all visible layers into one (DESTRUCTIVE; identities lost). stamp: merge visible into a NEW layer on top, leaving originals intact (Ctrl+Alt+Shift+E — the non-destructive "final tweak" composite for output sharpening/grain/contrast; prefer this when building on top rather than collapsing). flatten: flatten ALL layers into the background (DESTRUCTIVE; transparency filled with bg color — use sparingly, usually prefer visible or exporting a flattened copy). Returns context.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | visible: collapse all visible layers into one (DESTRUCTIVE; identities lost). stamp: merge visible into a NEW layer on top, originals kept (Ctrl+Alt+Shift+E — non-destructive "final tweak" composite). flatten: flatten ALL layers into the background (DESTRUCTIVE; transparency filled with bg color). |
Output Schema
| Name | Required | Description |
|---|---|---|
| merged | No | |
| context | No | |
| stamped | No | |
| flattened | No | |
| new_layer_name | No | |
| layer_count_after | No | |
| layer_count_before | No | |
| original_active_layer_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint annotation, the description details the exact destructive consequences: 'collapsing all visible layers into one (DESTRUCTIVE; identities lost)' and 'flatten ALL layers into the background (DESTRUCTIVE; transparency filled with bg color)'. It also clearly marks stamp as non-destructive and notes that it leaves originals intact, providing rich context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, front-loaded with the core action, and structured by mode. Every sentence adds value, providing both the what and the when without unnecessary fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the primary purpose, mode differences, destructive consequences, and usage guidance. However, it mentions 'Returns context' without explaining what that means, and it doesn't address potential edge cases like hidden layers or interactions with other tools, leaving slight gaps for a user.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description already covers the parameter semantics at 100%, so the baseline is 3. The tool description adds practical usage guidance for each enum value (e.g., 'prefer this when building on top', 'use sparingly'), which goes beyond the schema's literal definitions, justifying a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool merges layers and uses the `mode` parameter to choose between three distinct behaviors: visible, stamp, and flatten. It distinguishes itself from siblings by explaining what each mode does, making it unambiguous what the tool accomplishes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is provided for each mode: 'stamp' is recommended when building on top, 'flatten' should be used sparingly, and 'visible' is the preferred alternative to flattening. This clearly tells when to use which mode and even suggests alternatives like exporting a flattened copy.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_modify_selectionA
Modify the CURRENT selection — choose with op. (To create a NEW selection instead, use ps_select.) feather softens by radius_px (use when a selection was made hard, e.g. after select all/inverse, before applying an adjustment). refine_edge runs Select-and-Mask's global sliders headlessly (smooth, feather, contrast, shift_edge, edge-detection radius, decontaminate) to clean halos and soft/fuzzy edges (hair) after a rough color-range / magic-wand / subject selection. expand / contract grow / shrink the selection by amount px. border replaces the selection with an amount-px band around its edge. smooth rounds the corners with an amount-px radius. grow / similar expand the selection to similar-colour pixels by tolerance (+anti_alias) — grow to adjacent pixels only, similar document-wide. transform relatively scales (scale_x_percent / scale_y_percent), rotates (rotate_degrees) and/or translates (offset_x / offset_y) the marching ants — pixels are untouched. All require an active selection and return selection_info.
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | feather: soften the selection edge by radius_px. refine_edge: Select-and-Mask global sliders (smooth, feather, contrast, shift_edge, radius edge-detection, decontaminate) to clean halos / soft hair edges. expand: grow the selection outward by `amount` px. contract: shrink it inward by `amount` px. border: replace the selection with a `amount`-px-wide band straddling its edge. smooth: round off the selection corners with a `amount`-px radius. grow: expand the selection to adjacent similar-colour pixels (+tolerance, anti_alias). similar: expand the selection to ALL similar-colour pixels document-wide (+tolerance, anti_alias). transform: relatively scale (scale_x_percent / scale_y_percent), rotate (rotate_degrees) and/or translate (offset_x / offset_y) the marching ants — not pixels. expand/contract/border/smooth all require an active selection and take `amount`; expand/contract/smooth also take at_canvas_bounds. grow/similar also require an active selection. | |
| amount | No | Pixel amount: expand/contract distance, smooth radius, or border width. Required for expand/contract/border/smooth. | |
| radius | No | Edge-detection radius in pixels (0-250) — helps capture soft/fuzzy edges (hair). | |
| smooth | No | Smooth the selection edge (0-100). | |
| feather | No | Feather radius in pixels (0-1000) — softens the edge. | |
| contrast | No | Edge contrast percent (0-100) — re-sharpens an over-soft edge. | |
| offset_x | No | Translate the selection horizontally, pixels (relative). Default 0. | |
| offset_y | No | Translate the selection vertically, pixels (relative). Default 0. | |
| radius_px | No | Feather radius in pixels (must be > 0). | |
| tolerance | No | Color similarity tolerance (0-255) for which neighbouring pixels are added. Default 32. | |
| anti_alias | No | Soften the selection edge. Default true. | |
| shift_edge | No | Shift the edge inward (negative) or outward (positive), percent (-100 to 100). | |
| decontaminate | No | Decontaminate edge colors (removes color fringing). | |
| rotate_degrees | No | Rotate the selection clockwise, degrees. Default 0. | |
| scale_x_percent | No | Horizontal scale of the selection, percent. Default 100 (no change). | |
| scale_y_percent | No | Vertical scale of the selection, percent. Default 100 (no change). | |
| at_canvas_bounds | No | expand/contract/smooth: if true, the effect still applies where the selection meets the canvas edge. Default false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| mode | No | |
| method | No | op=grow/similar: "grow" or "similar". |
| output | No | |
| radius | No | |
| smooth | No | |
| feather | No | |
| refined | No | |
| contrast | No | |
| modified | No | |
| offset_x | No | |
| offset_y | No | |
| selected | No | op=grow/similar: true on success. |
| amount_px | No | |
| feathered | No | |
| radius_px | No | |
| tolerance | No | op=grow/similar: tolerance used. |
| anti_alias | No | op=grow/similar: anti_alias used. |
| shift_edge | No | |
| transformed | No | |
| decontaminate | No | |
| rotate_degrees | No | |
| selection_info | No | Rich post-op stats. Use these to verify the selection actually grabbed what was intended before committing it to a mask. `has_selection:false` short-circuits the rest of the fields (they will be absent). |
| scale_x_percent | No | |
| scale_y_percent | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are sparse (only idempotentHint=false), so the description carries the burden. It explicitly discloses key behaviors such as 'transform' leaving pixels untouched, 'refine_edge' running Select-and-Mask headlessly, and that all operations return selection_info and require an active selection. It doesn't detail every side effect, but it covers the important behavioral distinctions beyond just naming the operations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Despite covering many operations with 17 parameters, the description remains structured and front-loaded. It leads with the core purpose and the main alternative, then explains each operation in a compact, predictable pattern. Every sentence adds distinct operational value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a multi-op, parameter-heavy tool, the description covers prerequisites, per-operation parameters, behavioral caveats, return behavior, and the primary alternative. The presence of an output schema means return details don't need to be duplicated here. Nothing critical is missing for an agent to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaningful usage context beyond the schema, linking parameters to scenarios (e.g., feather radius after hard selections, refine_edge for halo cleanup, tolerance for grow versus similar) and clarifying that transform operates on the marching ants, not pixels. This goes beyond what standard schema prose alone provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the core action — 'Modify the CURRENT selection' — and lists all supported operations with specific verbs and effects (feather, refine_edge, expand, contract, etc.). It also differentiates itself from the sibling by explicitly pointing to ps_select when the goal is to create a NEW selection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives practical when-to-use guidance: 'use ps_select' for new selections, 'feather' after a hard selection, 'refine_edge' after rough color-range/magic-wand/subject selections, and clarifies grow vs similar. It clearly sets the condition that all operations require an active selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_move_layer_to_positionAIdempotent
Move a layer to a position in the stack — the single ordering primitive (the per-direction helpers _to_top / _to_bottom / _up / _down were removed 2026-05-31; this tool covers all four cases). Position keywords: ABOVE/BELOW (requires target_layer_name — places the moved layer immediately above/below the target), TOP/BOTTOM (absolute — target_layer_name not needed). By default the ACTIVE layer is moved; pass layer_to_move= to move a specific layer by name (recurses into groups). COMMON CASES: an adjustment layer just created landed below another adjustment that masks its effect → move it to TOP; a vignette darkens the wrong layers → move ABOVE the layer it should affect; a sky-replacement composite is showing through the foreground → move the foreground to TOP. Idempotent for a given (layer_to_move, target, position).
| Name | Required | Description | Default |
|---|---|---|---|
| position | Yes | Where to move the layer. ABOVE/BELOW = relative to target_layer_name (which is then REQUIRED); TOP/BOTTOM = absolute top/bottom of the layer stack (target_layer_name not needed). Uppercase required. | |
| layer_to_move | No | Optional: name of the layer being moved. If omitted, the active layer is moved (legacy behaviour). | |
| target_layer_name | No | Required for ABOVE/BELOW: the layer to move relative to. Ignored for TOP/BOTTOM. |
Output Schema
| Name | Required | Description |
|---|---|---|
| moved | No | |
| context | No | |
| message | No | |
| position | No | |
| direction | No | |
| layerName | No | |
| relativeTo | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral detail beyond the idempotentHint annotation: it notes recursion into groups, default active layer behavior, and the conditional requirement of target_layer_name for ABOVE/BELOW. It also discloses the historical removal of helper tools. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear lead sentence, parameter details, and a COMMON CASES section. Every sentence adds value, including the removal history which prevents confusion about missing siblings. It is concise despite being thorough.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's conditional logic (ABOVE/BELOW requires target, TOP/BOTTOM doesn't), multiple enum values, and three parameters, the description fully covers all usage aspects. It includes idempotency, default behavior, and practical examples. The presence of an output schema reduces the need to document return values, and the description still provides complete operational context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds substantial meaning: it explains how position interacts with target_layer_name, clarifies that ABOVE/BELOW requires the target while TOP/BOTTOM ignores it, and provides examples of how parameters map to real use cases. This far exceeds the schema's basic descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Move a layer to a position in the stack') with a clear resource (layer) and scope (position in stack). It explicitly distinguishes itself from siblings by calling itself 'the single ordering primitive' and referencing removed per-direction helpers, making it unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives rich usage context: explains ABOVE/BELOW vs TOP/BOTTOM, default active layer behavior, and provides concrete COMMON CASES for when to use each position type. It doesn't explicitly contrast with sibling tools (e.g., ps_move_layer_to_group), but the 'single ordering primitive' phrasing implies exclusivity for ordering tasks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_open_documentA
Open a file from disk into Photoshop with all dialogs suppressed (uses last-used Camera Raw settings for raw/HEIC). Returns document name, dimensions, color mode, and whether the source was a raw format. is_raw_source is workflow-critical, not a passive status field: when true, the first edit should be a Camera Raw develop pass on the base smart object (via a camera-raw develop tool, if one is registered in tools/list) — NOT stacked tonal adjustment layers. Use this in the pipeline to load Inbox files for editing. If the file is ALREADY open, its existing document is activated rather than opened a second time — already_open: true says so, and any edits made to it are still there (Photoshop would otherwise open a duplicate with a fresh Background, which silently strands prior work).
| Name | Required | Description | Default |
|---|---|---|---|
| bit_depth | No | Open-time bits per channel, RAW sources only. Set this here rather than converting later: ps_convert_image_mode FLATTENS the document, so depth cannot be changed once an edit stack exists. Prefer 16 for anything with heavy gradients (skies, skin, long tonal moves). Ignored for non-raw files, and the returned bits_per_channel always reports what was actually opened. | |
| file_path | Yes | Absolute path to the file to open | |
| suppress_dialogs | No | Suppress all PS dialogs during open (raw/HEIC use last-used ACR settings). Default true for pipeline use. |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| success | Yes | |
| width_px | No | |
| file_path | No | |
| height_px | No | |
| color_mode | No | |
| resolution | No | |
| already_open | No | |
| document_name | No | |
| is_raw_source | No | True when the source file was a raw capture (DNG/NEF/CR3/ARW/…). Workflow-critical: the open used last-used/default Camera Raw settings, so no deliberate develop has happened yet. When true, run the Camera Raw develop pass FIRST (via a camera-raw develop tool, if registered) for global tone/color — before any tonal adjustment layers — unless the user explicitly directs otherwise. |
| bits_per_channel | No | |
| bit_depth_warning | No | Present only when a requested bit_depth was not what the document actually opened at — because the file is not a raw source, or Photoshop declined the requested depth. Absent means bits_per_channel is what you asked for. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only declare openWorldHint=true and idempotentHint=false. The description adds substantial behavioral disclosure: dialogs are suppressed, raw/HEIC use last-used ACR settings, already-open documents are activated with prior edits preserved, and is_raw_source is workflow-critical rather than a passive status. This goes well beyond what structured annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and return values, then moves to workflow-critical caveats and the already-open behavior. Every sentence earns its place, and there is no redundant filler or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an open operation with a rich output schema, the description covers the essential behavioral contexts: dialog suppression, raw-source handling, pipeline usage, first-edit guidance, and duplicate-open prevention. Nothing needed for correct invocation is missing, and the output schema already carries return-value details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, with each parameter already well documented, so the baseline is 3. The main description does not need to re-explain parameters; it adds only contextual behavior such as 'all dialogs suppressed' and raw/HEIC ACR behavior, which are useful but not additional parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Open a file from disk into Photoshop', then lists concrete returned values (document name, dimensions, color mode, raw-source flag). This clearly distinguishes it from siblings like ps_create_document or ps_place_image, and states its pipeline role of loading Inbox files.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this in the pipeline to load Inbox files for editing' and gives conditional workflow guidance: for raw sources, the first edit should be a Camera Raw develop pass rather than stacked tonal layers. It also warns about the already-open case, telling the agent when not to expect a fresh duplicate and what behavior to rely on instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_overviewARead-onlyIdempotent
Orientation brief for the entire MCP — workflow contract, capabilities map by category, verification primitives, escape-hatch policy, known gaps. READ THIS FIRST when the user gives you an open-ended editing task. Read-only, idempotent, no document required, no Photoshop call (returns a static markdown brief). Skip it for trivial single-tool requests where you already know which tool fits.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| bytes | No | |
| sections | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it read-only and idempotent, and the description adds further behavioral context: it requires no document, makes no Photoshop call, and returns a static markdown brief. This goes beyond the annotations by clarifying the absence of side effects and the exact nature of the response.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose ('Orientation brief') and the critical usage directive ('READ THIS FIRST') before details. Every sentence earns its place: content scope, when to use, when to skip, and behavioral guarantees. It is compact despite covering many facets.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for the tool's purpose: it states what the brief contains, when to read it, when to skip it, and what it returns. The output schema exists, so return-value details are not needed, and the description covers workflow contract, capabilities, verification, escape hatches, and known gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and schema coverage is 100%, so the baseline is 4. The description adds the useful semantic note that 'no document is required,' which reinforces the no-parameter nature. No further parameter explanation is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states this is an orientation brief for the entire MCP, naming the content categories (workflow contract, capabilities map, verification primitives, escape-hatch policy, known gaps). It clearly differentiates from siblings like ps_list_capabilities by noting it is a static markdown brief with no Photoshop call.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance: 'READ THIS FIRST when the user gives you an open-ended editing task.' It also tells the agent when to skip it: 'Skip it for trivial single-tool requests where you already know which tool fits.' This is clear guidance with both inclusion and exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_pathADestructive
Work with editable vector PATHS — the connective tissue between selections, brush strokes, and clipping. One op-discriminated tool: create_from_selection (selection → work path), create_from_placement (NAME a curve → editable saved path, the grounded pen), save (name the work path), list, delete, load_as_selection (path → selection), stroke (paint a brush-family tool along a path), fill (fill a path region), set_clipping (mark a saved path as the clipping path). Reach for this when: tracing a named curve (an edge, a landmark contour) into an editable path, turning a precise selection into a reusable/strokeable outline, converting a saved path back to a selection, or outlining/filling a shape exactly. create_from_selection and load_as_selection are an exact round-trip. stroke/fill bake pixels and auto-duplicate the target layer. Every op returns path_info (counts + per-path subpath/anchor totals) so you can verify the path landed; load_as_selection also returns selection_info.
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | create_from_selection: convert the active selection into a work path (tolerance = crude↔detailed dial; CLEARS the selection). create_from_placement: NAME a curve (placement → a path relation: `along` a traced edge / landmark curve, or a `segment` between anchors) and get an editable, saved vector path following it — the grounded pen; needs `name` (+ optional `closed`). save: persist the current work path under a name (required for stroke/clip-by-name and to survive the next create). list: inventory all paths (name, kind, subpath + anchor counts) — read-only. delete: remove a path (name → that saved path; omit name → the current work path). load_as_selection: convert a path back into a selection (name → that saved path; omit → current work path; +feather, anti_alias, operation). stroke: paint along a path with a brush-family tool (+tool, apply_to_active_layer) — bakes pixels, auto-duplicates the layer. fill: fill a path region with a color (+color, opacity, mode, feather, anti_alias, apply_to_active_layer) — bakes pixels, auto-duplicates. set_clipping: mark a SAVED path as the clipping path (+flatness) — name required. | |
| mode | No | fill only: blend mode for the fill. Default 'normal'. | normal |
| name | No | Path name. REQUIRED for save, set_clipping, and create_from_placement (the new saved path is named). Optional for delete / load_as_selection / stroke / fill — when omitted those target the current work path. Ignored by create_from_selection / list. | |
| tool | No | stroke only: which brush-family tool paints the path (see this field's own enum for the full supported set). Default 'brush'. | brush |
| color | No | fill only: RGB fill color (each 0-255). Default black. | |
| closed | No | create_from_placement only: close the path into a loop (connect the last anchor back to the first). Default false (an open path). | |
| feather | No | load_as_selection / fill: soften the result edge by this many pixels. Default 0. | |
| opacity | No | fill only: fill opacity percent (0-100). Default 100. | |
| flatness | No | set_clipping only: device-pixel flatness for the clipping path (0.2-100; higher = coarser curve approximation). Omit for the PS default. | |
| operation | No | load_as_selection only: how the loaded selection combines with any existing one. Default 'replace'. | replace |
| placement | No | create_from_placement only: NAME the curve the path follows, as an anchor-relational placement that resolves to a PATH (relation `along` a traced edge / a Pro landmark curve, or a `segment` between two anchors). The spatial-grounding resolver + objective gate produce AND verify the curve; the path is created ONLY if the gate PASSES. Name the curve — do NOT hand-type anchor points. | |
| tolerance | No | create_from_selection only: makeWorkPath tolerance in pixels (0.5 = hug every detail → 10 = crude). Default 2. | |
| anti_alias | No | load_as_selection / fill: anti-alias the edge. Default true. | |
| apply_to_active_layer | No | If false (default), the stroke / fill op is applied to a duplicate of the active layer named "<OpName> (<Original Name>)" — the original is preserved and the LLM can undo simply by deleting the copy. If true, the stroke / fill op bakes directly into the active layer (the historical destructive behavior). |
Output Schema
| Name | Required | Description |
|---|---|---|
| mode | No | |
| name | No | |
| tool | No | |
| count | No | |
| paths | No | |
| saved | No | |
| closed | No | |
| filled | No | |
| loaded | No | |
| anchors | No | |
| context | No | |
| created | No | |
| deleted | No | |
| stroked | No | |
| operation | No | |
| path_info | No | |
| path_name | No | |
| placement | No | |
| tolerance | No | |
| tool_type | No | |
| selection_info | No | |
| target_was_copy | No | |
| clipping_path_set | No | |
| target_layer_name | No | |
| selection_consumed | No | |
| original_layer_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and idempotentHint=false, but the description adds substantial behavioral detail: create_from_selection CLEARS the selection, stroke/fill bake pixels and auto-duplicate the target layer, save persists the work path to survive the next create, and every op returns path_info with counts. This goes well beyond the annotations and gives the agent a realistic model of mutating side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized: it front-loads the resource, then uses one op-discriminated list to cover all mode-specific behavior, then a short 'reach for this when' section, then key cross-op behavior. For a 14-parameter tool with 9 operations, every sentence contributes operational knowledge without padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the operation set, required-vs-optional parameter behavior, destructive side effects, output/return guarantees (path_info and selection_info), and the relationship between operations. Combined with a complete input schema, an output schema, and annotations, an agent has essentially everything needed to select and invoke the correct op.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description adds high-value parameter semantics that the raw schema alone does not convey: the distinction between saved paths and the current work path, name being REQUIRED for save/set_clipping/create_from_placement while optional for delete/load_as_selection/stroke/fill, and the 'do NOT hand-type anchor points' warning for placement. This resolves ambiguity about parameter applicability across ops.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise resource — editable vector PATHS — and enumerates the exact operations via an op-discriminated list: create_from_selection, create_from_placement, save, list, delete, load_as_selection, stroke, fill, set_clipping. It also names concrete use cases like tracing a named curve or turning a selection into a reusable outline, making the tool's scope unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit 'Reach for this when' conditions and additional context such as 'create_from_selection and load_as_selection are an exact round-trip.' However it does not name sibling tools or state when NOT to useps_path in favor of ps_shape, ps_vector_mask, or ps_selection, so the exclusion guidance is weaker than the when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_pingARead-onlyIdempotent
Test connection to Photoshop and report session-start discovery signals. Read-only and idempotent. Call this once at the start of a session to confirm liveness before invoking any other tool. If the user has given you an open-ended editing task, ALSO call ps_overview after this — it returns the workflow contract + capabilities map + verification primitives so you can plan well. Returns version (folds the removed get-version tool), custom_action_sets (count of Action Sets loaded in the Photoshop Actions palette — non-zero means recorded workflows exist; if action tools are available in this build they will appear in tools/list), user_templates (count of saved Editmamei templates), and open_documents (names of documents already open in Photoshop, so the LLM does not have to ask which doc to edit).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| version | No | |
| degraded | No | List of optional discovery signals that could not be gathered (e.g. "pingState" if the go-core snippet builder itself failed to produce the in-PS state script — a broken/missing local install, unrelated to whether Photoshop is reachable; liveness falls back to a cheap ping probe in that case — "templates" if ~/.editmamei/templates was unreadable). Empty when all signals were collected cleanly. Returned defaults for any degraded field cannot be trusted as ground truth. |
| connected | No | |
| notify_user | No | True on the one ping whose text carries the update notice — relay that notice to the user before continuing. False on later pings and when no update is available. |
| open_documents | No | |
| user_templates | No | |
| update_available | No | Set when a newer Editmamei version is published, else null: { current, latest, channel (npm/mcpb/dev), how_to_update, fixed_tools (tools whose recorded failures the newer version fixes) }. The relay instruction rides the ping TEXT on the first ping — see notify_user. Anonymous npm-registry check at boot; opt out with `editmamei config set update_check false`. |
| custom_action_sets | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint; the description affirms these without contradicting them. It adds meaningful behavioral context beyond the annotations: the tool reports specific discovery signals, returns open_documents so the model doesn't ask the user, and consolidates the old get-version behavior. A small amount of credit is withheld because the safety profile was already covered by annotations, but the extra context is genuinely valuable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The most important directives are front-loaded ('Test connection', 'Read-only and idempotent', 'Call this once at the start'), and the return fields are enumerated with one-line explanations. There is a minor typo ('Editmamei') and the text is longer than strictly necessary, but each segment earns its place by guiding the agent on when and how to use the response.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters, an output schema, and a simple liveness-then-discover role, this description is complete. It tells the agent exactly when to call it, what it returns, why that return matters, and when to follow up with ps_overview. An agent can use this tool appropriately without additional documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no parameter schema to clarify. The description instead clarifies the semantics of the tool's outputs (version, custom_action_sets, user_templates, open_documents), which compensates for the absence of parameter-level detail. Since no parameters are required, the baseline of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Test connection to Photoshop') and states the tool's role as a liveness check plus discovery of session-start signals. It distinguishes itself from siblings by explicitly contrasting with ps_overview (workflow contract + capabilities map) and noting it folds in the removed get-version tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use guidance is present: call it once at the start of a session, before invoking any other tool, to confirm liveness. It also gives an if-then alternative: for open-ended editing tasks, ALSO call ps_overview afterward. This is clear, actionable routing between siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_place_imageA
Place an image file (JPEG, PNG, PSD, etc.) as a new Smart Object layer in the active document, optionally offset from center. Rasterize separately if you need to apply pixel-only operations. Open-world: reads from the filesystem. Returns the new layer name, bounds, and updated document context.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | X position offset in pixels from the canvas centre (default 0). Negative places the layer further left; bounded at ±300,000 px. | |
| y | No | Y position offset in pixels from the canvas centre (default 0). Negative places the layer further up; bounded at ±300,000 px. | |
| file_path | Yes | Full path to the image file (JPEG, PNG, PSD, etc.) | |
| width_percent | No | Scale the placed layer horizontally to this percent of its native width. Omit (or pass 100) to keep native size. Common ratios: 50 for half-size, 200 for double. Independent from height_percent — pass both to scale non-uniformly. | |
| height_percent | No | Scale the placed layer vertically to this percent of its native height. Omit (or pass 100) to keep native size. Pair with width_percent for uniform scale (set both to the same value). |
Output Schema
| Name | Required | Description |
|---|---|---|
| placed | No | |
| context | No | |
| filePath | No | |
| position | No | |
| layerName | No | |
| layerBounds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that the operation creates a Smart Object layer, reads from the filesystem, and returns layer name, bounds, and document context. This goes beyond the openWorldHint annotation and clarifies the non-pixel nature of the result. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core action, followed by a useful rasterization warning and a concise return-value summary. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers action, file types, smart-object behavior, positioning, and return context. With an output schema present and full parameter coverage, the description is complete enough for an agent to select and invoke the tool confidently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All five parameters are fully documented in the schema (100% coverage), so the description adds little beyond a general 'optionally offset from center' phrase. The schema carries the semantic load, making 3 an appropriate baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it places an image file as a new Smart Object layer in the active document, with an optional offset from center. The verb+resource+scope is specific and distinguishes it from related tools like convert_to_smart_object or rasterize_layer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides actionable guidance: rasterize separately if pixel-only operations are needed, and notes open-world filesystem reads. This helps the agent decide when to use the tool, though it does not explicitly name an alternative sibling tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_portrait_touchupADestructive
Detection-driven face touch-ups using LOCAL on-device face detection. op=dodge_face brightens the detected face(s) with a non-destructive masked adjustment layer. op=soften_skin applies a soft blur over the face(s) on a duplicate layer (light, bounding-box-level smoothing). Works from the face bounding box — precise landmark ops (eyes/teeth/lips) are a Pro feature. Multiple faces are handled together. Pair with ps_detect (target=faces) to preview detection first.
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | dodge_face: brighten the detected face(s) with a masked adjustment layer (non-destructive). soften_skin: a soft blur over the face(s) on a duplicate layer (light bbox-level smoothing). | |
| amount | No | dodge_face: brightening 1–100 (default 25). soften_skin: extra blur multiplier 0.5–3 (default 1, scaled to face size). | |
| max_dimension | No | Long-edge px of the detection export. Coordinates always return in document px. | |
| face_threshold | No | Minimum face confidence (0–1). |
Output Schema
| Name | Required | Description |
|---|---|---|
| op | No | |
| boxes | No | |
| faces | No | |
| image | No | |
| context | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotation Contradiction: The description states operations use a 'non-destructive masked adjustment layer' and a duplicate layer for blur, while the annotations set destructiveHint: true. This directly conflicts with the safe, non-destructive framing, so per the rubric transparency must be 1 despite other useful behavioral details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description front-loads the main purpose and then covers both operations, scope limitations, and integration advice. It is somewhat dense but every sentence contributes useful context without unnecessary fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core operations, behavior, limitations, and recommended pairing with ps_detect, and an output schema exists for return values. It feels complete for decision-making except for the conflicting destructive/non-destructive messaging.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all four parameters with full descriptions, including ranges, defaults, and per-op behavior, so the description adds little parameter-level value beyond high-level conceptual grouping. Baseline 3 is appropriate given 100% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies this as detection-driven face touch-ups with two concrete operations (dodge_face and soften_skin) and their effects. It distinguishes this tool from siblings like ps_retouch or ps_apply_adjustment by emphasizing local on-device face detection and bounding-box-level scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It offers explicit usage guidance by recommending pairing with ps_detect (target=faces) to preview detection first. It also notes that precise landmark ops (eyes/teeth/lips) are a Pro feature, giving the agent useful boundaries for when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_rasterize_layerADestructive
Rasterize the active layer (convert text or smart object to plain pixels). Destructive — the text/smart-object source is lost. No-op if already a normal raster layer. Returns context so the caller sees the layer kind transition.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| kind | No | |
| context | No | |
| message | No | |
| newKind | No | |
| rasterized | No | |
| originalKind | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds detail beyond the destructiveHint annotation by explicitly stating that the text/smart-object source is lost, and also discloses the no-op condition and the return behavior (context showing layer kind transition). This enriches the annotation without contradicting it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each providing essential information: primary operation, destructive nature, no-op condition, and return value. No fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless tool with an output schema, the description covers purpose, destructive nature, edge cases, and the return value. It is complete and self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has no parameters in the schema, so the description doesn't need to explain parameter syntax. The reference to 'active layer' as an implicit context is sufficient and adds meaning beyond the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (rasterize), the target (active layer), and the result (convert text or smart object to plain pixels). It distinguishes from sibling tools like ps_convert_to_smart_object by specifying the conversion direction to pixels.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool (when you need to flatten a text or smart object layer) and notes the no-op case for already-raster layers, which is a usage caveat. It does not explicitly compare with alternatives, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_read_sceneARead-onlyIdempotent
The full scene model — run this before a spatially-targeted edit, not the cheaper ps_detect: detected subjects (with the main one flagged) and faces in document pixels, a coarse sky/ground region map, the horizon line (y + placement + confidence), tonal zones (shadow/midtone/highlight bands + coverage), composition geometry (which thirds cell the subject sits in, balance, headroom), and the menu of selectable named regions. The structured model is complete on its own — pass annotate:true for an annotated preview JPEG when you actually need to see it drawn. Built using LOCAL on-device vision + classical CV; the image never leaves the machine. Select regions by name with ps_select_by_reference instead of guessing a rectangle. Read-only: renders a throwaway duplicate. Perception is cached per document state, so repeated reads are cheap.
| Name | Required | Description | Default |
|---|---|---|---|
| refresh | No | Force a fresh perception pass even if a cached model for the current document state exists. Perception is normally cached per (document, history-state) so it runs once per state. | |
| annotate | No | Also return an annotated preview JPEG with subject boxes (magenta), faces (cyan), and the horizon line (yellow) drawn. Default false: the structured scene model returned by this call is already complete on its own — ask for the image only when you actually need to see the annotation drawn. | |
| save_regions | No | EAGERLY derive every region (sky/ground/shadows/highlights/skin/subject/face) up front and SAVE each confident one as a managed `scene:*` alpha channel, so the returned menu carries a verified method + confidence for each. Costs one derive per target — measured at ~21s on a 4898x3265 layered document, against a 30s script timeout — so it is OFF by default. Leave it off unless you specifically need every region scored in one call: the default advertises the same menu as `on_demand` entries and ps_select_by_reference derives whichever region you actually ask for (then saves its channel, so repeats of THAT region are instant). The `scene:` channel-name prefix is RESERVED: channels matching it are treated as derived and are deleted on the next scene read and on ps_save_psd, so do not give a channel you want to keep a `scene:`-prefixed name. | |
| max_dimension | No | Long-edge px of the perception export. Returned coordinates are always in full document pixels. | |
| composition_context | No | Optional: tune the confidence gate for an artistic/non-standard composition (e.g. profile:big_sky) so a legitimately large region is not rejected. Same shape as ps_select_by_reference. |
Output Schema
| Name | Required | Description |
|---|---|---|
| doc | No | |
| faces | No | |
| horizon | No | |
| regions | No | |
| subjects | No | |
| provenance | No | |
| composition | No | |
| region_menu | No | |
| tonal_zones | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and the description adds substantial behavioral context: 'Read-only: renders a throwaway duplicate', LOCAL on-device processing ('image never leaves the machine'), per-document-state caching, and the reserved scene: channel prefix that gets deleted on subsequent scene reads and ps_save_psd. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the full result model and usage direction, then compactly covers privacy, the region-selection alternative, and caching. Despite covering a lot of ground, every sentence carries distinct information and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return types need no explanation, and the description covers all operational context an agent needs: when to call, what it returns, how to get annotations, privacy, caching, and the alternative selection tool. The save_regions caveats make cost and destructive behavior explicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds value beyond the schema: annotate:true is only for when a visual preview is needed, save_regions is eagerly derived and costly with a measured ~21s/30s timeout warning, and scene:-prefixed channels are reserved and deleted. This lifts it above the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('full scene model') and enumerates exactly what it returns: detected subjects, faces, sky/ground map, horizon, tonal zones, composition geometry, and named regions. It also explicitly differentiates from ps_detect ('not the cheaper ps_detect'), so an agent can select it correctly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to use the tool ('run this before a spatially-targeted edit'), names the cheaper alternative (ps_detect), and routes region selection to ps_select_by_reference instead of guessing rectangles. It also gives conditional guidance: pass annotate:true only when the annotated preview is actually needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_redoA
Step forward in the document history (equivalent to Ctrl/Cmd+Shift+Z). Only works if ps_undo was the last operation; making a fresh edit destroys the redo stack. Returns updated context.
| Name | Required | Description | Default |
|---|---|---|---|
| steps | No | Number of steps to redo (default: 1) |
Output Schema
| Name | Required | Description |
|---|---|---|
| steps | No | |
| redone | No | |
| undone | No | |
| context | No | |
| remainingStates | No | |
| availableRedoSteps | No | |
| currentHistoryState | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (idempotentHint: false), the description discloses the dependency on ps_undo, the effect of fresh edits on the redo stack, and the return of updated context. This is rich behavioral context with no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the action, and every sentence adds essential information. No redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one optional parameter and an output schema, the description explains the core behavior, prerequisites, invalidation condition, and return value. It is fully adequate for the agent to decide when and how to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with the 'steps' parameter already described as 'Number of steps to redo (default: 1)'. The description adds no extra parameter meaning, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the action: 'Step forward in the document history' with a familiar keyboard shortcut equivalent. The scope and resource are explicit, and the mention of ps_undo distinguishes it from the sibling undo tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit conditions for use: 'Only works if ps_undo was the last operation; making a fresh edit destroys the redo stack.' This tells the agent when the tool is valid and when it will fail, which is strong usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_replace_skyA
Run Photoshop's Sky Replacement (Adobe Sensei): detect the sky, composite a replacement, and relight/colour-grade the foreground to match. Non-destructive — everything lands in a "Sky Replacement Group" of editable layers above the original, so the result can be tuned or deleted afterwards. sky_file takes an ABSOLUTE path to ANY image on disk, not only Photoshop's built-in presets. Reach for harmonization_opacity and foreground_lighting_opacity when the composite reads as pasted-on; those two carry most of the believability. Fails cleanly when the image has no detectable sky (indoor or closed compositions).
| Name | Required | Description | Default |
|---|---|---|---|
| sky_file | Yes | ABSOLUTE path to the image to use as the sky. Any image Photoshop can open works — it does not need to be a registered Photoshop sky preset. The built-in skies live as .jpg files under the Sky_Presets folder inside your Photoshop settings directory, and their paths can be passed here directly. | |
| sky_name | No | Label recorded on the operation. Cosmetic — it does not select the sky, sky_file does. | Custom Sky |
| brightness | No | Brightness of the replaced sky itself. | |
| shift_edge | No | Moves the sky/foreground boundary inward (negative) or outward (positive). Use it when the horizon leaves a halo or eats into the foreground. | |
| temperature | No | Warms (positive) or cools (negative) the replaced sky. | |
| border_smoothness | No | Softens the boundary between sky and foreground. 0 is a hard cut. | |
| edge_lighting_opacity | No | Strength of the light wrap along the foreground edge where it meets the sky. | |
| harmonization_opacity | No | How strongly the foreground is colour-graded to match the new sky. This is what sells the composite — 0 leaves the foreground untouched and usually reads as pasted-on. | |
| foreground_lighting_opacity | No | Strength of the relighting applied to the foreground so it appears lit by the new sky. |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| replaced | No | |
| sky_file | No | |
| sky_name | No | |
| group_name | No | Name of the layer group Photoshop created. |
| group_layers | No | Layers inside the group, top to bottom — typically the sky layer, an edge-lighting group, a foreground-lighting layer and a foreground-colour curves layer. |
| strategy_used | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description provides critical behavioral disclosures beyond the sparse annotations: it is non-destructive, creates an editable 'Sky Replacement Group' above the original, accepts any absolute-path image as the sky, and fails cleanly on images with no detectable sky. These are exactly the kind of behavioral details an agent needs before invoking the tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is tightly structured: headline behavior, non-destructive guarantee, constraining details about the sky_file parameter, targeted tuning guidance, and a failure mode statement. Every sentence adds operational value and the most important caveats are near the front.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and the parameter schema is fully covered, the description is broadly complete for a composite tool of this complexity. It explains what happens to the document, how to tweak believability, and when the operation is impossible. It does not explicitly state prerequisites like having an open document or a target layer, which would make it fully self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents 100% of the parameters, so the baseline is 3. The description adds value above that by highlighting that harmonization_opacity and foreground_lighting_opacity carry the believability of the composite and should be used when the result looks pasted-on. It also reinforces that sky_file is absolute-path-based and need not be a preset, which is not obvious from the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pair: 'Run Photoshop's Sky Replacement (Adobe Sensei): detect the sky, composite a replacement, and relight/colour-grade the foreground to match.' This clearly distinguishes it from sky-selection siblings like ps_select_sky by making the full composite operation explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear operational context: when to reach for tuning parameters ('when the composite reads as pasted-on') and when the tool fails cleanly (no detectable sky). It does not explicitly say when to choose this tool over ps_select_sky or other sky-related alternatives, but its purpose is distinct enough that the usage context is largely clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_report_problemA
Collect an ANONYMIZED diagnostic bundle and write it to the user's Downloads folder so they can attach it to a bug report — use when Editmamei misbehaves (won't connect, a tool keeps failing, unexpected results). The bundle holds recent server logs, system info (Editmamei/OS/Photoshop versions), and a content-free summary of recent tool calls (name, success, duration, error class). It contains NO image content, NO tool arguments, and file paths reduced to basenames. Does not touch Photoshop; writes one JSON file. After calling, tell the user the file path and that they can attach it to a new issue at https://github.com/editmamei/editmamei/issues.
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | Optional short description of the problem (what went wrong, what you were doing). Embedded verbatim after sanitization. No file contents or paths needed. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | No | |
| bytes | No | |
| issues_url | No | |
| server_log_lines | No | |
| desktop_log_included | No | |
| recent_session_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond annotations by detailing exact contents (server logs, system info, content-free summary), what is excluded (no image content, no tool arguments, paths stripped to basenames), and side effects (writes one JSON file to Downloads). This adds privacy and safety context that annotations alone do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence contributes value, covering use cases, content, limitations, and follow-up instructions. It could be slightly more structured, but there is no superfluous wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and a relatively straightforward side-effect, the description fully covers the when, what, exclusions, and user-facing next steps. It leaves no practical gaps for an agent deciding to invoke or using this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description for the single 'note' parameter is already thorough (100% coverage), and the tool description does not add extra meaning beyond it. Since schema handles the parameter semantics fully, baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb phrase: 'Collect an ANONYMIZED diagnostic bundle and write it to the user's Downloads folder' with the clear goal of attaching to a bug report. This distinguishes it from all sibling Photoshop manipulation tools, making its purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use: 'use when Editmamei misbehaves (won't connect, a tool keeps failing, unexpected results)'. It also clarifies what it does not do ('Does not touch Photoshop') and provides post-call guidance, offering clear contextual direction without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_resize_imageADestructiveIdempotent
Resize the entire document canvas (all layers) to the specified absolute dimensions. Destructive: downscaling permanently loses pixel data. Idempotent: same width/height always yield the same result. For aspect-preserving downscale during export, see ps_export (format=jpeg / png) which resize a duplicate. Returns updated document context.
| Name | Required | Description | Default |
|---|---|---|---|
| width | Yes | New width in pixels (1..300,000 — Photoshop's max canvas size). | |
| height | Yes | New height in pixels (1..300,000 — Photoshop's max canvas size). |
Output Schema
| Name | Required | Description |
|---|---|---|
| width | No | |
| height | No | |
| context | No | |
| success | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (destructiveHint, idempotentHint), the description adds concrete consequences: 'downscaling permanently loses pixel data' and 'same width/height always yield the same result'. It also states the return value ('Returns updated document context'), providing useful behavioral context the annotations do not cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each serving a purpose: action + scope, destructive warning, and alternative guidance. It is front-loaded with the primary function and avoids redundant or filler content. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (canvas resize affecting all layers), the description is complete. Annotations cover destructive/idempotent safety, schema covers parameters, output schema exists for return values, and the description explicitly mentions returning the updated document context. No important aspect is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers 100% of parameter descriptions with clear min/max bounds, so the baseline is 3. The description only adds the phrase 'absolute dimensions' without further detail on usage or formatting, so it does not significantly enhance parameter understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Resize'), the resource ('entire document canvas'), and the scope ('all layers'). It distinguishes itself from sibling tools like ps_crop_document and ps_export by specifying absolute dimensions and noting the alternative for export-based resize.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells when to use this tool (resize the whole canvas to absolute dimensions) and when not to ('For aspect-preserving downscale during export, see ps_export'). This provides a clear alternative and exclusion, guiding the agent to the right tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_retouchADestructive
Selection-driven content-aware retouch — choose the technique with method. Requires an active selection (throws if none, so Content-Aware Fill never silently fills the whole layer). Auto-duplicates the active layer by default so the original is preserved (auto-duplicate-first); pass apply_to_active_layer: true to bake into the original. content_aware_fill synthesizes a fill from surroundings (remove wires/objects/blemishes); patch samples replacement pixels from a chosen offset — or NAME the source region with source_placement (grounded + gated); content_aware_move relocates the selection and fills the source — offset, or NAME where with destination_placement.
| Name | Required | Description | Default |
|---|---|---|---|
| scale | No | Allow PS to rescale sampled patches when synthesizing. Default false. | |
| method | Yes | Retouch technique (all require an active selection). content_aware_fill: synthesize a fill from surrounding content (color_adaptation, opacity, blend_mode, rotate/scale/mirror). patch: sample replacement pixels — offset_x + offset_y, OR source_placement to NAME the clean source region (patch_structure 1-7, patch_color 0-10, use_source). content_aware_move: relocate the selection and fill the source — offset_x + offset_y, OR destination_placement to NAME where to move it (patch_structure, reshuffle). | |
| mirror | No | Allow PS to mirror sampled patches when synthesizing. Default false. | |
| rotate | No | Allow PS to rotate sampled patches when synthesizing. Default false (Photoshop default). | |
| opacity | No | Fill opacity 1-100%. Default 100. | |
| offset_x | No | Horizontal pixel delta to move the selected content. Positive = right. Required unless destination_placement is given. | |
| offset_y | No | Vertical pixel delta to move the selected content. Positive = down. Required unless destination_placement is given. | |
| reshuffle | No | Allow PS to recompose the moved content from non-contiguous source pixels. Default true (Photoshop default for CAM). | |
| blend_mode | No | Blend mode for the fill. Default `normal`. Use `multiply` or `darken` when filling around hair to keep darker edges; `lighten` for highlights. | normal |
| use_source | No | When true (default), the user-drawn selection is the patch source — the natural "patch this region" semantic. False inverts to destination-mode patching. | |
| patch_color | No | Options bar > Color slider (0-10). Default 5. | |
| transparent | No | Respect layer transparency. Default false. | |
| patch_structure | No | Options bar > Structure slider (1-7). Default 4 (CAM default). | |
| color_adaptation | No | When true (default), PS adjusts the synthesized fill to match the surrounding region's color. Turn off only when matching color would compromise structure. | |
| source_placement | No | Grounded alternative to offset_x/offset_y: NAME the patch SOURCE (resolves to a POINT via the grounding resolver + objective gate — e.g. an extremum for the cleanest nearby skin, a grid intersection). The offset from the selection center to that point is computed for you. Wins over offset_x/offset_y. Provide THIS or offset_x + offset_y. | |
| sample_all_layers | No | Sample from all visible layers. Default false. | |
| heal_smooth_factor | No | Internal smoothing factor (0-10). Default 5. | |
| apply_to_active_layer | No | If false (default), the retouch op is applied to a duplicate of the active layer named "<OpName> (<Original Name>)" — the original is preserved and the LLM can undo simply by deleting the copy. If true, the retouch op bakes directly into the active layer (the historical destructive behavior). | |
| destination_placement | No | Grounded alternative to offset_x/offset_y: NAME where to move the selection (resolves to a POINT via the grounding resolver + objective gate — a grid intersection, an object centroid, an extremum). The selection center is moved ONTO that point; the offset is computed for you. Wins over offset_x/offset_y. Provide THIS or offset_x + offset_y. |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| retouch | No | |
| target_was_copy | No | |
| target_layer_name | No | |
| original_layer_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint annotation, it reveals the auto-duplicate default, the throw-if-no-selection behavior, and the apply_to_active_layer switch to destructive baking. It also characterizes what each method does (synthesize, sample, relocate). This substantially exceeds what annotations alone provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and puts constraints (selection, duplication) early. It is dense and a single long sentence sequence, but every clause earns its place; a little more structure would make it cleaner.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 19-parameter tool with a detailed schema and output schema, the description covers all key behavioral decisions: selection requirement, method semantics, non-destructive default, destructive off-switch, and grounded placement alternatives. Nothing essential for calling the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The method descriptions in the schema already repeat most of the semantics from the top-level description, and the description adds only a small amount of context (e.g., 'remove wires/objects/blemishes'). No extra per-parameter meaning beyond the schema is necessary.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening 'Selection-driven content-aware retouch' names the operation and resource, and the three method values clarify the scope (fill/patch/move). It doesn't explicitly differentiate from the sibling ps_portrait_touchup, so it falls just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It says an active selection is required and that the tool throws if none, which is a concrete exclusion. It also tells agents to choose by method and explains how to preserve vs bake into the original. It does not name when to prefer this over specific sibling tools, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_save_psdADestructiveIdempotent
Save the active document as a layered PSD to the given path. Saves as a copy, so the working document is unmodified and unrenamed. Use this in the pipeline to land an editable PSD into the Edit folder.
| Name | Required | Description | Default |
|---|---|---|---|
| output_path | Yes | Absolute output path including filename, e.g. E:\Photos\Edit\shell_01.psd | |
| keep_scene_channels | No | Keep the managed scene:* alpha channels ps_read_scene precomputes. Default false — they are DERIVED masks (rebuilt by the next scene read) and each is a full-resolution channel, so baking them into the .psd bloats it badly (~51MB per channel on a 51MP document). Set true only if you want the saved file to carry the masks. The result reports scene_channels_purged either way, so it's never silent. NOTE: the `scene:` channel-name prefix is RESERVED — the purge matches on the prefix alone, so a hand-made channel named e.g. `scene:mine` is deleted along with the derived ones. Name your own channels anything else. | |
| maximize_compatibility | No | Include flattened composite for compatibility with other apps. Default true. |
Output Schema
| Name | Required | Description |
|---|---|---|
| layers | No | |
| context | No | |
| success | Yes | |
| saved_to | No | |
| document_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (openWorld, idempotent, destructive), the description discloses that the working document remains 'unmodified and unrenamed' because it saves a copy. That is critical safety information. It doesn't mention potential file overwriting but destructiveHint covers that general trait.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences: purpose, safety note, and usage guidance. Front-loaded with the core action. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is brief but the full definition includes a rich schema (with defaults and detailed keep_scene_channels explanation) and an output schema. The description covers the essential copy behavior and pipeline context. Could mention overwrite semantics but annotations already signal destructive nature, so it's adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All three parameters are fully described in the input schema (100% coverage), including detailed notes on keep_scene_channels. The description itself adds no parameter-specific information, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Save' with a clear resource 'active document' as 'layered PSD' to 'given path', and explicitly says 'Saves as a copy'. This distinguishes it from export tools that might save other formats or modify the original. The phrase 'Use this in the pipeline' adds usage context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to use: 'in the pipeline to land an editable PSD into the Edit folder.' It doesn't explicitly exclude alternatives but provides clear context. No mention of alternatives like ps_export, so not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_selectA
Create a NEW selection — choose with mode. (To edit the CURRENT selection instead — including growing it by colour similarity — use ps_modify_selection.) all selects the canvas; none deselects; inverse inverts the current selection (e.g. select the subject, then inverse to act on the background). rectangle (left/top/right/bottom, optional feather_px to avoid hard block-edges in smooth sky). ellipse (left/top/right/bottom bounding box + anti_alias — circles/ovals). color_range (target red/green/blue + fuzziness — "select all the red / skin tones"). luminance_range (highlights/shadows/midtones — foundation for glow / dodge-burn). magic_wand (click x/y + tolerance, contiguous). focus_area selects by depth of field rather than subject or colour (+in_focus_radius, soft_mask) — check whole_canvas_selected/warning in the result before trusting it. grow / similar are DEPRECATED here (they act on the CURRENT selection, not a new one) — use ps_modify_selection(op=grow|similar) instead; kept for one release for backward compatibility, identical behaviour. rectangle/ellipse/magic_wand also accept a grounded placement (NAME a region/point instead of guessing pixels — resolved + gate-verified). The geometric/color/wand modes take selection_type (replace|add|subtract|intersect) to combine with an existing selection and return a rich selection_info bundle — verify it (or ps_get_selection_preview) before committing to a mask.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | Click X in document pixel coords. | |
| y | No | Click Y in document pixel coords. | |
| red | No | Target red (0-255). | |
| top | No | Top edge in pixels | |
| blue | No | Target blue (0-255). | |
| left | No | Left edge in pixels | |
| mode | Yes | all: select the whole canvas. none: deselect. inverse: invert the current selection. rectangle: left/top/right/bottom (+optional feather_px). ellipse: left/top/right/bottom bounding box (+anti_alias, +optional feather_px) — circles/ovals. color_range: target red/green/blue (+fuzziness) — "select all the red / skin". luminance_range: luminance highlights|shadows|midtones (+fuzziness, lower_limit, upper_limit) — glow/dodge-burn foundation. magic_wand: click x/y (+tolerance, contiguous, anti_alias, sample_all_layers). grow: DEPRECATED here — use ps_modify_selection(op=grow) instead (kept for one release for backward compatibility, identical behaviour). Expands the CURRENT selection to adjacent similar-colour pixels (+tolerance, anti_alias). similar: DEPRECATED here — use ps_modify_selection(op=similar) instead (kept for one release for backward compatibility, identical behaviour). Expands the CURRENT selection to ALL similar-colour pixels document-wide (+tolerance, anti_alias). skin_tones: select skin-coloured pixels (+fuzziness; use_faces=true adds face-aware refinement). out_of_gamut: select colours outside the printable CMYK gamut (no params). polygon: points [{x,y},...] in ABSOLUTE document pixels (min 3, auto-closes) — covers polygonal/freehand lasso. Coordinate-driven: you must know the pixel positions (use ps_inspect / ps_get_preview to aim, or ps_path create_from_placement → load_as_selection for a grounded outline). focus_area: select what the lens rendered SHARP by depth of field, not by subject or colour (+in_focus_radius, soft_mask) — takes no coordinates; check whole_canvas_selected in the result before trusting it. rectangle/ellipse/magic_wand also take a grounded `placement` instead of raw coords (region → the bbox; point → the wand click). rectangle/ellipse/polygon/focus_area/color_range/luminance_range/magic_wand/skin_tones/out_of_gamut also take selection_type to combine with an existing selection. | |
| green | No | Target green (0-255). | |
| right | No | Right edge in pixels | |
| bottom | No | Bottom edge in pixels | |
| points | No | Polygon vertices in ABSOLUTE document pixels: [{x, y}, ...], minimum 3. (0,0) is top-left. The ring auto-closes (last vertex connects back to the first). You must know the pixel coordinates to aim this — pair with ps_inspect (dimensions) / ps_get_preview (content). Covers polygonal/freehand/magnetic lasso shapes. | |
| fuzziness | No | skin_tones: tolerance/spread around skin-tone colours (0-200). Default 40. | |
| luminance | No | Which tonal band to select by brightness. | |
| placement | No | Grounded coordinates (rectangle/ellipse/magic_wand): NAME anchors + a relation instead of guessing pixels. rectangle/ellipse ← a REGION relation (inside/gap) → the selection bounding box; magic_wand ← a POINT relation (centroid/extremum/grid) → the click. Verified by the objective gate; wins over the raw edges/x-y. See the placement-resolver tool, when this build has one, for the vocabulary. | |
| soft_mask | No | False (default) yields a hard-edged selection — every pixel fully in or fully out, which is what you want before ps_modify_selection feathering. True lets Photoshop feather the focus falloff itself, useful when the subject edge is genuinely gradual (hair, fur, motion). | |
| tolerance | No | Color similarity tolerance (0-255). Default 32. | |
| use_faces | No | skin_tones only: refine the skin-tone selection using face detection. Default false (pure Lab skin-tone colour preset, no AI dependency). | |
| anti_alias | No | Soften the selection edge. Default true. | |
| contiguous | No | If true (default), only selects connected matching pixels. | |
| feather_px | No | Feather the selection edge by this many pixels after creating it. Default 0 (hard edge). REQUIRED for regional adjustments in smooth areas like open sky — a hard rectangular selection will produce a visible block-edge artifact when an adjustment is applied. Typical values: 40-180. | |
| lower_limit | No | highlights/midtones: lower brightness bound (0-255). Default 190 (highlights) / 105 (midtones). | |
| upper_limit | No | shadows/midtones: upper brightness bound (0-255). Default 65 (shadows) / 150 (midtones). | |
| selection_type | No | How this selection combines with any existing one. 'replace' (default) overwrites; 'add' unions with the existing selection; 'subtract' removes this from the existing; 'intersect' keeps only the overlap. | replace |
| in_focus_radius | No | How much blur still counts as "in focus", in pixels. Higher pulls more of the soft transition zone into the selection; lower keeps only the crisply resolved plane. 4.07 is the Photoshop dialog default and a sane starting point. The useful band is narrow, and a radius well above the default selects the entire frame — so move in small steps and CHECK the returned area_percent and whole_canvas_selected: a selection covering essentially everything means the radius is too high and the result is worthless, even though the call reports success. | |
| sample_all_layers | No | If true, samples color across all visible layers. If false (default), samples the active layer only. |
Output Schema
| Name | Required | Description |
|---|---|---|
| method | No | |
| preset | No | |
| warning | No | mode=focus_area: set when whole_canvas_selected is true. |
| inverted | No | |
| selected | No | |
| fuzziness | No | |
| luminance | No | |
| placement | No | |
| selection | No | |
| soft_mask | No | mode=focus_area: soft_mask used. |
| tolerance | No | |
| anti_alias | No | |
| contiguous | No | |
| deselected | No | |
| feather_px | No | |
| lower_limit | No | |
| point_count | No | |
| upper_limit | No | |
| sample_point | No | |
| target_color | No | |
| strategy_used | No | mode=focus_area: "executeAction:focusMask". |
| selection_info | No | Rich post-op stats. Use these to verify the selection actually grabbed what was intended before committing it to a mask. `has_selection:false` short-circuits the rest of the fields (they will be absent). |
| selection_type | No | |
| in_focus_radius | No | mode=focus_area: radius used. |
| requested_bounds | No | |
| sample_all_layers | No | |
| whole_canvas_selected | No | mode=focus_area: true when the RAW detection (before any selection_type combine) covered essentially the entire canvas — usually a non-result. selection_info reports the FINAL, post-combine selection and the two can legitimately disagree. |
| active_layer_temporarily_changed | No | mode=focus_area: true if the active layer was not an ordinary pixel layer and detection was temporarily retargeted to the bottom layer. Restored before return. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With almost no behavioral annotations beyond title and idempotentHint, the description carries the disclosure burden and does so thoroughly. It discloses that selection_type overwrites/unions/subtracts/intersects, that grow/similar act on the current selection and are kept for one release, that focus_area may report whole_canvas_selected without a useful selection, and that placement is gate-verified. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The text is long, but the tool has 25 parameters and 14 modes, and the content is front-loaded with the core purpose and the primary alternative in the first sentence. Minor redundancy exists between the prose mode list and the mode property description, but the structure groups modes and warnings effectively.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex selection tool with an output schema, the description is complete: it covers all mode families, coordinate requirements/alternatives, combination semantics, verification steps, deprecations, and failure signs. It even tells the agent how to aim coordinates using ps_inspect/ps_get_preview or grounded placement, leaving no prerequisite or expected-result gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though the schema already covers 100% of parameters, the description adds high-value semantics beyond naming them: feather_px is REQUIRED to avoid block edges in sky, in_focus_radius has a narrow useful band and should be checked via area_percent/whole_canvas_selected, placement wins over raw coordinates and is gate-verified, and selection_type explains exactly how modes combine with existing selections.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Create a NEW selection — choose with mode.' It explicitly distinguishes ps_select from ps_modify_selection, which edits the current selection, and the detailed mode breakdown makes it unambiguous which sibling or mode applies. This separates it from ps_select_subject, ps_select_sky, and other selection-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It directly tells the agent when to use this tool ('Create a NEW selection') and when not to ('To edit the CURRENT selection ... use ps_modify_selection'). It also redirects deprecated grow/similar modes to ps_modify_selection and recommends verification via ps_get_selection_preview, ps_inspect, or ps_path, giving clear decision criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_select_by_referenceA
Select a region by NAME instead of coordinates — the natural-mask alternative to a rectangle — with a CONFIDENCE GATE. target=sky/ground/foliage/subject/face/shadows/highlights/skin/above_horizon resolves through the right Photoshop-native method (threshold for sky, invert-sky−subjects for ground, luminance for shadows/highlights, skin-tone colour ∩ the subject box, the detected face/subject box) and is SCORED before it is offered: a clean region is left selected; an unconfident one is NOT selected and reported as honest absence (the city with no real sky gets no sky). Pro adds precise FACE-FEATURE targets backed by the face mesh — face_skin (the retouch mask: face minus eyes/brows/lips), face_eyes, face_brows, face_lips, face_teeth (mouth opening), face_nose, face_under_eye, face_cheeks — each a real geometry-following selection, derived on first request and then saved as a scene:face_* channel so repeats load instantly. passed/confidence are returned. A region derived here is cached as a scene:* channel keyed by TARGET ONLY, so a later call for the same target loads it by name; pass refresh:true to force a fresh derive after an edit that changes what the region means, and note that narrowing a call with label/instance/composition_context always derives (it neither reads nor writes that shared channel). The structural floor (coherence, horizon alignment) is never tuned; for an artistic/non-standard shot pass composition_context (e.g. profile:big_sky) to relax the compositional priors so a legitimately large sky is not rejected. For target=subject with several present, pass label and/or instance. Build/inspect with ps_read_scene first; verify with ps_get_selection_preview (the red-overlay is the human/agent oversight view). Prefer this over a rectangle for any real-world region.
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | For target=subject only: a COCO class ('person', 'dog', 'car', …) to pick instead of the largest subject. Ignored for other targets. | |
| target | Yes | What to select by NAME (no coordinates): 'sky' (threshold white split), 'above_horizon' (everything above the horizon line), 'ground' / 'foliage' (posterize-region blob), 'subject' (the main detected object's region — use `label`/`instance` to target one of several), 'face' (the primary detected face), 'shadows' / 'highlights' (luminance bands), 'skin' (skin-tone colour range). Resolves to a real pixel selection on the original — prefer this over a rectangle for any natural region. | |
| refresh | No | Force a fresh perception pass before resolving (default false uses the cached scene model for the current document state). | |
| instance | No | For target=subject only: 0-based index counting left-to-right among matching subjects (0 = leftmost). Omit to pick the main/largest. | |
| max_dimension | No | Long-edge px of the perception export when a fresh pass runs. | |
| composition_context | No | Optional: tune the confidence gate from what you SEE in the preview, so an artistic shot is not rejected for breaking norms. The structural floor (coherence / horizon alignment) is never tuned; only the compositional priors are. `profile` is the easy knob: big_sky / minimal allow a large sky; big_foreground expects little sky; balanced (default) / tight_subject use defaults. Explicit overrides (`sky_coverage_max`, `pass_threshold`) win. |
Output Schema
| Name | Required | Description |
|---|---|---|
| op | No | |
| doc | No | |
| detail | No | |
| method | No | |
| passed | No | |
| target | No | |
| reasons | No | |
| confidence | No | |
| selection_info | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
This is exceptionally transparent: it discloses the confidence gate, that unconfident regions are not selected and reported as absence, that results are cached as scene:* channels, that refresh forces a fresh derive, and that narrowing calls always derive. Given annotations carry almost no behavioral detail, the description fully carries that burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and front-loaded with the core concept, and nearly every clause adds functional information. However, it is quite long and includes rhetorical flourishes like 'honest absence' and 'the city with no real sky gets no sky' that could be trimmed without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 6 parameters, nested objects, and an output schema, the description is effectively complete. It covers invocation workflow, confidence behavior, caching side effects, Pro-specific targets, composition tuning, and return fields, so an agent has enough context to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema description coverage is 100%, the tool description adds substantial meaning: per-target resolution methods, the meaning of label/instance for subject selection, the behavior of refresh, and the semantics of composition_context profiles. This makes the target enum actionable beyond its raw schema values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool selects a region by NAME rather than coordinates, with a confidence gate, and identifies itself as the natural-mask alternative to a rectangle. However, it does not explicitly distinguish itself from sibling selection tools like ps_select_sky, ps_select_subject, or ps_select_focus_area, so an agent may not know at a glance which selection tool to prefer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance: build/inspect with ps_read_scene first, verify with ps_get_selection_preview, and prefer this over a rectangle for real-world regions. It also provides targeted conditions for when to pass label/instance and when to relax compositional priors via composition_context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_selection_channelA
Persist, restore, or manage a named Alpha channel — choose with op. save: store the current selection to channel_name (overwrites if it exists) so a complex AI/multi-step/feathered selection can be reloaded without rebuilding (throws if no active selection). load: restore a saved channel as the selection, with operation (replace|add|subtract|intersect) to combine — reapply one selection across layers. duplicate: copy an existing alpha/spot channel to a new one (optional new_channel_name). delete: remove an alpha/spot channel (won't touch the RGB/CMYK/Lab component channels).
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | save: store the current selection to a named Alpha channel (channel_name; overwrites if it exists). load: restore a saved Alpha channel as the selection (channel_name + operation to combine). duplicate: copy an existing alpha/spot channel (channel_name) to a new channel (optional new_channel_name; auto-named "<src> copy" otherwise). delete: remove an alpha/spot channel (channel_name). Refuses to delete component RGB/CMYK/Lab channels. | |
| operation | No | How this selection combines with any existing one. 'replace' (default) overwrites; 'add' unions with the existing selection; 'subtract' removes this from the existing; 'intersect' keeps only the overlap. | replace |
| channel_name | Yes | Name of the Alpha channel to restore. Must have been previously saved with ps_selection_channel (op=save). | |
| new_channel_name | No | duplicate only: name for the new channel. Optional — Photoshop auto-names it "<source> copy" when omitted. |
Output Schema
| Name | Required | Description |
|---|---|---|
| saved | No | |
| loaded | No | |
| deleted | No | |
| operation | No | |
| duplicated | No | |
| overwritten | No | True if an existing channel with the same name was replaced. |
| channel_name | No | |
| channel_count | No | Total channels in the document after the op. |
| selection_info | No | Rich post-op stats. Use these to verify the selection actually grabbed what was intended before committing it to a mask. `has_selection:false` short-circuits the rest of the fields (they will be absent). |
| new_channel_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only carry idempotentHint=false, so the description carries the behavioral burden. It discloses critical side effects: overwrites on save, throws if no active selection, delete refuses RGB/CMYK/Lab channels, and duplicate auto-names. This goes well beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact but dense, using a semicolon-separated structure for the four ops. It front-loads the overall purpose and then details each operation without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's non-trivial complexity (4 ops, 4 params), the description addresses all aspects: operation behaviors, parameter combinations, edge cases, and safety guardrails. The output schema exists so return values need not be described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with rich descriptions, so baseline is 3. The description adds contextual meaning such as the exception on save and the auto-naming fallback for duplicate, enriching param understanding beyond schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb phrase 'Persist, restore, or manage a named Alpha channel' and enumerates four operations (save/load/duplicate/delete) with clear behavior. It is clearly distinct from sibling selection tools like ps_select which handle primary selections rather than saved channels.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Each operation includes a use case: save for complex selections needing reload, load to reapply across layers, duplicate/delete for channel management. While it doesn't explicitly name sibling alternatives, the specialized domain and per-op guidance make appropriate usage clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_select_layerAIdempotent
Make a layer active by name. Recurses into groups; if a name appears more than once, picks the first match in stack order (top-to-bottom). Throws if no layer by that name exists. Foundational for multi-layer workflows — use after ps_duplicate_layer or ps_add_adjustment_layer when you need to focus a specific layer before applying further operations.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Name of the layer to make active. Recurses into groups; matches the first layer in stack order (top-to-bottom). Throws if no layer by that name exists. |
Output Schema
| Name | Required | Description |
|---|---|---|
| kind | No | |
| name | No | |
| context | No | |
| selected | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses multiple behavioral traits beyond the idempotentHint annotation: recurses into groups, picks first match in stack order (top-to-bottom), and throws if no layer exists. This is rich detail about selection rules and error behavior, which is especially valuable given minimal annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: purpose, behavior, and usage guidance. Front-loaded with the core action, no filler or redundant phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with an output schema, the description covers the essential aspects: what it does, how it resolves duplicate names, error behavior, and typical usage context. No significant gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description covers the name parameter fully (100% coverage), including recursion, stack order, and error behavior. The tool description repeats this information without adding new parameter-specific meaning, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific action 'Make a layer active by name' with clear resource (layer). It also differentiates from siblings like ps_set_layer by focusing on selection/activation, and includes behavior details that make the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage context: 'use after ps_duplicate_layer or ps_add_adjustment_layer when you need to focus a specific layer before applying further operations.' This gives clear when-to-use guidance but does not contrast with alternative tools or mention when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_select_skyAIdempotent
Run Photoshop's "Select Sky" (Adobe Sensei, PS 2021+). One-call sky masking for landscape work. Default sample_all_layers=true analyzes the full visible composite. Returns selection_info — high edge_complexity on tricky horizons (foreground objects against sky) is the signal to verify with ps_get_selection_preview before committing.
| Name | Required | Description | Default |
|---|---|---|---|
| selection_type | No | How this selection combines with any existing one. 'replace' (default) overwrites; 'add' unions with the existing selection; 'subtract' removes this from the existing; 'intersect' keeps only the overlap. | replace |
| sample_all_layers | No | If true (default), the sky model considers all visible layers — the correct setting for most workflows. If false, considers only the active layer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| method | No | |
| selected | No | |
| strategy_used | No | "dom:selectSky" (preferred DOM method when exposed) or "executeAction:selectSky" (AM fallback). |
| selection_info | No | Rich post-op stats. Use these to verify the selection actually grabbed what was intended before committing it to a mask. `has_selection:false` short-circuits the rest of the fields (they will be absent). |
| selection_type | No | |
| sample_all_layers | No | |
| active_layer_temporarily_changed | No | True if active layer was temporarily switched to the bottom layer during detection. Restored before return. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide idempotentHint, so the description carries the transparency burden. It adds valuable behavioral details: Adobe Sensei dependency, PS 2021+ version requirement, default sample_all_layers behavior, and the edge_complexity signal that warrants verification. This goes well beyond the minimal annotation and does not contradict it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and each sentence contributes information. However, it is slightly longer than necessary (4 sentences) and repeats the sample_all_layers default already in the schema. It is efficient but not as lean as the top-tier examples.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema (which explains return values) and fully documented parameters, the description adds useful context about the AI nature, version prerequisite, and practical verification workflow. It is complete enough for an agent to invoke correctly and know when to double-check results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers 100% of parameter descriptions, so the baseline is 3. The description reinforces the default for sample_all_layers but adds little beyond what the schema already states. No additional meaning is provided for selection_type.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action ('Run Photoshop's "Select Sky"') and the resource (Adobe Sensei-based sky masking). It distinguishes itself from sibling selection tools like ps_select_subject and ps_select by naming the exact feature and use case ('One-call sky masking for landscape work').
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context for when to use ('landscape work') and mentions a verification step with ps_get_selection_preview. It does not explicitly exclude alternative selection tools, but the mention of the preview tool and the sky-specific purpose gives adequate guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_select_subjectAIdempotent
Run Photoshop's "Select Subject" (Adobe Sensei). One-call selection of the main subject — person, animal, product, etc. ~2-5s on typical images. Default sample_all_layers=true analyzes the full visible composite, which matches PS 2025 behavior and works around the PS 2026 "active layer only" default that fails opaquely when the active layer is a blurred / adjusted copy. Combines with existing selection via selection_type. Returns selection_info so the agent can verify area / edge complexity; if results look off, call ps_get_selection_preview for a visual. On failure, the error message lists fallbacks (Cloud processing in PS Preferences, manual UI selection).
| Name | Required | Description | Default |
|---|---|---|---|
| selection_type | No | How this selection combines with any existing one. 'replace' (default) overwrites; 'add' unions with the existing selection; 'subtract' removes this from the existing; 'intersect' keeps only the overlap. | replace |
| sample_all_layers | No | If true (default), the model considers all visible layers — matches PS 2025 behavior and the user mental model of "select the subject of this image." If false, considers only the active layer (PS 2026 menu default — but on processed/blurred active layers this often yields "no subject" and an opaque "parameters not valid" error). Override to false only when you specifically want layer-isolated detection. |
Output Schema
| Name | Required | Description |
|---|---|---|
| method | No | |
| selected | No | |
| strategy_used | No | "dom:selectSubject" (preferred — DOM method, PS handles descriptor internals) or "executeAction:autoCutout" (legacy AM fallback). Telemetry surface: lets us see in the field whether the DOM path needs widening. |
| selection_info | No | Rich post-op stats. Use these to verify the selection actually grabbed what was intended before committing it to a mask. `has_selection:false` short-circuits the rest of the fields (they will be absent). |
| selection_type | No | |
| sample_all_layers | No | |
| active_layer_temporarily_changed | No | True if we temporarily switched the active layer to the bottom layer during detection (to work around PS 2026 "active layer only" behavior when sample_all_layers=true). Original active layer is restored before return. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only idempotentHint in annotations, the description carries a heavy burden and excels. It discloses performance (~2-5s), the default behavior of sample_all_layers and its role in avoiding a PS 2026 pitfall, the selection combination behavior, the output (selection_info for verification), and failure fallbacks. This is rich, actionable behavioral context beyond any structured hint. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and each of the seven sentences provides distinct value: purpose, output, performance, parameter rationale, combination semantics, verification alternative, and failure behavior. It is longer than minimal but justified given the PS 2026 nuance. It earns a 4; slightly dense but every part contributes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description is remarkably complete. It covers what the tool does, key parameters and their nuanced defaults, expected performance, return value (selection_info), an alternative when results are questionable, and fallback options on failure. Since an output schema exists, the description need not repeat return structure. No significant gap remains for an agent to misuse the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the schema already documents both parameters well. The description adds meaningful extra meaning for sample_all_layers by explaining why the default is true (matches PS 2025, works around PS 2026's opaque failure on blurred layers) and when to override it. For selection_type, it merely says 'combines with existing selection' which adds little beyond the schema, but the sample_all_layers context lifts the score above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: "Run Photoshop's 'Select Subject' (Adobe Sensei)." It clearly identifies the tool as one-call selection of the main subject (person, animal, product, etc.) and distinguishes it from siblings like ps_select_sky. The purpose is unmistakable and immediately front-loaded.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: it explains when to use the tool (one-call selection of the main subject), when to override the default sample_all_layers (when layer-isolated detection is needed), and it names an alternative for verification (ps_get_selection_preview if results look off). However, it does not explicitly contrast with siblings like ps_select or ps_select_sky, and exclusions are implicit rather than stated. That keeps it at a strong 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_sequenceADestructive
Run an ordered list of tool calls against the current document in ONE round trip. WHEN TO REACH FOR THIS: several dependent steps you already know you want (e.g. select → adjust → merge, or a repeated resize/export pass) where you do not need to look at the result between them — each step is dispatched the same way an ordinary call is and sees the document exactly as the previous step left it. Not for exploratory work: if the next step depends on inspecting this one first, call the tools individually instead. Every step must name a tool that already exists in this edition (ps_sequence cannot call itself). An inline preview (image content) returned by a step is dropped unless that step is the LAST one in the sequence, since previews are most of a result's bytes and the point of batching calls is to stop paying for them on every intermediate step. Each step keeps its own time limit, exactly as it would if you called it on its own. The sequence's overall budget only decides whether to START another step, so it never cuts one off mid-run — a call can therefore finish after that ceiling by however long the in-flight step still needs, plus the undo and its verification reads when on_error='rollback'. With return='full', every step's complete result (not just the last one's) lands in the logged call payload.
| Name | Required | Description | Default |
|---|---|---|---|
| steps | Yes | Ordered list of tool calls to run against the current document, 1 to 25 items. | |
| return | No | summary: one line per step plus the LAST step's full result. full: every step's full result — note this means every embedded payload (not just the last step's) lands in the logged call record. Either way, an inline preview (image content) is stripped from every step except the last — previews are most of a result's bytes, and a sequence exists to stop paying for them on intermediate steps. | summary |
| on_error | No | stop: halt at the first failing step and return results so far. continue: record the failure and run every remaining step anyway. rollback: on the first failing step, undo back to the history state captured before step one and VERIFY the document actually landed there (index, state name, and active document all re-checked) before reporting success — refused at VALIDATION time (before any step runs) if any step names one of: ps_open_document, ps_create_document, ps_close_document, ps_save_psd, ps_export, ps_document, ps_undo, ps_redo, since those sit outside what the history cursor can undo. Assumes nothing else edits the document while the sequence runs; a manual edit interleaved between steps corrupts the undo distance rollback computes. | stop |
Output Schema
| Name | Required | Description |
|---|---|---|
| final | No | The last step's full CallToolResult (summary mode only). |
| steps | Yes | One entry per step run — carries `text` in summary mode, `result` in full mode. |
| return | Yes | |
| on_error | Yes | |
| ran_steps | Yes | How many steps actually ran — excludes a step skipped by the time budget. |
| failed_step | No | The first failing step, or the step skipped by the overall time budget. Null when every step succeeded. |
| rolled_back | No | |
| total_steps | Yes | |
| cap_exceeded | No | |
| rollback_reason | No | Set only when on_error="rollback" and rolled_back is false: history_evicted, undo_failed, cursor_moved_backward, or document_changed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide destructiveHint/idempotentHint, so the description carries the load. It discloses preview dropping for non-last steps, per-step time limits, the overall budget's role in only starting steps, rollback verification, and the payload implications of return='full' — all behavior beyond the annotations. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a one-sentence purpose and a labeled WHEN TO REACH section, and the detailed tail is warranted by the tool's complexity. It is not a 5 because some preview and return='full' content is repeated verbatim from the schema's parameter descriptions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter meta-tool, this covers invocation shape, eligibility constraints, sequencing semantics, failure modes, preview behavior, time budgets, rollback caveats, and payload effects. There is no material gap an agent would need to guess about.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaningful semantics: each step sees the document exactly as the previous step left it, steps must name existing tools, and the overall budget only decides whether to start another step. It loses a point because much of the return/on_error guidance duplicates the schema's own parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'Run an ordered list of tool calls against the current document in ONE round trip.' It clearly distinguishes itself from the individual ps_* sibling tools by framing itself as a batching/sequencing tool, and it adds a hard boundary with 'ps_sequence cannot call itself.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'WHEN TO REACH FOR THIS' section gives concrete use cases (select → adjust → merge, repeated resize/export) and an explicit exclusion: 'Not for exploratory work... call the tools individually instead.' This tells an agent exactly when to choose sequencing over direct sibling calls.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_set_layerAIdempotent
Set a property of the active layer — chosen via property. Idempotent absolute setters; do not change which layer is active. opacity: pass opacity (whole layer incl. styles) and/or fill_percent (pixels only — Photoshop's separate "Fill" slider, for Hard Mix / stroke-only effects). blend_mode: how the layer composites below (NORMAL to reset). visibility: show/hide via visible. locked: allLocked via locked. name: rename via name. Returns context so the LLM keeps state awareness.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | New name for the active layer. | |
| locked | No | Whether the layer should be fully locked (allLocked). | |
| opacity | No | Layer opacity (0-100) — affects the whole layer including its styles. | |
| visible | No | Whether the layer should be visible. | |
| property | Yes | Which property to set on the active layer (idempotent absolute setters; do not change which layer is active). opacity: opacity (whole layer incl. styles) and/or fill_percent (pixels only — the Fill slider). blend_mode: how the layer composites. visibility: visible (show/hide). locked: locked (allLocked). name: rename. | |
| blend_mode | No | Blend mode name (Photoshop ExtendScript BlendMode enum). Use COLORBLEND for the "Color" mode — Photoshop reserves the bare "COLOR" name for the SolidColor class. | |
| fill_percent | No | Fill opacity (0-100) — the "Fill" slider. Affects the layer's pixels/fill but NOT its layer styles. Distinct from opacity; used for Hard Mix and stroke-only tricks. Pass opacity and/or fill_percent. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | |
| value | No | |
| locked | No | |
| context | No | |
| newName | No | |
| oldName | No | |
| opacity | No | |
| visible | No | |
| property | No | |
| verified | No | |
| layerName | No | |
| requested | No | |
| fill_opacity | No | |
| opacity_verified | No | |
| requested_opacity | No | |
| fill_opacity_verified | No | |
| requested_fill_opacity | No | |
| verification_unreadable | No | visibility only: true when the write itself did not throw but the own-flag verification read failed (Action Manager error, or the layer had no readable id) — verified is false, but this is NOT proof the write failed, just that it could not be confirmed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the idempotentHint annotation, the description adds behavioral details: idempotent absolute setters, no active layer change, and returns context for state awareness. It also clarifies the semantic difference between opacity and fill_percent, which is not captured in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured, using backtick formatting and per-property explanations. Every sentence contributes necessary information without redundancy, making it easy to scan and parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 7 parameters and complex interactions (opacity vs fill_percent, blend_mode enum nuances), the description covers all properties and their effects. The sibling set of tools and output schema further complete the picture, so an agent has sufficient information to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema fully documents parameters (100% coverage), but the description adds critical semantics: opacity affects the whole layer including styles, fill_percent affects pixels only, and blend_mode composites below with NORMAL to reset. These nuances go beyond the schema's field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Set a property of the active layer — chosen via property' and enumerates the properties (opacity, blend_mode, visibility, locked, name). This is a specific verb+resource that distinguishes it from sibling tools like ps_set_group_blend_mode and ps_set_text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear context on when to use the tool for layer property changes, including nuanced guidance like fill_percent for hard mix or stroke-only effects. It explicitly notes it does not change the active layer, useful for sequencing. However, it does not mention exclusions or alternatives directly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_shapeA
Draw a vector SHAPE layer — rectangle (optionally rounded via corner_radius), ellipse, or line — filled with a solid color, optionally stroked. Hoisted out of the active layer's group by default even though the underlying Mk-contentLayer descriptor carries no placement target and would otherwise nest the new layer INSIDE that group (pass into_active_group:true to keep that native nesting). Aim it EITHER by anchor-relational placement (preferred: name anchors + a relation and the resolver computes the geometry, verified by an objective gate — no pixel-guessing; rectangle/ellipse ← a region relation, line ← a path relation) OR by ABSOLUTE document pixels (top-left origin: rectangle/ellipse take left/top/right/bottom; line takes start_x/start_y → end_x/end_y plus weight — you must know the pixel positions, so prefer the anchor-relational placement path above and verify the result with a preview). Creates a new vector layer (non-destructive — delete it to remove). (AM-only; verified live on PS 27.2.0.)
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | rectangle/ellipse: bounding-box top edge, document px. | |
| left | No | rectangle/ellipse: bounding-box left edge, document px. | |
| type | Yes | rectangle: a box (left/top/right/bottom; corner_radius>0 rounds the corners). ellipse: an oval in the left/top/right/bottom bounding box. line: a straight line from (start_x,start_y) to (end_x,end_y) with `weight` thickness. | |
| end_x | No | line: end point X, document px. | |
| end_y | No | line: end point Y, document px. | |
| right | No | rectangle/ellipse: bounding-box right edge, document px. | |
| bottom | No | rectangle/ellipse: bounding-box bottom edge, document px. | |
| weight | No | line only: line thickness in px. Default 4. | |
| start_x | No | line: start point X, document px. | |
| start_y | No | line: start point Y, document px. | |
| placement | No | ANCHOR-RELATIONAL placement (preferred over guessing pixels): rectangle/ellipse ← a region relation (inside/gap) → the resolved region bounding box; line ← a path relation (along/offset-curve over a traced edge or a Pro face-mesh landmark curve) → a straight line between the resolved curve endpoints. The shape is created ONLY if the gate PASSES (otherwise an error and no layer). When set, left/top/right/bottom and start_x/start_y/end_x/end_y are ignored, but styling (fill_color/stroke/weight/corner_radius) still applies. See the placement-resolver tool, when this build has one, for the anchors + relation vocabulary. | |
| fill_color | No | Fill color (the line color for type=line). RGB 0-255. Default black. | |
| stroke_color | No | rectangle/ellipse stroke color when stroke_width>0. RGB 0-255. Default black. | |
| stroke_width | No | rectangle/ellipse: outline width in px. 0 (default) = no stroke (fill only). Ignored for line (use weight). | |
| corner_radius | No | rectangle only: corner radius in px. 0 (default) = sharp corners; >0 = rounded. | |
| into_active_group | No | Photoshop's Mk-contentLayer descriptor carries no placement target, so with a GROUP active it would natively nest the new shape layer INSIDE that group. Default false hoists the new layer back out so it lands above the active layer/group as a sibling. Pass true to keep it nested inside the active group instead. |
Output Schema
| Name | Required | Description |
|---|---|---|
| context | No | |
| hoisted | No | True when the new layer had to be moved back out of the previously-active group to honor into_active_group:false (the default). False when it landed correctly on its own, or when the move-back itself failed — check the layer tree if this matters and hoisted is false. |
| stroked | No | |
| placement | No | Present when anchor-relational placement was used: the resolved geometry + gate verdict. |
| layer_name | No | |
| shape_type | No | |
| parent_path | No | The containing-group name chain (outermost first), empty array at the document root. |
| shape_created | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations carrying only idempotentHint:false, the description carries the behavioral burden and does so thoroughly: it creates a new non-destructive layer, delete removes it, it hoists out of the active group by default, uses an objective placement gate that errors without creating if the gate fails, and is AM-only/version-verified. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but information-dense, with the core purpose front-loaded and the two aiming modes, group behavior, and destructiveness guidance each earning their place. For a tool with 16 parameters and two mutually exclusive coordinate modes, the length is proportionate and contains no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity, the fully-described schema, and the presence of an output schema, the description covers everything an agent needs: layer creation, group-nesting behavior, coordinate mode selection, placement gate behavior, styling application, and removal. No material gap remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents most parameter meanings, but the description adds valuable semantics beyond it: the top-left coordinate convention, which coordinate sets apply to rectangle/ellipse vs line, and the interaction that placement overrides absolute coordinates while styling still applies. This lifts it above the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Draw a vector SHAPE layer' with the supported types rectangle/ellipse/line and styling. It clearly describes what it creates, but it does not explicitly name or contrast sibling tools such as ps_vector_mask, ps_path, or ps_create_layer, so it stops short of full sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear within-tool usage guidance: anchor-relational placement is preferred over absolute pixels, and the default group-hoisting behavior is explained with into_active_group:true as the escape hatch. It does not explicitly state when to use ps_shape instead of sibling tools or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_textA
Text layer — create it or style it, chosen with op. create: a new text layer with text at x/y and font_size. set_content/set_font/set_color/set_alignment act on the currently active text layer (throws if it isn't one). Font names accept either the PostScript name ("ArialMT") or family name ("Arial", resolved to its Regular/first variant); throws clearly if no installed font matches. The set_* ops are idempotent.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | X position in pixels (default 100). Bounded at ±300,000 px. | |
| y | No | Y position in pixels (default 100). Bounded at ±300,000 px. | |
| op | Yes | create: new text layer with `text` at `x`/`y` (default 100,100) and `font_size` (default 24). set_content: replace the active text layer's content with `text`. set_font: set the active text layer's font to `font_name` (optionally `font_size`). set_color: set the active text layer's color to `red`/`green`/`blue`. set_alignment: set the active text layer's `alignment`. | |
| red | No | Red component (0-255). | |
| blue | No | Blue component (0-255). | |
| text | No | create: initial text content. set_content: new text content, replacing the existing text. | |
| green | No | Green component (0-255). | |
| alignment | No | Text alignment. | |
| font_name | No | Font family name (e.g., "Arial", "Helvetica"). | |
| font_size | No | Font size in points, up to 1296 — Photoshop's own ceiling for the Character panel. create: initial size (default 24). set_font: new size (optional — omit to leave the current size unchanged). |
Output Schema
| Name | Required | Description |
|---|---|---|
| font | No | op=set_font: the font actually matched. |
| size | No | op=set_font: the size applied, if given. |
| text | No | op=create/set_content: the text content. |
| color | No | op=set_color: the RGB() string applied. |
| context | No | |
| created | No | op=create: true on success. |
| fontSize | No | op=create: the size applied. |
| position | No | op=create: {x, y}. |
| alignment | No | op=set_alignment: the alignment applied. |
| layerName | No | op=create: the new layer name. |
| requested | No | op=set_font: the font requested. |
| matched_by | No | op=set_font: how `font_name` was resolved. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations are minimal, so the description carries the burden here. It adds valuable behavioral details beyond the schema: set_* operations require an active text layer and throw otherwise, font names accept both PostScript and family names with a documented resolution rule, failures throw clearly, and set_* are idempotent. This does not contradict idempotentHint=false because create (the operation-level default) is not idempotent even though the set_* sub-operations are.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, with the core purpose front-loaded and each sub-operation explained in one enumerative phrase. Examples like 'ArialMT' and 'Arial' are helpful without bloating the text, though a small bolding structure could improve parseability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a multi-op dispatcher with 10 parameters and 5 sub-operations, the description covers operation modes, activation requirements, parameter behavior, and failure cases. Since an output schema exists, it does not need to redundantly describe returns. Some document-level prerequisites are left implicit, but those are shared across the sibling ps_* tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema itself documents the majority of parameters. The description contributes real extra meaning, especially for font_name (PostScript vs family resolution), the throwing behavior when no installed font matches, and which parameter groups apply to which sub-operation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description immediately says 'Text layer — create it or style it, chosen with `op`' and then enumerates the create and set_* sub-operations. This is a clear verb, resource, and mode, though it never explicitly names sibling tools to say what ps_text is not.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete per-op usage guidance: use 'create' for a new text layer and use set_* operations on the currently active text layer, including the error condition that the active layer must be a text layer. It does not contrast ps_text with sibling tools, so it stops short of explicit when-not alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_transform_canvasA
Transform the whole document (canvas + all layers), not a single layer — choose with op. rotate spins the canvas by degrees (+cw; pass 90/180/-90 for quarter/half turns). flip mirrors the canvas horizontal|vertical. For rotating/flipping ONE layer use ps_transform_layer instead.
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | Which document-level transform to apply. rotate: spin the whole canvas by degrees (+cw; 90/180/-90 for quarter/half turns). flip: mirror the whole canvas horizontal|vertical. | |
| degrees | No | Rotation angle in degrees, positive = clockwise. Any value (incl. 90 / 180 / -90 for quarter/half turns). | |
| orientation | No | 'horizontal' mirrors the canvas left-right; 'vertical' mirrors top-bottom. |
Output Schema
| Name | Required | Description |
|---|---|---|
| axis | No | |
| degrees | No | |
| flipped_canvas | No | |
| rotated_canvas | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that the operation applies to the whole document rather than a single layer, and details the rotate/flip behaviors. However, with annotations lacking readOnlyHint/destructiveHint, the description doesn't address reversibility or side effects beyond what the schema already says. It adds some scope context but not safety/disclosure beyond that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with purpose, then op details, then alternative. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 100% schema coverage and output schema, the description is sufficient: it clarifies the document-level scope and points to the layer-level alternative. It doesn't need to explain return values because output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with each parameter described in detail. The description repeats the op behavior but doesn't add new meaning beyond the schema, so baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Transform the whole document (canvas + all layers), not a single layer' with a specific verb and resource, and explicitly distinguishes from ps_transform_layer. This leaves no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'For rotating/flipping ONE layer use ps_transform_layer instead,' providing a when-not-to-use and an alternative. It also implies when to use: when transforming the entire document via rotate/flip.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_transform_layerA
Transform the active layer — choose the operation with op. fit scales to fit (letterbox) or fill (crop) the canvas and centers (idempotent). scale does uniform (scale_percent) or non-uniform stretch/squash (scale_x_percent/scale_y_percent) — multiplicative, not idempotent. move translates via exactly one of delta (relative), absolute (top-left target), center_on (center target — best for "place inside the frame opening"), or an anchor-relational placement (preferred: a point relation → the layer center moves to the resolved, gate-verified point); mixing the raw modes errors. rotate rotates by relative degrees around center. flip mirrors horizontal/vertical. skew slants the layer (skew_h_degrees/skew_v_degrees). free is a numeric free-transform (scale + degrees + offset). scale/move/rotate/flip/skew/free auto-promote the background layer (background_promoted=true).
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | Which transform to apply to the active layer. fit: scale to fit/fill the canvas + center (mode fit|fill). scale: uniform scale_percent OR non-uniform scale_x_percent/scale_y_percent (center_anchor). move: translate — pass exactly ONE pair: delta_x+delta_y (relative), absolute_x+absolute_y (top-left), or center_on_x+center_on_y (center). rotate: degrees (relative, +cw). flip: axis horizontal|vertical. skew: slant via skew_h_degrees/skew_v_degrees (+ optional scale_x_percent/scale_y_percent, degrees, offset_x/offset_y). free: numeric free-transform — scale_x_percent/scale_y_percent + degrees + offset_x/offset_y. scale/move/rotate/flip/skew/free auto-promote the background layer (background_promoted in the result). | |
| axis | No | 'horizontal' mirrors left-right; 'vertical' mirrors top-bottom. | |
| mode | No | `fit` (default) scales the layer to fit inside the canvas while preserving aspect — letterboxes on the short edge. `fill` covers the entire canvas — crops on the long edge. Both preserve aspect ratio and center the layer. | fit |
| degrees | No | Rotation angle in degrees (positive = clockwise, negative = counter-clockwise). | |
| delta_x | No | RELATIVE mode: horizontal pixel offset from the layer's current position. Pair with delta_y. Mutually exclusive with absolute_*/center_on_*. | |
| delta_y | No | RELATIVE mode: vertical pixel offset from the layer's current position. Pair with delta_x. | |
| offset_x | No | op=skew/free: horizontal translation in pixels (default 0). | |
| offset_y | No | op=skew/free: vertical translation in pixels (default 0). | |
| placement | No | ANCHOR-RELATIONAL move (preferred over guessing a pixel): a POINT relation (centroid/midpoint/offset) → the layer's CENTER is moved to the resolved, gate-verified point (e.g. "center this layer on the detected subject" / "…in the gap between the two people"). Moves ONLY if the gate PASSES. When set, delta_*/absolute_*/center_on_* are ignored. See the placement-resolver tool, when this build has one, for the anchors + relation vocabulary. | |
| absolute_x | No | ABSOLUTE mode: target X for the layer's bounds top-left corner, in document pixels. Pair with absolute_y. Use when you know exactly where the top-left should land. Mutually exclusive with delta_* / center_on_*. | |
| absolute_y | No | ABSOLUTE mode: target Y for the layer's bounds top-left corner, in document pixels. Pair with absolute_x. | |
| center_on_x | No | CENTER mode: target X for the layer's bounds CENTER point, in document pixels. Pair with center_on_y. Use when placing a layer inside a known region (e.g. a frame opening). Mutually exclusive with delta_* / absolute_*. | |
| center_on_y | No | CENTER mode: target Y for the layer's bounds CENTER point, in document pixels. Pair with center_on_x. | |
| center_anchor | No | Scale from center (true) or top-left (false). Default: true. | |
| scale_percent | No | Uniform scale percentage (e.g. 50 = 50%, 200 = 200%). Use for proportional scaling. | |
| skew_h_degrees | No | op=skew: horizontal skew (slant) angle in degrees — positive slants the top edge right. At least one of skew_h_degrees / skew_v_degrees is required for op=skew. | |
| skew_v_degrees | No | op=skew: vertical skew (slant) angle in degrees — positive slants the left edge down. | |
| scale_x_percent | No | Non-uniform: horizontal scale percentage. Pair with scale_y_percent to stretch/squash (the #1 pixel-stretch effect). If only one axis is given the other defaults to 100%. | |
| scale_y_percent | No | Non-uniform: vertical scale percentage. Pair with scale_x_percent. |
Output Schema
| Name | Required | Description |
|---|---|---|
| axis | No | |
| mode | No | |
| moved | No | |
| fitted | No | |
| scaled | No | |
| context | No | |
| degrees | No | |
| flipped | No | |
| newSize | No | |
| percent | No | |
| rotated | No | |
| placement | No | Present when op=move used anchor-relational placement: the resolved point + gate verdict. |
| new_bounds | No | |
| scaleFactor | No | |
| transformed | No | |
| originalSize | No | |
| scalePercent | No | |
| rotate_degrees | No | |
| skew_h_degrees | No | |
| skew_v_degrees | No | |
| applied_delta_x | No | |
| applied_delta_y | No | |
| scale_x_percent | No | |
| scale_y_percent | No | |
| background_promoted | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide idempotentHint=false, so the description carries the behavioral burden. It discloses idempotency per operation, non-idempotent multiplicative scaling, automatic background-layer promotion, gate-verified placement that moves only on pass, and error conditions for mixing modes. This goes well beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence contributes operational meaning. It is front-loaded with the op list, then systematically expands each op without filler, which is appropriate for a tool with 19 parameters and 7 distinct operations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite the high complexity, the description covers every operation, parameter interactions, default behaviors, promotion side-effect, and gate semantics. An output schema exists, so return-value details are not required. An agent has enough information to call the tool correctly across all modes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with rich parameter descriptions, so the baseline is 3. The description adds meaningful cross-parameter semantics such as exclusivity of move modes, precedence of placement over delta_*/absolute_*/center_on_*, and the distinction between uniform and non-uniform scaling. This raises it above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Transform') and resource ('the active layer'), then enumerates the seven concrete operations via `op`. This clearly distinguishes it from sibling ps_transform_canvas, which operates on the canvas rather than a layer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear internal mode-selection guidance: placement is 'preferred', center_on is 'best for frame opening', and mixing raw move modes 'errors'. It does not explicitly route away from sibling tools like ps_move_layer_to_position, but it provides actionable context for choosing among this tool's own modes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_undoA
Step backward in the document history (equivalent to Ctrl/Cmd+Z). WHEN TO REACH FOR THIS: after an experimental destructive bake (ps_merge mode=visible/flatten, ps_filter op=apply type=*_blur/sharpen/noise) produced a wrong result; after a play_action whose scope you mispredicted; or to revert an entire branch of exploration. Non-destructive workflows (adjustment layers + masks) rarely need this — just tweak/delete the offending layer instead. Reversible via ps_redo as long as no new edit has been made since. Returns current history state, remaining steps, and document context.
| Name | Required | Description | Default |
|---|---|---|---|
| steps | No | Number of steps to undo (default: 1) |
Output Schema
| Name | Required | Description |
|---|---|---|
| steps | No | |
| redone | No | |
| undone | No | |
| context | No | |
| remainingStates | No | |
| availableRedoSteps | No | |
| currentHistoryState | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral detail beyond the annotations: it notes that undoing is reversible via ps_redo only under specific conditions, and states what the tool returns ('current history state, remaining steps, and document context'). It also subtly discloses that this is a state-changing operation in a history chain. The idempotentHint=false annotation aligns with this, with no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact yet information-dense, with a logical structure: first the core definition, then explicit scenarios, a rejection case, reversibility note, and return summary. Every sentence earns its place. The 'WHEN TO REACH FOR THIS:' label creates an easily scannable format that an AI agent can parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (1 optional parameter with a default, output schema present, sibling alternatives explicitly referenced), this description is fully complete. It answers the three key agent questions: what it does, when to invoke it, and what will happen (return values, reversibility limit). No further structural details are required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, steps, has full schema coverage (100%) with a clear description ('Number of steps to undo'). The description's phrase 'step backward in document history' semantically overlaps with the parameter meaning but does not add much new detail about steps' behavior (e.g., limits, interaction with remaining history). Therefore, the baseline 3 is appropriate — no extra parameter semantics beyond the schema are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb+resource statement: 'Step backward in the document history (equivalent to Ctrl/Cmd+Z).' This clearly differentiates it from sibling tools like ps_redo and ps_merge, especially with the explicit reversibility reference. The alternative 'just tweak/delete the offending layer instead' for non-destructive workflows also reinforces its unique role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
A dedicated 'WHEN TO REACH FOR THIS:' section lists concrete triggering scenarios (failed destructive bake, mispredicted play_action, reverting exploration) and explicitly states when not to use it (non-destructive workflows). It also names the recovery alternative ps_redo with the condition 'as long as no new edit has been made since,' which is exactly the kind of context an agent needs for correct routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ps_vector_maskADestructive
Attach, remove, (un)link, or (dis/en)able a layer VECTOR MASK — the path-driven, resolution-independent companion to a pixel layer mask. Ops: add (from the active path via source=from_current_path — the typical flow after ps_path op=create_from_selection / save — or an empty source=reveal_all/hide_all mask), delete, link, unlink, disable (turn the mask off without deleting it), enable (turn it back on). Reach for this when you want a crisp vector-edged mask rather than a painted pixel mask. add needs a non-background layer (and a path for from_current_path); the other ops need a layer that already has a vector mask. (Vector masks are AM-driven; verified live on PS 27.2.0.)
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | add: create a vector mask on the active layer — seeded from the active path (source=from_current_path, needs a path from ps_path) or as an empty reveal_all/hide_all mask (no path needed). delete: remove the active layer's vector mask. link: link the vector mask to the layer (they transform together). unlink: unlink the vector mask from the layer (transform independently). disable: turn the vector mask off (the layer renders unmasked) without deleting it. enable: turn a disabled vector mask back on. | |
| source | No | add only: what the vector mask is seeded from. 'from_current_path' = the active work/saved path (needs a path; the main consumer of ps_path). 'reveal_all' = an empty mask that reveals the whole layer. 'hide_all' = an empty mask that hides the whole layer (paint/draw paths to reveal). | from_current_path |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | No | |
| context | No | |
| layer_name | No | |
| vector_mask_added | No | |
| vector_mask_linked | No | |
| vector_mask_deleted | No | |
| vector_mask_enabled | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide destructiveHint=true and idempotentHint=false. The description adds substantial behavioral detail beyond these: delete removes the mask while disable only turns it off without deleting, enable turns it back on, and add requires a path for from_current_path. It also notes the tool is 'AM-driven and verified live on PS 27.2.0,' giving additional context about how it operates.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is information-dense but well-organized: it front-loads the verb+resource, enumerates ops with parenthetical explanations, uses bolded guidance ('Reach for this when'), and closes with preconditions and a version note. Every sentence earns its place; there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 ops, 2 params, preconditions), the description covers all op semantics, source variations, required layer state, typical workflows, and the alternative pixel mask tool. Since an output schema exists, the description does not need to detail return values. This is comprehensive for a multi-op tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even with 100% schema coverage, the description adds meaning beyond the enum definitions. It explains the 'typical flow after ps_path op=create_from_selection / save' for source=from_current_path, clarifies that 'the main consumer of ps_path', and ties the source values to concrete use cases (reveal_all vs hide_all). This connects the parameters to real workflows rather than just listing values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Attach, remove, (un)link, or (dis/en)able a layer VECTOR MASK' and immediately distinguishes it from a pixel layer mask with 'path-driven, resolution-independent companion.' This makes the tool's purpose unmistakable and clearly differentiates it from the sibling ps_layer_mask.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use this tool: 'Reach for this when you want a crisp vector-edged mask rather than a painted pixel mask.' It also gives the typical workflow ('the typical flow after ps_path op=create_from_selection / save') and specifies preconditions for each operation ('add needs a non-background layer', 'other ops need a layer that already has a vector mask'), which acts as when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v1.5.0- Changed
ps_open_document2 fields changed- added
Input schema / properties / bit_depthAdded value: +{ + "description": "Open-time bits per channel, RAW sources only. Set this here rather than converting later: ps_convert_image_mode FLATTENS the document, so depth cannot be changed once an edit stack exists. Prefer 16 for anything with heavy gradients (skies, skin, long tonal moves). Ignored for non-raw files, and the returned bits_per_channel always reports what was actually opened.", + "enum": [ + 8, + 16 + ], + "type": "number" +} - added
Output schema / properties / bit_depth_warningAdded value: +{ + "description": "Present only when a requested bit_depth was not what the document actually opened at — because the file is not a raw source, or Photoshop declined the requested depth. Absent means bits_per_channel is what you asked for.", + "type": "string" +}
7 tool updates
v1.4.0- Changed
ps_detect2 fields changed- changed
Input schema / properties / annotate / defaultPrevious value: -trueNew value: +false - changed
Input schema / properties / annotate / descriptionPrevious value: -"Return an annotated preview with the detected boxes drawn (faces cyan, objects magenta) so you can visually confirm the detections."New value: +"Also return an annotated preview JPEG with the detected boxes drawn (faces cyan, objects magenta). Default false: the labeled boxes returned by this call are already complete on their own — ask for the image only when you actually need to visually confirm a detection."
- Changed
ps_get_histogram1 field changed- changed
Input schema / properties / channel / descriptionPrevious value: -"Which channel to read. \"composite\" (default) is the visible flattened image; if the active layer is an adjustment/fill/shape layer the tool transparently switches to a pixel layer to read it. \"red\"/\"green\"/\"blue\" require an RGB doc; \"gray\" a grayscale doc. \"luminosity\" dispatches per doc mode — Lab uses the Lightness channel (exact), Grayscale uses Gray (exact), RGB synthesizes a Rec.709 weighted approximation from R+G+B (mean is exact; stdev/median are approximations). The result's `channel` field annotates which path landed when a fallback was used."New value: +"Which channel to read. \"composite\" (default) is the visible flattened image; if the active layer is an adjustment/fill/shape layer the tool transparently switches to a pixel layer to read it. \"red\"/\"green\"/\"blue\" require an RGB doc; \"gray\" a grayscale doc. \"luminosity\" dispatches per doc mode — Lab uses the Lightness channel (exact), Grayscale uses Gray (exact), and RGB reads the per-pixel luminance Photoshop reports, weighted 0.30/0.59/0.11, so its shape and any clipping or percentile read taken from it are sound. Note that weighting is not Rec.709, so a luminosity mean will not match one computed as 0.2126/0.7152/0.0722. A channel value naming a marginal mixture means the document histogram was unavailable and the read fell back to combining the channel histograms: that mean is still sound, its shape is not. The result's `channel` field annotates which path landed when a fallback was used."
- Changed
ps_get_selection_preview1 field changed- added
Input schema / properties / imageAdded value: +{ + "default": "overlay", + "description": "Which rendered image(s) to return inline. 'overlay' (default): a 50% red wash over the selected area (Quick Mask-style — most intuitive). 'mask': a B/W mask (black=selected, white=not) instead. 'both': the overlay followed by the mask, for when you need to compare them side by side. selection_info is returned regardless of this choice.", + "enum": [ + "overlay", + "mask", + "both" + ], + "type": "string" +}
- Changed
ps_read_scene2 fields changed- changed
Input schema / properties / annotate / defaultPrevious value: -trueNew value: +false - changed
Input schema / properties / annotate / descriptionPrevious value: -"Return an annotated preview with subject boxes (magenta), faces (cyan), and the horizon line (yellow) drawn so you can visually confirm the scene model."New value: +"Also return an annotated preview JPEG with subject boxes (magenta), faces (cyan), and the horizon line (yellow) drawn. Default false: the structured scene model returned by this call is already complete on its own — ask for the image only when you actually need to see the annotation drawn."
- Changed
ps_select10 fields changed- added
Input schema / properties / in_focus_radiusAdded value: +{ + "default": 4.07, + "description": "How much blur still counts as \"in focus\", in pixels. Higher pulls more of the soft transition zone into the selection; lower keeps only the crisply resolved plane. 4.07 is the Photoshop dialog default and a sane starting point. The useful band is narrow, and a radius well above the default selects the entire frame — so move in small steps and CHECK the returned area_percent and whole_canvas_selected: a selection covering essentially everything means the radius is too high and the result is worthless, even though the call reports success.", + "maximum": 15, + "minimum": 0.1, + "type": "number" +} - changed
Input schema / properties / mode / descriptionPrevious value: -"all: select the whole canvas. none: deselect. inverse: invert the current selection. rectangle: left/top/right/bottom (+optional feather_px). ellipse: left/top/right/bottom bounding box (+anti_alias, +optional feather_px) — circles/ovals. color_range: target red/green/blue (+fuzziness) — \"select all the red / skin\". luminance_range: luminance highlights|shadows|midtones (+fuzziness, lower_limit, upper_limit) — glow/dodge-burn foundation. magic_wand: click x/y (+tolerance, contiguous, anti_alias, sample_all_layers). grow: DEPRECATED here — use ps_modify_selection(op=grow) instead (kept for one release for backward compatibility, identical behaviour). Expands the CURRENT selection to adjacent similar-colour pixels (+tolerance, anti_alias). similar: DEPRECATED here — use ps_modify_selection(op=similar) instead (kept for one release for backward compatibility, identical behaviour). Expands the CURRENT selection to ALL similar-colour pixels document-wide (+tolerance, anti_alias). skin_tones: select skin-coloured pixels (+fuzziness; use_faces=true adds face-aware refinement). out_of_gamut: select colours outside the printable CMYK gamut (no params). polygon: points [{x,y},...] in ABSOLUTE document pixels (min 3, auto-closes) — covers polygonal/freehand lasso. Coordinate-driven: you must know the pixel positions (use ps_inspect / ps_get_preview to aim, or ps_path create_from_placement → load_as_selection for a grounded outline). rectangle/ellipse/magic_wand also take a grounded `placement` instead of raw coords (region → the bbox; point → the wand click). rectangle/ellipse/polygon/color_range/luminance_range/magic_wand/skin_tones/out_of_gamut also take selection_type to combine with an existing selection."New value: +"all: select the whole canvas. none: deselect. inverse: invert the current selection. rectangle: left/top/right/bottom (+optional feather_px). ellipse: left/top/right/bottom bounding box (+anti_alias, +optional feather_px) — circles/ovals. color_range: target red/green/blue (+fuzziness) — \"select all the red / skin\". luminance_range: luminance highlights|shadows|midtones (+fuzziness, lower_limit, upper_limit) — glow/dodge-burn foundation. magic_wand: click x/y (+tolerance, contiguous, anti_alias, sample_all_layers). grow: DEPRECATED here — use ps_modify_selection(op=grow) instead (kept for one release for backward compatibility, identical behaviour). Expands the CURRENT selection to adjacent similar-colour pixels (+tolerance, anti_alias). similar: DEPRECATED here — use ps_modify_selection(op=similar) instead (kept for one release for backward compatibility, identical behaviour). Expands the CURRENT selection to ALL similar-colour pixels document-wide (+tolerance, anti_alias). skin_tones: select skin-coloured pixels (+fuzziness; use_faces=true adds face-aware refinement). out_of_gamut: select colours outside the printable CMYK gamut (no params). polygon: points [{x,y},...] in ABSOLUTE document pixels (min 3, auto-closes) — covers polygonal/freehand lasso. Coordinate-driven: you must know the pixel positions (use ps_inspect / ps_get_preview to aim, or ps_path create_from_placement → load_as_selection for a grounded outline). focus_area: select what the lens rendered SHARP by depth of field, not by subject or colour (+in_focus_radius, soft_mask) — takes no coordinates; check whole_canvas_selected in the result before trusting it. rectangle/ellipse/magic_wand also take a grounded `placement` instead of raw coords (region → the bbox; point → the wand click). rectangle/ellipse/polygon/focus_area/color_range/luminance_range/magic_wand/skin_tones/out_of_gamut also take selection_type to combine with an existing selection." - changed
Input schema / properties / mode / enumPrevious value: -[ - "all", - "none", - "inverse", - "rectangle", - "ellipse", - "color_range", - "luminance_range", - "magic_wand", - "grow", - "similar", - "skin_tones", - "out_of_gamut", - "polygon" -]New value: +[ + "all", + "none", + "inverse", + "rectangle", + "ellipse", + "color_range", + "luminance_range", + "magic_wand", + "grow", + "similar", + "skin_tones", + "out_of_gamut", + "polygon", + "focus_area" +] - added
Input schema / properties / soft_maskAdded value: +{ + "default": false, + "description": "False (default) yields a hard-edged selection — every pixel fully in or fully out, which is what you want before ps_modify_selection feathering. True lets Photoshop feather the focus falloff itself, useful when the subject edge is genuinely gradual (hair, fur, motion).", + "type": "boolean" +} - added
Output schema / properties / active_layer_temporarily_changedAdded value: +{ + "description": "mode=focus_area: true if the active layer was not an ordinary pixel layer and detection was temporarily retargeted to the bottom layer. Restored before return.", + "type": "boolean" +} - added
Output schema / properties / in_focus_radiusAdded value: +{ + "description": "mode=focus_area: radius used.", + "type": "number" +} - added
Output schema / properties / soft_maskAdded value: +{ + "description": "mode=focus_area: soft_mask used.", + "type": "boolean" +} - added
Output schema / properties / strategy_usedAdded value: +{ + "description": "mode=focus_area: \"executeAction:focusMask\".", + "type": "string" +} - added
Output schema / properties / warningAdded value: +{ + "description": "mode=focus_area: set when whole_canvas_selected is true.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / whole_canvas_selectedAdded value: +{ + "description": "mode=focus_area: true when the RAW detection (before any selection_type combine) covered essentially the entire canvas — usually a non-result. selection_info reports the FINAL, post-combine selection and the two can legitimately disagree.", + "type": "boolean" +}
- Removed
ps_select_focus_area - Added
ps_sequence
11 tool updates
v1.3.0- Changed
ps_apply_brush_stroke4 fields changed- changed
Input schema / properties / placement / properties / anchors / descriptionPrevious value: -"Named anchors, same vocabulary as ps_resolve_placement (face/object/grid/extremum/corner/edge/landmark)."New value: +"Named anchors, same vocabulary as the placement-resolver tool, when this build has one (face/object/grid/extremum/corner/edge/landmark)." - changed
Input schema / properties / placement / properties / relation / descriptionPrevious value: -"The relation, same vocabulary as ps_resolve_placement."New value: +"The relation, same vocabulary as the placement-resolver tool, when this build has one." - changed
Input schema / properties / source_placement / properties / anchors / descriptionPrevious value: -"Named anchors, same vocabulary as ps_resolve_placement (face/object/grid/extremum/corner/edge/landmark)."New value: +"Named anchors, same vocabulary as the placement-resolver tool, when this build has one (face/object/grid/extremum/corner/edge/landmark)." - changed
Input schema / properties / source_placement / properties / relation / descriptionPrevious value: -"The relation, same vocabulary as ps_resolve_placement."New value: +"The relation, same vocabulary as the placement-resolver tool, when this build has one."
- Changed
ps_close_document2 fields changed- added
Input schema / properties / idAdded value: +{ + "description": "Target an open document by its Photoshop document id. Unambiguous — prefer this when names collide.", + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / nameAdded value: +{ + "description": "Target an open document by its exact Photoshop name, INCLUDING the extension as shown in the tab (e.g. 'portrait.jpg', not 'portrait'). If two open documents share a name the call fails rather than guessing — target by id instead.", + "type": "string" +}
- Changed
ps_crop_document3 fields changed- changed
Input schema / properties / placement / descriptionPrevious value: -"ANCHOR-RELATIONAL crop (preferred over guessing pixels): a REGION relation (inside/gap) → the crop is the resolved region bounding box, verified by the gate. Crops ONLY if the gate PASSES. When set, left/top/right/bottom are ignored. See ps_resolve_placement for the anchors + relation vocabulary."New value: +"ANCHOR-RELATIONAL crop (preferred over guessing pixels): a REGION relation (inside/gap) → the crop is the resolved region bounding box, verified by the gate. Crops ONLY if the gate PASSES. When set, left/top/right/bottom are ignored. See the placement-resolver tool, when this build has one, for the anchors + relation vocabulary." - changed
Input schema / properties / placement / properties / anchors / descriptionPrevious value: -"Named anchors, same vocabulary as ps_resolve_placement (face/object/grid/extremum/corner/edge/landmark)."New value: +"Named anchors, same vocabulary as the placement-resolver tool, when this build has one (face/object/grid/extremum/corner/edge/landmark)." - changed
Input schema / properties / placement / properties / relation / descriptionPrevious value: -"The relation, same vocabulary as ps_resolve_placement."New value: +"The relation, same vocabulary as the placement-resolver tool, when this build has one."
- Added
ps_document - Changed
ps_filter2 fields changed- changed
Input schema / properties / center_placement / properties / anchors / descriptionPrevious value: -"Named anchors, same vocabulary as ps_resolve_placement (face/object/grid/extremum/corner/edge/landmark)."New value: +"Named anchors, same vocabulary as the placement-resolver tool, when this build has one (face/object/grid/extremum/corner/edge/landmark)." - changed
Input schema / properties / center_placement / properties / relation / descriptionPrevious value: -"The relation, same vocabulary as ps_resolve_placement."New value: +"The relation, same vocabulary as the placement-resolver tool, when this build has one."
- Changed
ps_path3 fields changed- changed
Input schema / properties / placement / properties / anchors / descriptionPrevious value: -"Named anchors, same vocabulary as ps_resolve_placement (face/object/grid/extremum/corner/edge/landmark)."New value: +"Named anchors, same vocabulary as the placement-resolver tool, when this build has one (face/object/grid/extremum/corner/edge/landmark)." - changed
Input schema / properties / placement / properties / relation / descriptionPrevious value: -"The relation, same vocabulary as ps_resolve_placement."New value: +"The relation, same vocabulary as the placement-resolver tool, when this build has one." - changed
Input schema / properties / tool / descriptionPrevious value: -"stroke only: which brush-family tool paints the path. Default 'brush'. Same 16-tool set as ps_apply_brush_stroke."New value: +"stroke only: which brush-family tool paints the path (see this field's own enum for the full supported set). Default 'brush'."
- Changed
ps_read_scene5 fields changed- changed
Input schema / properties / save_regions / defaultPrevious value: -trueNew value: +false - changed
Input schema / properties / save_regions / descriptionPrevious value: -"Precompute every confident region (sky/ground/shadows/highlights/skin/subject/face — and, on a Pro host with a face, the face-feature set scene:face_skin/_eyes/_brows/_lips/_teeth/_nose/_under_eye/_cheeks) and SAVE each as a managed `scene:*` alpha channel, returning the `regions` MENU of what is confidently selectable (each with its method + confidence). ps_select_by_reference then loads the saved channel instantly. Set false for a light read with no channels. The `scene:` channel-name prefix is RESERVED: channels matching it are treated as derived and are deleted on the next scene read and on ps_save_psd, so do not give a channel you want to keep a `scene:`-prefixed name."New value: +"EAGERLY derive every region (sky/ground/shadows/highlights/skin/subject/face) up front and SAVE each confident one as a managed `scene:*` alpha channel, so the returned menu carries a verified method + confidence for each. Costs one derive per target — measured at ~21s on a 4898x3265 layered document, against a 30s script timeout — so it is OFF by default. Leave it off unless you specifically need every region scored in one call: the default advertises the same menu as `on_demand` entries and ps_select_by_reference derives whichever region you actually ask for (then saves its channel, so repeats of THAT region are instant). The `scene:` channel-name prefix is RESERVED: channels matching it are treated as derived and are deleted on the next scene read and on ps_save_psd, so do not give a channel you want to keep a `scene:`-prefixed name." - changed
Output schema / properties / regions / items / properties / selectable_state / descriptionPrevious value: -"`selectable`: a precomputed channel is ready to load. `not_selectable`: resolution ran and this region did not pass the confidence gate. `not_resolved`: precompute did not run or failed, so absence here is NOT evidence the region is unavailable."New value: +"`selectable`: a precomputed channel is ready to load. `not_selectable`: resolution ran and this region did not pass the confidence gate. `candidate`: the DEFAULT read advertised this region without deriving it — ps_select_by_reference scores it when you ask, and it may still turn out not to pass. `not_resolved`: an eagerly-requested precompute did not run or failed, so absence here is NOT evidence the region is unavailable." - changed
Output schema / properties / regions / items / properties / selectable_state / enumPrevious value: -[ - "selectable", - "not_selectable", - "not_resolved" -]New value: +[ + "selectable", + "not_selectable", + "candidate", + "not_resolved" +] - changed
Output schema / properties / regions / items / properties / selectable_via / descriptionPrevious value: -"The method that resolved it (only when selectable)."New value: +"The method that resolved it, when one did. Reads 'on_demand' for a `candidate` — nothing has resolved it yet and the method is chosen at derive time."
- Changed
ps_retouch4 fields changed- changed
Input schema / properties / destination_placement / properties / anchors / descriptionPrevious value: -"Named anchors, same vocabulary as ps_resolve_placement (face/object/grid/extremum/corner/edge/landmark)."New value: +"Named anchors, same vocabulary as the placement-resolver tool, when this build has one (face/object/grid/extremum/corner/edge/landmark)." - changed
Input schema / properties / destination_placement / properties / relation / descriptionPrevious value: -"The relation, same vocabulary as ps_resolve_placement."New value: +"The relation, same vocabulary as the placement-resolver tool, when this build has one." - changed
Input schema / properties / source_placement / properties / anchors / descriptionPrevious value: -"Named anchors, same vocabulary as ps_resolve_placement (face/object/grid/extremum/corner/edge/landmark)."New value: +"Named anchors, same vocabulary as the placement-resolver tool, when this build has one (face/object/grid/extremum/corner/edge/landmark)." - changed
Input schema / properties / source_placement / properties / relation / descriptionPrevious value: -"The relation, same vocabulary as ps_resolve_placement."New value: +"The relation, same vocabulary as the placement-resolver tool, when this build has one."
- Changed
ps_select3 fields changed- changed
Input schema / properties / placement / descriptionPrevious value: -"Grounded coordinates (rectangle/ellipse/magic_wand): NAME anchors + a relation instead of guessing pixels. rectangle/ellipse ← a REGION relation (inside/gap) → the selection bounding box; magic_wand ← a POINT relation (centroid/extremum/grid) → the click. Verified by the objective gate; wins over the raw edges/x-y. See ps_resolve_placement for the vocabulary."New value: +"Grounded coordinates (rectangle/ellipse/magic_wand): NAME anchors + a relation instead of guessing pixels. rectangle/ellipse ← a REGION relation (inside/gap) → the selection bounding box; magic_wand ← a POINT relation (centroid/extremum/grid) → the click. Verified by the objective gate; wins over the raw edges/x-y. See the placement-resolver tool, when this build has one, for the vocabulary." - changed
Input schema / properties / placement / properties / anchors / descriptionPrevious value: -"Named anchors, same vocabulary as ps_resolve_placement (face/object/grid/extremum/corner/edge/landmark)."New value: +"Named anchors, same vocabulary as the placement-resolver tool, when this build has one (face/object/grid/extremum/corner/edge/landmark)." - changed
Input schema / properties / placement / properties / relation / descriptionPrevious value: -"The relation, same vocabulary as ps_resolve_placement."New value: +"The relation, same vocabulary as the placement-resolver tool, when this build has one."
- Changed
ps_shape3 fields changed- changed
Input schema / properties / placement / descriptionPrevious value: -"ANCHOR-RELATIONAL placement (preferred over guessing pixels): rectangle/ellipse ← a region relation (inside/gap) → the resolved region bounding box; line ← a path relation (along/offset-curve over a traced edge or a Pro face-mesh landmark curve) → a straight line between the resolved curve endpoints. The shape is created ONLY if the gate PASSES (otherwise an error and no layer). When set, left/top/right/bottom and start_x/start_y/end_x/end_y are ignored, but styling (fill_color/stroke/weight/corner_radius) still applies. See ps_resolve_placement for the anchors + relation vocabulary."New value: +"ANCHOR-RELATIONAL placement (preferred over guessing pixels): rectangle/ellipse ← a region relation (inside/gap) → the resolved region bounding box; line ← a path relation (along/offset-curve over a traced edge or a Pro face-mesh landmark curve) → a straight line between the resolved curve endpoints. The shape is created ONLY if the gate PASSES (otherwise an error and no layer). When set, left/top/right/bottom and start_x/start_y/end_x/end_y are ignored, but styling (fill_color/stroke/weight/corner_radius) still applies. See the placement-resolver tool, when this build has one, for the anchors + relation vocabulary." - changed
Input schema / properties / placement / properties / anchors / descriptionPrevious value: -"Named anchors, same vocabulary as ps_resolve_placement (face/object/grid/extremum/corner/edge/landmark)."New value: +"Named anchors, same vocabulary as the placement-resolver tool, when this build has one (face/object/grid/extremum/corner/edge/landmark)." - changed
Input schema / properties / placement / properties / relation / descriptionPrevious value: -"The relation, same vocabulary as ps_resolve_placement."New value: +"The relation, same vocabulary as the placement-resolver tool, when this build has one."
- Changed
ps_transform_layer3 fields changed- changed
Input schema / properties / placement / descriptionPrevious value: -"ANCHOR-RELATIONAL move (preferred over guessing a pixel): a POINT relation (centroid/midpoint/offset) → the layer's CENTER is moved to the resolved, gate-verified point (e.g. \"center this layer on the detected subject\" / \"…in the gap between the two people\"). Moves ONLY if the gate PASSES. When set, delta_*/absolute_*/center_on_* are ignored. See ps_resolve_placement for the anchors + relation vocabulary."New value: +"ANCHOR-RELATIONAL move (preferred over guessing a pixel): a POINT relation (centroid/midpoint/offset) → the layer's CENTER is moved to the resolved, gate-verified point (e.g. \"center this layer on the detected subject\" / \"…in the gap between the two people\"). Moves ONLY if the gate PASSES. When set, delta_*/absolute_*/center_on_* are ignored. See the placement-resolver tool, when this build has one, for the anchors + relation vocabulary." - changed
Input schema / properties / placement / properties / anchors / descriptionPrevious value: -"Named anchors, same vocabulary as ps_resolve_placement (face/object/grid/extremum/corner/edge/landmark)."New value: +"Named anchors, same vocabulary as the placement-resolver tool, when this build has one (face/object/grid/extremum/corner/edge/landmark)." - changed
Input schema / properties / placement / properties / relation / descriptionPrevious value: -"The relation, same vocabulary as ps_resolve_placement."New value: +"The relation, same vocabulary as the placement-resolver tool, when this build has one."
20 tool updates
v1.2.0- Removed
ps_apply_filter - Added
ps_clipping_mask - Removed
ps_create_clipping_mask - Removed
ps_create_group - Removed
ps_create_text_layer - Removed
ps_delete_group - Added
ps_filter - Added
ps_group - Changed
ps_inspect11 fields changed- changed
Input schema / properties / what / descriptionPrevious value: -"Which read-only state to return. metadata: document/IPTC/camera-EXIF/GPS/ACR develop settings + active context (optionally subset with `sections`; sections=[\"context\"] is the cheap orientation probe). layer_tree: the full recursive layer tree (name/kind/visibility/opacity/blend/clipping/bounds) — use whenever you need what is inside a group. history: all history states + the current cursor, for deciding how far to undo. selection_info: current selection bounds/coverage/edge-complexity without modifying anything."New value: +"Which read-only state to return. metadata: document/IPTC/camera-EXIF/GPS/ACR develop settings + active context (optionally subset with `sections`; sections=[\"context\"] is the cheap orientation probe). layer_tree: the full recursive layer tree (name/kind/visibility/opacity/blend/clipping/bounds) — use whenever you need what is inside a group. history: all history states + the current cursor, for deciding how far to undo. selection_info: current selection bounds/coverage/edge-complexity without modifying anything. smart_object: whether the ACTIVE layer is a Smart Object and, if so, whether its source is embedded or linked to a file on disk, plus how many Smart Filters it carries." - changed
Input schema / properties / what / enumPrevious value: -[ - "metadata", - "layer_tree", - "history", - "selection_info" -]New value: +[ + "metadata", + "layer_tree", + "history", + "selection_info", + "smart_object" +] - added
Output schema / properties / boundsAdded value: +{ + "type": "array" +} - added
Output schema / properties / document_idAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / file_referenceAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / is_smart_objectAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / layer_kindAdded value: +{ + "type": "string" +} - added
Output schema / properties / layer_nameAdded value: +{ + "type": "string" +} - added
Output schema / properties / linkedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / placedAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / smart_filter_countAdded value: +{ + "type": "number" +}
- Changed
ps_modify_selection8 fields changed- added
Input schema / properties / anti_aliasAdded value: +{ + "default": true, + "description": "Soften the selection edge. Default true.", + "type": "boolean" +} - changed
Input schema / properties / op / descriptionPrevious value: -"feather: soften the selection edge by radius_px. refine_edge: Select-and-Mask global sliders (smooth, feather, contrast, shift_edge, radius edge-detection, decontaminate) to clean halos / soft hair edges. expand: grow the selection outward by `amount` px. contract: shrink it inward by `amount` px. border: replace the selection with a `amount`-px-wide band straddling its edge. smooth: round off the selection corners with a `amount`-px radius. transform: relatively scale (scale_x_percent / scale_y_percent), rotate (rotate_degrees) and/or translate (offset_x / offset_y) the marching ants — not pixels. expand/contract/border/smooth all require an active selection and take `amount`; expand/contract/smooth also take at_canvas_bounds."New value: +"feather: soften the selection edge by radius_px. refine_edge: Select-and-Mask global sliders (smooth, feather, contrast, shift_edge, radius edge-detection, decontaminate) to clean halos / soft hair edges. expand: grow the selection outward by `amount` px. contract: shrink it inward by `amount` px. border: replace the selection with a `amount`-px-wide band straddling its edge. smooth: round off the selection corners with a `amount`-px radius. grow: expand the selection to adjacent similar-colour pixels (+tolerance, anti_alias). similar: expand the selection to ALL similar-colour pixels document-wide (+tolerance, anti_alias). transform: relatively scale (scale_x_percent / scale_y_percent), rotate (rotate_degrees) and/or translate (offset_x / offset_y) the marching ants — not pixels. expand/contract/border/smooth all require an active selection and take `amount`; expand/contract/smooth also take at_canvas_bounds. grow/similar also require an active selection." - changed
Input schema / properties / op / enumPrevious value: -[ - "feather", - "refine_edge", - "expand", - "contract", - "border", - "smooth", - "transform" -]New value: +[ + "feather", + "refine_edge", + "expand", + "contract", + "border", + "smooth", + "transform", + "grow", + "similar" +] - added
Input schema / properties / toleranceAdded value: +{ + "default": 32, + "description": "Color similarity tolerance (0-255) for which neighbouring pixels are added. Default 32.", + "maximum": 255, + "minimum": 0, + "type": "integer" +} - added
Output schema / properties / anti_aliasAdded value: +{ + "description": "op=grow/similar: anti_alias used.", + "type": "boolean" +} - added
Output schema / properties / methodAdded value: +{ + "description": "op=grow/similar: \"grow\" or \"similar\".", + "type": "string" +} - added
Output schema / properties / selectedAdded value: +{ + "description": "op=grow/similar: true on success.", + "type": "boolean" +} - added
Output schema / properties / toleranceAdded value: +{ + "description": "op=grow/similar: tolerance used.", + "type": "number" +}
- Removed
ps_move_layer_to_group - Changed
ps_ping3 fields changed- added
Output schema / properties / notify_userAdded value: +{ + "description": "True on the one ping whose text carries the update notice — relay that notice to the user before continuing. False on later pings and when no update is available.", + "type": "boolean" +} - changed
Output schema / properties / update_available / descriptionPrevious value: -"Set when a newer Editmamei version is published, else null. When present, TELL THE USER: relay current → latest and how_to_update verbatim. { current, latest, channel (npm/mcpb/dev), how_to_update }. Anonymous npm-registry check at boot; opt out with `editmamei config set update_check false`."New value: +"Set when a newer Editmamei version is published, else null: { current, latest, channel (npm/mcpb/dev), how_to_update, fixed_tools (tools whose recorded failures the newer version fixes) }. The relay instruction rides the ping TEXT on the first ping — see notify_user. Anonymous npm-registry check at boot; opt out with `editmamei config set update_check false`." - added
Output schema / properties / update_available / properties / fixed_toolsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +}
- Removed
ps_release_clipping_mask - Added
ps_replace_sky - Changed
ps_select1 field changed- changed
Input schema / properties / mode / descriptionPrevious value: -"all: select the whole canvas. none: deselect. inverse: invert the current selection. rectangle: left/top/right/bottom (+optional feather_px). ellipse: left/top/right/bottom bounding box (+anti_alias, +optional feather_px) — circles/ovals. color_range: target red/green/blue (+fuzziness) — \"select all the red / skin\". luminance_range: luminance highlights|shadows|midtones (+fuzziness, lower_limit, upper_limit) — glow/dodge-burn foundation. magic_wand: click x/y (+tolerance, contiguous, anti_alias, sample_all_layers). grow: expand the CURRENT selection to adjacent similar-colour pixels (+tolerance, anti_alias). similar: expand the CURRENT selection to ALL similar-colour pixels document-wide (+tolerance, anti_alias). skin_tones: select skin-coloured pixels (+fuzziness; use_faces=true adds face-aware refinement). out_of_gamut: select colours outside the printable CMYK gamut (no params). polygon: points [{x,y},...] in ABSOLUTE document pixels (min 3, auto-closes) — covers polygonal/freehand lasso. Coordinate-driven: you must know the pixel positions (use ps_inspect / ps_get_preview to aim, or ps_path create_from_placement → load_as_selection for a grounded outline). rectangle/ellipse/magic_wand also take a grounded `placement` instead of raw coords (region → the bbox; point → the wand click). rectangle/ellipse/polygon/color_range/luminance_range/magic_wand/skin_tones/out_of_gamut also take selection_type to combine with an existing selection."New value: +"all: select the whole canvas. none: deselect. inverse: invert the current selection. rectangle: left/top/right/bottom (+optional feather_px). ellipse: left/top/right/bottom bounding box (+anti_alias, +optional feather_px) — circles/ovals. color_range: target red/green/blue (+fuzziness) — \"select all the red / skin\". luminance_range: luminance highlights|shadows|midtones (+fuzziness, lower_limit, upper_limit) — glow/dodge-burn foundation. magic_wand: click x/y (+tolerance, contiguous, anti_alias, sample_all_layers). grow: DEPRECATED here — use ps_modify_selection(op=grow) instead (kept for one release for backward compatibility, identical behaviour). Expands the CURRENT selection to adjacent similar-colour pixels (+tolerance, anti_alias). similar: DEPRECATED here — use ps_modify_selection(op=similar) instead (kept for one release for backward compatibility, identical behaviour). Expands the CURRENT selection to ALL similar-colour pixels document-wide (+tolerance, anti_alias). skin_tones: select skin-coloured pixels (+fuzziness; use_faces=true adds face-aware refinement). out_of_gamut: select colours outside the printable CMYK gamut (no params). polygon: points [{x,y},...] in ABSOLUTE document pixels (min 3, auto-closes) — covers polygonal/freehand lasso. Coordinate-driven: you must know the pixel positions (use ps_inspect / ps_get_preview to aim, or ps_path create_from_placement → load_as_selection for a grounded outline). rectangle/ellipse/magic_wand also take a grounded `placement` instead of raw coords (region → the bbox; point → the wand click). rectangle/ellipse/polygon/color_range/luminance_range/magic_wand/skin_tones/out_of_gamut also take selection_type to combine with an existing selection."
- Added
ps_select_focus_area - Removed
ps_set_group_blend_mode - Removed
ps_set_text - Added
ps_text - Removed
ps_ungroup
2 tool updates
v1.0.3- Changed
ps_add_adjustment_layer1 field changed- added
Output schema / properties / raw_develop_pendingAdded value: +{ + "description": "Advisory, present only when the active document was opened from a raw source this session and no Camera Raw develop pass has run yet. Nothing failed — the layer was created. Global tone/color on raw sources normally starts with the camera-raw develop pass; ignore if the user prescribed this exact layer or the file was already developed elsewhere.", + "type": "string" +}
- Changed
ps_open_document1 field changed- added
Output schema / properties / is_raw_source / descriptionAdded value: +"True when the source file was a raw capture (DNG/NEF/CR3/ARW/…). Workflow-critical: the open used last-used/default Camera Raw settings, so no deliberate develop has happened yet. When true, run the Camera Raw develop pass FIRST (via a camera-raw develop tool, if registered) for global tone/color — before any tonal adjustment layers — unless the user explicitly directs otherwise."
67 tool updates
v1.0.2- First observed
ps_add_adjustment_layer - First observed
ps_add_fill_layer - First observed
ps_add_layer_style - First observed
ps_apply_adjustment - First observed
ps_apply_brush_stroke - First observed
ps_apply_filter - First observed
ps_apply_image - First observed
ps_bake_layer - First observed
ps_calculations - First observed
ps_close_document - First observed
ps_compare_regions - First observed
ps_convert_image_mode - First observed
ps_convert_to_smart_object - First observed
ps_copy_to_new_layer - First observed
ps_create_clipping_mask - First observed
ps_create_document - First observed
ps_create_group - First observed
ps_create_layer - First observed
ps_create_text_layer - First observed
ps_crop_document - First observed
ps_delete_group - First observed
ps_delete_layer - First observed
ps_detect - First observed
ps_duplicate_layer - First observed
ps_export - First observed
ps_fill_layer - First observed
ps_get_histogram - First observed
ps_get_layer_bounds_diff - First observed
ps_get_preview - First observed
ps_get_selection_preview - First observed
ps_guides - First observed
ps_inspect - First observed
ps_layer_mask - First observed
ps_list_capabilities - First observed
ps_merge - First observed
ps_modify_selection - First observed
ps_move_layer_to_group - First observed
ps_move_layer_to_position - First observed
ps_open_document - First observed
ps_overview - First observed
ps_path - First observed
ps_ping - First observed
ps_place_image - First observed
ps_portrait_touchup - First observed
ps_rasterize_layer - First observed
ps_read_scene - First observed
ps_redo - First observed
ps_release_clipping_mask - First observed
ps_report_problem - First observed
ps_resize_image - First observed
ps_retouch - First observed
ps_save_psd - First observed
ps_select - First observed
ps_select_by_reference - First observed
ps_select_layer - First observed
ps_select_sky - First observed
ps_select_subject - First observed
ps_selection_channel - First observed
ps_set_group_blend_mode - First observed
ps_set_layer - First observed
ps_set_text - First observed
ps_shape - First observed
ps_transform_canvas - First observed
ps_transform_layer - First observed
ps_undo - First observed
ps_ungroup - First observed
ps_vector_mask
TDQS
Scored across 64 tools
Every tool targets a distinct resource/action combination — documents, layers, selections, masks, paths, channels, and adjustments are cleanly separated. The descriptions actively preempt confusion by cross-referencing near-neighbors (ps_fill_layer vs ps_add_fill_layer, ps_select vs ps_modify_selection, ps_apply_adjustment vs ps_add_adjustment_layer), so an agent can reliably pick the right tool.
All tools share the ps_ prefix and snake_case, with a dominant verb_noun pattern (ps_create_layer, ps_open_document, ps_delete_layer) and a recognizable secondary convention where op-discriminated tools get noun names (ps_document, ps_group, ps_path, ps_text). However, a few op-discriminated tools are bare verbs rather than nouns (ps_filter, ps_merge, ps_inspect, ps_retouch) and ps_ping/ps_undo/ps_redo break the verb_noun pattern — minor deviations in an otherwise predictable scheme.
64 tools is objectively heavy and well past the 25+ threshold, but the apparent scope is nothing less than full Photoshop control, and nearly every tool earns its place with a distinct operation; several tools pack multiple operations behind one name via op/mode discriminators. The set shows careful curation (the descriptions document recently removed redundant tools), though the sheer volume still strains an agent's ability to hold the full surface in context.
The surface covers the full document/layer/selection/mask/adjustment/filter/text/shape/path/channel lifecycle with no dead ends in core workflows, plus strong agent-specific additions: vision tools (ps_detect, ps_read_scene) and numeric verification (ps_get_histogram, ps_compare_regions, ps_get_layer_bounds_diff). Minor gaps remain relative to Photoshop's full feature set — Liquify, auto-blend/auto-align layers, additional export formats like TIFF/WebP, and camera-raw/action tools are conditional or absent — but agents can work around these.
Maintenance
Related MCP Connectors
AI-native video editing OS — timeline editing, generation, color, and export as MCP tools.
Edit images over MCP with object removal, background removal, and guided generative edits.
The Figma MCP server brings Figma design context directly into your AI workflow.
MCP server for NanoBanana AI image generation and editing
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server for controlling Adobe Photoshop from AI assistants, with Windows-first workflow, structured state, smoke-tested action playback, and a bundled Codex skill for image editing.3MIT
- AlicenseAqualityDmaintenanceA professional MCP server that lets AI assistants directly control Adobe Photoshop for document creation, layer management, filters, adjustments, shapes, text, and design intelligence like palette generation and font pairing.322MIT
- AlicenseBqualityAmaintenanceEnables AI assistants to control Adobe Photoshop programmatically, supporting recipe workflows, state awareness, and generative AI features through natural language commands.201198,930 npm479MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to control Adobe Photoshop programmatically through natural language, with state awareness, recipe tools, and a standalone UI.8,930 npmMIT