Skip to main content
Glama

atx-mcp

English | 日本語 | 简体中文

atx-mcp MCP server – quality and maintenance score on Glama Mentioned in Awesome MCP Servers

A deterministic (non-generative) asset transformation MCP server for general-purpose AI agents, written in Rust.

It executes editing intent — "level the horizon, crop to 16:9, brighten it up a touch" — as a declarative transform recipe, and tracks every result as an immutable revision. The original asset is never modified.

Before/after: a tilted synthetic cityscape straightened, levels auto-corrected, and a subtle look applied Tilt correction + auto levels + a look applied (a fully deterministic recipe) — left: input / right: output.

See docs/DESIGN.md for the full design.

Use cases

  1. Eye-catch image for an article

    "Straighten this photo and crop it to a 16:9, 1600px eye-catch. WebP." import_assetdetect_tilt (the AI skips correction when it's already near-level) → apply_transform (rotate → crop → resize → encode) → export_asset. The original is never touched, and the same recipe reproduces the same result every time.

  2. Multiple sizes for social/CMS

    "Generate the OGP, Instagram square, and thumbnail versions of this photo." One original fans out into OGP 1200×630, Instagram 1080 square, and a 400px thumbnail in parallel. The same-recipe-same-revision idempotency means re-running never double-creates output; a one-word preset name works too.

  3. Safe to publish

    "Strip the location data for sure, but don't touch the colors." strip_metadata (exif) removes EXIF including GPS while keeping the ICC profile intact. The AI can also warn ahead of time by checking has_gps from inspect_image.

  4. Color and look adjustments

    "Make just the sky bluer, leave everything else alone." Covers curves / levels / hsl / white_balance, the film_soft preset, and importing your own .cube LUT with import_asset then applying it with lut.

  5. Local (masked) adjustments

    "Darken just the sky a bit, keep the ground as is." generate_mask builds a mask (gradient, luminosity range, or hue range); after wiring it into the adjustment, render_preview with overlay:"mask" shows exactly where it will bite before you commit.

  6. Layer compositing

    "Blur a copy of this photo and blend it in at 50% screen for a soft glow." The layers stack combines 16 blend modes, opacity, and masks to build reproducible composites like soft focus.

  7. Watermarks, retouching, and perspective

    "Stamp my logo in the corner, remove the power lines, and fix the converging verticals." svg_overlay burns in a logo, clone/heal remove blemishes or wires by compositing both texture and tone, and perspective corrects converging verticals.

  8. Reading documents (OCR pre-processing)

    "Read this receipt photo for me." / "What does this slide say?" detect_document finds the page or screen and returns a perspective quad ready to paste, the ocr_document preset (grayscale, auto levels, light sharpen) and trim concentrate the pixel budget on the text, and render_preview with long_edge:1568 hands the model an image it can actually read. No OCR engine is bundled: the model does the reading, atx only makes the pixels legible and reproducible. detect_text_blocks answers the question that decides the rest — "will this text survive the downscale, and where do I cut?" — by returning the text blocks in reading order plus ready-to-paste crop bands. threshold (Otsu / Sauvola) and ocr_binarize exist for external OCR engines.

  9. Verification and accountability

    "Show me this image before and after the edits, side by side." compare_revisions places before/after side by side, or returns a difference heatmap with stats like mean_abs_diff. Every revision keeps its lineage, so the full edit history behind any image used in an article can be traced and reproduced — byte-identical on any machine.

What atx doesn't do — generative editing, RAW development, ML-based auto-cropping, OCR itself — is out of scope; see docs/DESIGN.md for the roadmap.

Related MCP server: imagegrain MCP

Install

atx-mcp is a single self-contained binary with no runtime dependencies. Pick one of the following.

1. cargo binstall (prebuilt binary, no compilation)

cargo binstall atx-mcp
claude mcp add --scope user asset-transform -- atx-mcp --workspace /path/to/asset-workspace

cargo-binstall downloads the release archive built by this repository's CI instead of compiling, so this is the fastest route for anyone who already has a Rust toolchain. (--scope user makes the server available in every project; omit it for the current project only.)

2. cargo install (builds from source)

cargo install atx-mcp

Works on any platform a Rust toolchain supports, including ones without a prebuilt binary. Needs a C compiler as well (libwebp is built from its vendored source).

3. Prebuilt binary (no Rust toolchain)

Installer scripts (default install location is ~/.local/bin, or %LOCALAPPDATA%\Programs\atx-mcp on Windows; the archive is verified against SHA256SUMS before extraction):

# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/gridhra/atx-mcp/main/scripts/install.sh | sh
# Windows
irm https://raw.githubusercontent.com/gridhra/atx-mcp/main/scripts/install.ps1 | iex

To download manually, grab atx-mcp-<version>-<target>.tar.gz (.zip on Windows) from Releases. Supported targets:

Platform

Target triple

macOS (Apple Silicon)

aarch64-apple-darwin

macOS (Intel)

x86_64-apple-darwin

Linux x86_64

x86_64-unknown-linux-musl (statically linked, no glibc required)

Linux arm64

aarch64-unknown-linux-musl (statically linked, no glibc required)

Windows x86_64

x86_64-pc-windows-msvc

claude mcp add asset-transform -- ~/.local/bin/atx-mcp --workspace /path/to/asset-workspace

4. Docker

ghcr.io/gridhra/atx-mcp is a FROM scratch image holding the statically linked binary and nothing else (linux/amd64 and linux/arm64).

claude mcp add asset-transform -- \
  docker run -i --rm -v "$PWD:/workspace" ghcr.io/gridhra/atx-mcp:0.6.2

Two things to keep in mind. -i is required: the server speaks the MCP stdio transport and needs stdin to stay open. And paths are container paths: the directory you bind-mount appears as /workspace inside the container, so import_asset and export_asset take paths like /workspace/photos/shot.jpg, not host paths.

5. npx (Node.js 18+, nothing to install)

The prebuilt native binary for your platform is pulled in automatically via optionalDependencies.

claude mcp add --scope user asset-transform -- npx -y atx-mcp --workspace /path/to/asset-workspace

Or add it directly to your MCP client config:

{
  "mcpServers": {
    "asset-transform": {
      "command": "npx",
      "args": ["-y", "atx-mcp", "--workspace", "/path/to/asset-workspace"]
    }
  }
}

--workspace (env: ATX_WORKSPACE) is the directory used as the asset store. It is created automatically if it doesn't exist.

Tools (13)

Tool

Role

list_operations

Compact catalog of the recipe vocabulary: every operation with a one-line description and terse parameter hints, plus the built-in preset names. Optional category:"geometry"|"color"|"filter"|"output" narrows it (read-only)

explain_operation

Full reference for one operation: parameter table (type, range, required/default, semantics), ready-to-paste JSON examples and gotchas. A built-in preset name works too and returns its full operation list. An unknown name returns the valid operations and presets, grouped (read-only)

import_asset

Import a local image into the workspace (sha256-idempotent). Takes path for one file or paths for a batch of up to 64 (a failing file does not abort the batch). Warns via already_derived_from when the bytes are already the output of a recipe in this workspace

inspect_image

Inspect dimensions, EXIF summary, ICC profile, presence of GPS data, luma statistics, a sharpness score (variance of the Laplacian — relative, so compare it against a known-good capture of the same subject) and a perceptual_hash (dHash, 16 hex digits) for "is this the same picture?". include_exif:true additionally returns every EXIF field as {ifd, tag, value} entries — off by default because the full dump can carry GPS coordinates and names (read-only)

detect_tilt

Estimate tilt angle via Canny+Hough (coarse) plus a projection profile (sub-0.1° refinement). Also returns horizontal/vertical family estimates; the full score curve is opt-in via include_score_curve:true. Returns "do not correct" when confidence is low (read-only)

detect_document

Find the dominant quadrilateral (page, screen, whiteboard, sign) via Canny + contours and return it as a perspective-ready quad (tl, tr, br, bl) with confidence, area_ratio, an output_size_hint and a paste-ready suggested_operation. Returns quad:null with a reason (no_quad_found / already_rectified / low_confidence) rather than guessing (read-only)

detect_text_blocks

Find the text-like blocks (headline, paragraphs, table, caption) via Otsu binarization + run-length smearing + connected components, in reading order, each with line_count, median_line_height_px and ink_ratio. legibility.line_height_at_1568_px says whether the text survives a downscale to long edge 1568 (below ~16px it usually does not), and legibility.recommended_bands splits the image into horizontal bands that clear that bar — each entry is already a crop operation to paste before render_preview (read-only)

generate_mask

Generate a deterministic grayscale mask (linear_gradient / radial_gradient / luminosity_range / color_range) as a PNG revision with the same dimensions as the reference image, to be referenced from an operation's mask field (idempotent)

render_preview

Apply a recipe (or a preset) at low resolution (long edge ≤768 by default, long_edge 256..1568 to hand a vision model a legible page) and return it as an inline image. overlay:"grid"|"thirds"|"horizon" overlays composition guide lines, and overlay:"mask" (with mask_revision_id) tints the coverage of a mask (drawn on the preview only; it has no effect on the actual transform). Also reports estimated_vision_tokens, a rough width*height/750 budget for the returned image

apply_transform

Apply a recipe (or a preset) at full resolution and produce a new revision (the same recipe always yields the same revision). Takes revision_id for one image or revision_ids to run the same recipe over a batch of up to 64

compare_revisions

Downscale two revisions to long edge ≤640 and return them composited into a single inline image, arranged via layout:"side_by_side"|"stacked" (for A/B and before/after visual comparison), or layout:"diff" for a single pixel-difference heatmap plus mean_abs_diff/max_abs_diff/changed_pixel_ratio and an ssim score (requires equal dimensions). Every layout also reports perceptual_hash_distance, the Hamming distance between the two dHash values (≤5 usually means the same picture re-encoded or resized, ≥20 means two different pictures)

list_assets

Read the revision ledger (read-only)

export_asset

Write revisions out of the workspace: revision_id + dest_path for one file, or revision_ids + dest_dir for up to 64 at once, named by filename_template (default "{revision_id}.{ext}", also {index} / {stem}). An existing file is only overwritten when overwrite:true is explicitly set, and it never writes inside the workspace store or through a symbolic link

Recipe example

{
  "operations": [
    { "op": "rotate", "angle_degrees": -1.8 },
    { "op": "crop", "aspect_ratio": "16:9" },
    { "op": "resize", "width": 1600 },
    { "op": "encode", "format": "webp", "quality": 82 }
  ]
}

Supported ops (29): auto_orient / rotate / perspective / crop (crop, pad) / trim / resize (cover, contain, fill) / adjust / color_matrix / curves / levels / lut / white_balance / hsl / blur / median / unsharp_mask / convolve / threshold / clone / heal / svg_overlay / flip / vignette / grain / gradient_map / pixelate / auto_levels / encode (jpeg, png, webp, avif) / strip_metadata. The operation vocabulary is deliberately kept out of the tool schemas: call list_operations for the up-to-date catalog and explain_operation for one operation's full schema, examples and gotchas.

LUT (.cube)

A .cube 3D/1D LUT is an asset, not an image: import it first, then point a recipe at the revision it produced.

  1. import_asset the .cube file. It is stored as an immutable revision with mime_type: "application/x-cube" (inspect_image refuses it on purpose — it is not an image).

  2. Reference the returned revision_id from a recipe:

{ "op": "lut", "lut_revision_id": "rev_...", "strength": 0.8 }

strength (0..1, default 1.0) blends linearly with the original. Because revisions are immutable, including the referenced id in the recipe_hash keeps the transform fully deterministic — but it also means the recipe is only reproducible inside a workspace that holds that LUT, so move the .cube alongside the recipe when you move a look between machines. Referencing an unknown id fails with a structured error before any pixel work happens.

SVG overlays (logos and watermarks)

An .svg is a vector asset, like a .cube LUT: import it first, then stamp it onto a raster image from a recipe.

  1. import_asset the .svg file. It is stored as an immutable revision with mime_type: "image/svg+xml", and the summary reports the SVG's intrinsic size (0x0 means it has none — no viewBox and no absolute width/height on the root <svg>). inspect_image refuses it on purpose: it is a vector asset, not a raster image.

  2. Reference the returned revision_id from a recipe:

{ "op": "svg_overlay", "svg_revision_id": "rev_...",
  "x": 24, "y": 24, "width": 320, "opacity": 0.25, "blend_mode": "normal" }

x/y are the overlay's top-left corner in the coordinates of the image at that point in the pipeline (so put the overlay after your resize/crop); negative values are allowed and the overflow is clipped. Omit width and height to rasterize at the SVG's intrinsic size, give one to scale while preserving the aspect ratio, or give both to stretch to an exact box — an SVG with no intrinsic size is a structured error unless you give both. Compositing uses the same W3C formula and the same 16 blend_mode values as layers.

Text in an SVG

atx never reads system fonts: the installed fonts differ from machine to machine and would break byte-for-byte reproducibility. <text> is therefore skipped unless you ask for it:

{ "op": "svg_overlay", "svg_revision_id": "rev_...", "x": 120, "y": 80,
  "width": 48, "render_text": true, "font_revision_ids": ["rev_..."] }
  • render_text defaults to false, which keeps the old behaviour exactly (the shapes render, the glyphs do not, and the result carries a warning). Converting text to paths in your vector editor still works and needs no font at all.

  • render_text:true draws the text with one bundled font, Roboto Regular (embedded in the binary), plus any fonts you pass in font_revision_ids (up to 4). Nothing else is ever loaded, so the output is identical on every machine.

  • A font is an asset like a LUT or an SVG: import_asset a .ttf / .otf file, and the summary reports the family names to write in font-family. Japanese and other CJK text needs an imported font — Roboto has no CJK glyphs, and characters missing from every loaded font render as boxes and are counted in a warning. inspect_image refuses a font revision on purpose: it is an asset, not an image.

Masks (local adjustments)

A mask is a grayscale image revision: its BT.709 luma is the weight, so white means "apply this operation at full strength" and black means "leave the pixel alone". Any of the 14 tone/filter ops (adjust, color_matrix, curves, levels, hsl, lut, white_balance, blur, median, unsharp_mask, convolve, grain, gradient_map, auto_levels) accepts one.

  1. generate_mask builds one deterministically against a reference image, with exactly that image's dimensions:

kind

Parameters

What it selects

linear_gradient

angle_degrees (0 = white at the top fading down, positive = clockwise), start, end (0..1 positions along the axis where the weight goes 1→0)

A graduated filter (skies, foregrounds)

radial_gradient

center_x, center_y (0..1 relative), radius (0..1 of the half-diagonal), feather (0..1 extra falloff band)

A vignette or a subject spotlight

luminosity_range

min, max (0..255), feather (luma units of soft shoulder outside the range)

Highlights, midtones or shadows

color_range

hue_center (0..360), hue_width (1..180 half-width), feather (extra degrees)

One hue family (sky blue, foliage green)

You can also import_asset your own grayscale image instead.

  1. Attach the returned revision_id to an operation:

{ "op": "curves", "master": [[0,0],[128,168],[255,255]],
  "mask": { "revision_id": "rev_...", "invert": false, "feather_px": 8.0 } }

invert (default false) flips the weight to 1-w; feather_px (default 0.0) blurs the mask edge by that gaussian sigma in pixels of the current image.

  1. render_preview with overlay:"mask" and mask_revision_id tints the preview red where the weight exceeds 0.5 and dims it elsewhere, so the coverage can be checked before committing.

Masks are referenced by revision id exactly like LUTs, so the same caveat applies: the recipe hash includes the id, and the recipe only reproduces inside a workspace that holds that mask.

Layers

A recipe may carry a layers stack instead of (or in addition to) a flat operations list. Layers composite bottom-to-top, each layer's ops run against its own source before it is blended onto the running composite:

{
  "layers": [
    { "source": "base", "ops": [] },
    {
      "source": { "revision_id": "rev_..." },
      "ops": [{ "op": "blur", "sigma": 8 }],
      "blend_mode": "multiply",
      "opacity": 0.6
    }
  ],
  "operations": [
    { "op": "resize", "width": 1600 },
    { "op": "encode", "format": "webp", "quality": 82 }
  ]
}
  • source is either "base" (the input revision passed to apply_transform / render_preview) or {"revision_id": "rev_..."} (any other revision already in the workspace). Every layer's source must match the base image's dimensions exactly, or the recipe fails with a structured error before any pixel work happens.

  • ops is a normal operations list, applied to that layer's source alone.

  • mask, blend_mode (default "normal") and opacity (default 1.0) control how the layer composites onto the layers below it.

  • Blend mode is one of 16 W3C modes: the 12 separable modes normal, multiply, screen, overlay, darken, lighten, color_dodge, color_burn, hard_light, soft_light, difference, exclusion, plus the 4 non-separable modes hue, saturation, color, luminosity.

  • When layers is present, the top-level operations becomes the finishing pass, applied once to the composited result — this is where resize and the final encode belong (encode must still be last and appear at most once).

  • Call explain_operation {"operation":"layers"} for the full reference.

Presets

A preset can also be inlined inside a recipe as a single operation — {"op": "preset", "name": "ocr_document"} — so a named look can be combined with your own ops. The macro expands in place before anything runs, so the recipe hashes exactly as if you had written the preset's operations out by hand, and a preset that carries layers cannot be inlined (that is a structured error). Call explain_operation {"operation":"preset"} for the rules.

apply_transform and render_preview take either recipe (the raw DSL) or preset (a built-in named recipe from crates/atx-mcp/presets/) — exactly one of the two:

Set

Preset

What it does

basics

eyecatch_16_9

Center-crop to 16:9, resize to 1600px wide, WebP q82

basics

film_soft

Soft film look: gentle S-curve plus a 15% pull towards luma

basics

product_clean

Clean product shot: near-neutral white balance, levels lift, light sharpen

basics

thumbnail_square

Center-crop to 1:1, resize to 800x800, WebP q80

basics

web_optimize

Fit inside 2000x2000 without upscaling, WebP q80

basics

grayscale

Black and white via a BT.709 luma color_matrix

basics

sepia

Classic sepia tone via color_matrix

film

film_warm

Warm film stock: amber white balance, soft S-curve, light grain

film

film_cool

Cool film stock: blue-leaning white balance, soft S-curve, light grain

film

matte_fade

Faded matte: lifted blacks via curves, slight desaturation

film

film_grain_strong

Heavy, coarse grain over a gentle S-curve (pushed/high-ISO look)

film

cinema_teal_orange

Teal-and-orange cinematic grade via targeted hsl shifts

mono

bw_neutral

Neutral black and white via a BT.709 luma color_matrix

mono

bw_high_contrast

High-contrast black and white: luma conversion plus a strong S-curve

mono

bw_red_filter

B&W through a simulated red filter (classic sky darkener)

mono

bw_soft

Soft, low-contrast black and white (matte curve)

mono

duotone_navy_cream

Navy-to-cream duotone via gradient_map

editorial

product_white

Auto levels stretch, neutral white balance, final sharpen

editorial

food_vivid

Warm orange/yellow saturation boost plus a contrast lift

editorial

portrait_soft

Soft matte curve, light desaturation, subtle vignette

editorial

landscape_punch

Contrast + saturation lift plus a light vignette

editorial

architecture_clean

Auto levels, sharpen, slight desaturation (pair with a manual perspective op)

social

og_1200x630

Open Graph share image: crop 1200:630, resize to 1200 wide, WebP q82

social

x_wide_16_9

X (Twitter) wide card: crop 16:9, resize to 1600 wide, WebP q82

social

instagram_square_1080

Instagram square post: crop 1:1, resize to 1080x1080, WebP q85

social

instagram_portrait_4_5

Instagram portrait post: crop 4:5, resize to 1080x1350, WebP q85

social

youtube_thumb_1280x720

YouTube thumbnail: crop 16:9, resize to 1280x720, WebP q85

social

hero_2400

Large hero/banner image: fit inside 2400px, WebP q85

building block

soft_vignette

Subtle vignette on its own, for stacking after other looks

building block

grain_fine

Light, fine, deterministic grain on its own, for stacking

ocr

ocr_document

Make a page/slide/whiteboard photo legible for a vision model: grayscale, auto levels, light sharpen (no binarization)

ocr

ocr_receipt

Noisy or faded receipts: grayscale, median denoise, stronger auto levels, sharpen

ocr

ocr_binarize

Sauvola adaptive binarization for external OCR engines (prefer ocr_document when a vision model reads the result)

ocr

ocr_dark_ui

Dark-mode screenshots: trim the margins, then invert to dark-on-light grayscale

A preset is pure sugar: it resolves to its recipe and flows through the normal pipeline, and the recipe_hash (the idempotency key) is computed on the resolved recipe — so a preset call and the equivalent raw recipe land on the same revision.

Guarantees

  • Deterministic: the same input + the same recipe always produces byte-identical output (regression-checked with golden tests)

  • Idempotent: recipes are normalized (keys sorted, f64 values quantized to a 1e-6 grid) and hashed with sha256. If (input revision, recipe hash) matches an existing pair, the existing revision is returned instead of a new one

  • Originals are protected: objects/ is an append-only, content-addressed store — there is no delete or overwrite API

Development

cargo test --workspace     # unit + integration + property (proptest) tests
cargo clippy --workspace --all-targets -- -D warnings

Crate layout: atx-core (recipe/transform engine) / atx-geometry (tilt detection) / atx-store (immutable asset store) / atx-mcp (rmcp stdio server).

The three libraries are published on crates.io under longer names, because atx-core there is an unrelated project:

Directory

Published as

Library name in code

crates/atx-core

asset-transform-core

atx_core

crates/atx-geometry

asset-transform-geometry

atx_geometry

crates/atx-store

asset-transform-store

atx_store

crates/atx-mcp

atx-mcp

atx_mcp (binary atx-mcp)

So to use the transform engine as a library, depend on asset-transform-core = "0.6.2" and write use atx_core::….

Name

"atx" stands for Asset Transform; the trailing x follows the familiar shorthand for "transform" (as in xform / tx). It was chosen as a short, easy-to-type binary name and directory prefix (crates/atx-core, etc.), and it has no relation to the PC ATX form factor or Markdown ATX-style headings. The crates.io packages spell the name out in full (asset-transform-core, and so on).

License

MIT. See LICENSE.

Non-crate material shipped inside the binary (the bundled Roboto Regular font) is listed with its source and license in THIRD_PARTY_NOTICES.md.

If atx-mcp saves you time, you can buy me a coffee

Available Tools

12 tools
apply_transformA
Idempotent

Apply a transform recipe at full resolution and issue a new revision. Pass either recipe ({"operations": [...]}, applied in order, at most one "encode" and it must be last) or preset (a built-in named recipe) - exactly one of the two - and either revision_id (one image) or revision_ids (the same recipe over a batch of up to 64; one failure does not abort the rest). Call list_operations for the operation catalog and the preset names, explain_operation for one operation's full schema. Idempotent: the same (revision_id, resolved recipe) returns the existing derived revision; a preset hashes identically to the equivalent raw recipe. Note: if the recipe's encode format is png, webp, or avif, any ICC color profile on the source is dropped (embedding is only supported for jpeg output); this is reported as a warning, not an error.

ParametersJSON Schema
NameRequiredDescriptionDefault
presetNoビルトインプリセット名(`list_operations` の presets セクション参照)。 指定するとそのプリセットのレシピが使われる。`recipe` とは排他。
recipeNo変換レシピ。`{"operations": [...]}`。`preset` とはどちらか一方のみ指定する。
revision_idNo入力 revision ID("rev_...")。`revision_ids` とは排他で、どちらか一方が必須。
revision_idsNo同じレシピを複数 revision に適用する(1..=64 件)。`revision_id` とは排他。 1件が失敗してもバッチは中断せず、その要素に error が入る。

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses meaningful behavioral traits: idempotent behavior with existing derived revisions, preset-to-recipe hash equivalence, ICC color profile dropping for certain encode formats, and warning-as-not-error semantics. It also clarifies that a new revision is issued. This goes well beyond what readOnlyHint, destructiveHint, and idempotentHint already communicate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is packed with essential information but remains well-structured and front-loaded with the core purpose. Each sentence contributes unique value: input constraints, sibling tool pointers, idempotence, and an edge-case warning. No filler is present.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex transform tool, the description covers input selection, mutual exclusivity, batch behavior, idempotence, encoding caveats, and where to find operation catalog details. An output schema exists, so return-value details need not be duplicated. The description is complete enough for an agent to call the tool correctly in both single and batch scenarios.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Even though schema description coverage is 100%, the description adds critical parameter semantics not encoded in the schema: recipe structure with operations applied in order, at most one encode operation and it must be last, the exact one-of relationship, batch size limit of 64, and per-item failure isolation. The note about ICC profile behavior further clarifies the recipe parameter's practical effects.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description begins with a specific verb and resource: 'Apply a transform recipe at full resolution and issue a new revision.' It clearly distinguishes this from siblings like render_preview and export_asset by emphasizing full-resolution processing and revision creation. The operation's core input alternatives are also stated, leaving 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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage context: exactly one of recipe/preset and exactly one of revision_id/revision_ids, plus batch limits and failure semantics. It also points to sibling tools list_operations and explain_operation for prerequisite knowledge. However, it does not explicitly state when not to use this tool versus siblings like render_preview, so it stops short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_revisionsA
Idempotent

Scale two revisions to a long edge of 640px each and compose them on one canvas (side by side, or stacked) with an 8px gap, returned inline as a JPEG. A is placed left/top, B is placed right/bottom. Useful for before/after or A/B visual checks. layout="diff" instead requires A and B to share the exact same dimensions and returns a single pixel-difference heatmap plus mean_abs_diff/max_abs_diff/changed_pixel_ratio.

ParametersJSON Schema
NameRequiredDescriptionDefault
layoutNo`"side_by_side"`(既定、水平に並べる)| `"stacked"`(垂直に並べる)| `"diff"`(並べる代わりに1枚の差分ヒートマップを作る。A/B の寸法が完全一致している必要がある)。side_by_side
revision_id_aYes比較対象 A の revision ID("rev_...")。合成画像の左(または上)に置かれる。
revision_id_bYes比較対象 B の revision ID("rev_...")。合成画像の右(または下)に置かれる。

Output Schema

ParametersJSON Schema
NameRequiredDescription
aYes
bYes
widthYes合成画像(比較プレビュー)の寸法・容量。
heightYes
layoutYes
byte_sizeYes
mime_typeYes
a_positionYesA が合成画像のどこに置かれるか("left" | "top")。
b_positionYesB が合成画像のどこに置かれるか("right" | "bottom")。
max_abs_diffNo`layout: "diff"` のときだけ載る: 画素ごとのチャンネル最大絶対差 d の、全画素中の最大値。
preview_pathYes比較プレビュー画像の絶対パス。
mean_abs_diffNo`layout: "diff"` のときだけ載る: 全チャンネル・全画素平均の絶対差(0..255 スケール)。
changed_pixel_ratioNo`layout: "diff"` のときだけ載る: d > 2 の画素が全体に占める割合(0.0..=1.0)。

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses key behaviors: scaling to a 640px long edge, an 8px gap, placement of A and B, and the diff mode's requirement for identical dimensions plus its output metrics. Annotations provide idempotentHint=true and destructiveHint=false, and the description does not contradict them. It adds context about the output format (JPEG) and diff-specific metrics, which is valuable beyond 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the primary behavior, then pivots to the diff variant. Each sentence serves a purpose—no filler. It could be slightly more concise, but it remains efficient and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (3 params, output schema present, annotations provided), the description covers the essential aspects: main usage, diff mode requirements, output format, and key behavioral details. It doesn't discuss error conditions or performance limits, but these are not critical for an agent to invoke the tool correctly. The presence of an output schema means the description need not elaborate on return values, and it still explains diff metrics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents each parameter thoroughly (layout enum, revision IDs, placement). The description adds the scaling and gap behavior, but these are tool-wide behaviors rather than parameter-specific semantics. It does reinforce the diff layout's dimension requirement, which is already in the schema. The description adds marginal value, so a baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: it scales two revisions, composes them on a canvas (side by side or stacked), and returns a JPEG. It also explicitly differentiates the diff mode, which produces a pixel-difference heatmap. This is specific and distinct from sibling tools like apply_transform or detect_document, which focus on transformation or analysis rather than visual comparison.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear use case: 'Useful for before/after or A/B visual checks.' It also explains when the diff layout is appropriate (when A and B share exact dimensions). However, it doesn't explicitly mention when not to use this tool or name alternatives, though among the siblings none serve the same comparison purpose, so the guidance is adequate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detect_documentA
Read-onlyIdempotent

Detect the dominant quadrilateral (a sheet of paper, a screen, a whiteboard, a sign) in a revision with a contour-based search, and return it as a ready-to-paste perspective operation. This is to perspective what detect_tilt is to rotate: read-only, it never modifies the image, and a null quad means "do not correct". The quad is in post-EXIF-orientation pixel coordinates, ordered tl, tr, br, bl, and output_size_hint is exactly the size perspective will produce from it. Optional min_area_ratio (0.05..=1.0, default 0.2) is the smallest fraction of the frame a candidate may cover. When quad is null the reason is the first warning: no_quad_found, already_rectified (the page already fills the frame) or low_confidence.

ParametersJSON Schema
NameRequiredDescriptionDefault
revision_idYes対象 revision ID("rev_...")。
min_area_ratioNo画像面積に対する候補四角形の最小面積比(0.05..=1.0)。省略時は 0.2。

Output Schema

ParametersJSON Schema
NameRequiredDescription
detectionYes検出結果。`quad` が null なら「補正しない」で、理由は `warnings` の先頭に入る。
revision_idYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds valuable behavior beyond that: coordinate ordering (tl, tr, br, bl), post-EXIF-orientation coordinates, output_size_hint semantics, min_area_ratio constraints, and the exact warning reasons when quad is null. This is rich, non-redundant behavioral detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, each earning its place: purpose and analogy, coordinate/output semantics, and parameter/warning behavior. It front-loads the core action and keeps supporting details compact, with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the annotations, full schema coverage, and presence of an output schema, the description covers everything an agent needs: operation type, coordinate system, ordering, output sizing, parameter defaults, and failure/warning semantics. No important calling decision is left unexplained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema coverage is 100%, so the baseline is 3. The description still adds meaning to min_area_ratio as 'the smallest fraction of the frame a candidate may cover', and clarifies that output_size_hint matches what perspective will produce. It does not add much to revision_id, but that is already well covered by the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

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: 'Detect the dominant quadrilateral ... in a revision with a contour-based search', and clarifies the return as a 'ready-to-paste perspective operation'. It also distinguishes itself from sibling detect_tilt by drawing the perspective/rotate analogy, so an agent can tell what this tool uniquely does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives strong context: it is read-only, never modifies the image, and a null quad means 'do not correct'. It also relates the tool to perspective via detect_tilt, which implies when to use it. It does not spell out explicit exclusion cases or name more alternatives, so it stops short of the strongest possible guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detect_tiltA
Read-onlyIdempotent

Detect the tilt (roll) of a revision: Canny + Hough dominant lines for coarse candidates, refined below 0.1 degree with an edge projection-profile search. Horizontal-only and vertical-only estimates are reported separately so a disagreement can be read as perspective/camera position rather than roll, Set include_score_curve=true to also get the whole search range as a score curve (omitted by default to keep the answer small). Read-only: it never modifies the image. A null recommended angle means "do not correct".

ParametersJSON Schema
NameRequiredDescriptionDefault
revision_idYes対象 revision ID("rev_...")。
max_abs_angleNo探索する最大傾き角(度、0.5..=45)。省略時は 15。
include_score_curveNo探索範囲全体のスコア曲線(最大 300 点)を結果に含めるか。既定 false。 ピークの鋭さ・多峰性を自分で読みたいときだけ true にする(既定では省かれる)。

Output Schema

ParametersJSON Schema
NameRequiredDescription
detectionYes検出結果。`score_curve` は `include_score_curve: true` のときだけ載る。
revision_idYes

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint/idempotentHint annotations, the description explicitly says it never modifies the image, describes processing stages (Canny/Hough then projection-profile refinement), discloses response-size behavior (score curve omitted by default), and defines the null recommended-angle sentinel. This gives an agent strong expectations for side effects and outputs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and method, and each clause adds useful context. It is slightly dense and contains a minor punctuation issue ('roll,' followed by 'Set'), but no sentence is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and annotations covering safety/idempotency, the description supplies the remaining operational context: algorithm, default response size, read-only behavior, and the meaning of null. An agent has enough to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the schema already explains revision_id, max_abs_angle, and include_score_curve. The description reinforces include_score_curve's behavior and adds 'to keep the answer small', but it contributes little beyond the schema and does not deepen revision_id or max_abs_angle semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening states a specific verb and resource: 'Detect the tilt (roll) of a revision' rather than a generic or tautological phrase. It also details what the tool returns (horizontal-only and vertical-only estimates, optional score curve), so an agent can distinguish it from siblings like detect_document.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear context is given: the tool is for measuring roll/tilt of a revision, and the description explains how to interpret disagreement between estimates and when to set include_score_curve=true. However, it does not explicitly name alternatives or state when not to use this tool versus siblings such as apply_transform or detect_document.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

explain_operationA
Read-onlyIdempotent

Full reference for one recipe operation: every parameter with its type, range, required/default status and semantics, one or two ready-to-paste JSON examples, and the gotchas worth knowing before using it. A built-in preset name works too and returns its full operation list, so a preset can be read and copied as a raw recipe. An unknown name returns a structured error listing every valid operation and preset. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
operationYes説明したい op 名(`{"op": "..."}` に書く名前)。

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, but the description goes further: it states 'Read-only' explicitly, describes support for preset names, and explains the structured error response for unknown names listing all valid operations. This adds behavioral context beyond the annotations, covering error handling and preset behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is approximately 80 words, composed of three sentences. It front-loads the main purpose ('Full reference for one recipe operation'), then details content, presets, and errors. Reasonably concise and logically structured, though it could be slightly tighter.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only reference tool with one parameter and an output schema, the description covers return content (parameters, examples, gotchas), preset handling, and error behavior (unknown names return a structured error with valid operations). All essential information for correct invocation is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, 'operation', has a schema description explaining it as the op name to write in the format {"op": "..."}. Schema description coverage is 100%, so the description adds no additional meaning about the parameter itself; it focuses on the return value. Baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Full reference for one recipe operation' with detailed content (parameters, examples, gotchas). It also covers preset handling and error behavior, distinguishing it from sibling tools like list_operations. The verb 'explain' and resource 'operation' are specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for when detailed information about a specific operation is needed, contrasting with listing all operations. It does not explicitly name an alternative, but the context 'one recipe operation' and the error fallback listing all valid operations provide clear guidance. No explicit exclusions, but sufficient context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

export_assetA
Destructive

Copy a revision's bytes out of the workspace to a destination path. Refuses to overwrite an existing file unless overwrite=true (ask the user first).

ParametersJSON Schema
NameRequiredDescriptionDefault
dest_pathYes書き出し先パス(ワークスペース外)。
overwriteNo既存ファイルを上書きしてよいか。既定 false(既存なら失敗する)。
revision_idYes書き出す revision ID("rev_...")。

Output Schema

ParametersJSON Schema
NameRequiredDescription
pathYes実際に書き出した絶対パス。
byte_sizeYes
overwrittenYes既存ファイルを上書きした場合 true。
revision_idYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide destructiveHint=true and readOnlyHint=false. The description adds meaningful behavioral detail: it refuses to overwrite unless overwrite=true and instructs the agent to ask the user first. This goes beyond the annotations and helps the agent avoid unintended data loss.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the first states the core operation, and the second front-loads the most important safety constraint. There is no filler or repetition of schema fields, making it highly efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple three-parameter tool with an output schema and clear annotations, the description covers the essential behavior: what the tool copies, where it copies to, and the overwrite guardrail with user-consent guidance. Nothing critical for invoking it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters. The description adds value by clarifying the overwrite behavior and the user-consent requirement, but it does not substantially deepen meaning for revision_id or dest_path beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Copy') and resource ('a revision's bytes') and states the destination context ('out of the workspace to a destination path'). This clearly distinguishes it from sibling tools like import_asset, which would perform the reverse operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The purpose makes the tool's usage context clear, but the description does not explicitly say when to prefer this tool over alternatives or mention any exclusions. The overwrite caveat is behavioral guidance rather than selection guidance, so usage direction is mostly implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generate_maskA
Idempotent

Generate a deterministic grayscale mask as a new PNG revision, with exactly the dimensions of reference_revision_id. kind is "linear_gradient" (angle_degrees, start, end), "radial_gradient" (center_x, center_y, radius, feather), "luminosity_range" (min, max, feather) or "color_range" (hue_center, hue_width, feather); the gradients use only the reference's dimensions, the other two compute weights from its pixels. White = the masked operation applies fully, black = not at all. Reference the returned revision_id from any tone/filter operation as "mask": {"revision_id": "rev_...", "invert": false, "feather_px": 0}, or visualise it with render_preview overlay="mask". Idempotent: the same params over the same reference produce byte-identical PNG bytes and return the existing revision.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNolinear_gradient: 軸上で重みが 0.0 に達する位置(0..1、`start` 以上)。既定 1.0。
maxNoluminosity_range: 完全に選択される輝度域の上限(0..255、`min` 以上)。既定 255。
minNoluminosity_range: 完全に選択される輝度域の下限(0..255)。既定 0。
kindYes`"linear_gradient"` | `"radial_gradient"` | `"luminosity_range"` | `"color_range"`。
startNolinear_gradient: 軸上で重みが 1.0 のままでいる終端位置(0..1)。既定 0.0。
radiusNoradial_gradient: 重みが 1.0 の内円の半径(対角線の半分に対する比 0..1)。既定 0.5。
featherNo減衰帯の幅。radial_gradient では対角線の半分に対する比(0..1、既定 0.25)、 luminosity_range では輝度単位(0..255、既定 16)、 color_range では色相の度数(0..180、既定 15)。linear_gradient では使わない (`start`/`end` の間隔がフェザそのもの)。
center_xNoradial_gradient: 中心の X(画像幅に対する相対値 0..1)。既定 0.5。
center_yNoradial_gradient: 中心の Y(画像高に対する相対値 0..1)。既定 0.5。
hue_widthNocolor_range: 中心からの**片側**幅(度、1..180)。既定 30。
hue_centerNocolor_range: 中心色相(度、0..360)。必須。
angle_degreesNolinear_gradient: グラデーション軸の角度(度)。0 = 上が白で下へ向かって黒、 90 = 左が白で右へ向かって黒(正の角度で時計回り)。既定 0。
reference_revision_idYes寸法(と、輝度/色域マスクでは画素)の供給元になる画像 revision ID。

Output Schema

ParametersJSON Schema
NameRequiredDescription
kindYes生成した種別(`linear_gradient` 等)。
nextYes次の一手(op への参照の仕方)。
widthYes
heightYes
reusedYes同じマスクが既に生成済みで既存 revision を返した場合 true(冪等ヒット)。
revisionYes
generatorYes既定値まで解決したパラメータの正規化 JSON(origin の generator と同一文字列)。
mean_weightYesマスクの平均重み(0..1)。1 に近いほど広く、0 に近いほど狭い被覆。
reference_revision_idYes参照した画像 revision(寸法・画素の供給元)。

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes beyond annotations by detailing the deterministic and idempotent behavior (same params produce byte-identical PNG and return existing revision). It also clarifies what the mask represents (white = full application, black = none) and that gradients use dimensions while ranges use pixels. The idempotentHint annotation is confirmed and expanded with specifics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is moderately long but every sentence serves a purpose: it defines the function, parameter kinds, output semantics, usage example, and idempotency. The front-loaded summary of kinds is efficient, and the JSON usage example is compact yet informative. No fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (13 parameters, 4 kinds) and presence of output schema, the description covers key aspects: output semantics, idempotency, and usage integration. It omits explicit return value format (though output schema exists) and some edge cases, but the examples and schema descriptions cover most. The description is sufficient for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with detailed descriptions for each parameter including default values and units. The description adds clarity by grouping parameters by kind and explaining the common semantics (like feather behavior) but does not add substantial new information beyond the schema. The description's parameter list matches the schema and provides complementary context (e.g., which parameters apply to which kind), but this is largely redundant.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: generating a deterministic grayscale mask as a new PNG revision with exact dimensions from a reference. It enumerates four distinct mask kinds with their parametersholistic details, and explains the white/black semantics. This distinguishes it from siblings like render_preview or apply_transform by focusing on mask generation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains how to use the result: referencing the returned revision_id in tone/filter operations with a concrete JSON example, and how to visualize it with render_preview overlay. It does not explicitly mention when not to use it, but the detailed operation contracts and idempotency note provide clear context for typical use cases. The alternatives are implied by sibling tools, and the usage examples are sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

import_assetA
Idempotent

Import a local image file into the workspace and issue an immutable revision. Pass either path (one file) or paths (a batch of up to 64; one bad file does not abort the batch, it lands in failed) - exactly one of the two. Idempotent: importing the same bytes again returns the existing revision. If the imported bytes are already the output of a recipe held in this workspace, the result carries a warning plus already_derived_from so the same recipe is not applied twice.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNo取り込むローカルファイルの絶対パス(または cwd からの相対パス)。 `paths` とは排他で、どちらか一方が必須。
pathsNo複数ファイルを1回で取り込む(1..=64 件)。`path` とは排他。 1件が失敗してもバッチは中断せず、`failed` に理由が入る。

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the idempotentHint annotation by describing immutable revisions, partial batch failures, and the already_derived_from warning. These behaviors are not inferable from annotations alone and are critical for correct invocation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tightly packed sentences with no fluff. The core contract, parameter choice, and edge cases are all covered efficiently, and the most important information comes first.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the invocation contract, failure mode, idempotency, and duplicate-recipe warning. With an output schema present and annotations providing the safety profile, nothing essential is missing for correct use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents path/paths exclusivity, batch size, and failure behavior. The description reinforces exactly-one selection and batch failure semantics but adds little new parameter-specific information beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Import a local image file into the workspace and issue an immutable revision.' This clearly distinguishes it from sibling tools like export_asset by direction and outcome.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit guidance for the two mutually exclusive invocation modes (path vs paths) and explains batch failure behavior. It does not name alternative sibling tools explicitly, but the import/export contrast and local-file scope make the intended use clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inspect_imageA
Read-onlyIdempotent

Inspect a revision: dimensions, MIME type, byte size, alpha/ICC presence, EXIF orientation and summary, and whether GPS (PII) metadata is present.

ParametersJSON Schema
NameRequiredDescriptionDefault
revision_idYes対象 revision ID("rev_...")。

Output Schema

ParametersJSON Schema
NameRequiredDescription
infoYes
pathYes
revision_idYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is clear. The description adds meaningful behavioral detail by listing the specific metadata categories inspected, including the noteworthy GPS/PII check, which goes beyond the annotation fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single compact sentence that front-loads the core action and then uses a colon-delimited list of concrete inspected properties. There is no filler or redundant restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the single simple parameter, the presence of an output schema, and annotations that fully define the operation's safety and idempotence, the description is complete enough for an agent to select and invoke the tool correctly. It even calls out the privacy-relevant GPS/PII aspect, which is useful context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is only one parameter, revision_id, and the schema description covers it fully (100% coverage), including the 'rev_...' format. The description adds no additional parameter-specific semantics, 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.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Inspect') and a specific resource ('a revision'), then enumerates exactly what is inspected: dimensions, MIME type, byte size, alpha/ICC, EXIF, and GPS/PII presence. This clearly distinguishes it from siblings like render_preview or compare_revisions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies its use case (metadata inspection of a revision) but does not explicitly state when to prefer it over alternatives or when not to use it. There are no exclusionary or comparative statements referencing sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_assetsB
Read-onlyIdempotent

List revisions in the workspace ledger (lineage, recipe hash, dimensions, sizes).

ParametersJSON Schema
NameRequiredDescriptionDefault
asset_idNo指定した asset_id の revision だけに絞る。省略時は全件。

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYes
revisionsYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is clear. The description adds that it lists revisions and includes specific data fields, which is useful context but does not disclose behavioral traits like pagination or ordering. With annotations covering safety, a 3 is appropriate; no contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One concise sentence that front-loads the action and includes only essential information. No filler or redundancy; every word contributes to clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with one well-documented parameter, an output schema, and safety annotations, the description is sufficient for correct invocation. It does not explain domain-specific terms like 'workspace ledger', but that is likely implicit in the system context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for the single parameter asset_id, which includes a clear description (filter by asset_id, omit for all). The tool description adds no additional meaning beyond what the schema already provides, so the baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action (List) and resource (revisions in the workspace ledger), and enumerates returned fields (lineage, recipe hash, dimensions, sizes). It distinguishes from siblings like list_operations by focusing on revisions. However, the tool name 'list_assets' suggests assets rather than revisions, creating slight ambiguity about what is being listed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives, nor any exclusions or conditions. An agent must infer usage from the name and description alone; there is no explicit 'use when...' or 'instead of...' context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_operationsA
Read-onlyIdempotent

Compact catalog of the recipe vocabulary: every operation with a one-line description and its parameter names with terse type/range hints, plus the built-in preset names. Optional category ("geometry" | "color" | "filter" | "output") narrows the list. Call explain_operation for the full schema of one operation. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
categoryNo絞り込む分類(`"geometry"` | `"color"` | `"filter"` | `"output"`)。省略時は全件。

Output Schema

ParametersJSON Schema
NameRequiredDescription
opsYesop の名前と分類だけ。要約・パラメータはテキスト側 / `explain_operation` 側。
countYes
presetsYesビルトインプリセット名(`apply_transform` / `render_preview` の `preset` に渡せる)。 説明はテキストサマリ側にだけ載せる。

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds behavioral context by specifying what the catalog contains and that category narrows the output. It also repeats the read-only property, which is consistent 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: it states what the tool returns, then covers the optional filter, the sibling tool to use for more detail, and the read-only nature. Every sentence earns its place with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple single-optional-parameter interface, an output schema, and annotations that already convey safety, the description provides everything needed to invoke the tool correctly. It includes the category values, the filtering behavior, and the fallback tool for deeper detail. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 the category parameter, including its allowed values and default behavior. The description adds 'narrows the list' but does not materially go beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific purpose: listing every operation in the recipe vocabulary with one-line descriptions, parameter hints, and preset names. It differentiates itself from explain_operation by explicitly directing users there for full schema details. This is far beyond a vague or tautological description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the optional category filter and its allowed values, and explicitly names explain_operation as the alternative when full schema details are needed. This gives an agent clear guidance on when to use this tool versus its sibling. The read-only note reinforces safe usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

render_previewA
Idempotent

Render a recipe as a small JPEG preview (long edge <= 768 by default) and return it inline plus a file path, so the composition can be checked before committing to apply_transform. Takes either recipe or preset, exactly like apply_transform. Optional long_edge (256..=1568) sets the preview size: raise it to 1568 when the point of the preview is to READ text in the image; 768 is too small for that. Optional overlay ("grid" | "thirds" | "horizon") draws semi-transparent composition guide lines on the returned preview only (never on the apply_transform output). overlay="mask" instead visualises a mask: pass mask_revision_id (required for this overlay and rejected for the others) and the preview is tinted red where the mask weight exceeds 0.5 and dimmed elsewhere, so the coverage can be eyeballed. Note: if the recipe's encode format is png, webp, or avif, any ICC color profile on the source is dropped (embedding is only supported for jpeg output); this is reported as a warning, not an error.

ParametersJSON Schema
NameRequiredDescriptionDefault
presetNoビルトインプリセット名。`recipe` とは排他。
recipeNo変換レシピ。`{"operations": [...]}`。`preset` とはどちらか一方のみ指定する。
overlayNo構図確認用のガイド線。`"grid"`(1/8 刻みの格子)| `"thirds"`(三分割法)| `"horizon"`(1/12 刻みの水平線のみ、傾き目視用)| `"mask"`(マスクの被覆可視化。 `mask_revision_id` が必須)。省略時はオーバレイなし。
long_edgeNoプレビューの長辺(256..=1568)。省略時は 768。 文字を読む用途では 1568 まで上げる(DESIGN.md §9.12)。
revision_idYes入力 revision ID("rev_...")。
mask_revision_idNo`overlay: "mask"` で可視化するマスク画像 revision ID。 `overlay` が `"mask"` のときのみ指定でき、そのときは必須。

Output Schema

ParametersJSON Schema
NameRequiredDescription
widthYes
heightYes
overlayNo適用した overlay。未指定なら null。
warningsYes
byte_sizeYes
mime_typeYes
recipe_hashYes
preview_pathYesプレビュー画像の絶対パス。
engine_versionYes
mask_revision_idNo`overlay: "mask"` で可視化したマスクの revision ID。それ以外では null。
source_revision_idYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context: the preview is returned inline plus a file path, overlay lines are drawn only on the preview and never on apply_transform output, and the ICC color profile dropping behavior for non-jpeg encode formats is disclosed as a warning. This goes beyond the annotations and helps the agent anticipate side effects and edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized: it front-loads the core purpose and return behavior, then explains optional parameters and edge cases. Every sentence adds information. It is longer than a typical description, but the complexity of the tool (multiple overlays, conditional mask_revision_id, ICC profile caveat) justifies the length. Slight redundancy with the schema's parameter descriptions prevents a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

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, conditional requirements, multiple overlay modes, output schema present), the description covers all essential behavioral aspects: what is returned, when to use it, how to choose long_edge, how overlays work, the mask_revision_id condition, and the ICC profile warning. The output schema exists, so return values need not be described in detail. Nothing critical is missing for an agent to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters. The description adds meaning beyond the schema by explaining the purpose of long_edge (768 is too small for reading text, raise to 1568), the exclusivity of recipe/preset, and the conditional requirement of mask_revision_id for overlay='mask'. It also clarifies that overlay lines never appear on apply_transform output. This is meaningful added value, though the schema already carries the basic semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Render'), a specific resource ('a recipe as a small JPEG preview'), and the purpose ('so the composition can be checked before committing to apply_transform'). It clearly distinguishes itself from the sibling apply_transform by emphasizing it is a preview-only operation. The description also names the key alternatives (recipe or preset) and the optional overlay modes, making the tool's role unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use this tool ('before committing to apply_transform') and names the sibling apply_transform as the alternative. It also gives concrete guidance for parameter choices: raise long_edge to 1568 when reading text, use overlay modes for composition guides, and use overlay='mask' with mask_revision_id for mask coverage. This is explicit, actionable usage 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. 12 tool updatesv0.5.2
    • First observedapply_transform
    • First observedcompare_revisions
    • First observeddetect_document
    • First observeddetect_tilt
    • First observedexplain_operation
    • First observedexport_asset
    • First observedgenerate_mask
    • First observedimport_asset
    • First observedinspect_image
    • First observedlist_assets
    • First observedlist_operations
    • First observedrender_preview

TDQS

A4.3/5.0

Scored across 12 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: apply_transform and render_preview are differentiated by output resolution and intent, detect_document and detect_tilt are both read-only but target different geometric features, and the asset management tools (import/export/list/inspect) have no overlap. No two tools could be confused.

Naming Consistency5/5

All 12 tools follow a consistent verb_noun pattern in snake_case (e.g., apply_transform, compare_revisions, list_assets). No deviations or mixed conventions.

Tool Count5/5

12 tools is well-scoped for an image processing and asset management server. Each tool earns its place covering the core workflow: import, inspect, transform, preview, apply, export, plus detection, mask generation, comparison, and reference operations.

Completeness5/5

The tool surface is complete for its domain: import (import_asset), list (list_assets), inspect (inspect_image), transform (apply_transform), preview (render_preview), export (export_asset), and supporting operations like detect_document, detect_tilt, generate_mask, compare_revisions, explain_operation, and list_operations. No obvious dead ends; even idempotency is handled. The only potential gap is lack of delete/update, but revisions are immutable by design, so that's intentional.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers