Aseprite MCP
An MCP server that lets an AI agent create, edit, animate, validate, and export Aseprite pixel-art sprites headlessly.
Create/manage sprites: new
.asepritefiles, RGB/indexed/gray modes, resize, crop, scale, flatten, trim, save copies, import flat images.Draw and edit pixels: pixels, pixel maps, lines, polylines, curves, rectangles, ellipses, flood fill, brushes, patterns, gradients, checkerboards, text, outlines, drop/cast shadows, color replacement, inversion, brightness/hue/saturation adjustments.
Organize assets: layers/groups, frames, cels, cel linking/z-index, animation tags, slices/9-patch, pivots, custom properties.
Manage palettes: read/set/edit/load/extract/sort/quantize palettes, generate/ramp-between/ramp-from-art ramps, cycle palettes, set transparent index.
Animate and check motion: add/duplicate/move frames, set durations, tween/offset/smear cels, apply timing curves, validate loops and contact/timing faults.
Shade and light: ramp-aware shading, gradient mapping, specular highlights, contact/cast shadows, glow, dither bands, smart outlines, stray-pixel cleanup.
Build tilemaps and references: tilemap layers, tiles, tile pixels, grid placement/fill/read, reference layers and image sequences for rotoscoping.
Inspect and self-correct:
get_sprite_info,render_preview,get_pixels,assess_sprite,diff_sprites,list_sprites,health_check.Export for games: PNG, GIF, tag GIFs, sprite sheets, packed sheets, frames, layers, tags, onion skin, Godot SpriteFrames, slice metadata, Minecraft textures/resource packs, game asset bundles.
Scaffold workflows and batch: characters, idle animations, tilesets, icon sets, RPG item sheets, 8-direction walk templates, asset specs; atomic
apply_operationswith dry-run.Run safely: workspace-sandboxed paths by default, no-clobber outputs, bounded work/timeouts, no shell injection, optional live Aseprite GUI companion.
Provides tools for creating and editing Aseprite sprites, including drawing, animation, layers, frames, tags, palettes, effects, text, tilemaps, and exporting to PNG/GIF/sprite sheets.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Aseprite MCPCreate a 32x32 pixel art of a red apple and export as PNG."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Aseprite MCP
An extensive Model Context Protocol server that lets an AI agent (Claude Code, Claude Desktop, or any MCP client) create and edit Aseprite sprites: draw pixel art, build animations, manage layers/frames/tags/palettes, and export to PNG/GIF/sprite sheets, all headlessly.
📖 Full tool reference: docs/TOOLS.md: every tool with its parameters.
It works by generating Lua scripts and running them through Aseprite's batch mode
(aseprite -b --script ...), plus the Aseprite CLI for exports. Every operation opens a
real .aseprite file, edits it, and saves, so your files stay fully editable in the
Aseprite GUI.
163 tools across every part of a sprite: drawing (pixel-perfect and anti-aliased), custom brushes and symmetry, ramp-aware shading, selections that scope later edits, palettes, layers, frames, cels, animation tags, slices and 9-patch, effects, text, tilemaps, transforms, and export (per-layer, per-tag, sprite sheets, GIF, onion-skin, Godot, Minecraft). See the tool catalogue or the full reference.
Whole assets in one call - workflow tools scaffold and validate a character, an icon set, a tileset or an eight-direction walk template, and a batch op-runner applies hundreds of edits atomically in a single Aseprite process.
Shading that stays on the palette -
shade_region_by_lightturns a flat region into a lit form from a ramp and a light direction (with an optional second, weaker fill light so the shadow side stays readable),gradient_mapbrings imported or filtered art onto a ramp in the first place, andspecular_highlight,contact_shadow,cast_shadow,glow,outline_smartanddither_bandfinish it. A brightness filter moves every pixel off the palette; these move pixels along the ramp, so the art still uses exactly the colours it was given. A glow of blended alpha or a shadow of multiplied alpha would break that, which is why both are built of ramp steps arranged in space instead.Indexed mode that draws -
create_spritegives an indexed sprite a real 33-entry palette (a transparent entry at index 0, then Aseprite's 32 defaults) rather than the 256 identical blacks that made every colour equidistant, so every draw resolved to index 0 and vanished while reporting success.set_color_modequantizes the palette from the art instead of mapping onto whatever the file happened to carry, and refuses a conversion that would make drawn pixels disappear.Work you can check -
assess_spritemeasures the drawing itself: pixels with no neighbour of their own colour, jagged diagonals, how much of the canvas the art fills, whether it is centred, and what fraction of it sits exactly on a declared ramp. An agent cannot look at its own sprite, so every fault comes back as a line saying what it is and which tool puts it right, andremove_stray_pixelsis the one that answers for noise.Edits you can check -
diff_spritescompares two frames and says what changed, in buckets that mean different things: pixels that entered or left the silhouette, pixels repainted inside it, and pixels that changed only their alpha. An edit that silently went nowhere, to the wrong layer, inside a stale selection, off the canvas, looks exactly like an edit that was not needed, so "nothing changed" is reported loudly rather than quietly. Passexpect=to turn the measurement into a check.Animation you can check -
offset_celsmoves a cel along a line or an arc across any number of frames in one launch, with the spacing distributed so it reads as speed rather than as a limp;tween_celsdoes the other three things an inbetween does, scaling, turning and fading one drawn cel across frames, with the anchor on the contact edge so a squash lands on the ground;smear_framedraws one frame's subject along its own movement, stepping down a declared ramp so the trail stays on the palette;apply_timing_curvegives the cycle a shape in time by setting durations, never by duplicating a frame; andvalidate_loopmeasures the result and names the faults a still frame hides: a wrap frame repeating the first, a pose held by duplication, placeholder timing, a contact edge that drifts.Calls you can check - the three bullets above measure the artwork; this one measures the call. A tool that did something other than what it was asked for is the failure this server keeps finding, and it is always quiet, so the result says what happened rather than that it happened. A write whose selection excluded every pixel reports
pixels_outside_selectionrather than a bareok.shade_region_by_lightandspecular_highlightreportregion_componentsandregion_bounds, becausebase_colorscopes by colour distance and two materials' ramps are routinely closer than the default tolerance: every step of a gold ramp is within it of a step of a brass one, so a pass can land somewhere its caller never looked.generate_rampreportsdistinctand, when lightness clamping has collapsed two steps onto one colour, thelight_rangethat would not have.dither_bandnames the two colours its 1-based steps resolved to. Every one of those exists because its absence cost a debugging session, and the showcase generators are where they were spent. Pixel art is authored, not rendered, and the server now takes it that way:draw_pixel_mapaccepts the same character gridget_pixels(format="map")emits, so per-pixel intent can be written down and read back. A caller handed only a thousand-entry coordinate list does not write a thousand considered pixels, it writes a formula that emits them, and a formula produces the smooth monotone surfaces that make generated pixel art look generated. The shape is uniform rather than nearly uniform: every result that describes a sprite carriesok, which thirty of them did not until the key moved into the one function they all return through, and a workflow manifest reports the same pixel counters at its top level as a bare call does, so one check reads both.Sandboxed file access: by default the file capability is scoped to the workspace (relative paths only; absolute/
..paths rejected unless you opt in).No-clobber by default: output-writing tools refuse to overwrite an existing file; pass
overwrite=Trueto replace it intentionally.Structured results: every editing tool returns JSON describing the updated sprite, and every pixel-writing one returns how many pixels it wrote, clipped, skipped, or lost to an active selection.
render_previewreturns a PNG so the agent can see its work and self-correct.Deterministic, stateless, robust: each call is an isolated, headless Aseprite run.
Contents
What the tools produce, with the numbers behind it: a lit scene, an equipment sheet, per-cel ordering, palette reduction | |
Getting it running | |
Claude Code, Claude Desktop, Cursor, Codex, Continue, Zed, Goose (full guide) | |
Whole assets in one call; many edits in one process | |
All 163 tools by domain (full reference) | |
Watching edits land; an end-to-end run | |
Architecture, the sandbox, and what is enforced | |
Honest edges, and what to do when something breaks |
Related MCP server: aseprite-mcp
Showcase
Every image here was produced entirely through MCP tool calls, and every number under them is real output from the same run.
Shade a form, not a filter
create_sprite("orb.aseprite", 32, 32)
ramp = generate_ramp("#5a7fd4", steps=5, hue_shift=-40, saturation_shift=-18)["colors"]
draw_ellipse_in_box("orb.aseprite", 4, 4, 24, 24, ramp[2], filled=True)
shade_region_by_light("orb.aseprite", ramp, light_angle=125, light_z=0.55, rim=0.25)
dither_band("orb.aseprite", ramp, from_step=1, to_step=2, pattern="bayer4", width=2)
outline_smart("orb.aseprite", ramp, darken_steps=2, light_angle=125)A brightness filter would have moved every pixel off the palette. These tools move pixels along the ramp, so the result still uses exactly the five colours it was given: the shading is made of the palette rather than applied on top of it.
Animate it, then measure the animation
frames = list(range(1, 13))
offset_cels("throw.aseprite", "ball", frames, dx=46, arc_height=20) # the arc
offset_cels("throw.aseprite", "shadow", frames, dx=46) # straight along the ground
apply_timing_curve("throw.aseprite", curve="hold_extremes", base_ms=70)
validate_loop("throw.aseprite", layer="ball", loops=False)spacing 8.06 6.4 6.4 5.0 4.03 4.0 4.03 5.0 6.4 6.4 8.06
contact_row 32 25 20 16 13 12 12 13 16 20 25 32
durations 175 70 70 70 70 70 175 70 70 70 70 70
passed: trueAn agent cannot watch a GIF play. It can read that the spacing is symmetric about the apex, that the ball slows as it rises and speeds as it falls, and that the extremes are held two and a half times as long as the passing frames.
Reorder one cel, not the layer stack
set_cel_z_index("swing.aseprite", "sword", frame=2, z=0) # blade behind the shield
set_cel_z_index("swing.aseprite", "sword", frame=3, z=2) # blade in front, same layerA blade that crosses a shield is behind it on the approach and in front of it on the follow-through, and a layer stack cannot say that: a layer's position applies to every frame at once. Moving the layer changes the other frames; duplicating the sword onto a second layer means hiding one of the two per frame and keeping two drawings in step forever.
z is an offset on the layer's own stack position, so 0 means "wherever this layer
sits" and a cel one layer down needs only z=1 to draw in front of the one above it. The
result reports the frame's competing cels back to front, because a number alone does not
tell you the arm moved:
frame 2 z=0 renders: sword then shield pixel (45,20) is #5c7a3a, the shield's oak
frame 3 z=2 renders: shield then sword pixel (45,20) is #eef1f5, the blade's steelThat pixel is the whole claim, and the generator asserts
it: a z-index that round-tripped through the file while
changing nothing about the render would produce an identical-looking strip. The blade is
drawn long enough to show its tip on the far side, because "behind" only reads as
occlusion when you can see both ends of the thing being occluded. Note also that
z is refused outside -32768 to 32767, because the editor accepts a larger number in
memory and then stores it in a 16-bit field, so saving and reopening turned 32768 into
-32768.
Turn a blend into pixel art
quantize_palette("dusk.aseprite", max_colors=14) # derive a palette from the art
set_color_mode("dusk.aseprite", "indexed", palette_source="keep") # then map the art onto itextract_palette reports the colours an image already uses and set_color_mode maps art
onto a palette that exists; quantize_palette is the step in between, deriving a small
palette from the artwork.
It is two calls on purpose, and the first one touches no pixels. Quantizing derives the palette and says so:
max_colors=14 palette holds 14, art has 117, 8 of them exactly
warning: 109 of the 117 colours in the art are not in the derived palette and will be
approximated by their nearest entry when the sprite is converted to indexed.
converted to indexed 3888 drawn pixels, verified=True, now 13 coloursverified=True is the conversion confirming it did not lose a single drawn pixel, which
is the one thing a mode change must never do quietly. max_colors is also a ceiling with
a cliff in it: a budget equal to the number of colours in the art is where the reduction
collapses, and four colours at max_colors=4 come back as one averaged grey while
max_colors=5 returns all four. The result says which happened rather than reporting a
clean reduction either way.
Light a room, not a sprite
Three things in that picture are worth more than the picture.
Thirty-five blocks, one shading call. shade_region_by_light builds a distance field
over everything matching one base colour, and a field over a mask with thirty-five
disconnected parts describes each part on its own. The mortar joints are what make the mask
thirty-five components instead of one slab, so the whole wall takes its form from a single
call:
shade_region_by_light("dungeon.aseprite", STONE, base_color=STONE[8],
light_angle=155, bulge=0.75, tolerance=1.0, layer="wall")An earlier version of this section claimed that and left out what it cost. The claim is only
worth anything if the blocks come out different, and with every block 17 pixels wide they
did not: a distance field over two components of the same size is the same field twice, so
same-sized blocks are shaded identically and differ only in how far the falloff pushed them.
Measured by normalising value away, so two blocks count as the same when their pixels rank
the same whatever their brightness, 8 of 24 sampled blocks came back pixel for pixel
identical at 6 tones, all in the dim zone where shift_along_ramp had clamped their darks
together. The far wall was one tile repeated.
Two changes fixed it, and the generator now asserts both. Block widths cycle through
(17, 11, 23, 14, 20) with a per-course phase, so the fields differ; and the ramps are
thirteen steps rather than nine, so a darkened block still has somewhere to go:
wall: 35 blocks, 31 distinct shading patterns, 28 of them unique, every block at 4 tones or moreThe falloff is zones down a ramp. No tool here lights a scene from a point, and faking
one by blending would land every pixel between palette entries. shift_along_ramp moves a
rectangle one or two steps down the surface's own ramp instead, which is how a pixel artist
builds a falloff. The trick is hiding the seams, and that is why it is a rectangle per
course rather than one band across the room: the only cut that does not show is one along a
joint, and because the courses are staggered no single column is a joint on all of them.
falloff (one rectangle per course per zone)
wall 45 blocks, 12 runs darkened, 6 blocks off-value
floor 22 blocks, 8 runs darkened, 4 blocks off-value
floor row 56: step 8 at x=20, step 3 at x=95That last line is asserted by the generator, because a falloff nobody measured is a falloff you have to take on trust. At one step a zone the assertion still passed and the room still looked evenly lit, which is a measurement being satisfied by something no reader can see. The reverse cost more: that same assertion went on passing while the far wall was a repeating tile, because nothing was measuring that. An assertion covers the failure it was written for and no other, which is why there are now three of them on this one picture.
The flicker is four frames with four durations. set_all_frame_durations would give an
even pulse, and an even pulse reads as a machine rather than as fire. The flame also leans a
different way and stands a different height on each frame, and the generator asserts all
four silhouettes differ:
flame rows lean ms halo
frame 1 14 +0.00 90 115 pixels in 3 rings
frame 2 12 +0.18 70 103 pixels in 3 rings
frame 3 15 -0.14 110 122 pixels in 3 rings
frame 4 12 +0.10 80 116 pixels in 3 ringsThe torchlight is the wall, brightened. This is the part that took the longest to get
right, and the answer turned out not to be a tool. Three drafts used glow, whose rings are
ramp steps rather than alpha, and all three read as a sticker. glow grows its rings
outward from the subject's silhouette, so a tall narrow flame gives a tall narrow egg with
a hard elliptical boundary, and it paints at full opacity, so inside it the mortar joints
and the block shading vanish into a smooth oval. Light brightens a surface. It does not
erase it.
So the pool is the masonry moved up its own ramp, by however many steps the distance from the flame allows:
lift = round(POOL_GAIN * (1.0 - reach / POOL_RADIUS) ** 2)
target = min(step + lift, len(STONE) - 1)Every pixel on that wall is already an exact ramp entry, so finding its step is a table
lookup and lifting it is arithmetic on an integer. One get_pixels over the pool's bounding
box, one draw_pixels back:
light pool: lifted 1503 wall pixels up their own ramp, 0 off-ramp and left aloneThe joints lift too, which is exactly why the masonry survives inside the light. glow is
still there, at radius=3, for the heat right at the flame, which is the job it is good at.
The sconce casts onto the wall it is bolted to, with light_angle=90 and a high
light_height so the shadow falls straight down and short. It had none for three drafts,
which is the single commonest reason a lit object reads as pasted on.
The floor recedes. Its courses grow taller and its stones grow wider down the frame, because flat equal courses read as a second wall lying down:
floor: course heights [5, 6, 7, 8], stone widths [17, 21, 26, 31], down the frameWhere it meets the wall there is a shorter, darker skirting course and then three rows of flagstone stepped down their own ramp, rather than the four flat full-width rows an earlier version put there. That did stop two surfaces of grey blocks reading as one wall, the way a letterbox bar stops a bad crop.
The chest's shadow is cast_shadow with ground_layer="floor", which clips it to the
flagstones so it cannot run off the floor and hang in the air, and it uses the floor's ramp
rather than the chest's, because a shadow is a darkening of what it lies on. The chest's own
contact shadow had to move: contact_shadow takes the occluder's colour, and run after the
brass pass that had already repainted the straps, only 3 pixels of the chest were still the
colour it was given. It runs before that pass now and reports 102 darkened wood pixels,
which the generator asserts is not zero.
Animate a palette, not the pixels
Every other animation here moves something. This one moves nothing: there is one drawn
frame, and the lava flows because its indices rotate. cycle_palette generates the
timeline from that single frame, and the twenty-four frames of the loop contain no new
drawing at all.
The technique constrains the art rather than the other way round, and
lava.py records the three drafts it took to learn how. A
rotation can only translate a pattern that is monotone in index space, so the lava has
to be painted as a sawtooth of consecutive indices laid across the direction of travel; a
triangle would reflect instead of flowing. The run has to close, because a one-way dark
to white ramp puts a bright-to-black seam at every wrap, which reads as a moving staircase.
And it has to be long and weighted: with eight entries the bright one recurs every eight
pixels, which is a bright line every eight pixels however the brightnesses are arranged, so
the fall came out as a drill thread. This run is twenty-four entries of which twelve are
crust that barely differ, built by three ramp_between calls joined at shared ends, and
what travels is the crack.
The direction is a sign, and not the one you would reason to. step=1 puts frame two's
row y where frame one's row y - 1 was, so the pattern travels down and the cataract
falls. The first draft had it running uphill.
The cataract and the pool drift differently, and both come out of the same call: the fall is banded by row and the pool across the flow, so one rotation moves one down and the other sideways. Nothing in the generator says "move this down and that right".
The stone is the control, and the generator holds it to that: it reads the same rock window
on all twenty-four frames and requires it unchanged, which is what separates "the colours
rotated" from "the picture was redrawn". It also checks the flow by comparing two frames
through a shifted window, which is how the backwards step was caught. Aseprite's Lua API
exposes no per-frame palette (measured on 1.3.18.6 and written down in cycle_palette's own
docstring), so the rotation is applied to the pixels' own indices and the result says which
mechanism ran: method: "pixel_remap". On an indexed sprite the two are the same picture,
and the move never routes a colour through a nearest-entry match, so the palette comes back
byte for byte.
Scaffold a one-shot, and let the timing do the hitting
A one-shot is where a scaffolded animation goes wrong in three ways at once: the frame count
is a guess, the frames are numbered instead of named, and the whole thing is tagged as a loop
with uniform timing. scaffold_cycle(kind="attack") settles all three before a pixel is
drawn, and attack.py is the drawing laid over what it built.
The timing is the part worth looking at, and it is not the timing you would guess. The curve puts the 24-millisecond frame on the swing, not on the impact:
phase | duration | why |
anticipation | 240 ms | the wind-up, held long enough to read as intent |
swing | 24 ms | one frame you barely see, which is what makes it a snap |
impact | 200 ms | held, because the hit has to land rather than flash past |
recoil | 80 ms | |
recover | 80 ms |
That ordering is the craft: the fast frame is the blur between poses, and the pose that has to be understood is the one that holds. Uniform timing at 80 ms would run the same five drawings in the same order and read as a shove. The generator pins the snap to frame two for exactly that reason, because "the shortest frame is the impact" is the plausible wrong answer and a test that only checked for non-uniformity would accept it.
Each phase gets a tag named for the pose (attack_anticipation through attack_recover,
plus attack over the whole cycle), and every one is written with repeats=1 rather than
left at 0, which means "play forever" in the file format. That field is what validate_loop
reads, so a one-shot tagged as a loop makes the checker report a duplicated seam frame on an
animation that has no seam. The per-phase tags matter as much as the whole-cycle one, since a
single-frame tag left looping says "hold this pose forever".
validate_loop also found an art bug here, which is the kind of thing this server is for: it
reported the drawn content's bottom row moving 4px across the phases, because the recover
blade was swinging clean through the floor. Fixing the arc did not end it either, since the
centreline then cleared the ground and the blade's own thickness still did not. The
generator checks that directly now, because a background was added and the contact
measurement stopped being able to say so.
Make fast movement read as speed, in colours the sprite already had
Two frames of something moving quickly are two frames of it being in two places, which the
eye reads as teleportation. A smear is the frame an animator draws to fix that, and
smear_frame takes the movement vector from the cels themselves, so there is nothing to
keep in sync with the drawing. Top to bottom: the movement as it arrives, the stretch
smear that elongates the subject back along its path, and the echo smear that draws it
several times.
The trail is made of colours the sprite already had. Each pixel of it is the nearest
ramp entry to the subject's own colour there, stepped toward the dark end and clamped, so
the smear never invents a colour and palette_conformance stays at 1.0.
smear.py asserts that directly: every colour in the trail is
on the ramp it was given, the trail lies between the two positions, and the subject's own
pixels are untouched because the trail goes behind it.
This piece is indexed on purpose, because smear_frame was the one ramp-taking tool
with no reading of what its ramp becomes on a palette: it resolves the ramp in Python into a
lookup table and never passes a ramp to Lua, so the harness that measures that had nothing
to see. The reading exists now, and building this piece immediately taught three things the
docstring does not say.
A stretch trail asks for one shift level per ramp entry, so it is as long as the ramp, and it measures its room by where the subject's lightest colour sits. Two drafts went into lengthening the ramp and shortening the movement before the message was read properly: what fixed it was giving the sphere a specular highlight, so a pixel finally sat on the ramp's top step. A highlight turned out to be load-bearing.
And on a shaded subject the reading then fires anyway, in both modes, because the darker
pixels run out of ramp before the trail ends and clamp at the dark entry. That is not
avoidable by drawing better: the only subject that cannot clamp is one painted in a single
colour. The reading used to blame the palette for it and suggest adding colours, while its
own numbers said the palette held every target exactly
(#226). It now tells the two
apart, a clamp being copies that wanted one colour and a short palette copies that wanted
several, and gives each its own remedy: for a stretch, mode='echo'. The generator asserts
on the sentence as well as on trail_on_palette's counts, and the "crushed palette" case it
builds turned out to be clamps too: the two colours there that share a palette entry belong
to different parts of the subject, so no copy merges because of the palette.
Scaffold a whole asset in one call
validate_sprite_for_game_export -> passed (width, height, color_mode, min_frames, required_tags)
export_game_asset_bundle -> hero.png, hero.gif, hero_sheet.png (+JSON), hero_idle.gif, manifest.json
sword 17 colours, from 4 ramps and nothing else
shield 19 colours, from 3 ramps and nothing else
helm 12 colours, from 2 ramps and nothing else
key 9 colours, from 1 ramp and nothing else
scroll 14 colours, from 3 ramps and nothing else
sword: blade is rows 0 to 26, 68% of its height
centres: sword=19.5 shield=19.0 helm=19.0 key=19.5 scroll=18.5 spread 1.0Those checks earn their keep, and each of them was added after the thing it checks had already gone wrong.
The colour census: base_color scopes a shading pass by colour distance, and at the
default tolerance of 24 every step of a gold ramp is within reach of a step of a brass one,
so a pass meant for one item also matched art in a different cell and reshaded it. Nothing
looked wrong, and three rounds went into redrawing the wrong thing before the colours were
counted. That was #183, and it
is fixed: both tools report region_components and region_bounds now, so a pass scoped to
a 27px coin that comes back with a box spanning 200 pixels of canvas says so in its own
result. The census here stays, because a script asserting what it needs is cheaper to read
than one trusting that someone else asserted it.
The blade's share: a draft of this sword was 54% blade at a 1 to 2.3 aspect, which is a spearhead, and at inventory size it read as a crystal shard on a stick. 54% is not something anybody notices as a number, which is the whole reason for printing it.
The centre line: five items at five different heights read as five sprites from five games.
A fourth check, not shown here, asserts each glint's pixels are inside the part named for
it. Two of the four used to be wrong: scoped to a whole 40px cell, specular_highlight
built its normals from the entire compound object, and the sword's glint landed on its
leather grip while the blade had none. It is worth knowing that check has a hole in it
too, because the key passed it while still being wrong: it proves a glint is on the right
part, not on the right side of it.
Requirements
Aseprite 1.3+ (the scripting API). The Steam and standalone builds both work.
Python 3.10+
uv (recommended), or any PEP 517 installer.
Install
git clone https://github.com/MalloyTheDev/aseprite-mcp.git
cd aseprite-mcp
uv syncThat creates a virtual environment and installs the aseprite-mcp package and its
dependencies. The test suite comes in two tiers: the pure-Python tests always run, and
the ones that drive a real Aseprite are opt-in behind --run-aseprite (and skip, saying
so, when the flag is given and Aseprite cannot be found):
uv run pytest # pure-Python tests; no Aseprite needed
uv run pytest --run-aseprite # plus the integration and golden-output testsConfiguration
Everything is configurable via environment variables (all optional):
Variable | Purpose | Default |
| Full path to | Auto-detected (Steam, standalone, PATH). |
| Folder where relative sprite paths are resolved. |
|
| Per-operation timeout in seconds (clamped to 1-3600). |
|
| Allow absolute / workspace-escaping paths ( | off (sandboxed) |
|
|
|
stdio is the right default: it is what desktop MCP clients launch, and it keeps the
server reachable only by the process that started it. The HTTP transports exist for
agents that cannot spawn a local process. Treat them as a deliberate exposure decision:
this server's file access is scoped by a workspace directory, not by an identity, so
binding it to a reachable port gives every caller that can reach it the same filesystem
access the local user has. Bind to loopback, or put authentication in front of it.
On this machine Aseprite was detected at
C:\Program Files (x86)\Steam\steamapps\common\Aseprite\Aseprite.exe, so ASEPRITE_PATH
is not strictly required, but setting it explicitly is the most reliable.
Register with an MCP client
Using something other than Claude? docs/CLIENTS.md has a
copy-paste config block per client format (Codex CLI's TOML, Continue's config.yaml,
Zed's context_servers, Goose's extensions, and the mcpServers JSON that Claude
Desktop, Cursor, Cline, Roo Code, Windsurf and LM Studio share), the config file path for
each one, the launch form that avoids the Windows venv lock, and the strict-mode notes for
OpenAI or Grok style function-calling bridges. The two quick starts below cover the common
case.
Replace /ABSOLUTE/PATH/TO/aseprite-mcp below with the absolute path to your clone.
Claude Code (CLI)
claude mcp add aseprite -- uv --directory /ABSOLUTE/PATH/TO/aseprite-mcp run aseprite-mcpTo set the Aseprite path explicitly (recommended if auto-detection fails):
claude mcp add aseprite \
--env ASEPRITE_PATH="/path/to/Aseprite.exe" \
-- uv --directory /ABSOLUTE/PATH/TO/aseprite-mcp run aseprite-mcpClaude Desktop / generic MCP client (JSON)
Add this to your client's MCP server config (e.g. claude_desktop_config.json). A
ready-to-copy template lives in mcp-config.example.json
(Windows-style paths shown; adjust for your OS):
{
"mcpServers": {
"aseprite": {
"command": "uv",
"args": ["--directory", "C:\\path\\to\\aseprite-mcp", "run", "aseprite-mcp"],
"env": {
"ASEPRITE_PATH": "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Aseprite\\Aseprite.exe",
"ASEPRITE_MCP_WORKSPACE": "C:\\path\\to\\aseprite-mcp\\workspace"
}
}
}
}Restart the client; the aseprite server and its full tool set will be available (the
current count is at the top of docs/TOOLS.md). Ask the agent to run
health_check to confirm Aseprite is wired up correctly, and see
docs/CLIENTS.md for what the answer should look
like.
High-level workflows
Beyond the low-level tools, a few workflow tools scaffold a whole asset in one call and return a manifest (created files, paths, frames, tags, dimensions, and suggested next steps) so an agent can keep going. They compose the low-level tools: deterministic scaffolding, no AI generation.
Tool | Description |
| Transparent canvas + body/details layers + a generated shading ramp + an outlined placeholder. |
| Turn a 1-frame sprite into a 4-frame idle "bob" loop with a tag. |
| Scaffold a named cycle ( |
| Canvas + tilemap layer + a starter tileset (grass/dirt/water/stone, or your own). |
| Grid sheet of icon cells, each a placeholder inside a named slice ( |
| Grid sheet with a named slice per item (sword/shield/potion/…). |
| 8-direction walk template: frames + one tag per direction (N/NE/E/…). |
| PNG + animated GIF + sprite sheet (+ JSON) + per-tag GIFs + |
| Godot 4 |
| Engine-agnostic |
| Check a sprite is game-ready (dimensions/tile multiple, colour mode, frames, required tags, transparency, palette budget, exports exist) → pass/fail report. |
| Describe an asset once ( |
| Closes the loop: does the sprite that got built actually match the spec it was built from. Canvas, layer names, frame count, tags, slices, palette capacity. Reports what it checked as well as what failed, so "nothing was wrong" and "nothing was checked" cannot be confused. |
"Make me an idle-animated hero and a game-ready bundle."
create_character_sprite("hero", 32, 32, base_color="#3878c8")builds layers, palette and a placeholder.Draw the character on the
body/detailslayers (low-level tools).make_4_frame_idle_animation("hero.aseprite")makes a 4-frame loop taggedidle.validate_sprite_for_game_export("hero.aseprite", expected_width=32, required_tags=["idle"])confirms it is game-ready.export_game_asset_bundle("hero.aseprite", scale=8)judges every frame, then writes PNG/GIF/sheet+JSON/manifest intohero_bundle/. A defect refuses the bundle with the frames and the fix named; the manifest'sassessmentlists the readings worth a look that do not block it.
Bring art in from elsewhere
Art made outside the server (a PixelPrep conversion, a downloaded sheet, a screenshot) comes in through two tools, and the rest of the toolset then works on it as on anything drawn here.
import_image("scene.png", "scene.aseprite")for one picture. A PNG with an alpha channel, which is what PixelPrep writes, arrives as an ordinary layer; an opaque one without alpha, or an opaque indexed PNG, arrives as a Background, which Aseprite draws opaque everywhere.import_spritesheet("walk.aseprite", "walk_strip.png", 32, 48)for a strip, a column (layout="vertical") or a grid (layout="grid") of frames. A cell size that does not divide the sheet is refused before anything is launched, and spare grid cells come back asempty_frames.set_color_mode("scene.aseprite", "indexed")to limit the palette. An opaque scene keeps every pixel: one of its colours can land on the transparent index (in both scenes tried while building this it was the darkest), which a Background shows as a colour, and the readers and drawing tools treat it as one.assess_spriteandrender_previewto look at it (a large scene previews at a scale that keeps the image within 2048 px), then edit it like any other sprite.For animation,
export_motion_trailshows every frame of a motion in one image, so arcs and spacing can be judged before anything is exported.
Workflow manifest contract
Every workflow tool returns a standardized workflow_manifest.v1 object (defined in
core/manifest.py) so the asset layer stays
consistent as it grows. Always present: ok, schema_version, kind, created_files[],
suggested_next_actions[], warnings[]. Included when relevant: sprite{}, exports[],
palette{}, animation{}, tilemap{}, tiling{}, validation{}, operations[],
plan[] and dry_run. File/export entries are {role, path, format, metadata_path?}.
A manifest also reports what it wrote, at the top level beside ok:
pixels_written, pixels_clipped, pixels_skipped, pixels_outside_selection,
selection_applied and linked_frames_also_changed. Top level rather than in a pixels
section of their own, because the sections above each describe the product while these
are a verdict on the call, and because every other result in this server reports them
there: one rule reads them across all 163 tools. They are absent rather than zero, so a
key that is present at all means there is something to read, and a tool that writes no
pixels grows no 0 that reads as a claim about pixels. apply_operations used to drop
them, which let a batch report status: applied for an op whose every pixel an active
selection had refused.
{
"ok": true,
"schema_version": "workflow_manifest.v1",
"kind": "character_sprite",
"sprite": { "path": "...", "width": 32, "height": 32, "color_mode": "rgb",
"frames": 1, "layers": ["body", "details"], "tags": [] },
"created_files": [ { "role": "source_sprite", "path": "...", "format": "aseprite" } ],
"palette": { "colors": ["#1b1f2a", "..."], "count": 5 },
"pixels_written": 437,
"suggested_next_actions": ["Draw the character on the 'body' layer", "..."],
"warnings": []
}Batch operations
apply_operations applies a list of edits to one sprite in a single Aseprite process,
atomically: open once → run every op inside one transaction → save only if all
succeed. This collapses multi-launch agent flows (add layer → draw → add frame → tag)
into one fast, all-or-nothing call. Pass dry_run=true to validate the op list without
launching Aseprite.
apply_operations("hero.aseprite", [
{"op": "add_layer", "args": {"name": "fg"}},
{"op": "fill_layer", "args": {"layer": "fg", "color": "#1d2b53"}},
{"op": "draw_rectangle", "args": {"layer": "fg", "x": 2, "y": 2, "width": 12, "height": 8, "color": "#ff004d"}},
{"op": "add_frame", "args": {"copy_from": 1, "duration_ms": 120}},
{"op": "add_tag", "args": {"name": "idle", "from": 1, "to": 2}}
])If any op fails, the whole batch rolls back and the error names the failing op index. v1 ops: layer add/rename/visible/opacity/remove · frame add/duplicate/remove/duration/all-durations · cel position/opacity/copy/delete · tag add/remove · draw set_pixel/pixels/line/rectangle/fill_rectangle/ellipse/fill_ellipse/fill_layer/clear_layer · slice add/remove · replace_color.
Tool catalogue
Relative filenames resolve inside the workspace (absolute paths require
ASEPRITE_MCP_ALLOW_ABSOLUTE=1; see Security).
Frames and palette-aware operations are 1-based for frames, 0-based for palette
indices. Colours accept #RRGGBB, #RRGGBBAA, r,g,b, r,g,b,a, index:N, or a name
(black, white, red, green, blue, yellow, cyan, magenta, transparent, …).
Sprite lifecycle
Tool | Description |
| Create & save a new sprite ( |
| Save a copy under a new path (optionally flattened). |
| Convert between |
| Change canvas size without scaling art ( |
| Crop the canvas to a rectangle. |
| Scale the whole sprite (by factor or to dimensions; |
| Flatten all layers into one. |
| Auto-crop the canvas to non-transparent content. |
| Toggle the opaque Background layer. |
Inspection & preview
Tool | Description |
| Full structured state: size, mode, frames, layer tree, tags, palette. |
| Render a frame to a PNG image you can view, scaled up for small sprites; a large one is fitted to 2048 px on its longer side. A frame the sprite does not have is refused. |
| Read the pixel colours of a region, composited or from one named layer, as rows or as a compact symbol map (≤ 64×64 per call). |
| Measure the drawing: colours and ramps, noise, jagged diagonals, how much of the canvas is used, centring, symmetry, palette conformance against a declared ramp, and tile seams. Each measurement worth acting on comes back with a line saying why. |
| Compare two frames pixel for pixel: pixels added to or removed from the silhouette, repainted inside it, or changed in alpha alone, plus the colours involved and the box they sit in. Says so loudly when nothing changed, and takes |
| List sprite/image files in the workspace. |
Layers
Tool | Description |
| Add a layer (optional group, opacity, blend mode, visibility). |
| Add a group layer. |
| Delete / rename a layer. |
| Update opacity, blend mode, visibility, editability, name. |
| Reorder a layer (1-based stack index, 1 = bottom). |
| Duplicate / merge a layer down. |
Frames (animation)
Tool | Description |
| Add a frame: empty at the end, or a copy right after the frame it copies. |
| Duplicate / delete a frame. |
| Set per-frame / uniform durations (ms). |
| Turn a run of frames round, or move one frame to another position. Cels on every layer, durations and cel links all travel with the frame. |
Cels (a layer's image at a frame)
Tool | Description |
| Inspect a cel (exists, position, bounds, opacity). |
| Read / write custom properties on a sprite, layer, cel, tag, slice or tile, stored inside the |
| Move / fade a cel. |
| Copy a cel between frames / delete it. |
| Share one image across frames (a held pose: editing any of them edits all, and the file stores it once) / give a frame its own copy back. |
| Reorder one cel against its layer's neighbours, for a limb that is in front on one frame and behind on the next, without restructuring the layer stack. |
Animation tags
Tool | Description |
| Tag a frame range with a name, direction, colour, and a repeat count (0 means forever, which is how a cycle is marked). |
| Edit / delete a tag. |
Animation (motion, timing, checks)
Tool | Description |
| Move a drawn cel along a line or an arc across frames in one launch, spacing distributed so it reads as speed rather than as a limp. |
| Scale, turn and fade one drawn cel across frames in one launch: squash and stretch (the two axes go opposite ways), whole-degree rotation sampled nearest-neighbour so no colour is invented, and a fade that sets cel opacity rather than baking alpha. |
| Draw one frame's subject along its own movement, so fast motion reads as speed rather than as teleportation. |
| Give a cycle a shape in time ( |
| Measure a cycle instead of playing it: per-frame hashes, spacing, contact rows, durations, and the faults a still frame hides (a wrap frame repeating the first, duplicated poses, placeholder timing, a drifting contact edge). |
Easing belongs in one of these at a time. Eased spacing plus an eased duration curve is the
same curve applied twice, and reads as slow motion; apply_timing_curve measures the cels
and says so rather than doing it quietly.
Drawing
Tool | Description |
| Plot individual pixels (per-pixel or shared colour). |
| Draw from a character grid, one character per pixel, with a legend of symbol to colour. The write side of |
| Line / connected segments; |
| Quadratic Bézier curve. |
| Outline or filled rectangle / ellipse; ellipse has |
| An ellipse filling the same bounding box |
| Flood fill (paint bucket) from a point. |
| Fill the whole cel / erase it to transparent. |
Brushes & symmetry
Tool | Description |
| Stamp a custom brush shape (ASCII mask) at many points. |
| Tile an image/sprite across a region (with spacing, opacity, blend). |
| Reflect one half of a layer onto the other (build symmetric art). |
| Plot pixels with horizontal/vertical/4-way mirroring. |
Shading & light
Tool | Description |
| Shade a flat region as a lit form, from a ramp and a light direction. |
| Shade a form built from flat planes, one tone per plane, from a map whose legend names directions instead of colours. For anything hard: a crate, a helm, cut stone. |
| Put every pixel on a ramp by its brightness, whatever it started as: the tool that brings imported or filtered art onto a palette at all. Optional ordered dithering. |
| Move pixels along a colour ramp, keeping every one of them on the palette. |
| Place a small glint where the light reflects at the viewer, never on an edge pixel. The ramp's top step, or a brighter colour for metal. |
| Darken the pixels where one form meets another, along its ramp. |
| Darken the seam where two masses of the same material overlap, from a character map whose legend names the masses and says which is nearer the viewer. |
| Light an interior source onto the surface around it, up that surface's own ramp by distance. |
| Outline a shape in colours taken from its own ramp, not one flat colour. |
| Dither the boundary between two adjacent ramp steps, widening the transition. |
Selections
Tool | Description |
| Select a rectangle, ellipse, or polygon ( |
| Magic wand: select every pixel matching a colour. |
| Grow, shrink, or outline the current selection. |
| Swap selected for unselected / clear it. |
| Report whether there is a selection and what it covers. |
A selection is not stored in the .aseprite file, and every call here is its own Aseprite
process, so it is kept in a .msk sidecar beside the sprite and loaded again on the next
call. It scopes every later edit until deselect, which is how an image editor behaves,
and every result that touched pixels reports selection_applied.
"Scopes every later edit" is now enforced rather than asserted. The mask is consulted in
one function that every write goes through, and a test holds each write path to it
separately, asserting the pixels outside the selection rather than a count. That is there
because nine of them used to bypass it: the anti-aliased coverage write, the flood fill,
every per-pixel effect pass, mirror_layer and the batch runner's replace op all edited
the whole layer while the result still said selection_applied: true. A count can be
satisfied by a tool that wrote the right number of pixels in the wrong places.
Slices (named regions / 9-patch)
Tool | Description |
| Manage slices with optional 9-patch center, pivot, colour, and data. |
Effects & colour adjustments
Tool | Description |
| Linear/radial gradient, multi-stop, optional Bayer dithering. |
| Two-colour checkerboard pattern. |
| Pixel outline around art (outside/inside, 4/8-connectivity, thickness). With a light angle the weight tapers across the terminator, 2 then 1 then 0 over a band of edge, instead of switching per pixel and breaking the keyline into scraps. |
| Hard drop shadow on a new layer beneath the art. |
| A shadow on the ground, away from the light and foreshortened by its height, built of ramp steps and clipped to the surface it falls on. |
| A halo of several rings, each a step further down a ramp, optionally dithered at the outer edge. Its own layer, so deleting it removes the effect, and one cel a frame, so one layer carries an animated one. |
| Swap a colour (with per-channel tolerance). |
| Replace pixels with no neighbour of their own colour by the colour around them: the dirt a shading pass leaves, without touching a dither or introducing a colour. |
| Even out the run lengths along a silhouette's diagonals, which is the wander that reads as programmer art. Merges a stray one-row run into its neighbour and reports the jagged-corner count before and after; it only ever adds a pixel, so the extent cannot move, and it declines a 1:1 diagonal, a spike, a notch or a hairline by name. |
| Invert RGB (alpha preserved). |
| Colour grading. |
Text
Tool | Description |
| Render text (built-in bitmap font or a TrueType file) as crisp pixels. |
Tilemaps (Aseprite 1.3+)
Tool | Description |
| Create a tilemap layer with a tile size + empty grid. |
| Define/draw the tileset artwork. |
| Place tiles on the grid. |
| Read the grid of tile indices. |
Image stamping
Tool | Description |
| Composite another image/sprite file onto a layer (opacity, blend mode). |
| Composite an inline base64 image onto a layer. |
Palette
Tool | Description |
| Read / replace the whole palette. |
| Edit individual entries / size. |
| Load a palette from |
| Set the transparent index (indexed sprites). |
| Collect the unique colours used in a sprite/image. |
| Sort by hue/luminance/saturation/value (remaps indexed pixels). |
| Derive a palette from the artwork itself, reduced to at most N colours. |
| Which palette indices the art actually draws with, as runs of consecutive entries, so the run worth cycling is visible before you cycle it. Indexed sprites only, because an RGB pixel carries no index. |
| Animate an indexed sprite by rotating a run of palette indices across new frames, the classic palette-cycling effect for water, fire and glows. Aseprite's Lua API exposes no per-frame palette, so the rotation is applied to the pixels' own indices and the result says so ( |
| Build a hue-shifted shading ramp from a base colour. Says how many steps came back distinct, since lightness clamps at both ends. |
| Build a ramp from its two ends, the cool shadow and the warm highlight, interpolated in Oklab so the middle is a blend rather than a hue rotation. |
| Recover the ramp a sprite is already painted with, ordered dark to light, with the share of the art each step covers. |
Palette cycling is the one animation technique here that moves no pixels: rotate a run of
indices and water flows, lava creeps, a portal turns. list_palette_usage is the step
before it, because the run worth cycling is a property of the art rather than of the
palette: an index the drawing never uses contributes nothing, and a run of two is a flicker
rather than a flow. One measured limitation shapes the tool: Aseprite's Lua API exposes
no per-frame palette, so the rotation is applied to the pixels' own indices instead and
the result says which it did (method: "pixel_remap"). On an indexed sprite the two are
the same picture, and the move is exact because it never resolves a colour to a nearest
entry.
Transform & export
Tool | Description |
| Flip (h/v) / rotate (90/180/270) the whole sprite. |
| Export one frame as a flattened PNG (scaled). |
| Export the animation as an animated GIF. |
| Export only a named tag's frames as a GIF. |
| Pack frames into a sheet (+ JSON metadata; layer/tag filters & splits). |
| Pack frames with extrude (the one-pixel border that stops texture bleeding in a game engine), merged duplicates and trim. |
| Export each frame to its own file ( |
| Export one layer / each layer to separate files. |
| Export each animation tag's frames to separate files. |
| Render a frame with neighbouring frames ghosted behind it. |
| Every frame of a motion in one image, oldest faintest, so arcs and spacing can be judged at a glance. |
| Build an editable |
| Slice a sprite sheet image into frames, one per cell: a strip, a column or a grid. |
Minecraft resource packs
Tool | Description |
| Export a sprite into a resource pack at its correct texture path. |
| Check a sprite against Minecraft's texture rules before it ships. |
| Write |
| Write the |
Reference / rotoscope
Tool | Description |
| Add a dimmed, locked layer holding a reference image to trace over. |
| Import a sequence of images as per-frame references (rotoscoping). |
Batch operations
Tool | Description |
| Apply many edits to one sprite atomically in a single process ( |
GUI companion mode
Tool | Description |
| Open a sprite in the live Aseprite GUI window (non-blocking) to watch edits. |
| Report whether the Aseprite GUI can be launched. |
Health & self-test
Tool | Description |
| Self-test: Aseprite found?, version, workspace, tool count, and a real create+export round-trip. |
Live viewing (GUI companion mode)
The server edits files headlessly, but you can watch the work in the real Aseprite
window. Call open_in_editor("sprite.aseprite") and Aseprite opens it in a normal,
non-blocking window. As the agent keeps saving edits with the other tools, Aseprite
detects the on-disk change and offers to reload (or reloads automatically, depending on
your Aseprite preferences), so edits appear without re-opening.
What this is and isn't: Aseprite's Lua scripting sandbox has no networking or timers,
so the server can't stream a live canvas into the GUI frame-by-frame. The companion view
above (open once → headless edits → Aseprite reloads) is the robust, supported workflow.
The agent's own "eyes" remain render_preview, which returns a PNG it can inspect directly.
Example agent workflow
"Make me a 32×32 walking-slime animation."
create_sprite("slime.aseprite", 32, 32, "rgb")fill_layerthe background,add_layer("slime.aseprite", "slime"), draw the body withdraw_ellipse/fill_area/draw_pixels.add_frame("slime.aseprite", copy_from=1)a couple of times; nudge the body withset_cel_positionto create a bounce.set_all_frame_durations("slime.aseprite", 120)andadd_tag("slime.aseprite", "walk", 1, 3, "pingpong").render_previewto check it, iterate, thenexport_gif("walk.aseprite", "walk.gif", scale=8). Passloop=Falsefor a one-shot: an attack or a death is not a cycle, and a GIF declares that in its own metadata rather than in a caption.
How it works
client (any MCP client) ──MCP──> aseprite-mcp (MCPServer, Python)
│ builds a Lua body + ARG table
▼
luagen.assemble_script ──> temp .lua
│ (prelude: JSON encoder, colour/pixel
│ helpers, drawing primitives, info)
▼
Aseprite.exe -b --script temp.lua
│ prints @@ASEMCP@@<json> (or @@ASEMCP_ERR@@)
▼
runner parses the sentinel ──> dict back to the clientDrawing primitives (line, rectangle, ellipse, flood fill) are implemented deterministically
in Lua and operate on a full-canvas copy of the target cel, so coordinates are always in
sprite space and results are identical across runs. Exports use the Aseprite CLI's native
flags (--sheet, --scale, --data, …).
Project layout
src/aseprite_mcp/
app.py MCPServer instance, tool classification, portable schemas
server.py imports every tool module, picks the transport, main()
core/ config (locate Aseprite, workspace, path sandbox), paths (output
paths + the no-clobber check), limits, errors, models, luagen
(Python->Lua + the shared PRELUDE), runner (run_lua / run_cli,
sentinel parsing), oplib (the batch op registry), manifest,
validation, asset_spec, minecraft, engines/ and slice_metadata
(engine export formats), ramps, indexed and lighting (colour
and light arithmetic), quality and spritediff (the measurements),
loopcheck, timing, frameops, motion and inbetween (animation maths)
tools/ one module per domain: sprite, inspect, layers, frames, tags,
cels, animation, drawing, brushes, shading, selection, effects,
text, tilemap, image, palette, slices, transform, export,
export_presets, minecraft, reference, workflow, asset_spec,
batch, gui, health (+ common.py)
docs/TOOLS.md full auto-generated tool reference, every registered tool
docs/CLIENTS.md per-client setup, transports, and what to do when a client
mangles arguments
scripts/ gen_tool_docs.py (regenerates docs/TOOLS.md), quality_report.py,
release_gate.py, showcase/ (regenerates the images above)
tests/ pytest suite: the pure tests always run, the rest need
--run-asepriteSecurity
This server hands an AI agent a file capability, so access is scoped by default:
Workspace-sandboxed paths. Relative filenames resolve under
ASEPRITE_MCP_WORKSPACE, which defaults to<repo>/workspacefrom a source checkout and to a per-user data directory from an installed package, never to a path inside the Python installation. Absolute paths and paths that escape the workspace via..(or a symlink that points outside it) are rejected unless you setASEPRITE_MCP_ALLOW_ABSOLUTE=1.No-clobber by default. Every output-writing tool (
create_sprite,save_sprite_as,import_image,import_spritesheet, allexport_*,export_game_asset_bundle) refuses to overwrite an existing file; passoverwrite=Trueto replace it on purpose. Multi-file exports validate every target up front, so they fail before writing anything if any target already exists. Pattern exports (frames/walk_{frame}.png) are expanded by Aseprite itself, so they are checked against everything the pattern could match.Bounded work per call. A single call cannot exhaust the host: batch op-lists and pixel/tile/colour lists are capped, canvases are capped at 16384px per axis and 16,777,216 pixels of area (so two individually-legal axes can't add up to gigabytes), inline base64 images at 32 MB, and text rasterization is budgeted while it renders. An outside image whose header declares more than the canvas caps is refused before it is opened, an export's
scaleand a sheet'spaddingare held so the rendered image stays inside them, andrender_previewfits a large sprite to 2048 px.ASEPRITE_MCP_TIMEOUTis clamped to 1-3600s so it can't be set to something that disables the timeout.No shell, no injection. Aseprite is invoked with list-form arguments (never a shell), and every user value is passed into generated Lua through an escaped
ARGtable: user input is never concatenated into Lua source.Bring your own Aseprite. The server only runs the Aseprite binary you point it at.
Run health_check to confirm the configuration (Aseprite path, workspace, sandbox state).
Notes & limitations
Each call is its own process. A tool call is an independent headless Aseprite run, so in-memory state (undo history, the "active" sprite) does not carry over, and operations take explicit coordinates rather than relying on what was open. The one piece of editor state that does survive is the selection: the selection tools keep it in a
.msksidecar beside the sprite and reload it on the next call, so it scopes later edits anddeselectis a real step rather than a formality. A future live-GUI mode can layer on top of this without changing the tool API.docs/HEADLESS.mdrecords what else batch mode takes away, which parts of the Aseprite API are unusable or unsafe under it, and why several tools are shaped the way they are.Use a
.aseprite/.aseextension to keep layers, frames, and tags editable. Saving to.png/.gifflattens.get_pixelsis capped at 4096 px (e.g. 64×64) per call; read in tiles for larger areas.Anti-aliasing (
antialias=True) only applies to RGB sprites; it's ignored on indexed/gray. Tilemaps and reference layers require Aseprite 1.3+.Indexed sprites and the Background. On an ordinary layer the transparent palette index means "no pixel". On a Background Aseprite draws it as a colour, and so do
get_pixels,assess_sprite,diff_sprites, the palette tools,trim_sprite,set_color_mode's conversion check, the drawing tools, and every effect and shading tool that reads the layer it is about to write (replace_color, the filters, the shading masks,remove_stray_pixels,normalize_edge_runs,fill_gradientwithrespect_alpha). The same scene behaves the same as an RGB or an indexed Background.add_outlinerefuses a Background of either kind, since nothing on one is empty.Fills start from Aseprite's factory colours. Where a Background gains pixels (
convert_layer_to_background, or growing its canvas withresize_canvasorcrop_sprite) they are black, or the transparent index on an indexed sprite, whatever the editor's colour bar holds. A headless run used to inherit that colour bar.
Troubleshooting
"Could not locate Aseprite." Set
ASEPRITE_PATHto the full executable path.Nothing happens / permission denied on save. Ensure the workspace path is writable. Relative filenames go under
ASEPRITE_MCP_WORKSPACE;health_checkreports the directory files are actually landing in.Timeouts on big operations: raise
ASEPRITE_MCP_TIMEOUT(seconds).A tool errors with a Lua message. The message is surfaced verbatim from Aseprite, it usually names the bad argument (e.g. a missing layer/frame).
Tests all skip. The Aseprite-driving tests are opt-in: run
uv run pytest --run-aseprite. With the flag given and no Aseprite found they still skip, naming that as the reason, so setASEPRITE_PATHas well.
Client-side problems (sprites landing in a venv directory, a text-only model that cannot
see render_preview, the Windows lock on .venv\Scripts\aseprite-mcp.exe that blocks
uv sync, a server that never appears) are covered in
docs/CLIENTS.md.
Development
uv run pytest # pure-Python tests (no Aseprite needed)
uv run pytest --run-aseprite # plus the integration and golden tests
uv run aseprite-mcp # run the server over stdio (manual debugging)
uv run python scripts/gen_tool_docs.py # regenerate docs/TOOLS.mdSee CONTRIBUTING.md for the architecture and how to add a tool, and CHANGELOG.md for release notes.
Contributing
Contributions are welcome! Please read CONTRIBUTING.md, add a test for your change, and regenerate the tool reference before opening a PR.
License
MIT © Brendan Malloy.
Disclaimer
This is an independent, unofficial project and is not affiliated with or endorsed by Aseprite or Igara Studio S.A. "Aseprite" is a trademark of its respective owner. You need your own licensed copy of Aseprite for this server to function.
Available Tools
156 toolsadd_drop_shadowB
Add a hard drop shadow for a layer's artwork on a new layer placed beneath it.
Args:
layer: The layer casting the shadow.
offset_x, offset_y: Shadow offset in pixels.
color: Shadow colour (often semi-transparent black, the default).
opacity: Opacity (0-255) of the shadow layer.
frame: Frame to build the shadow for.
| Name | Required | Description | Default |
|---|---|---|---|
| color | No | Default: "#00000080". | #00000080 |
| frame | No | Default: 1. | |
| layer | Yes | ||
| opacity | No | Default: 255. | |
| filename | Yes | ||
| offset_x | No | Default: 1. | |
| offset_y | No | Default: 1. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare a write operation (readOnlyHint=false) and closed-world scope, so safety is partly covered. The description adds useful side-effect context — a new layer is created beneath the source artwork — but says nothing about permissions, reversibility, or return value.
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?
Purpose is front-loaded in the first sentence and the Args block is tightly scoped with no filler. The bulleted list could be slightly more economical but every line carries information.
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 7-parameter mutation tool with no output schema, the description covers most parameters but omits the required filename and gives no guidance on frame/layer interaction or the resulting layer's naming. Adequate but leaving clear 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 description adds genuine meaning the schema lacks: offset units (pixels), opacity range (0-255), and color being semi-transparent black by default. However, the required 'filename' parameter is never mentioned, and schema coverage sits at 71%, so the doc is not fully compensating.
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 ('Add a hard drop shadow') and clarifies the output is a new layer placed beneath the source. It does not, however, distinguish itself from close siblings like cast_shadow or contact_shadow, leaving the agent to infer which shadow tool applies.
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 explains what the shadow is but gives no when-to-use, when-not-to-use, or alternative guidance. With cast_shadow and contact_shadow sitting as siblings, the absence of any routing hint is a real gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_frameA
Add a frame: appended when it is empty, inserted when it copies another.
Args:
duration_ms: Frame duration in milliseconds (default 100).
copy_from: If given (1-based), duplicate the content of that frame; otherwise the
new frame is empty and goes at the end. Must name an existing frame: an
out-of-range number is rejected, not clamped. **A copy is inserted, not
appended**, so every frame from that point on is renumbered: on a two-frame
sprite, `copy_from=1` gives three frames whose second is the original first.
Pass no `copy_from` and the sprite's existing frames keep their numbers.
Returns the new frame number and updated frame count. With `copy_from`, `newFrame` is
where the copy landed, which is also the number the frames after it shifted from.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| copy_from | No | ||
| duration_ms | No | Default: 100. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give a generic mutation/safety profile (readOnlyHint false, destructiveHint false). The description goes well beyond that by disclosing the frame-renumbering side effect of insertion, with a concrete two-frame worked example, plus the rejection-not-clamp behavior and the exact return contents (newFrame and updated frame count). This is exactly the kind of non-obvious behavioral context the description should carry.
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?
Front-loads the core behavior in the opening line, then uses a clean Args structure. It is somewhat verbose and uses bolding for emphasis, but each sentence carries real semantic content (renumbering, rejection semantics, return values) rather than 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?
With no output schema, the description appropriately explains the return values, and for a mutating tool it covers the key side effect (renumbering) and error behavior. The only shortfall is the undocumented required filename parameter, which is left unexplained in both schema and 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 only 33% (just duration_ms's default), so the description must compensate, and it does for two of three params: duration_ms default, and copy_from's 1-based indexing, existence requirement, out-of-range rejection and renumbering effect. The required filename parameter is never mentioned in either the schema or the Args list, leaving a small gap.
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 ('Add a frame') and immediately characterizes the two operating modes: appended when empty, inserted when copying. Combined with the copy_from detail, an agent can distinguish this from siblings like duplicate_frame or move_frame without opening a schema.
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 clearly explains the two conditional modes (pass copy_from to duplicate content, omit it to append an empty frame) and warns that an out-of-range value is rejected rather than clamped. It stops short of naming an alternative sibling (e.g. duplicate_frame) for the copy case, so guidance is strong but not fully explicit about when to prefer another tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_group_layerA
Add a new (empty) group layer on top of the stack. Nest layers into it with add_layer(group=...) or move_layer(group=...).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=false, destructive=false, and openWorld=false, so the safety profile is covered. The description adds useful behavioral detail beyond that: the layer is created empty, it sits on top of the stack, and it acts as a nesting container for subsequent add_layer/move_layer calls.
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, zero filler, with the core action front-loaded ahead of the follow-up nesting hint. 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 two-parameter mutation whose safety profile is covered by annotations, the description is adequate to call the tool correctly, but the complete absence of filename/name semantics is a real gap and there is no output schema to lean on.
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 0% for both required parameters (filename, name), and the description says nothing about either. An agent gets no guidance on whether filename is the sprite file path or what name refers to, so the description fails to compensate for the coverage gap.
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 ('Add a new (empty) group layer') plus placement ('on top of the stack'). It distinguishes itself from the sibling add_layer by clarifying that this creates a container that other layers are nested into rather than a drawable 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 follow-up context by naming the exact sibling calls (add_layer(group=...) or move_layer(group=...)) used to populate the new group. It does not state when to prefer a group layer over other structuring approaches or any exclusions, so it falls short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_layerA
Add a new (empty) normal layer on top of the stack.
Args:
name: Layer name.
group: Optional name of an existing group layer to nest the new layer in.
opacity: 0-255.
blend_mode: normal, multiply, screen, overlay, darken, lighten,
color_dodge, color_burn, hard_light, soft_light, difference,
exclusion, hue, saturation, color, luminosity, addition, subtract, divide.
visible: Initial visibility.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| group | No | ||
| opacity | No | Default: 255. | |
| visible | No | Default: true. | |
| filename | Yes | ||
| blend_mode | No | Default: "normal". | normal |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds useful context that the created layer is empty and placed at the top of the stack, but says nothing about what happens to the active selection, whether the layer becomes selected/current, or return 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 first sentence fully front-loads the action, and the Args block is terse. The long blend_mode list is the only bulk, and it is necessary information not available elsewhere.
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 6-param mutation with no output schema and annotations covering safety, the description covers nearly everything needed to invoke it correctly. The lone gap is the undocumented required 'filename' parameter, which forces the agent to guess which sprite file is targeted.
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?
With 50% schema coverage and zero schema enums, the description carries real weight: it enumerates all 18 legal blend_mode values (absent from the schema) and documents name, group, opacity and visible. Only 'filename' is left undocumented, which keeps it short of 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?
States a concrete verb+resource (add a layer) and narrows it with 'new (empty) normal layer on top of the stack', which distinguishes it from sibling operations like add_group_layer and duplicate_layer. It does not explicitly name those siblings, but the type and placement are 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?
Usage is only implied: 'on top of the stack' tells the agent where the layer lands, and 'normal layer' hints at the alternative of a group layer. There is no explicit when-to-use/when-not or routing to add_group_layer or add_reference_layer, so the agent must infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_outlineB
Add a pixel outline around the artwork on a layer.
Args:
color: Outline colour.
thickness: Outline width in pixels (default 1).
connectivity: 4 (orthogonal only) or 8 (includes diagonals, default).
where: "outside" (grow into transparency, default) or "inside"
(recolour the shape's border pixels).
| Name | Required | Description | Default |
|---|---|---|---|
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| where | No | Default: "outside". | outside |
| filename | Yes | ||
| thickness | No | Default: 1. | |
| connectivity | No | Default: 8. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint false and openWorldHint false, establishing a local write operation. The description adds semantics for the where option (outside grows into transparency, inside recolours border) but does not state that the layer is modified in place or whether existing artwork is required.
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?
Front-loaded purpose followed by a structured Args list. Concise and readable, though it repeats schema defaults for thickness, connectivity, and where.
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 7-parameter mutation tool with no output schema, the description covers the main operation and key parameters but leaves filename, layer, and frame undocumented. It also does not clarify which layer is modified if 'layer' is omitted.
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 57% and the schema descriptions are only default values. The description provides meaningful semantics for color, thickness, connectivity, and where, but omits filename, layer, and frame. This adds substantial value for the core outline parameters.
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 (add) and resource (pixel outline) plus target (artwork on a layer). It does not differentiate from the sibling tool outline_smart, so sibling differentiation is absent.
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?
No when-to-use guidance or alternatives are provided; the description only documents parameters. An agent must infer context from the tool name and siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_palette_colorC
Append a colour to the end of the palette.
| Name | Required | Description | Default |
|---|---|---|---|
| color | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=false, so the safety profile is covered; the description's 'append' is consistent with that but adds almost nothing beyond it. It omits any behavioral context such as palette size limits, whether the color is deduplicated, or error behavior when the palette is full.
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?
A single efficient sentence with the action and target front-loaded and no filler. It is not padded, though its brevity is partly under-specification rather than disciplined economy.
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 mutating two-parameter tool with no output schema, zero schema description coverage, and only weak annotation support, the description leaves key call-time details unknown: what filename identifies, what color encoding is valid, and whether the operation can fail. It is too thin to call the tool correctly with confidence.
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 0% and the description partially compensates only for 'color' by implying it is a palette colour. The accepted color format (hex, RGB, name) is never stated, and the required 'filename' parameter is not addressed at all, leaving half the input unexplained.
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 gives a specific verb ('Append') and resource ('colour') plus the insertion position ('to the end of the palette'), which implicitly distinguishes it from set_palette_color, which presumably overwrites an existing entry. It is clear what the tool does, though it never names the sibling it contrasts with.
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?
There is no guidance on when to use this rather than set_palette_color, load_palette, or resize_palette, and no mention of prerequisites such as the palette needing to exist or the filename needing to resolve. The agent must infer usage entirely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_reference_layerA
Add a dimmed, locked layer holding a reference image to trace over.
Args:
image_file: The reference image/sprite.
layer_name: Name for the new layer (default "reference").
opacity: Layer opacity (0-255); dim it so your art stands out.
scale_to_fit: Resize the reference to the canvas size (smooth).
x, y: Placement when not scaling to fit.
frame: Which existing frame to place the reference on (1-based). An
out-of-range frame is rejected with the sprite's valid range.
Exclude this layer from exports with ignore_layer="<layer_name>".
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | Default: 0. | |
| y | No | Default: 0. | |
| frame | No | Default: 1. | |
| opacity | No | Default: 128. | |
| filename | Yes | ||
| image_file | Yes | ||
| layer_name | No | Default: "reference". | reference |
| scale_to_fit | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare the mutation/safety profile (readOnly=false, destructive=false, openWorld=false), and the description adds real behavioral context beyond them: the layer is dimmed and locked, the frame argument is validated with an out-of-range rejection, and the layer can be excluded from exports. It stops short of describing return values or lock semantics fully, warranting a 4.
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 core purpose is front-loaded in the first sentence, followed by an arg list that maps cleanly to parameters. Slightly verbose in enumerating defaults, but every line carries useful information.
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 8-parameter mutation tool with no output schema, the description covers behavior, most parameters, and a follow-up export note. The omission of the required 'filename' parameter keeps it from being fully 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 coverage is 75%, and the description adds genuine meaning: opacity range 0-255 with dimming intent, scale_to_fit as smooth resize, x/y as placement only when not scaling, and frame as 1-based with rejection behavior. Only the required 'filename' parameter is left undocumented, so it falls just short of full compensation.
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 (Add), resource (layer), and defining traits (dimmed, locked, holding a reference image to trace over). This clearly distinguishes it from generic siblings like add_layer or add_group_layer without needing to open any schema.
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 phrase 'to trace over' implies the intended use case, and the closing note gives a follow-up action (exclude via ignore_layer). However, no alternative tool is named and there is no explicit when-to-use/when-not guidance versus add_layer or import_reference_sequence.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_sliceB
Create a slice (named region) at (x, y, width, height).
Args:
center_*: Optional 9-patch center rectangle, **relative to the slice's
top-left**. Provide all four to mark the stretchable middle.
pivot_*: Optional pivot point (relative to the slice).
color: Optional slice colour shown in the editor.
data: Optional user data. A string is stored as it arrives; a dict or list is
JSON-encoded, so {"type": "hitbox", "id": "body"} round-trips through
export_slice_metadata, which derives the slice's type and id from it.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | ||
| y | Yes | ||
| data | No | ||
| name | Yes | ||
| color | No | ||
| width | Yes | ||
| height | Yes | ||
| pivot_x | No | ||
| pivot_y | No | ||
| center_x | No | ||
| center_y | No | ||
| filename | Yes | ||
| center_width | No | ||
| center_height | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, non-destructive, closed-world mutation, so the safety profile is covered. The description adds real behavioral value by explaining that dict/list data is JSON-encoded and round-trips through export_slice_metadata, but it says nothing about failure modes (e.g., overlapping slices, missing filename) or whether the sprite must already exist.
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 one-line summary is front-loaded and the args list is tight, with conditional guidance folded into the relevant entries rather than repeated. Only the omission of filename and x/y semantics keeps it from being fully 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?
For a 14-parameter mutation tool with zero schema descriptions and no output schema, the description covers the tricky optional params but leaves gaps: filename is undocumented, x/y origin is unspecified, and there is no indication of what happens if a slice already exists at that location.
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 0% across 14 parameters, so the description carries the load and does so for the non-obvious ones: center_* is a 9-patch rect relative to the slice's top-left and all four must be supplied, pivot_* is a point relative to the slice, and data has special encoding rules. It omits filename and the coordinate origin for x/y, keeping it short of 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?
States a specific verb and resource ('Create a slice (named region)') plus the positional parameters, so the agent knows it adds a slice rather than modifying or removing one. It does not explicitly name the sibling alternatives (set_slice, remove_slice), but the create semantics are 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?
There is no when-to-use guidance, no prerequisites, and no reference to alternatives such as set_slice for editing an existing slice or list_slices for inspection. The args section explains what fields mean, not when this tool is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_tagA
Create an animation tag spanning frames [from_frame, to_frame] (1-based).
Both frames must already exist: an out-of-range number is rejected with the sprite's
valid range rather than clamped to it (which used to report a tag added while
creating it over a different range).
Args:
direction: "forward" (default), "reverse", "pingpong", or "pingpong_reverse".
color: Optional tag colour, shown in the timeline.
repeats: How many times the tag plays. **0, the default, means forever**, which
is how a cycle is marked in the file; 1 is a one-shot such as an attack, a
hurt or a death. This is the sprite's own answer to whether these frames
loop, and `validate_loop` reads it: a repeated last frame is an error for a
cycle and only a warning for a one-shot.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| color | No | ||
| repeats | No | Default: 0. | |
| filename | Yes | ||
| to_frame | Yes | ||
| direction | No | Default: "forward". | forward |
| from_frame | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the non-destructive mutation annotations, the description discloses real behavior: the strict out-of-range rejection and its history, the meaning of repeats=0 ('forever', the cycle marker), and the fact that validate_loop reads repeats and treats a repeated last frame as an error for a cycle versus a warning for a one-shot. That is substantive context an agent could not derive from 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?
Core contract and the frames constraint are front-loaded, and the Args block is compact. The parenthetical about the previous clamping bug is historical trivia that does not help an agent invoke the tool, a minor bit of non-earning text.
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 7-parameter, no-output-schema mutation tool it covers error behavior, the direction domain, and the important repeats default. It leaves name/filename semantics and whether names must be unique or an existing tag is overwritten unstated, which is the remaining 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 coverage is only 29% and no enums are declared, so the description carries most of the load: it enumerates the four direction values, explains color is a timeline-displayed tag colour, and gives repeats' default and semantics in depth. It does not explain name or filename, so it is strong but not fully compensating.
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 ('Create an animation tag spanning frames [from_frame, to_frame]') and states the 1-based indexing, so the agent knows exactly what is being produced. It does not, however, distinguish itself from the sibling set_tag, leaving the boundary between creating and replacing a tag to inference.
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 a precondition (both frames must already exist and out-of-range values are rejected rather than clamped), which implies usage context. But it never states when to reach for add_tag versus set_tag, remove_tag, or validate_loop, so routing guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_tileB
Add a new tile to the layer's tileset (optionally filled with a solid colour). Returns the new tile's index.
| Name | Required | Description | Default |
|---|---|---|---|
| color | No | ||
| frame | No | Default: 1. | |
| layer | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare this is a non-read-only, non-destructive, closed-world write, so the safety profile is covered. The description adds that the tile may be optionally filled and that the new index is returned, but says nothing about persistence, required layer type, or side effects on existing tiles.
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 tight sentences with zero filler; the core action is front-loaded and the return value is appended compactly.
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 4-parameter mutation tool with 25% schema coverage and no output schema, the description covers the return value but leaves 'filename' and 'frame' entirely unexplained and gives no guidance on the tileset/layer preconditions.
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 only 25%, and the description mentions just the optional colour fill. The required 'filename' and the 'frame' parameter (with its default) remain undocumented in both description and schema, leaving half the parameters semantically opaque.
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: 'Add a new tile to the layer's tileset', with the optional solid-colour fill noted. It is distinguishable from mutation siblings like set_tile/set_tiles, though it does not explicitly contrast itself with fill_tile or create_tilemap_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?
There is no statement of when to use this versus alternatives such as set_tile, fill_tile, or paint_tile_pixels, nor any prerequisite (e.g. layer must already be a tileset). Usage must be inferred from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adjust_brightness_contrastB
Adjust brightness (-255..255, additive) and contrast (-255..255) of a layer.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | No | ||
| contrast | No | Default: 0. | |
| filename | Yes | ||
| brightness | No | Default: 0. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and openWorldHint=false, so the mutating, local nature is known. The description adds one genuinely useful behavioral trait - brightness is 'additive' - but says nothing about reversibility, whether changes are baked into pixels, or permission requirements.
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?
A single front-loaded sentence that names the operation, both adjustable dimensions, the valid range, the compositing mode, and the target scope. 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 5-parameter mutating tool with no output schema and only 60% schema coverage, the description covers the two numeric parameters well but leaves frame/layer/filename and the mutation's side effects unspecified. Adequate but with clear 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?
Schema coverage is 60% and the schema only documents defaults, so the description's ranges (-255..255) and the additive semantics for brightness do add meaning. However, frame, layer, and filename receive no semantic explanation in either place, leaving a partial gap.
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 ('Adjust') plus the exact resources (brightness and contrast) and the scope ('of a layer'), with valid ranges in parentheses. It does not differentiate itself from the sibling adjust_hue_saturation, but the operation itself is 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?
No guidance on when to use this versus the other adjustment tools (adjust_hue_saturation, desaturate, gradient_map) or when not to. The agent must infer applicability from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adjust_hue_saturationB
Shift hue (degrees) and scale saturation/lightness (percent, -100..100).
| Name | Required | Description | Default |
|---|---|---|---|
| hue | No | Default: 0. | |
| frame | No | Default: 1. | |
| layer | No | ||
| filename | Yes | ||
| lightness | No | Default: 0. | |
| saturation | No | Default: 0. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, so the agent knows this is a mutating operation. However, the description does not disclose what exactly gets modified (e.g., a specific layer or frame in a file), whether changes are reversible, or any permission requirements. It adds only the units and range for the adjustment values, not the behavioral context of a mutation.
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, front-loaded sentence that is appropriately sized and contains no filler. Every part, the operations and the units, 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 tool with 6 parameters (including required filename, plus layer and frame targeting) and no output schema, the description is too thin. It explains the adjustment values but not what object is being modified or how the target is selected, leaving significant gaps for 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 67%, and for the core adjustment parameters the schema only says 'Default: 0.' The description adds crucial meaning by specifying that hue is in degrees and saturation/lightness are percentages in the -100..100 range. It does not clarify the roles of filename, layer, or frame.
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: shifting hue and scaling saturation/lightness. It is clear about what adjustments are performed but does not differentiate this tool from close siblings like adjust_brightness_contrast or desaturate, nor does it mention the target resource (file, layer, frame).
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?
No guidance is provided about when to use this tool versus alternatives such as desaturate or adjust_brightness_contrast. It gives no prerequisites or context for selection, leaving the agent to infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
apply_operationsADestructive
Apply a list of edit operations to a sprite in one atomic, single-process batch.
Each operation is {"op": "<name>", "args": {...}}. Ops run in order against the
same open sprite, so later ops see earlier ones (e.g. add a layer then draw on it).
Arguments not listed for an op are rejected rather than ignored.
Atomic: if any op fails the whole batch is rolled back and nothing is saved; the
error names the failing op index. dry_run=True validates the op list and returns
the plan without launching Aseprite (shape checks only; runtime issues like a
missing layer surface on a real run).
Frames are 1-based, and an arg=frame argument must name a frame that already
exists: an out-of-range frame is rejected with the sprite's valid range rather than
clamped, so a per-op summary always describes the frames actually touched.
Returns a workflow_manifest.v1 (kind "batch") with a per-op operations list, and,
when the ops touched pixels, the same pixels_written / pixels_outside_selection /
selection_applied fields every other tool reports: a batch run under an active
selection is clipped to it, and these say how much the mask refused.
Operations and their arguments ('?' marks an optional argument): add_frame(duration_ms=int?, copy_from=frame?) add_layer(name=str, group=str?, opacity=int?, blend_mode=str?, visible=bool?) add_slice(name=str, x=int, y=int, width=int, height=int, color=color?) add_tag(name=str, from=frame, to=frame, direction=str?, color=color?) [also accepts from_frame for from, to_frame for to] clear_layer(layer=str?, frame=frame?) copy_cel(layer=str, from=frame, to=frame, to_layer=str?) [also accepts from_frame for from, to_frame for to] delete_cel(layer=str, frame=frame) draw_ellipse(layer=str?, frame=frame?, cx=int, cy=int, rx=int, ry=int, color=color) draw_line(layer=str?, frame=frame?, x1=int, y1=int, x2=int, y2=int, color=color) draw_pixels(layer=str?, frame=frame?, pixels=list, color=color?) draw_rectangle(layer=str?, frame=frame?, x=int, y=int, width=int, height=int, color=color) duplicate_frame(frame=frame) fill_ellipse(layer=str?, frame=frame?, cx=int, cy=int, rx=int, ry=int, color=color) fill_layer(layer=str?, frame=frame?, color=color) fill_rectangle(layer=str?, frame=frame?, x=int, y=int, width=int, height=int, color=color) remove_frame(frame=frame) remove_layer(layer=str) remove_slice(name=str) remove_tag(name=str) rename_layer(layer=str, new_name=str) replace_color(layer=str?, frame=frame?, from=color, to=color, tolerance=int?) [also accepts from_color for from, to_color for to] set_all_frame_durations(duration_ms=int) set_cel_opacity(layer=str, frame=frame, opacity=int) set_cel_position(layer=str, frame=frame, x=int, y=int) set_frame_duration(frame=frame, duration_ms=int) set_layer_opacity(layer=str, opacity=int) set_layer_visible(layer=str, visible=bool) set_pixel(layer=str?, frame=frame?, x=int, y=int, color=color)
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Default: false. | |
| filename | Yes | ||
| operations | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, yet the description adds substantial behavior beyond that: full-batch rollback on any op failure, the error naming the failing op index, dry_run validating shape only ('runtime issues surface on a real run'), 1-based frame rejection rather than clamping, and selection clipping. This is rich, non-obvious disclosure.
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?
Key semantics (atomicity, ordering, dry_run, frame numbering) are front-loaded before the long op catalog. The catalog is long but every line is functional reference an agent needs to construct valid operations, so no sentence 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?
Despite having no output schema, the description specifies the return value (workflow_manifest.v1 with a per-op operations list and pixels_written/pixels_outside_selection/selection_applied when pixels are touched). Combined with the destructiveness annotations, an agent has everything needed 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?
Schema coverage is only 33% (filename and the operations array are opaque), so the description carries the burden and does so exhaustively: it enumerates every op with its argument names, marks optionals with '?', documents aliases (from_frame/to_frame, from_color/to_color), and states that unlisted args are rejected. This is far beyond what the schema 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?
States a specific verb and resource ('Apply a list of edit operations to a sprite') plus the key differentiator of 'atomic, single-process batch'. This clearly separates it from the many single-op siblings like draw_line, add_layer, and set_frame_duration that do one thing each.
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?
Explains the batching context well: ops run in order against the same open sprite, so later ops see earlier ones, and dry_run=True is recommended for validation before a real run. It does not explicitly name when to prefer this over calling individual op tools, so it stops short of full when/when-not/alternatives guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
apply_timing_curveA
Give an animation a shape in time, by setting durations and never duplicating frames.
Uniform timing is the placeholder every animation starts with and almost none should
keep. A cycle holds its extremes two to four times as long as the poses it passes
through; an attack holds the anticipation, snaps through the strike in 20 to 40ms, and
holds the impact.
Args:
curve: `hold_extremes` (the ends of a cycle are held, the passing frames are not),
`attack` (anticipation, snap, impact, recovery), `ease_in` (starts slow),
`ease_out` (ends slow), or `flat` (every frame the same, to start over).
frames: The frames to time, in order. Defaults to a tag's frames, or all of them.
tag: Time one tag's frames instead of naming them.
base_ms: The duration of a passing frame. Everything else is a multiple of it.
hold_frames: Frames to hold whatever the curve says, at three times `base_ms`.
snap_frames: Frames to snap through, at the shortest duration that still registers.
A hold is a longer duration on one frame, never a repeated frame: duplicating costs a
frame, shifts every tag index, and hides the repeat from `validate_loop`. The returned
`frames_added` is always 0, and it is returned so that claim can be checked.
Easing here and easing the spacing elsewhere are the same curve applied twice, which
reads as slow motion rather than as weight. The cels are measured on the way through,
so asking for an eased curve over spacing that is already eased comes back with a
warning rather than quietly doing it.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | ||
| curve | No | Default: "hold_extremes". | hold_extremes |
| frames | No | ||
| base_ms | No | Default: 100. | |
| filename | Yes | ||
| hold_frames | No | ||
| snap_frames | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false; the description carries the rest and does so richly: holds are durations not duplicated frames, duplicating shifts every tag index and hides the repeat from validate_loop, frames_added is always 0 and returned so the claim is checkable, and a double-ease request returns a warning rather than silently proceeding.
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?
Front-loaded with the purpose sentence and structured into prose rationale followed by an Args list. The aphorism about uniform timing being a placeholder is mildly expendable, but the rest 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?
No output schema, yet the description explains the meaningful return value (frames_added always 0) and the warning path, which is more than required. The main omission is the required `filename` parameter, and the warning's exact shape is not spelled out.
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 only 29% and there are no enums, so the description does the heavy lifting: it enumerates and explains all five `curve` values, defines base_ms as the passing-frame duration with everything else a multiple of it, and clarifies hold_frames (3x base_ms) and snap_frames (shortest registrable duration). Only the required `filename` is left undocumented.
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 states a specific verb+resource: 'Give an animation a shape in time, by setting durations.' The 'never duplicating frames' clause and the curve taxonomy distinguish it from generic siblings like set_frame_duration and set_all_frame_durations.
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 when-to-use guidance per curve ('a cycle holds its extremes two to four times as long as the poses it passes through', attack = anticipation/snap/impact), plus an explicit when-not-to-do-something warning about combining easing here with eased spacing. It stops short of naming sibling alternatives like set_frame_duration.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assess_spriteARead-only
Measure the drawing itself and say what is worth fixing.
`get_sprite_info` says what a sprite contains and `render_preview` returns a picture
a text-only model cannot read. This answers the question in between: is the art any
good, in the ways that can be counted.
Reports how many colours are in use and roughly how many ramps they form, pixels with
no neighbour of their own colour (noise), jagged corners on diagonals, the drawn
bounding box, how much of the canvas it fills, whether it sits centred, and how far
the silhouette is from its own mirror. Each measurement that is worth acting on comes
back with a line saying why, so the numbers do not have to be interpreted.
Args:
ramp: Declare the ramp the art should be on and the report adds palette
conformance: the fraction of drawn pixels sitting exactly on it. This is the
measurement that separates shading from filtering, and it is omitted rather
than reported as a meaningless 1.0 when no ramp is given. On an **indexed**
sprite the readings also say how much of the ramp the palette can actually
hold, because conformance cannot see a ramp step that collapsed onto its
neighbour: the colour it collapsed to is still on the ramp, so banded
shading still scores 1.0.
check_tiling: For a tile, also measure how much worse the wrapping edge looks
than the interior, per axis. Near 1.0 wraps; much above 1.0 has a seam.
layer: Measure one layer instead of the flattened frame.
Reads the whole frame in one Aseprite launch. None of the pixels are returned, only
the measurements, so this is cheap to call after every pass.
| Name | Required | Description | Default |
|---|---|---|---|
| ramp | No | ||
| frame | No | Default: 1. | |
| layer | No | ||
| filename | Yes | ||
| check_tiling | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint/openWorldHint; the description adds substantial context beyond them: it reads the whole frame in one Aseprite launch, returns no pixels (measurements only), is cheap, and explains the subtle indexed-palette limitation where ramp conformance can falsely read 1.0.
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?
Front-loaded with the core purpose and the sibling contrast before detail. The prose is dense and occasionally elaborate, but nearly every clause carries information; the long ramp paragraph is the only place readability dips.
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 no output schema, the description enumerates what comes back (colour count, ramps, noise, jagged corners, bounding box, fill, centring, symmetry distance) and notes each actionable measurement is annotated with a reason. Enough for an agent to interpret results without a 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?
Schema coverage is only 40%, so the description carries the load and does so well for ramp, check_tiling, and layer, including when measurements are omitted vs reported. It never explains `frame` or `filename`, which keeps it off 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?
States a specific verb+resource ('measure the drawing itself') and explicitly positions itself between get_sprite_info and render_preview, naming both siblings. An agent can distinguish it from every neighbouring tool without opening a schema.
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 explicit routing: get_sprite_info for contents, render_preview for a picture, this tool for countable quality. Closes with 'cheap to call after every pass', which tells the agent the cadence and cost of use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
build_asset_from_specADestructive
Build the asset described by an aseprite_mcp.asset_spec.v1 document.
Executes the (validated) plan by dispatching each step to an existing tool: scaffolds
the sprite for its `kind`, applies palette / extra layers / animation frames+tags /
slices, and runs the requested exports. **Structure only - no pixels are drawn;** the
returned manifest's `suggested_next_actions` hand the actual art back to you.
Args:
overwrite: Passed to the export steps (replace existing export files). The sprite
itself is created no-clobber, so building over an existing ``<name>.aseprite``
raises - build to a new name or remove the old file.
Returns a ``workflow_manifest.v1`` (kind ``asset_spec``) with the created files, the
executed `plan`, and next actions. Raises ``ValidationFailed`` if the spec is invalid.
| Name | Required | Description | Default |
|---|---|---|---|
| spec | Yes | ||
| overwrite | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true, and the description openly explains that the sprite itself is created no-clobber (raises on existing <name>.aseprite) while overwrite only affects export files. This is exactly the kind of nuance annotations alone cannot convey, though it doesn't cover all mutation boundaries or return format details in full.
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?
It is appropriately sized and front-loaded: a one-sentence summary, then a paragraph explaining execution flow, then Args and Returns sections. Every sentence carries information and nothing is 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 no output schema, the description appropriately explains the return type (workflow_manifest.v1) and its contents. It covers the no-clobber behavior, the validation failure mode, and the suggested_next_actions mechanism. It could be slightly more complete by mentioning any constraints on the spec format or typical failure modes, but it is adequate for a complex orchestrator 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 spec param is a nested object with no schema description, but the description explains its role (drives scaffolding, palette, layers, animation, exports) and references a versioned document type. The overwrite parameter gets a full behavioral explanation (passed to export steps, no-clobber for sprite creation) that goes beyond the schema's 'Default: false.' This adds substantial meaning despite 50% 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 states a specific verb and resource: 'Build the asset described by a aseprite_mcp.asset_spec.v1 document.' It clearly identifies itself as a high-level orchestrator that dispatches to existing tools, distinguishing it from atomic siblings like draw_pixels or export_png. An agent can tell this composes a batch of operations based on a spec.
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?
Usage is implied by the description's emphasis on executing a validated plan and handing art back via suggested_next_actions, but it does not explicitly state when to use this vs plan_asset_spec or validate_asset_spec (siblings in the list). The overwrite arg behavior is explained, but there are no explicit when/when-not/alternatives statements.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cast_shadowA
Lay a subject's shadow on the ground, away from the light and made of ramp steps.
`add_drop_shadow` offsets a copy of the artwork and tints it, which is a sticker of
the subject floating beside it. A cast shadow is a different thing: it falls on a
*surface*, away from the light, and flattens as it goes, so on the ground it is a
foreshortened ellipse under the subject rather than a second copy of its silhouette.
Built entirely of ramp steps, which is the point. A shadow made by multiplying alpha
lands every pixel of it between palette entries, and then `palette_conformance` drops
and nothing downstream holds together: indexed export, tileset reuse, a consistent
look between two sprites. The core is `ramp[0]` and each pixel of `softness` around it
is one step lighter, so the whole effect is ramp entries arranged in space.
Where it falls: the direction is away from `light_angle`, and the length comes from
`light_height` as the actual cotangent of the light's elevation. An overhead light
casts an ellipse straight underneath; a low light throws it far to one side.
Onto what: `ground_layer`. Name the layer holding the floor and the shadow is clipped
to it, so it cannot run off the edge of a platform and hang in the air, and if that
layer has nothing where the shadow would land the call is refused rather than drawing
a shadow onto nothing.
Args:
layer: The layer casting the shadow. Its cel is never modified. A background
layer is refused: it is opaque and covers the canvas, so it has no silhouette
to cast. `convert_background_to_layer` first if the subject is one.
ramp: Colours darkest first, normally the *ground's* ramp rather than the
subject's, since the shadow is a darkening of the surface it lies on.
Required, and deliberately so: a shadow built out of alpha instead is
`add_drop_shadow`, which already exists.
light_angle: Degrees. 0 is from the right, 90 from above, 135 from the upper left.
The shadow falls the opposite way.
light_height: The light's elevation, above 0 and up to 1. 1.0 is directly
overhead and casts no length at all; small values are a low sun and throw a
long shadow. This is the control that changes the shadow's length.
ground_y: The row the shadow lies on. Defaults to the subject's own contact row,
the lowest row it has a pixel on, which is the same measurement
`validate_loop` reports as `contact_rows`. Refused if it sits above that row,
because a floor running through the subject is not a floor.
ground_layer: The layer holding the surface. When given, the shadow is clipped to
that layer's pixels and the call is refused if there is nothing there to
catch it. Consulted for its pixels, not for whether the picture shows them: a
hidden layer, or one at a low opacity, still holds the pixels the clip asks
about, so the shadow is drawn and the result reports what the floor actually
is (see below) rather than the call being refused over it.
softness: Pixels of penumbra around the core, each one ramp step lighter. 0 is a
hard-edged shadow, 1 or 2 is the usual soft contact.
opacity: The shadow *layer's* opacity, 0 to 255. Left at 255 the shadow's pixels
are exactly ramp entries, which is what keeps conformance at 1.0; lowering it
blends them with whatever is underneath and takes the composite off the ramp,
so prefer a lighter ramp step over a lower opacity.
new_layer: Name for the shadow's own layer, created directly below `layer`, or
reused when a previous call of this tool made it and `frame` has no cel on it
yet. That is how one shadow layer carries a whole walk cycle. A second call for
the same layer *and* frame is refused, because two effects composited into one
cel are a picture neither call describes, and so is a layer of that name this
tool did not create.
frame: Frame to build the shadow for, 1-based.
Returns the ellipse it used as `shadow_ellipse` (`[cx, cy, rx, ry]`), the
`contact_row` it measured, and `shadow_pixels`. A shadow that landed entirely off the
canvas is refused rather than reported as a success that drew nothing.
With a `ground_layer` the result also says what that floor is: `ground_layer_visible`,
`ground_layer_opacity`, and `ground_layer_hidden` naming the layer and any group whose
flag is off, which is present only when something is. A floor the picture does not
show, or shows faintly, is reported in `warnings` as well, because a crisp shadow on
an invisible surface is usually a layer named by mistake rather than an intent.
`clipped_pixels` is routinely large next to `shadow_pixels` when `ground_layer` is a
thin floor, and that is arithmetic rather than a fault: the ellipse is centred on the
contact row and so half of it lies above the floor's top edge, where there is no
surface. Pass `ground_y` at the floor's own top row to push it down, or leave
`ground_layer` out and let the subject hide the upper half.
A shadow is refused when rasterising it would allocate more points than the limit,
which is reachable from legal arguments on a large canvas: the ellipse's radii grow
with the subject's size and with how low the light sits, and the point list is built
in full before any pixel is drawn, so that cost is memory rather than patience. The
message names both radii and the remedy. `ellipse_points` in the result says how close
an accepted shadow came.
| Name | Required | Description | Default |
|---|---|---|---|
| ramp | Yes | ||
| frame | No | Default: 1. | |
| layer | Yes | ||
| opacity | No | Default: 255. | |
| filename | Yes | ||
| ground_y | No | ||
| softness | No | Default: 1. | |
| new_layer | No | Default: "shadow". | shadow |
| light_angle | No | Default: 135.0. | |
| ground_layer | No | ||
| light_height | No | Default: 0.6. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false; the description carries far more: the source cel is never modified, the new layer is created directly below `layer` and reused across frames, a second call for the same layer+frame is refused, a foreign layer of the same name is refused, and opacity below 255 breaks palette conformance. It also discloses the point-allocation limit and that the point list is built in full before drawing.
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?
Front-loaded with purpose and sibling differentiation before the mechanism and per-argument detail. Given 11 parameters and several non-obvious refusal rules, the length is largely justified, though several passages are rhetorically padded ('which is the point', 'a picture neither call describes') and could be tightened without losing information.
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?
No output schema exists, and the description compensates by documenting the return fields (shadow_ellipse, contact_row, shadow_pixels, clipped_pixels, ellipse_points) and the conditional ground_layer_visible/opacity/hidden warnings. Return semantics, refusal semantics, and argument interactions are all present, leaving little an agent needs that 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 only 55%, but the description compensates heavily: ramp ordering (darkest first, ground's ramp), light_angle's degree convention, light_height as cotangent of elevation, ground_y default and refusal rule, ground_layer's clip semantics (including that hidden/low-opacity layers still hold pixels), softness as ramp steps lighter, and opacity's conformance tradeoff. `filename` is left implicit, but the semantic gaps are otherwise well covered.
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 (lay a subject's shadow on the ground) plus the mechanism (made of ramp steps), and explicitly contrasts itself with `add_drop_shadow`, naming that sibling and explaining how the two effects differ. An agent can distinguish this from every other shadow/palette tool without opening a schema.
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 routing to `add_drop_shadow` for alpha-based shadows, plus named prerequisites (`convert_background_to_layer` for background subjects), refusal conditions (background layer, ground_y above contact row, empty ground_layer, duplicate call on same layer+frame), and the offered remedy for large clipped_pixels. When-to-use and when-refused are both spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_layerBDestructive
Erase the target layer/frame cel to full transparency.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | No | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, so the mutating, destructive nature is covered. The description adds meaningful context by clarifying the result is full transparency rather than deletion, distinguishing it from delete_cel. It does not state reversibility, permissions, or whether off-target cels are affected.
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?
A single tight sentence, front-loaded with the action and outcome. No wasted words, though it is terse enough to leave gaps rather than being over-long.
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 destructive mutation with no output schema, the description conveys the core effect but leaves parameter behavior underspecified and offers no guidance on siblings. It is minimally adequate but not 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 coverage is only 33% and the layer and filename parameters have no descriptions. The phrase "target layer/frame cel" loosely gestures at the layer and frame params but adds no semantics for defaults, required filename, or what frame omission means.
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 plus the outcome: "Erase the target layer/frame cel to full transparency." An agent can tell this empties a cel rather than deleting it. However, it does not distinguish itself from close siblings like fill_layer, remove_layer, or delete_cel.
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?
No when-to-use guidance and no named alternatives, despite several overlapping siblings (fill_layer, delete_cel, remove_layer). The agent must infer the use case from the purpose alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
contact_shadowA
Darken the pixels where one form meets another, along its ramp.
Ambient occlusion as pixel artists actually draw it: a line one or two steps darker
where two shapes touch. It is what stops a shaded object looking like it is floating
in front of the thing it is standing on.
Args:
ramp: Colours darkest first. Darkened pixels stay on this ramp.
occluder_color: The colour of the form casting the occlusion, for example the
ground a character stands on, or the blade a crossguard meets.
radius: How far the darkening reaches from the occluder, in pixels. 1 or 2 is
usually right; beyond that it reads as a drop shadow rather than contact.
depth: How many ramp steps darker, at the contact line. 1 is the common choice.
direction: Degrees, restricting occlusion to one side. Omit for all directions,
which is what you want for a contact line; set it when only one side of the
form is actually touching something.
tolerance: How close a pixel must be to a ramp entry to be darkened. Pixels
further away are left alone, so this does not spill onto other materials.
occluder_tolerance: How close a pixel must be to `occluder_color` to count as the
occluder, as a weighted RGB distance. Defaults to `tolerance`, which is what
this did before it was a separate argument. It wants to be **tight**: the
occluder is a flat fill you named, while `tolerance` has to stay loose enough
for shaded art that varies, and one number cannot be both. At the shared
default of 24 a ground colour within 24 of the subject's own ramp makes the
subject its own occluder: measured on a 24x24 sprite with a subject painted
`#5a5a7a` and ground `#60607e`, `occluder_pixels` came back as 312 (the 144
ground pixels plus all 168 of the subject) and nothing was darkened at all.
The result carries a warning naming any ramp entry this cannot be told apart
from, because that overlap is invisible otherwise.
layer: Target layer (default: top layer).
frame: Target frame, 1-based.
Refuses a pass that darkened nothing rather than reporting `darkened_pixels: 0` as a
success, and the refusal carries the three counts that say which of the possible
causes it was. A contact shadow that changed no pixel is not a contact shadow.
Run this **before** the passes that repaint the occluder, not after. The occluder is
found by colour, so a `shade_region_by_light` or `shift_along_ramp` that has already
moved the ground off `occluder_color` leaves this matching a handful of pixels and
reporting the handful as a success.
| Name | Required | Description | Default |
|---|---|---|---|
| ramp | Yes | ||
| depth | No | Default: 1. | |
| frame | No | Default: 1. | |
| layer | No | ||
| radius | No | Default: 1. | |
| filename | Yes | ||
| direction | No | ||
| tolerance | No | Default: 24.0. | |
| occluder_color | Yes | ||
| occluder_tolerance | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false (a write operation) but the description goes far beyond: it explains the tool's refusal behavior ('Refuses a pass that darkened nothing... the refusal carries the three counts'), it explains the warning about ambiguous ramp entries, and it describes the exact failure mode when occluder_tolerance is too loose (with a concrete example and numbers). This is exceptional transparency for a mutation tool, adding significant value 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 well-structured with a clear opening statement, parameter-by-parameter explanations, and a final usage-ordering rule. However, it is quite long and the occluder_tolerance paragraph is dense and somewhat rambling. It remains front-loaded with the core purpose, but the length and detail level, while useful, could be trimmed slightly without losing 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 10 parameters, low schema coverage, no output schema, and the tool's mutation nature, the description covers everything an agent needs: purpose, parameter semantics, behavioral quirks (refusal, warning), and ordering constraints. There are no significant gaps for correct invocation. 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?
Schema description coverage is only 40% (many parameters lack schema descriptions), so the description must carry the burden. It does so thoroughly: it explains each parameter's meaning, provides guidance for values (radius: '1 or 2 is usually right'), explains defaults and interactions (occluder_tolerance defaults to tolerance and why it should be tight), and gives a concrete example of misconfiguration. This fully compensates for the sparse 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 opens with a specific verb and effect ('Darken the pixels where one form meets another, along its ramp') and elaborates with an analogy that leaves no ambiguity about what the tool does. Sibling tools include cast_shadow, glow, and add_drop_shadow, and the description explicitly distinguishes contact shadow from drop shadow ('beyond that it reads as a drop shadow rather than contact'). An agent can select this tool with confidence.
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 guidance on when to use the tool ('Run this before the passes that repaint the occluder') and what not to do ('not after'). It also explains the failure mode of using it after other passes. It distinguishes the tool from related operations by warning about ordering relative to shade_region_by_light and shift_along_ramp. This is as good as it gets.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
convert_background_to_layerB
Convert the Background layer back into a normal (transparent-capable) layer.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=false, so the agent knows this mutates state. The description adds useful semantic context by identifying that the Background layer is changed into a normal transparent-capable layer, but says nothing about reversibility, permissions, or side effects on existing content.
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?
A single front-loaded sentence with no redundant wording. The key action and result are stated immediately.
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 mutation tool with readOnlyHint=false and no output schema, the core effect is covered. However, with 0% schema description coverage and no parameter explanation, the definition remains incomplete regarding which file the operation targets and what error or edge conditions exist.
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 0% for the single required 'filename' parameter, and the description adds no explanation of it. The agent can infer it refers to a file, but the description does not compensate for the schema gap.
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 ('Convert back') and resource ('the Background layer') with the exact resulting state ('normal (transparent-capable) layer'). This clearly distinguishes it from the inverse sibling convert_layer_to_background.
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?
No explicit when-to-use guidance, prerequisites, or alternatives are given. It implies the operation is needed when a transparent-capable layer is desired, but does not say when to choose this over other layer operations or what conditions must hold.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
convert_layer_to_backgroundC
Convert a normal layer into the sprite's opaque Background layer.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false, which tell the agent this mutates state; the description adds that the resulting layer is opaque but says nothing about whether the original layer is replaced, what happens to an existing background layer, or whether the operation is reversible. No destructiveHint is declared and the description does not compensate.
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?
A single tight sentence with no wasted words, front-loading the verb and the target resource.
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 mutating, non-read-only tool with no output schema and undocumented parameters, the description should state preconditions (e.g., only one background layer allowed) and the effect on existing content. None of that is present, leaving the definition inadequate for its 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 description coverage is 0% for both required parameters (filename, layer), and the description never mentions them. It does not clarify how the layer is identified (name vs. index) or what filename refers to, so the agent must guess at 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?
Names a specific verb (convert) and resource (a normal layer) and states the transformation target (the sprite's opaque Background layer). It is distinguishable in intent, though it does not explicitly name the reverse sibling convert_background_to_layer, so it stops 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?
The description gives no when-to-use or when-not-to-use guidance, and does not mention the natural alternative convert_background_to_layer. An agent must infer the correct context from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
copy_celB
Copy a cel's image (and position) from one frame to another on the same layer.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | Yes | ||
| filename | Yes | ||
| to_frame | Yes | ||
| from_frame | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and openWorldHint=false, so the agent knows this is a mutation. The description adds that the copied data includes image and position, but it omits whether the destination cel is overwritten, what happens if the cel is missing, or any permission requirements.
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?
A single sentence, front-loaded with the core operation and containing no filler. It is appropriately sized for the amount of information it chooses to convey.
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 four-parameter mutation tool with no schema descriptions and no output schema, the description is too sparse. It does not explain how filename identifies the sprite, what happens to an existing destination cel, or any error conditions, leaving the agent under-informed for 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 0% for four required parameters. The description implies meanings for from_frame, to_frame, and layer, but it never names them and completely omits the filename parameter, so it fails to compensate for the undocumented 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 uses a specific verb+resource ('Copy a cel's image') and clarifies scope ('from one frame to another on the same layer'). It is clear what the tool does, but it does not name a sibling alternative to distinguish it from tools like link_cels or duplicate_frame.
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?
There is no explicit guidance on when to use this tool versus alternatives such as link_cels, offset_cels, or tween_cels. The description only states the operation, leaving usage context to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_character_spriteA
Scaffold a character sprite project: a transparent canvas with a tidy layer
stack (body + details), an auto-generated shading palette ramp from base_color,
and (optionally) an outlined placeholder body to draw over.
Returns a ``workflow_manifest.v1`` manifest (sprite summary, created files,
palette, and suggested next actions), plus `pixels_written` for the placeholder it
drew. With `with_placeholder=False` nothing is drawn and the field is absent.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| width | No | Default: 32. | |
| height | No | Default: 32. | |
| base_color | No | Default: "#3878c8". | #3878c8 |
| with_placeholder | No | Default: true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false. The description adds real context beyond that: it lists the created files, describes the auto-generated palette ramp, and specifies the conditional behavior of with_placeholder=False (nothing drawn, pixels_written absent). It stops short of noting overwrite/collision or permission requirements for a write 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?
Front-loaded with the primary action and artifact list, then a second paragraph on the return contract. Both sentences carry weight; nothing is padded, though the return detail could be tightened.
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 no output schema, the description rightly covers the workflow_manifest.v1 return and the conditional pixels_written field. Combined with the artifact enumeration, an agent has what it needs to call this correctly; only edge cases like existing-name conflicts are unaddressed.
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 80%, so most params are self-documented and the baseline would be 3. The description earns above baseline by explaining what base_color actually drives (an auto-generated shading ramp) and the effect of with_placeholder, meaning not captured in the schema. name/width/height remain unelaborated in the 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?
States a specific verb and resource ('scaffold a character sprite project') and enumerates the concrete artifacts produced: transparent canvas, body+details layer stack, palette ramp, optional placeholder. The agent can distinguish it from the generic 'create_sprite' sibling by the scaffolding behavior, though no sibling is named explicitly.
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?
Usage is implied by the scaffolding framing and the with_placeholder toggle, but there is no explicit when-to-use/when-not guidance nor any pointer to alternatives like create_sprite or create_icon_set. The agent must infer that this is a project-start helper.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_icon_setB
Scaffold an icon set: a grid sheet with count icon cells, each a placeholder
inside a named slice (icon_0, icon_1, …) for easy atlas export.
Returns a ``workflow_manifest.v1`` manifest (kind "icon_set"); the per-icon regions
appear as slices under `sprite.slices`.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| count | No | Default: 4. | |
| columns | No | ||
| icon_size | No | Default: 16. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false, so the mutation hint is covered, but the description adds real value by disclosing the return artifact: a `workflow_manifest.v1` manifest of kind "icon_set" with per-icon regions exposed as slices under `sprite.slices`. That return contract matters since no output schema exists. It does not state persistence behavior or whether an existing set is overwritten.
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 tight sentences: the scaffolding behavior and cell naming come first, the return shape second. Nothing is padded. The phrase 'for easy atlas export' earns its place as rationale, though it is not strictly required.
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 creation tool with no output schema, explaining the returned manifest is genuinely helpful and largely closes the return-value gap. What remains missing is the semantics of `columns` and `icon_size` (grid layout and cell pixel dimensions), plus whether the scaffold writes to a sprite file on disk. Adequate but with clear 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?
Schema description coverage is 50%, and the description compensates for `count` by describing cells and their naming scheme (icon_0, icon_1, …), matched to slices. However, `columns` and `icon_size` are left entirely to the schema, whose only descriptions are 'Default: 16.' — no meaning or units are added.
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 (scaffold) and resource (icon set) with concrete structure: a grid sheet of `count` cells, each a named placeholder slice. This clearly distinguishes it from siblings like create_sprite or create_tileset_project. It stops short of naming an alternative, but the purpose itself is 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?
No when-to-use guidance, prerequisites, or comparison to alternatives anywhere in the text. It does not tell the agent when scaffolding an icon set is preferable to creating a sprite and adding slices manually via add_slice. Usage must be inferred from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_rpg_item_sheetB
Scaffold an RPG item sheet: a grid sheet with one named slice per item (default sword/shield/potion/coin/key/gem), each with a placeholder.
Returns a ``workflow_manifest.v1`` manifest (kind "rpg_item_sheet"); item regions
appear as slices (named after each item) under `sprite.slices`.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| items | No | ||
| columns | No | ||
| item_size | No | Default: 16. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is not read-only and not open-world. The description adds some behavioral context by disclosing the return manifest kind and slice structure, but it does not say whether it overwrites existing data, what permissions are needed, or what side effects occur.
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 compact, front-loaded sections: what it scaffolds first, then return details. Every sentence earns its place, with no redundant or filler text.
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 composite creation tool with low schema coverage and no output schema, the description covers purpose and return format adequately. However, it omits parameter explanations, side effects, prerequisites, and usage context, leaving meaningful 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?
Schema description coverage is only 25%, so the description must compensate. It partly explains the items parameter via default item names and the slice mapping, but does not explain name or columns, and item_size is only documented in the schema with a default.
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 ("Scaffold") and resource ("RPG item sheet"), and describes the output: a grid sheet with one named slice per item and default items. It is clear but does not explicitly distinguish itself from sibling creation tools like create_sprite or create_character_sprite.
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 no when-to-use guidance, no prerequisites, and no alternatives. The purpose implies a scaffolding scenario, but there is no explicit instruction about when to choose this over other creation tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_spriteADestructive
Create a new sprite file and save it.
Args:
filename: Output path. Relative paths go in the workspace. Use a
.aseprite/.ase extension to keep layers & frames editable.
width, height: Canvas size in pixels. Each axis is capped at 16384px
and the total area at 16,777,216 pixels (e.g. 4096x4096).
color_mode: "rgb" (default), "indexed", or "gray".
background: Optional fill colour for the first layer (e.g. "#1d2b53").
Omit for a transparent canvas.
overwrite: Replace `filename` if it already exists (default False = no-clobber).
An **indexed** sprite is created with a usable 33-colour palette: a transparent
entry at index 0 (the index that means "no pixel here"), then the 32 colours
Aseprite ships as its default. Aseprite's own new indexed sprite has 256 entries of
identical black instead, which made every colour equidistant from every entry, so
every draw resolved to index 0 and was invisible while reporting success. A
`background` colour that the default palette does not contain is appended to it, so
the background is the exact colour asked for rather than the nearest one available.
Replace the whole palette with `set_palette` when you have one in mind.
Returns the new sprite's structured info.
| Name | Required | Description | Default |
|---|---|---|---|
| width | Yes | ||
| height | Yes | ||
| filename | Yes | ||
| overwrite | No | Default: false. | |
| background | No | ||
| color_mode | No | Default: "rgb". | rgb |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, but the description adds substantial behavior the schema cannot convey: no-clobber default on `overwrite`, the 16384px per-axis / 16,777,216px area caps, and a detailed disclosure of how indexed sprites differ from Aseprite's own black-256-entry default and how an unmatched `background` colour is appended rather than snapped.
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?
Front-loaded with the action, then parameter guidance, then the palette caveat. The indexed-palette paragraph is long and partially defensive in tone, but it carries real decision-relevant information and is not duplicative; still, it could be tightened by a sentence or two.
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 6-parameter creation tool with no output schema, the description covers defaults, limits, overwrite risk, extension choice, and returns ('Returns the new sprite's structured info'). With no output schema, the description notes the return shape adequately, and nothing needed to call this 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 description coverage is only 33% (just the two defaults), yet the description documents all six parameters: filename path/extension rules, per-axis and total-area pixel caps, the three color_mode values (the schema has no enum), background fill syntax and omit-for-transparent semantics, and overwrite's no-clobber default.
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 first line states a specific verb+resource ('Create a new sprite file and save it') and the body goes on to distinguish the creation behavior from the palette-editing sibling by name ('Replace the whole palette with set_palette'). An agent can tell this apart from save_sprite_as, list_sprites, and set_color_mode without opening any schema.
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 when-to-use guidance: pick a .aseprite/.ase extension when layers & frames must stay editable, omit `background` for transparency, and defer to `set_palette` when a specific palette is in mind. It does not state when creation should be avoided entirely (e.g., use save_sprite_as on an existing sprite), so it falls just short of explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_tilemap_layerB
Create a tilemap layer with an empty grid.
Args:
name: Layer name.
tile_width, tile_height: Tile size in pixels (sets the sprite grid).
columns, rows: Grid size in tiles (default: enough to cover the canvas).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| rows | No | ||
| frame | No | Default: 1. | |
| columns | No | ||
| filename | Yes | ||
| tile_width | No | Default: 16. | |
| tile_height | No | Default: 16. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool is a non-read-only, non-destructive, closed-world mutation. The description adds that the layer starts with an 'empty grid' and that tile size sets the sprite grid, which is useful. It omits that the operation writes to a file (required 'filename') or any permission/persistence 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?
Front-loaded with the core action, followed by a tight Args list. No wasted prose, appropriate size for a creation 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 7-parameter mutation tool with no output schema, the description explains most grid parameters but leaves the required 'filename' undocumented, leaving the agent unsure where the layer is created. Adequate but with a clear 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 coverage is only 43%, so the description should compensate. It documents name, tile_width, tile_height, columns, and rows, but omits the required 'filename' parameter entirely and never mentions 'frame'. Partial compensation for the coverage gap.
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+resource: 'Create a tilemap layer with an empty grid.' This is clear and distinguishable from generic sibling tools like add_layer, though it doesn't explicitly differentiate from similar creation tools such as create_tileset_project.
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?
No guidance on when to use this versus alternatives like add_layer or create_tileset_project, and no prerequisites. Usage context is only implied by the phrase 'tilemap layer'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_tileset_projectA
Scaffold a tilemap project: a canvas sized columns×rows tiles, a tilemap layer, and a starter tileset (grass/dirt/water/stone by default, or your own [{"name","color"}] list). The grid is filled with the first tile to start.
Returns a ``workflow_manifest.v1`` manifest with a tilemap block mapping tile
names to their tileset indices.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| rows | No | Default: 4. | |
| tiles | No | ||
| columns | No | Default: 4. | |
| tile_size | No | Default: 16. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, so the mutation and closed-world profile is already known. The description adds real behavioral context beyond that: the grid is pre-filled with the first tile, and a workflow_manifest.v1 is returned with a tilemap block. It doesn't say whether an existing project is overwritten, but this is solid added value.
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?
Front-loaded with the core action, then scope, then return value in three tight sentences. The default-tileset aside is parenthetically compact. Slightly dense but no filler sentences.
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 mutation tool with no output schema, the description covers what is created, the pre-fill behavior, and the returned manifest shape. The only notable omission is overwrite/idempotency behavior, but nothing critical to correct invocation 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 60%, with rows/columns/tile_size only carrying defaults and the 'tiles' array undocumented. The description compensates by explaining that columns×rows defines canvas size in tiles and that 'tiles' accepts either the default grass/dirt/water/stone set or a custom [{"name","color"}] list, giving the otherwise-bare parameter real meaning.
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 ('Scaffold') and resource ('tilemap project'), then enumerates exactly what gets created: canvas, tilemap layer, starter tileset. This distinguishes it from siblings like create_tilemap_layer or create_sprite, which build only one component.
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?
Usage is implied by the scaffold framing (start a new tilemap project), but there is no explicit when-to-use versus alternatives such as create_tilemap_layer or create_sprite, and no mention of prerequisites or when-not to use it. Adequate but with clear gaps.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crop_spriteBDestructive
Crop the canvas to the rectangle (x, y, width, height).
The resulting canvas is subject to the same dimension/area caps as `create_sprite`
(a "crop" to a larger rectangle grows the canvas).
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | ||
| y | Yes | ||
| width | Yes | ||
| height | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description adds genuinely useful behavior beyond that: the resulting canvas inherits create_sprite's dimension/area caps, and a crop to a larger rectangle GROWS the canvas rather than failing — a counterintuitive trait worth surfacing.
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 tight sentences with the core action front-loaded and the surprising edge-case behavior immediately after. 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 destructive 5-parameter mutation with no output schema and zero schema description coverage, the description covers crop semantics well but omits the filename parameter, origin convention, and out-of-bounds/clamping behavior. Annotations cover the safety profile, so the remaining gap is moderate.
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 0% and none of the five parameters are documented in the schema. The description names x, y, width, height but never says x/y are the top-left corner or how out-of-bounds values behave, and the required `filename` parameter is not mentioned at all.
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 (crop) and resource (canvas) and identifies the exact parameters that define the rectangle. It doesn't explicitly differentiate itself from adjacent transforms like trim_sprite, resize_canvas, or scale_sprite, though the parenthetical clarifies its unusual grow-on-larger-rectangle semantics.
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?
No when-to-use guidance is given and no alternatives are named, despite siblings like trim_sprite and resize_canvas that overlap conceptually. The note about area caps implies constraints but does not tell the agent when to prefer this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cycle_paletteA
Animate a sprite by cycling a run of palette colours, the oldest trick in the medium: the pixels do not move, the colours do, and water flows.
**What this ships, and why.** Aseprite's file format carries a palette per frame, but
its Lua API does not expose one, so the real thing cannot be authored from here.
Measured on 1.3.18.6: `#spr.palettes` is 1 and stays 1, the collection is read-only
(`spr.palettes[2] = ...` and `table.insert` both raise "attempt to index a nil value
(field '__setters')"), `Palette` has no `frame` property, `Sprite:newPalette` does not
exist, and `Sprite:setPalette` replaces the single sprite-wide palette no matter which
frame `app.frame` is on, as does `app.command.LoadPalette`. So this is the fallback:
the frames are generated, it costs one frame of storage each, and it works everywhere
a frame does, including in a GIF or a PNG sequence.
What rotates is the pixels' own indices, not the palette. On an indexed sprite those
are the same picture, and the index move is exact: no colour matching, nothing routed
through `nearest_index`, and the palette comes back byte for byte as it went in, so
`get_palette` still shows the ramp that was authored.
Args:
indices: The palette indices to rotate, **in the order the colours travel**. At
least two, distinct, each one in the palette, and none of them an entry that
cannot draw (the sprite's transparent index, or an entry whose alpha is 0):
rotating one of those through the cycle would make drawn pixels vanish.
`list_palette_usage` reports the contiguous runs worth passing here.
frame_count: How many frames the cycle occupies. Defaults to `len(indices)`, which
is one frame per colour, and is capped there: past that the rotation repeats a
frame already written, so the extra frames cost storage and show nothing new.
step: How far the colours travel per frame. Positive moves them forward along
`indices`; negative moves them back. A multiple of `len(indices)` is refused
rather than silently producing identical frames.
layer: Cycle only this layer's pixels. Default: every pixel layer.
The sprite must have exactly one frame. A cycle generates the whole timeline from the
one drawn frame, so a sprite that already animates would have its timeline redefined,
and that is refused rather than guessed at: `duplicate_frame` the pose into a sprite
of its own first.
Refuses, before anything is written, an index outside the palette (it names the size),
an index that cannot draw, a repeated index, a step that is a whole number of laps, and
a cycle none of whose indices appear in the art, which would write identical frames and
animate nothing. That last refusal names the indices the art *is* drawn with.
Returns the frames it wrote and how many pixels moved on each, `closes` (whether the
rotation returns to where it started at the wrap), and `warnings` when the cycle does
not close, or when an index in it has no pixels to travel through. `warnings` is
absent rather than empty when there is nothing to say.
| Name | Required | Description | Default |
|---|---|---|---|
| step | No | Default: 1. | |
| layer | No | ||
| indices | Yes | ||
| filename | Yes | ||
| frame_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false; the description goes far beyond them, disclosing that it rewrites the entire timeline, costs one frame of storage per colour, rotates index data rather than palette entries, and enumerates every refusal (out-of-palette index, non-drawing index, repeats, whole-lap step, no-op cycles) before listing what the return payload contains.
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?
Purpose is front-loaded and the Args section is well structured, but the middle paragraph justifying the fallback against Aseprite 1.3.18.6 internals is dense and only partly load-bearing for an agent. Most sentences still earn their place given the tool's non-obvious semantics.
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?
There is no output schema, and the description fully covers what comes back (frames written, per-frame pixel movement, closes, and warnings that are absent rather than empty). Combined with the refusal list and preconditions, an agent has everything needed to invoke 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?
Schema coverage is only 20% (just step's default), and the description compensates thoroughly for indices (order, distinctness, palette membership, alpha-0 exclusion), frame_count (default and cap logic), step (direction and whole-lap refusal) and layer (default scope). The required filename parameter is left undocumented in both schema and description, a small remaining gap.
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 ("Animate a sprite by cycling a run of palette colours") and immediately disambiguates from related tools by insisting the pixels don't move, the colours do. An agent can distinguish this from set_palette, get_palette, generate_ramp and shift_along_ramp without opening any schema.
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 explicit prerequisites and when-not conditions: the sprite must have exactly one frame, and a sprite that already animates is refused with a named workaround (duplicate_frame into its own sprite). It also routes the agent to list_palette_usage for finding the runs worth passing, and explains the fallback context versus per-frame palettes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_celBDestructive
Delete a cel (the layer becomes empty at that frame).
| Name | Required | Description | Default |
|---|---|---|---|
| frame | Yes | ||
| layer | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description adds the meaningful consequence that the layer itself survives and only becomes empty at that frame, but says nothing about reversibility or side effects on linked cels.
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?
A single short sentence with the verb-resource pair front-loaded and the clarifying consequence in a parenthetical. Nothing is redundant or padded.
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 destructive mutation with no output schema and zero parameter documentation, the description conveys the core effect but omits error behavior, whether the cel can be restored, and how the filename/layer/frame arguments are validated.
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 0% and all three parameters (filename, layer, frame) are required and undocumented. The description adds no parameter detail at all, so it fails to compensate for the coverage gap even though the names are largely self-explanatory.
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 (Delete) and resource (cel) and adds the effect 'the layer becomes empty at that frame,' which usefully separates this from clear_layer/remove_layer semantics. It doesn't name a sibling tool explicitly, so an agent must still infer the distinction from 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?
There is no when-to-use or when-not-to-use guidance and no named alternative such as clear_layer, remove_layer, or remove_frame. Usage is only implied by the parenthetical about the resulting empty layer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
desaturateB
Desaturate toward grayscale by amount percent (0-100).
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | No | ||
| amount | No | Default: 100. | |
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, confirming this is a mutation. The description adds the amount range (0-100) and direction (toward grayscale), which is useful context, but does not disclose what exactly gets modified (layer, frame) or whether changes are reversible.
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?
A single, front-loaded sentence with zero waste. Every word contributes to stating the operation and its degree.
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 mutating tool with four parameters and no output schema, the description is too thin. It omits which sprite/layer/frame is affected and leaves required 'filename' and optional 'layer' unexplained, so an agent cannot fully predict the tool's effect.
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 50%. The description adds meaning for 'amount' (percent toward grayscale, 0-100), which goes beyond the schema's bare 'Default: 100.' However, it does not explain the required 'filename' or the optional 'layer' and 'frame' parameters, so partial compensation only.
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 ('Desaturate') and the effect ('toward grayscale by amount percent'), so the agent knows the operation. It does not differentiate from sibling tools like adjust_hue_saturation or invert_colors, but the core purpose is clear.
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?
No when-to-use guidance, prerequisites, or mention of alternatives. The description only states what the tool does, leaving the agent to infer when to select it over sibling color operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deselectA
Clear the selection, so edits affect the whole layer again.
A real step, not a formality: the selection lives in a sidecar beside the sprite and
persists across calls, so leaving one active will silently scope every later edit.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say readOnlyHint=false and openWorldHint=false; the description adds crucial behavioral context beyond that: the selection persists across calls in a sidecar and can silently scope future edits, making this a necessary state-clearing operation rather than a formality. This is exactly the kind of hidden-state disclosure that annotations cannot 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?
Two sentences, front-loaded with the action and effect, followed by a compact rationale. Every sentence earns its place 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?
For a simple state-clearing tool with one parameter and no output schema, the description provides adequate context: it explains what is cleared and why it matters. The lack of any mention of the filename parameter or return value is a minor gap, but not critical given the tool's simplicity.
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 has a single required 'filename' parameter with 0% schema description coverage. The description does not explain the filename parameter at all. However, with only one parameter (baseline 4 for 0 params, but here 1 param with no description), the baseline is adjusted: the description's silence on the parameter is a gap, but not severe since the parameter is self-evident from context (the sprite file). A score of 3 reflects that the description adds no parameter-specific meaning.
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 ('Clear') and resource ('the selection'), and immediately explains the effect: 'edits affect the whole layer again.' It is easily distinguished from siblings like modify_selection, invert_selection, and select_region, which create or alter selection rather than clear it.
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 clearly implies when to use it by warning that leaving a selection active will 'silently scope every later edit,' effectively guiding the agent to call deselect before doing layer-wide edits. It does not explicitly name alternatives or state a when-not-to-use condition, so it falls 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.
diff_spritesARead-only
Compare two frames pixel for pixel and say what changed.
This is the tool for the question an editing agent cannot otherwise answer: *did my
last call do what I meant?* `assess_sprite` judges one frame on its own and
`render_preview` returns a picture a text-only model cannot read. This reports the
difference between two frames as counts, which is the only form in which "the shading
pass moved the outline" is visible without eyes.
**Nothing changed is the loudest result, not the quiet one.** An edit that silently
went nowhere, to the wrong layer, inside a stale selection, off the canvas, looks
exactly like an edit that was not needed. When the two frames are identical this says
so first and names the usual causes.
A difference is never reported as a fault, because different is not wrong. Pass
`expect` to turn the measurement into a check.
Args:
filename: The sprite to compare, and the "before" side of the report.
frame: Which frame of it (1-based).
layer: Compare this layer alone instead of the composite, on both sides unless
`other_layer` says otherwise. Worth reaching for: drawing tools write to ONE
layer, so a composite diff can show nothing while the layer underneath
changed completely, and the reverse.
other: The sprite to compare against. Defaults to `filename`, which is what makes
a frame-to-frame diff inside one animation this same call.
other_frame: Which frame of `other` (1-based).
other_layer: The layer to read on the `other` side, when it is named differently.
expect: What the change should be: "identical", "silhouette", "interior",
"coverage" or "mixed". Adds a verdict block with a pass or a fail, and is
omitted rather than guessed at.
Returns counts in four buckets that add up to `changed_pixels`, so a change is never
reported as a single number that could mean two different things:
* `silhouette_added` / `silhouette_removed`: pixels that entered or left the shape.
These are the ones that move a collision box, an outline and a trimmed export box.
* `interior_changed`: pixels that were visible before and after and changed colour.
* `coverage_changed`: pixels that kept their colour and changed only their alpha,
which is an opacity or anti-aliasing change rather than a repaint.
Both frames must be the same size; a mismatch is refused with both canvas sizes and
both content boxes, because a diff of differently sized frames is an offset question
in disguise. Different colour modes compare fine: both sides are read as RGBA, so an
indexed sprite and its RGB export can be checked against each other.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | No | ||
| other | No | ||
| expect | No | ||
| filename | Yes | ||
| other_frame | No | Default: 1. | |
| other_layer | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say read-only and closed-world. The description adds substantial behavior: identical frames are reported first with probable causes, differences are never framed as faults, the four output buckets that sum to changed_pixels, size mismatch is refused with canvas sizes and content boxes, and cross-color-mode comparison is allowed. That is well beyond what readOnlyHint conveys.
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?
Front-loaded with the one-line purpose, then use-case, then args, then return shape, then edge cases. It is longer than most definitions but nearly every sentence adds decision-relevant detail. Slightly more prose than strictly necessary in the framing paragraphs, but it earns its space.
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?
No output schema exists, and the description documents the return shape explicitly (four buckets summing to changed_pixels). Combined with the expect verdict, the mismatch refusal, and the color-mode note, an agent has everything needed to invoke and interpret 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?
Schema coverage is only 29% and the description fully compensates: it defines each of the 7 params (defaults for frame/other_frame, the layer/other_layer relationship, other defaulting to filename for intra-animation diffs, and the enum values for expect plus its pass/fail verdict block). This is the rare case where the description carries parameter meaning the schema omits.
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 (compare pixel for pixel) and names what it returns (what changed). Explicitly contrasts with siblings assess_sprite (judges one frame) and render_preview (returns a picture), so the agent can position this tool without opening other schemas.
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 the exact question this tool answers ('did my last call do what I meant?') and names the two alternatives it is not. The layer arg even explains when to reach for composite vs layer diffing, which is a when-to-use distinction inside a parameter.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dither_bandA
Dither the boundary between two adjacent ramp steps, widening the transition.
Dithering in pixel art is a limited-palette necessity rather than a style: it buys
an apparent extra shade between two you already have. It reads as dated when applied
globally, which is why this is scoped to one boundary rather than offered as a
filter over the whole sprite.
Args:
ramp: Colours darkest first.
from_step, to_step: 1-based indices into `ramp`, and they must be adjacent.
Dithering between distant steps produces visible noise, not a gradient.
**1-based, while `ramp` is a list the caller indexes from 0**, so the pair
that dithers `ramp[3]` against `ramp[4]` is `from_step=4, to_step=5`. The two
conventions usually sit a line apart:
shade_region_by_light(f, GOLD, base_color=GOLD[4], ...)
dither_band(f, GOLD, from_step=5, to_step=6, ...) # GOLD[4], GOLD[5]
Off by one still names an adjacent pair, so the call succeeds and dithers the
wrong boundary. The result reports `from_color` and `to_color` for that
reason: it is the only way to check the intent from the output.
pattern: "bayer4" (finest, the usual choice), "bayer2" (chunkier) or "checker"
(a hard 50/50 that suits a sharp material change).
width: How far the dithered zone reaches into each band, in pixels. This is what
widens the transition, which is the point of dithering: at width=1 only the
seam itself alternates, and every pattern collapses to the same result
because a one-pixel-deep band can only alternate.
tolerance: How close a pixel must be to one of the two colours to take part.
layer: Target layer (default: top layer).
frame: Target frame, 1-based.
Only pixels of the two named colours that border each other are touched, so the
rest of the sprite is untouched even where it uses the same ramp.
Returns `dithered_pixels`, and `from_color`/`to_color`, the two colours the steps
actually resolved to.
| Name | Required | Description | Default |
|---|---|---|---|
| ramp | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| width | No | Default: 2. | |
| pattern | No | Default: "bayer4". | bayer4 |
| to_step | Yes | ||
| filename | Yes | ||
| from_step | Yes | ||
| tolerance | No | Default: 24.0. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply readOnlyHint=false and openWorldHint=false, so the description carries most of the burden and does so well: it discloses that only pixels of the two named colours that border each other are touched, that the rest of the sprite is untouched, and that the result reports from_color/to_color. It does not explicitly state persistence/undo behavior, which keeps it from a 5.
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?
Front-loaded with purpose, then organized into a rationale block and an Args block. The indexing explanation is lengthy but earns its place given the documented off-by-one hazard. Slightly verbose, but no clearly wasted sentence.
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 9-parameter mutation tool with no output schema and low schema coverage, the description supplies the missing behavioural and parameter context, including return fields, scope of effect, and the indexing convention. Nothing an agent needs to invoke it correctly appears to be 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 only 44%, yet the description documents nearly every parameter with meaning beyond the schema: 1-based from_step/to_step semantics with a worked off-by-one example, the three pattern choices and their trade-offs, width's effect (and that width=1 collapses all patterns), tolerance, layer and frame. This fully compensates for the sparse 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?
States a specific verb (dither) and resource (the boundary between two adjacent ramp steps) plus the effect (widening the transition). It is immediately distinguishable from ramp-generation siblings like generate_ramp/ramp_between and from shade_region_by_light, which the description itself contrasts against.
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?
Explains the context for use (limited-palette necessity, buys an extra apparent shade) and why it is deliberately scoped to one boundary rather than a global filter. It also states the adjacency constraint. However, it never explicitly routes the agent to a named alternative tool for the global case, so it stops 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.
draw_brushB
Stamp a custom brush shape at a list of points.
Args:
brush: The brush as rows of characters. Any character other than space,
'.', or '0' is a filled cell. e.g. a plus brush: ["010", "111", "010"].
points: Positions to stamp at, list of {"x": int, "y": int}.
color: Colour to stamp the brush in.
anchor: "center" (default) or "topleft", where each point sits in the brush.
| Name | Required | Description | Default |
|---|---|---|---|
| brush | Yes | ||
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| anchor | No | Default: "center". | center |
| points | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, so the agent already knows this mutates local state. The description adds meaningful input semantics (brush character encoding, anchor placement) but never says which file/layer/frame is affected, that it is destructive to existing pixels, or that 'filename' is required – gaps the annotations alone do not close.
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?
Front-loaded one-line purpose followed by a compact Args block; every line earns its place and there is no filler. The only minor cost is the verbose brush example, which is nonetheless useful.
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 7-parameter mutation tool with no output schema and low schema coverage, the description covers the novel brush/point semantics but omits required-parameter guidance (filename) and the frame/layer targeting behavior, leaving an agent to infer how the stamp is scoped.
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 only 29%, so the description carries real weight, and it does document brush, points, color, and anchor well (including the character-fill rule and the center/topleft values). However, three parameters – filename, frame, and layer – are undocumented in both schema and description, leaving the coverage gap only partly filled.
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 line gives a specific verb (stamp) and resource (custom brush shape) plus the target (a list of points), which is clear enough to distinguish it from pixel- or line-drawing siblings. It does not explicitly contrast itself with the closest alternatives like stamp_pattern or draw_pixel_map, so it stops 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?
There is no guidance on when to reach for this tool versus stamp_pattern, draw_pixel_map, or draw_pixels, nor any prerequisites (e.g. an open sprite, valid layer/frame). The Args block documents inputs but never states the usage context or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_curveA
Draw a quadratic Bézier curve from (x0,y0) to (x1,y1) bending toward the
control point (control_x, control_y). steps controls smoothness.
Coordinates: (0, 0) is the top-left pixel. x grows right, y grows DOWN. A span given as position plus size covers x .. x + width - 1, so width is a count of pixels, not an offset to the far edge.
Centring differs between primitives, so check this when aligning two shapes:
draw_rectangle(x, width) spans x .. x+width-1, centred on x + (width-1)/2. An even width therefore centres on a half pixel.
draw_ellipse(center, radius) spans center-radius .. center+radius, which is always an ODD 2*radius+1 pixels wide and always centred on a whole pixel.
draw_ellipse_in_box(x, y, width, height) takes the same bounding box as draw_rectangle and fills it exactly, so it is the one to use for an even diameter, a disc centred on an even canvas, or a circle that has to line up with a rectangle.
draw_symmetric_pixels mirrors about the canvas, not about either of the above.
Writes falling outside the canvas are dropped rather than raising. Every drawing tool reports pixels_written, and pixels_clipped when anything was dropped, so compare those against what you asked for rather than trusting ok.
| Name | Required | Description | Default |
|---|---|---|---|
| x0 | Yes | ||
| x1 | Yes | ||
| y0 | Yes | ||
| y1 | Yes | ||
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| steps | No | Default: 32. | |
| filename | Yes | ||
| control_x | Yes | ||
| control_y | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply readOnlyHint=false and openWorldHint=false. The description adds genuine behavioral context beyond that: out-of-canvas writes are silently dropped rather than raising, every drawing call returns pixels_written and pixels_clipped, and the agent is told not to trust `ok` alone. It does not state whether the call needs an open sprite or which cel/layer is mutated, so it is not a full 5.
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 purpose is front-loaded correctly, but the bulk of the text is a shared drawing-convention preamble about draw_rectangle, draw_ellipse, draw_ellipse_in_box, and draw_symmetric_pixels — tools other than this one. It is dense rather than padded, yet a large fraction of the content does not earn its place in a curve-specific definition.
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 no output schema, the description correctly steps in to describe the return payload (pixels_written, pixels_clipped) and the coordinate system and clipping policy, which is what an agent needs to call and verify this draw op. What remains missing — layer/frame targeting and preconditions — is secondary for a single-primitive draw call.
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 only 18% (basically just the two defaults), so the description has to carry the load. It explains the six geometric coordinates and gives `steps` a meaning ('controls smoothness'), but leaves frame, layer, and filename semantically undocumented. Partial compensation for a low-coverage schema lands at 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?
The opening sentence names a specific verb and resource — 'Draw a quadratic Bézier curve' — and enumerates the exact anchor and control points plus the `steps` parameter that governs it. That is precise enough to separate it from draw_line, draw_polyline, and the other drawing siblings without inspecting schemas.
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 centring section gives real routing advice (use draw_ellipse_in_box for even diameters, etc.), but it tells the agent when to prefer OTHER primitives, not when to reach for draw_curve over draw_line or draw_polyline. Usage of this tool itself is only implied by the name and the Bézier phrasing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_ellipseA
Draw an ellipse centred at (center_x, center_y) with the given radii.
For a circle, use the same value for radius_x and radius_y. filled=False draws a 1px outline, and a filled ellipse is exactly that outline with its interior: the two are one shape rendered two ways, so a fill and an outline of the same call line up. antialias smooths a filled ellipse with sub-pixel coverage (RGB sprites only; ignored otherwise).
Coordinates: (0, 0) is the top-left pixel. x grows right, y grows DOWN. A span given as position plus size covers x .. x + width - 1, so width is a count of pixels, not an offset to the far edge.
Centring differs between primitives, so check this when aligning two shapes:
draw_rectangle(x, width) spans x .. x+width-1, centred on x + (width-1)/2. An even width therefore centres on a half pixel.
draw_ellipse(center, radius) spans center-radius .. center+radius, which is always an ODD 2*radius+1 pixels wide and always centred on a whole pixel.
draw_ellipse_in_box(x, y, width, height) takes the same bounding box as draw_rectangle and fills it exactly, so it is the one to use for an even diameter, a disc centred on an even canvas, or a circle that has to line up with a rectangle.
draw_symmetric_pixels mirrors about the canvas, not about either of the above.
Writes falling outside the canvas are dropped rather than raising. Every drawing tool reports pixels_written, and pixels_clipped when anything was dropped, so compare those against what you asked for rather than trusting ok.
| Name | Required | Description | Default |
|---|---|---|---|
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| filled | No | Default: false. | |
| center_x | Yes | ||
| center_y | Yes | ||
| filename | Yes | ||
| radius_x | Yes | ||
| radius_y | Yes | ||
| antialias | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark this as a non-read-only, closed-world write. The description adds real behavioral context: filled=False gives a 1px outline that lines up exactly with the filled version, antialias applies only to filled RGB sprites, out-of-canvas writes are dropped rather than raising, and pixels_written/pixels_clipped should be compared against intent instead of trusting ok.
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?
Purpose and the fill/antialias semantics are front-loaded, and the coordinate and centring details are grouped into scannable bullets. It is somewhat long for a single drawing primitive, but nearly every line carries non-obvious information.
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?
There is no output schema, yet the description covers the coordinate system, clipping behavior, and the keys returned (pixels_written, pixels_clipped), so return-shape handling is addressed. The main omission is format/meaning for color, layer, and frame, which a caller still has to infer.
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 only 30%, so the description must compensate. It gives strong meaning for center, radius, filled, and antialias (odd 2*radius+1 span, whole-pixel centring, fill/outline equivalence), but leaves color, layer, frame, and filename entirely unexplained - roughly half the parameters remain undocumented in either place.
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 first sentence states a specific verb and resource with the exact anchoring parameters (center_x, center_y, radii). It also distinguishes this primitive from draw_ellipse_in_box, draw_rectangle, and draw_symmetric_pixels via the centring bullet list, so an agent can select it without opening another schema.
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 routing guidance: use this for a circle (radius_x == radius_y) and for pixel-centred spans, and switch to draw_ellipse_in_box for even diameters, discs on even canvases, or circles that must align with a rectangle. The when-to-use-vs-sibling condition is spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_ellipse_in_boxA
Draw an ellipse that fills the given bounding box exactly.
Takes the same box as draw_rectangle, so the two share a centre and an extent: this is how to draw a disc centred on an even canvas, or a circle that lines up with a rectangle. draw_ellipse takes a centre and radii instead, which can only ever be an odd 2*radius+1 across.
An even side is drawn the way it is drawn by hand: the odd ellipse one pixel smaller, with its middle row or column repeated. Give an odd width and height and the result is pixel for pixel what draw_ellipse produces for the same shape, because both use the same geometry.
filled=False draws a 1px outline. antialias smooths a filled ellipse with sub-pixel coverage (RGB sprites only; ignored otherwise).
Coordinates: (0, 0) is the top-left pixel. x grows right, y grows DOWN. A span given as position plus size covers x .. x + width - 1, so width is a count of pixels, not an offset to the far edge.
Centring differs between primitives, so check this when aligning two shapes:
draw_rectangle(x, width) spans x .. x+width-1, centred on x + (width-1)/2. An even width therefore centres on a half pixel.
draw_ellipse(center, radius) spans center-radius .. center+radius, which is always an ODD 2*radius+1 pixels wide and always centred on a whole pixel.
draw_ellipse_in_box(x, y, width, height) takes the same bounding box as draw_rectangle and fills it exactly, so it is the one to use for an even diameter, a disc centred on an even canvas, or a circle that has to line up with a rectangle.
draw_symmetric_pixels mirrors about the canvas, not about either of the above.
Writes falling outside the canvas are dropped rather than raising. Every drawing tool reports pixels_written, and pixels_clipped when anything was dropped, so compare those against what you asked for rather than trusting ok.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | ||
| y | Yes | ||
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| width | Yes | ||
| filled | No | Default: false. | |
| height | Yes | ||
| filename | Yes | ||
| antialias | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only state readOnlyHint=false and openWorldHint=false. The description adds substantial behavioral detail beyond that: out-of-canvas writes are dropped rather than raising, results are reported via pixels_written/pixels_clipped that should be checked instead of trusting ok, and antialias applies only to filled RGB sprites. This is rich context the annotations do not carry.
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?
Front-loaded with the core purpose, then structured into geometry, centring comparison, and clipping notes. It is long, but nearly every sentence carries distinct information (odd/even parity, layout alignment, clip reporting); the bulleted centring section is the only part that could be tightened.
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 10-parameter mutation tool with no output schema, it covers the critical drawing semantics, coordinate convention, and return-field behavior. It leaves color format and the frame/layer parameters unexplained, so it is strong but not fully 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?
With only 30% schema coverage, the description must compensate and largely does: it defines the box semantics of x/y/width/height ('x .. x + width - 1, so width is a count of pixels, not an offset'), explains filled=False as a 1px outline, and clarifies antialias behavior. Gaps remain for color, layer, and frame, which are undocumented in both schema and description.
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 precise verb+resource+scope: draw an ellipse that fills the given bounding box exactly. It explicitly distinguishes itself from draw_ellipse (centre+radii, odd sizes), draw_rectangle (shares the box), and draw_symmetric_pixels, so an agent can pick correctly without opening schemas.
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?
States explicitly when to use this tool ('the one to use for an even diameter, a disc centred on an even canvas, or a circle that has to line up with a rectangle') and pins the comparison against named alternatives, including the odd-vs-even size distinction versus draw_ellipse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_image_base64A
Composite an inline base64-encoded PNG (or other image) onto a layer at (x, y).
Useful for pasting externally generated artwork. `image_base64` may include a
`data:image/png;base64,` prefix. The decoded image is capped at 32 MB; for
anything larger, write the file into the workspace and use `stamp_file`.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | ||
| y | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| opacity | No | Default: 255. | |
| filename | Yes | ||
| blend_mode | No | Default: "normal". | normal |
| image_base64 | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only state readOnlyHint=false and openWorldHint=false, which already imply a local mutating operation. The description adds real context beyond that: the 32 MB decoded-size cap, tolerance for a data: URI prefix, and the fallback path for oversized images. It does not describe how existing layer content is affected by compositing.
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, front-loaded with the core action, then the use case, then the base64/size caveats and fallback. No filler; every sentence carries operational information.
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?
No output schema exists, so return values needn't be explained. The call-critical details (base64 prefix, size cap, preference for stamp_file on large inputs) are present, though unaddressed parameters like blend_mode and opacity leave some gaps for a compositing 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 only 38% for 8 parameters. The description clarifies image_base64 format (optional data: URI prefix) and implies x/y placement, which does add meaning. However, layer, opacity, blend_mode, and frame are undocumented in both schema and description, so it only partially compensates for the coverage gap.
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 (composite) plus resource (inline base64-encoded image) and the destination (a layer at (x, y)). It is immediately distinguishable from the sibling stamp_file, which is file-based, and from draw_pixels/draw_pixel_map which draw pixel data rather than images.
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 a use case ('pasting externally generated artwork') and explicitly names the alternative stamp_file with the condition that selects it (>32 MB). No explicit when-not beyond the size threshold, but the routing guidance is concrete and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_lineA
Draw a straight line from (x1,y1) to (x2,y2).
Args: pixel_perfect: Remove L-shaped corner pixels for a clean 1px pixel-art line. antialias: Smooth (Xiaolin Wu) line with alpha blending, RGB sprites only; ignored on indexed/gray. Takes precedence over pixel_perfect.
Coordinates: (0, 0) is the top-left pixel. x grows right, y grows DOWN. A span given as position plus size covers x .. x + width - 1, so width is a count of pixels, not an offset to the far edge.
Centring differs between primitives, so check this when aligning two shapes:
draw_rectangle(x, width) spans x .. x+width-1, centred on x + (width-1)/2. An even width therefore centres on a half pixel.
draw_ellipse(center, radius) spans center-radius .. center+radius, which is always an ODD 2*radius+1 pixels wide and always centred on a whole pixel.
draw_ellipse_in_box(x, y, width, height) takes the same bounding box as draw_rectangle and fills it exactly, so it is the one to use for an even diameter, a disc centred on an even canvas, or a circle that has to line up with a rectangle.
draw_symmetric_pixels mirrors about the canvas, not about either of the above.
Writes falling outside the canvas are dropped rather than raising. Every drawing tool reports pixels_written, and pixels_clipped when anything was dropped, so compare those against what you asked for rather than trusting ok.
| Name | Required | Description | Default |
|---|---|---|---|
| x1 | Yes | ||
| x2 | Yes | ||
| y1 | Yes | ||
| y2 | Yes | ||
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| filename | Yes | ||
| antialias | No | Default: false. | |
| pixel_perfect | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide readOnlyHint=false and openWorldHint=false. The description adds substantial behavioral context: out-of-canvas writes are dropped rather than raising, and reports pixels_written/pixels_clipped so the agent should compare against expectations rather than trusting 'ok'. This is exactly the kind of non-obvious behavior annotations cannot 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?
Front-loads the core action and args, then provides useful coordinate/centring reference material. The centring section is lengthy and somewhat tangential to drawing a line, but it is structured and earns its place for alignment work. Slightly verbose but well organized.
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 drawing primitive with no output schema and low schema coverage, the description covers coordinate conventions, mode interactions, clipping behavior, and sibling primitive distinctions. An agent has everything needed to call it correctly and interpret 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?
Schema coverage is only 30%, so the description must compensate. It explains pixel_perfect and antialias semantics, and critically defines the coordinate system ((0,0) top-left, y grows down, span = x..x+width-1). It does not explain frame, layer, or color parameters, leaving some gaps, but adds meaningful 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?
States a specific verb+resource ('Draw a straight line') with exact endpoint syntax '(x1,y1) to (x2,y2)'. Distinguishes itself from sibling primitives like draw_rectangle, draw_ellipse, and draw_polyline by naming them and clarifying their differing centring conventions.
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?
Clearly explains the alternative modes (pixel_perfect vs antialias) and when antialias applies (RGB only, ignored on indexed/gray, takes precedence over pixel_perfect). Does not give an explicit when-to-use-this-tool-instead-of-siblings directive, but the centring comparisons guide the agent toward the right primitive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_pixel_mapA
Draw from a character grid, one character per pixel: the way pixel art is authored.
This is the write side of get_pixels(format="map") and takes exactly the shape that
returns, a legend plus one string per row, so a read, an edit and a write
round-trip. Until this existed the server could show a caller per-pixel intent and
could not receive it: the only way to author a figure was a list of
{"x", "y", "color"} dictionaries, one per pixel.
That asymmetry shaped the art it produced, which is the real reason this is here. A caller reaching for a thousand-entry dictionary list does not write a thousand considered pixels, it writes a formula that emits them, and a formula produces smooth monotone surfaces. Hand-placed pixel art is the opposite of that: a highlight nudged two pixels off the geometric centre, an outline that thickens on the shadow side, three pixels clustered to imply a chip in the stone. A grid is the notation those decisions can be written in, and it is about a tenth the size: a 16x16 of three colours is roughly 3,400 characters as dictionaries and 350 as a map.
Args:
rows: One string per row, one character per pixel, every row the same length.
A ragged map is refused rather than padded, because padding would shift every
pixel after the short row.
legend: Symbol to colour, as {"a": "#1b2b4a", "b": "red"}. "." means leave
that pixel alone and needs no entry; any other character can say the same
with the value "transparent", which is what the read side emits. A
character the legend does not define is refused, not skipped: a typo in a
grid would otherwise paint nothing and report success.
x, y: Where the map's top-left corner lands on the canvas. Defaults to the
canvas origin.
layer: Target layer name or 1-based index (default: top layer).
frame: Target frame, 1-based (default 1).
Transparent cells are left untouched rather than erased, so a map can be stamped over existing art; clear the layer first if you want the map to be the whole of it.
Returns the usual write counters plus map_width, map_height,
pixels_transparent (cells deliberately left alone) and colors_used.
Coordinates: (0, 0) is the top-left pixel. x grows right, y grows DOWN. A span given as position plus size covers x .. x + width - 1, so width is a count of pixels, not an offset to the far edge.
Centring differs between primitives, so check this when aligning two shapes:
draw_rectangle(x, width) spans x .. x+width-1, centred on x + (width-1)/2. An even width therefore centres on a half pixel.
draw_ellipse(center, radius) spans center-radius .. center+radius, which is always an ODD 2*radius+1 pixels wide and always centred on a whole pixel.
draw_ellipse_in_box(x, y, width, height) takes the same bounding box as draw_rectangle and fills it exactly, so it is the one to use for an even diameter, a disc centred on an even canvas, or a circle that has to line up with a rectangle.
draw_symmetric_pixels mirrors about the canvas, not about either of the above.
Writes falling outside the canvas are dropped rather than raising. Every drawing tool reports pixels_written, and pixels_clipped when anything was dropped, so compare those against what you asked for rather than trusting ok.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | Default: 0. | |
| y | No | Default: 0. | |
| rows | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| legend | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare `readOnlyHint=false` and `openWorldHint=false`; the description adds substantial behavioral detail beyond that: ragged maps are refused rather than padded, undefined legend characters are refused rather than skipped, transparent cells are left untouched so maps can be stamped over existing art, and out-of-bounds writes are dropped with `pixels_clipped` reported. This is rich disclosure of failure modes and 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 well-structured with clear sections for args, returns, coordinates, and centering, but it is long and includes extended rationale about the asymmetry of prior APIs and the nature of hand-placed pixel art. Some of that narrative is justification rather than actionable guidance, so it is not as concise as it could be.
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?
There is no output schema, but the description explains the returned counters (`map_width`, `map_height`, `pixels_transparent`, `colors_used`) and the general write counters, along with clipping behavior, coordinate conventions, and centering differences among related primitives. For a complex 7-parameter write tool with minimal annotations, this is complete enough to invoke correctly, with only the trivial omission of `filename`.
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?
With only 43% schema description coverage, the description carries most parameter meaning: it explains `rows` (one string per row, equal lengths, ragged refused), `legend` (symbol-to-color mapping, `.` and `transparent` semantics, undefined characters refused), `x`/`y` (top-left placement), `layer` (name or 1-based index, default top), and `frame` (1-based, default 1). It does not mention the required `filename` parameter, leaving a small gap.
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 from a character grid, one character per pixel') and explicitly positions itself as the write side of `get_pixels(format="map")`, distinguishing it from dictionary-list pixel writing and from sibling drawing tools. An agent can identify exactly what it does without opening the schema.
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: it round-trips with `get_pixels(format="map")` and is the notation for hand-placed pixel art, contrasted with formula-generated dictionary lists. However, it does not explicitly state when to choose this over `draw_pixels`, `draw_line`, or other drawing primitives, nor does it give exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_pixelsA
Plot individual pixels.
Args:
pixels: List of {"x": int, "y": int, "color": "#hex"?}. If a pixel omits
"color", the shared color argument is used.
color: Default colour for pixels that don't specify their own.
layer: Target layer name or 1-based index (default: top layer).
frame: Target frame, 1-based (default 1).
Coordinates: (0, 0) is the top-left pixel. x grows right, y grows DOWN. A span given as position plus size covers x .. x + width - 1, so width is a count of pixels, not an offset to the far edge.
Centring differs between primitives, so check this when aligning two shapes:
draw_rectangle(x, width) spans x .. x+width-1, centred on x + (width-1)/2. An even width therefore centres on a half pixel.
draw_ellipse(center, radius) spans center-radius .. center+radius, which is always an ODD 2*radius+1 pixels wide and always centred on a whole pixel.
draw_ellipse_in_box(x, y, width, height) takes the same bounding box as draw_rectangle and fills it exactly, so it is the one to use for an even diameter, a disc centred on an even canvas, or a circle that has to line up with a rectangle.
draw_symmetric_pixels mirrors about the canvas, not about either of the above.
Writes falling outside the canvas are dropped rather than raising. Every drawing tool reports pixels_written, and pixels_clipped when anything was dropped, so compare those against what you asked for rather than trusting ok.
| Name | Required | Description | Default |
|---|---|---|---|
| color | No | ||
| frame | No | Default: 1. | |
| layer | No | ||
| pixels | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations (readOnlyHint=false, openWorldHint=false) by disclosing that out-of-canvas writes are silently dropped rather than raising, that pixels_written/pixels_clipped are reported, and advising the agent not to trust `ok`. These are exactly the failure-mode details an agent needs before calling a mutation 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?
Front-loaded with the core purpose and the args block, then the coordinate and centring conventions. The centring bullets lean toward sibling-tool documentation, but each carries useful alignment information and nothing is 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?
No output schema exists, and the description compensates by naming the returned counters (pixels_written, pixels_clipped) and their clipping semantics, plus the coordinate origin and drop-outside-canvas rule. The main gap is that `filename` is never tied to a canvas/sprite concept.
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?
With only 20% schema description coverage, the description carries the load well: it documents the pixel object shape ({x, y, color?}), the fallback `color`, `layer` accepting a name or 1-based index with a default of top layer, and `frame` being 1-based with default 1. Only the required `filename` parameter is left unexplained anywhere.
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: "Plot individual pixels" with a per-pixel list contract. It is clearly a raster-primitive tool, though it never explicitly distinguishes itself from the nearby sibling draw_pixel_map or draw_brush, leaving the agent to infer the difference.
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?
Usage context is implied rather than stated: the centring section tells the agent which primitive to pick for even vs odd diameters, but that is guidance about sibling tools. There is no explicit "use draw_pixels when... / prefer draw_pixel_map when..." routing for this tool itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_polylineA
Draw connected line segments through a list of points.
points: list of {"x": int, "y": int}. Set closed=True to connect the last point back to the first (outline a polygon). pixel_perfect removes L-corner pixels across the whole path for a clean pixel-art outline.
Coordinates: (0, 0) is the top-left pixel. x grows right, y grows DOWN. A span given as position plus size covers x .. x + width - 1, so width is a count of pixels, not an offset to the far edge.
Centring differs between primitives, so check this when aligning two shapes:
draw_rectangle(x, width) spans x .. x+width-1, centred on x + (width-1)/2. An even width therefore centres on a half pixel.
draw_ellipse(center, radius) spans center-radius .. center+radius, which is always an ODD 2*radius+1 pixels wide and always centred on a whole pixel.
draw_ellipse_in_box(x, y, width, height) takes the same bounding box as draw_rectangle and fills it exactly, so it is the one to use for an even diameter, a disc centred on an even canvas, or a circle that has to line up with a rectangle.
draw_symmetric_pixels mirrors about the canvas, not about either of the above.
Writes falling outside the canvas are dropped rather than raising. Every drawing tool reports pixels_written, and pixels_clipped when anything was dropped, so compare those against what you asked for rather than trusting ok.
| Name | Required | Description | Default |
|---|---|---|---|
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| closed | No | Default: false. | |
| points | Yes | ||
| filename | Yes | ||
| pixel_perfect | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false, so the description carries the behavioral burden and does so well: out-of-canvas writes are silently dropped rather than raising, and every drawing tool reports pixels_written/pixels_clipped, with the explicit warning to compare those rather than trusting 'ok'. That is exactly the failure-mode context an agent needs before a write.
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?
Purpose is front-loaded, followed by parameter semantics, then coordinate conventions and clipping behavior; each block earns its place. The multi-bullet centring comparison is tangential to this specific tool and could be relegated elsewhere, which keeps it from a full 5.
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 no output schema, the description steps in to describe the returned pixels_written/pixels_clipped counters and the clipping failure mode, plus the coordinate system and centring conventions. The only remaining gap is the semantics of color, frame and layer, which an agent must infer.
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 only 43%, so the description must compensate, and it does for the non-obvious parameters: points is defined as a list of {x:int, y:int}, closed is explained as connecting last point to first, and pixel_perfect removes L-corner pixels. color, frame, layer and filename remain undocumented in both schema and description, which keeps it short of 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?
The opening sentence names a specific verb and resource — 'Draw connected line segments through a list of points' — which is clearly distinct from siblings like draw_line, draw_curve, draw_rectangle and draw_ellipse. An agent can identify the tool's job without inspecting the schema.
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 hints that closed=True produces a polygon outline, but it never states when to prefer draw_polyline over draw_line or draw_curve. The comparative guidance it does give (draw_ellipse_in_box vs draw_rectangle centring) is about other primitives rather than about selecting this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_rectangleA
Draw a rectangle. filled=False draws a 1px outline, True fills it.
Coordinates: (0, 0) is the top-left pixel. x grows right, y grows DOWN. A span given as position plus size covers x .. x + width - 1, so width is a count of pixels, not an offset to the far edge.
Centring differs between primitives, so check this when aligning two shapes:
draw_rectangle(x, width) spans x .. x+width-1, centred on x + (width-1)/2. An even width therefore centres on a half pixel.
draw_ellipse(center, radius) spans center-radius .. center+radius, which is always an ODD 2*radius+1 pixels wide and always centred on a whole pixel.
draw_ellipse_in_box(x, y, width, height) takes the same bounding box as draw_rectangle and fills it exactly, so it is the one to use for an even diameter, a disc centred on an even canvas, or a circle that has to line up with a rectangle.
draw_symmetric_pixels mirrors about the canvas, not about either of the above.
Writes falling outside the canvas are dropped rather than raising. Every drawing tool reports pixels_written, and pixels_clipped when anything was dropped, so compare those against what you asked for rather than trusting ok.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | ||
| y | Yes | ||
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| width | Yes | ||
| filled | No | Default: false. | |
| height | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give readOnlyHint=false and openWorldHint=false, so the description carries the behavioural load and does so: out-of-canvas writes are dropped rather than raising, and the tool returns pixels_written/pixels_clipped which should be compared against intent rather than trusting 'ok'. That is exactly the kind of trait an agent needs and cannot get from structured fields.
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?
Front-loaded with the core behaviour, then the coordinate/centring detail. Every bullet carries real information an agent needs for alignment, though the centring section is long enough that a shorter phrasing could convey the same rule.
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 mutation tool with no output schema, the description closes the biggest gaps by naming the returned counters (pixels_written, pixels_clipped) and the clipping policy. It is not fully complete because four of nine parameters (filename, color, layer, frame) get no explanation anywhere.
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 only 22%, so the description must compensate, and it does for the geometric core: it defines the origin, growth direction, the x..x+width-1 span rule, and the filled flag. However, filename, color, layer and frame are left entirely undocumented in both schema and prose, so the compensation is substantial but incomplete.
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 rectangle') and immediately pins down the filled flag's meaning. It also explicitly distinguishes itself from near-siblings (draw_ellipse, draw_ellipse_in_box, draw_symmetric_pixels), so an agent can route correctly without opening schemas.
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 explicit when-to-use-which guidance: pick draw_ellipse_in_box for even diameters, a disc centred on an even canvas, or a circle that must line up with a rectangle, and notes draw_symmetric_pixels mirrors about the canvas. It also states the alignment/centring condition that governs the choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_symmetric_pixelsB
Plot pixels together with their mirror image(s).
mode: "horizontal" (mirror across vertical axis_x), "vertical" (across axis_y),
or "both" (4-way radial symmetry). Axes default to the canvas centre.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Default: "horizontal". | horizontal |
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| axis_x | No | ||
| axis_y | No | ||
| pixels | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, so the agent knows this is a local mutation. The description usefully adds the mirroring behavior and axis defaults, but says nothing about whether it overwrites or blends existing pixels, which layer/frame it targets, or any return value.
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 with the core purpose front-loaded and no filler. The mode enumeration is compact, though the parenthetical phrasing ("across vertical axis_x") is slightly terse and could be misread.
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 mutation tool with 8 parameters, 25% schema coverage, and no output schema, the description covers the symmetry concept and axis defaults but omits the pixels payload shape, color format, and frame/layer targeting. An agent can grasp intent but lacks enough detail to call it correctly without inspecting the 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?
Schema description coverage is only 25%, so the description must carry weight; it does explain the mode enum values and that axis_x/axis_y default to the canvas centre. However, the required parameters (filename, pixels, color) and the format of the pixels array (objects with additionalProperties) remain undocumented in both schema and description.
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?
"Plot pixels together with their mirror image(s)" gives a specific verb (plot/draw), resource (pixels), and the distinguishing feature (mirror symmetry) that separates it from the sibling draw_pixels. It does not explicitly name an alternative, but the symmetry concept makes the tool's niche clear without opening the schema.
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 explains the mode values (horizontal/vertical/both) but never states when to choose this tool over draw_pixels or mirror_layer. Usage is only implied by the mode semantics, with no when-to-use or when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draw_textA
Draw text onto a layer at (x, y) in a single colour.
Args:
text: The string (supports "\n" for multiple lines).
x, y: Top-left position of the text.
color: Text colour.
scale: Integer pixel-scaling of the rendered glyphs (default 1).
font_path: Optional path to a .ttf/.otf font. If omitted, a built-in
bitmap font is used (best for tiny pixel text).
font_size: Point size when a TrueType font_path is given.
spacing: Extra pixels between lines.
threshold: 0-255 cutoff; pixels brighter than this are drawn (lower =
heavier text). Keeps glyphs crisp (no anti-aliasing artefacts).
scale is capped at 64, font_size at 512, and the rendered text at 200,000
pixels; the pixel budget is enforced while rasterizing, not afterwards.
Returns the standard draw result plus the rendered text's pixel size.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | ||
| y | Yes | ||
| text | Yes | ||
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| scale | No | Default: 1. | |
| spacing | No | Default: 1. | |
| filename | Yes | ||
| font_path | No | ||
| font_size | No | Default: 16. | |
| threshold | No | Default: 128. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, so the mutating, local nature is already known. The description adds value beyond that: the scale=64, font_size=512, and 200,000-pixel caps, the fact that the pixel budget is enforced during rasterization (not afterwards, implying no silent retro-crop), and the threshold's crisp anti-aliasing 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?
Front-loads the one-line purpose, then an Args block, then caps explanation, then return note. Every sentence carries information, though the return sentence is somewhat redundant given output schema absence is answered anywhere.
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 12-param draw tool with no output schema and partial schema coverage, the description covers the majority of parameters plus hard limits and return shape. Missing only minor details like frame/layer targeting and spacing units beyond lines, but the important behavioral limits are present.
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?
With 42% schema description coverage and 12 parameters, the schema leaves many parameters with only default values. The description explains text (supports \n), x/y as top-left, color, scale limits, font_path fallback behavior, font_size context, spacing meaning, and threshold 0-255 semantics, substantially compensating for the schema gap.
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 (draw) and resource (text) with precise location semantics (top-left x,y). Distinct from sibling raster tools like draw_line or fill_area, and from stamp_file/draw_image_base64, which place images not glyphs.
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?
Implies usage (drawing glyph strings onto a layer) and offers a hint via font_path semantics – omit it for built-in bitmap text, provide a .ttf/.otf for TrueType. However, there is no explicit when-to-use vs when-not-to-use guidance relative to sibling text-ish or image-drawing tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
duplicate_frameA
Duplicate an existing frame (1-based); the copy is inserted after it.
`frame` must already exist: an out-of-range number is rejected with the sprite's
valid range rather than clamped to it.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and destructiveHint=false, so the mutation/safety profile is already covered; the description goes beyond that by disclosing error semantics (rejection with the sprite's valid range instead of silent clamping) and 1-based indexing. It stops short of saying what is returned or whether the change is persisted to `filename`.
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, front-loading the verb+resource and the insertion position, with the precondition detail following. No filler; each clause adds usable information.
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 no output schema, the description should clarify the return value (new frame index?) and whether `filename` identifies the file being mutated on disk. Those gaps plus the undocumented `filename` parameter leave an agent short of a fully confident call, despite solid coverage of the frame argument.
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 0%, so the description carries the full burden and it only partially delivers: `frame` is well specified (1-based, must exist, error behavior on out-of-range), but `filename` — the required target file — is never mentioned or explained. Half the parameter surface is still undocumented.
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 (duplicate an existing frame) and adds the key behavioral detail that the copy lands immediately after the source. It is implicitly distinguishable from siblings like add_frame, remove_frame and move_frame, but never names or contrasts them explicitly.
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 a real precondition — the target frame must already exist and out-of-range values are rejected with the valid range rather than clamped — which tells the agent when this call is legal. However, it offers no routing guidance among alternatives such as add_frame (for a blank frame) or copy_cel/duplicate_layer, leaving the choice of tool to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
duplicate_layerB
Duplicate a layer (including its cels) as a new layer on top.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false and openWorldHint=false, so safety is covered. The description adds real behavioral value by specifying that cels are included and the new layer is placed on top, but says nothing about whether the original is untouched, naming, or what identifies the new layer afterwards.
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?
One short sentence, front-loaded with the verb and the key behavioral caveat (cels included, placed on top). 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 two undocumented required parameters and no output schema, the description should at least clarify how the layer is addressed and what is returned. It omits both, leaving the agent to guess at identification semantics for a tool that creates a new object.
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 0%, so the description carries the full burden and fails it: neither 'filename' (which sprite file?) nor 'layer' (name, index, or id?) is explained. Both are required, so ambiguity in 'layer' is a genuine invocation risk.
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 (duplicate) and resource (layer), plus a meaningful detail: cels are copied and the copy lands on top. This distinguishes it from add_layer (empty layer) and duplicate_frame (frame-level sibling). It does not explicitly name a sibling, so it stops short of 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?
No when-to-use context, no prerequisites, and no routing to alternatives such as add_layer or copy_cel when only part of the layer is wanted. The agent must infer that this is for whole-layer copies from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_framesADestructive
Export each frame to its own image file.
output_pattern must contain "{frame}" (and optionally "{tag}", "{layer}"),
e.g. "frames/walk_{frame}.png". Aseprite substitutes the values.
overwrite: Replace files the pattern would expand onto (default False = no-clobber).
| Name | Required | Description | Default |
|---|---|---|---|
| scale | No | Default: 1. | |
| filename | Yes | ||
| overwrite | No | Default: false. | |
| output_pattern | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false, giving the safety profile. The description adds the important no-clobber default behavior and the overwrite semantics, which is useful beyond annotations. However, it doesn't state where files are written, whether parent directories are created, or the interaction between destructiveness and the no-clobber default.
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 tight, front-loaded sentences. The key constraint (output_pattern must contain {frame}) follows immediately after the purpose statement, and the overwrite clarification is appended 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?
Adequate for a 4-param mutation tool with annotations and no output schema. It covers the pattern DSL and overwrite behavior, but omits output location context, directory creation, and how scale interacts with each export.
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 50%; the description explains output_pattern placeholder syntax ({frame}, {tag}, {layer}) and overwrite semantics, compensating for the schema's bareness on those two. The other two parameters (scale, filename) get no description elaboration beyond what the schema shows.
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 (export) and resource (each frame to its own image file) with explicit granularity. This clearly distinguishes it from export_png (single image), export_spritesheet (packed sheet), and export_gif (animation).
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?
Implied usage is clear from the purpose (per-frame image export), but there's no explicit guidance on when to choose this over export_layer or export_layers, nor any stated prerequisites. No when-not-to-use or alternative routing is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_game_asset_bundleADestructive
Export a sprite into a game-ready bundle directory: a flattened PNG, an animated
GIF, a packed sprite sheet (+ JSON data), a GIF per animation tag, and a
manifest.json describing everything.
Args:
overwrite: Replace existing bundle files (default False = no-clobber). Every
planned output is checked up front, so the bundle fails before writing any
file if a target already exists.
Returns a ``workflow_manifest.v1`` manifest (the same object is also written to
disk as manifest.json inside the bundle).
| Name | Required | Description | Default |
|---|---|---|---|
| scale | No | Default: 1. | |
| filename | Yes | ||
| overwrite | No | Default: false. | |
| bundle_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag this as non-read-only and destructive, and the description adds genuinely useful behavior: no-clobber default, an up-front check of every planned output, and fail-before-writing semantics. It could still say more about permissions or clobber risk per file, but it meaningfully exceeds the annotation baseline.
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?
Front-loaded with the artifact list, then a focused Args block on the one parameter that needs explanation, then a tight Returns sentence. Only minor redundancy in restating that the manifest is both returned and written as manifest.json.
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 no output schema, and the description correctly fills that gap by naming the returned workflow_manifest.v1 and its on-disk counterpart. Mutation semantics and the overwrite flag are covered, though scale/bundle_name remain unaddressed for a 4-parameter 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 description coverage is only 50% (filename and bundle_name have no descriptions; scale/overwrite only carry boilerplate defaults). The description thoroughly explains overwrite's no-clobber behavior, but adds nothing for scale, bundle_name, or filename, so it only partially compensates for the coverage gap.
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 (Export) and resource (sprite into a game-ready bundle directory), then enumerates the exact artifacts produced: flattened PNG, animated GIF, packed sprite sheet + JSON, per-tag GIFs, and manifest.json. This clearly distinguishes it from the single-purpose siblings export_png, export_gif, and export_spritesheet_packed.
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?
Usage is implied by the artifact list (use this instead of calling the individual export tools when you want everything at once), but the description never explicitly says when to choose this over export_png/export_gif/export_spritesheet or what prerequisites exist. The reader must infer the routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_gifADestructive
Export the full animation as an animated GIF (honours frame durations).
Tag *ranges* are honoured, but a tag's playback direction is not: a GIF is a flat
frame sequence. A ping-pong tag exports forward, and the result says so in
`warnings` rather than letting the caller find out in-engine.
overwrite: Replace `output` if it already exists (default False = no-clobber).
| Name | Required | Description | Default |
|---|---|---|---|
| scale | No | Default: 1. | |
| output | Yes | ||
| filename | Yes | ||
| overwrite | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real context beyond the annotations: GIFs are flat frame sequences, ping-pong tags silently export forward and the loss is surfaced in `warnings`, and overwrite defaults to no-clobber. The no-clobber/overwrite disclosure is valuable for a destructiveHint=true tool, though permission requirements and error behavior remain unstated.
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?
Front-loaded with the core action, then the important tag-direction caveat, then the overwrite note. Each block earns its place, though the phrasing is slightly loose.
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?
No output schema exists, and the description usefully names the `warnings` channel where downgraded playback direction is reported. With a destructive write and 4 params, it covers the main behavioral traps, though the required path params and scale remain unexplained.
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 50%, with `output` and `filename` carrying no descriptions. The description explains `overwrite` semantics well (replace if exists, default False), but adds nothing for `scale` or the two required path parameters, so it only partially compensates for the coverage gap.
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 (Export) and resource (the full animation as an animated GIF), and the phrase 'full animation' implicitly distinguishes it from the tag-scoped sibling export_tag_gif. It stops short of explicitly naming that alternative, so the distinction requires inference.
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?
Usage is implied rather than stated: 'Export the full animation' suggests this is the whole-sprite exporter versus export_tag_gif, but no explicit when-to-use or when-not guidance is given. The tag-range caveat is behavioral rather than a selection cue.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_godot_spriteframesADestructive
Export a sprite as a Godot 4 SpriteFrames resource (.tres) + a packed sheet.
Produces three files: a packed PNG sprite sheet, its JSON frame/tag metadata, and a
``SpriteFrames`` .tres that references the sheet via ``AtlasTexture`` regions, one
Godot animation per Aseprite tag (or a single ``default`` animation if untagged), with
per-frame timing taken from Aseprite frame durations.
v1 emits ``SpriteFrames`` only (no pivot/origin/hitbox/9-slice). Aseprite tag direction
isn't represented (Godot animations only loop or not); ``default_loop`` is applied to all.
Args:
output: Destination .tres path (workspace-relative).
sheet_output: Sheet PNG path. Defaults to ``<output stem>.png`` beside the .tres.
scale: Integer upscaling factor for the sheet.
texture_res_path: The ``res://`` path of the sheet inside your Godot project (the
AtlasTexture atlas). Defaults to ``res://<sheet filename>`` (same-folder import).
default_loop: ``loop`` flag for every generated animation (default True).
overwrite: Replace existing outputs (default False = no-clobber). All three targets
are validated up front, so nothing is written if any already exists.
Returns a ``workflow_manifest.v1`` manifest (kind ``engine_preset``).
| Name | Required | Description | Default |
|---|---|---|---|
| scale | No | Default: 1. | |
| output | Yes | ||
| filename | Yes | ||
| overwrite | No | Default: false. | |
| default_loop | No | Default: true. | |
| sheet_output | No | ||
| texture_res_path | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true, but the description adds substantial context beyond them: no-clobber default, up-front validation of all three targets ('nothing is written if any already exists'), and v1 limitations (no pivot/origin/hitbox/9-slice, tag direction not represented, default_loop applied to all). This materially mitigates and elaborates the destructive profile.
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?
Purpose and outputs are front-loaded, followed by an Args block and a concise return line; every sentence carries information. It is somewhat long, but no sentence is filler given the mutation and v1 caveats it must convey.
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 mutation tool with no output schema, it discloses the return type (workflow_manifest.v1, kind engine_preset), side effects, no-clobber semantics, and scope limitations. The only meaningful omission is the required filename parameter, which is undocumented in both description and 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?
Schema coverage is only 43% (most params carry just a 'Default:' string), so the description compensates well: it explains output, sheet_output's derivation from output stem, scale's meaning as upscaling factor, texture_res_path's res:// role and default, plus default_loop and overwrite semantics. The required 'filename' param remains unexplained, so it falls short of full compensation.
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 ('Export a sprite as a Godot 4 SpriteFrames resource (.tres) + packed sheet') and enumerates the three concrete artifacts produced. This distinguishes it from siblings like export_spritesheet, export_gif, and export_game_asset_bundle without opening any schema.
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?
Usage is implied by the Godot-4 engine target and the v1 scope note, but the description never names an alternative export tool or states when to prefer this over export_spritesheet/export_game_asset_bundle. No explicit when/when-not routing is provided, leaving selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_layerBDestructive
Export a single layer of one frame as a PNG (others excluded).
overwrite: Replace `output` if it already exists (default False = no-clobber).
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | Yes | ||
| scale | No | Default: 1. | |
| output | Yes | ||
| filename | Yes | ||
| overwrite | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, and the description adds useful non-clobber context: overwrite defaults to False so an existing `output` is preserved unless opted in. It does not, however, clarify whether the export writes files to disk, what happens on path conflicts beyond the overwrite flag, or any auth constraints.
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 lines, front-loaded with the purpose and followed by the one non-obvious parameter's behavior. No filler or repetition of the title.
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 destructive, six-parameter write tool with no output schema, the definition covers the core action and the overwrite semantics but is thin on the remaining parameters and on side effects. Adequate but with clear 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?
Schema description coverage is 50% and six parameters exist, so the schema does only part of the work. The description adds real meaning for `overwrite` (no-clobber default), but says nothing about `filename` vs `output`, `scale`, or `frame`, leaving half the parameters ambiguous.
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 (export), resource (single layer of one frame), format (PNG), and scope (others excluded), which meaningfully distinguishes it from export_png and export_layers. It stops short of naming those siblings explicitly, so an agent must infer the routing.
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 parenthetical 'others excluded' implies this is the narrow per-layer variant, but the description never says when to prefer it over export_png, export_layers, export_frames, or export_spritesheet. No prerequisites or alternatives are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_layersADestructive
Export each layer to its own image file.
output_pattern must contain "{layer}" (e.g. "layers/{layer}.png"); add
"{frame}" too for animations. include_hidden also exports hidden layers.
overwrite: Replace files the pattern would expand onto (default False =
no-clobber). Aseprite expands the placeholders, so the check refuses when any
file matching the pattern already exists.
| Name | Required | Description | Default |
|---|---|---|---|
| scale | No | Default: 1. | |
| filename | Yes | ||
| overwrite | No | Default: false. | |
| include_hidden | No | Default: false. | |
| output_pattern | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true, and the description goes further by explaining exactly what the destruction means: the default is no-clobber, and the check refuses when any file matching the expanded pattern already exists. It stops short of describing the return payload, partial-write behavior, or whether directories are auto-created.
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 core action is front-loaded and each subsequent sentence maps to a distinct parameter concern with no filler. The final sentence on Aseprite's placeholder expansion is dense but earns its place by explaining why the existence check works the way it does.
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 five-parameter, destructive, no-output-schema tool, the description covers the highest-risk parts: output path templating, hidden-layer inclusion, and clobber protection. It omits only secondary concerns like scale behavior and what the call returns, which are minor against the covered risk surface.
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 60% and the description meaningfully lifts three of the bare parameters: it documents output_pattern placeholder syntax and the '{frame}' variant, explains include_hidden's effect, and details overwrite's no-clobber semantics. 'scale' and 'filename' remain undocumented in both places, which is the remaining gap.
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 first sentence gives a specific verb and scope: 'Export each layer to its own image file,' which distinguishes it from bulk exporters like export_png and from the singular export_layer. It never names those siblings as alternatives, so the differentiation is implied rather than stated.
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?
Usage conditions are implied through the required '{layer}' placeholder and the note about adding '{frame}' for animations, which tells the agent when the tool applies. There is no explicit when-not guidance or pointer to export_layer for single-layer output, leaving sibling routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_minecraft_textureADestructive
Export a sprite into a resource pack at its correct texture path.
A single-frame sprite exports as a plain PNG. A multi-frame sprite exports as a
**vertical strip** (frame 1 on top, no padding) and gets a ``.png.mcmeta`` sidecar -
that pairing is what the game reads as an animation, and either half alone is broken.
Args:
pack_root: The resource-pack directory (its ``assets/`` tree is written under this).
namespace: Your mod/pack id. Defaults to "minecraft", which overrides vanilla.
category: Texture subdirectory - block, item, entity, gui, particle, ...
texture_name: In-pack texture name, ``/`` allowed for subdirectories. Defaults to
the sprite's filename stem.
frametime: Ticks per frame for the animation sidecar (1 tick = 50 ms).
interpolate: Blend between animation frames.
frame_order: Optional playback order (see ``write_texture_mcmeta``).
overwrite: Replace existing files (default False = no-clobber).
Returns a ``workflow_manifest.v1`` manifest (kind ``minecraft_texture``).
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | Default: "block". | block |
| filename | Yes | ||
| frametime | No | Default: 1. | |
| namespace | No | Default: "minecraft". | minecraft |
| overwrite | No | Default: false. | |
| pack_root | Yes | ||
| frame_order | No | ||
| interpolate | No | Default: false. | |
| texture_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, and the description adds concrete value beyond them: the no-clobber default for overwrite, the requirement that the .png.mcmeta sidecar and the vertical-strip PNG must be written together, and the fact that assets/ is written under pack_root. It does not discuss permissions or rate limits, but for a local file-writing tool that is minor.
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 critical behavioral distinction (PNG vs vertical strip + mcmeta) is front-loaded before the Args block, and the Args block is compact. It runs slightly long, but nearly every line carries information an agent needs to call the tool correctly.
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 9-parameter mutation tool with no output schema, the description covers behavior, parameter meaning, side effects, and the return value ('workflow_manifest.v1' manifest, kind 'minecraft_texture'). Nothing essential to a correct invocation 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 only 56% (mostly bare defaults), yet the description documents essentially every parameter meaningfully: pack_root's assets/ tree, namespace's vanilla-override semantics, category values, texture_name's '/'-based subdirectories, frametime in ticks (1 tick = 50 ms), interpolate blending, and overwrite's no-clobber default. This is strong compensation for the schema gap.
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 ('Export a sprite into a resource pack at its correct texture path') and immediately distinguishes this tool from the many sibling export_* tools by specifying the Minecraft resource-pack target. The single-frame vs multi-frame behavior further pins down what it produces.
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 clearly states the condition that changes behavior (single-frame vs multi-frame) and routes frame_order to the sibling write_texture_mcmeta. It does not, however, explicitly say when to prefer this over export_png or validate_minecraft_texture, so routing is implied rather than fully spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_onion_skinADestructive
Export a frame with neighbouring frames ghosted behind it (onion skin).
Args:
frame: The in-focus frame (drawn fully opaque), 1-based.
previous, next: How many earlier/later frames to ghost.
ghost_opacity: Max opacity (0-255) of the nearest ghost; further frames fade.
scale: Integer upscaling factor for the output PNG.
overwrite: Replace `output` if it already exists (default False = no-clobber).
| Name | Required | Description | Default |
|---|---|---|---|
| next | No | Default: 0. | |
| frame | Yes | ||
| scale | No | Default: 4. | |
| output | Yes | ||
| filename | Yes | ||
| previous | No | Default: 2. | |
| overwrite | No | Default: false. | |
| ghost_opacity | No | Default: 80. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag the tool as a non-read-only, destructive write (destructiveHint=true), so the no-clobber behaviour needs credit only for the added detail: 'overwrite: Replace output if it already exists (default False = no-clobber)'. That is a genuinely useful behavioural fact beyond the annotation. However, other behaviours an agent needs—output format/bit depth beyond PNG, failure behaviour when the frame is out of range, and whether neighbouring frames are silently clipped at sequence bounds—are absent.
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 front-loaded one-sentence summary is strong and the per-argument list is tight; each line earns its place. The Google-style 'Args:' block formatting is slightly awkward embedded in a description field but does not waste 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?
For an 8-parameter destructive export with no output schema, the description covers the fusion/ghost semantics and the clobber flag but leaves filename/output semantics and error/boundary behaviour unspecified. Adequate, not 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?
At 63% schema coverage, several params carry only a 'Default: N' stub. The description compensates well for the semantically important ones: frame is 'the in-focus frame (drawn fully opaque), 1-based', previous/next are 'how many earlier/later frames to ghost', ghost_opacity is 'max opacity (0-255) of the nearest ghost; further frames fade', and scale is 'integer upscaling factor'. The 1-based indexing and fade semantics are real added meaning. Only filename and output remain unexplained.
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 (export) and resource (a frame with ghosted neighbouring frames), and the parenthetical '(onion skin)' names the exact technique. Among a large set of export_* siblings, this is clearly distinguishable as the onion-skin renderer.
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 usage by defining what onion skinning is, but never states when to choose this over the neighbouring export_frames, export_layer, or render_preview siblings, nor any prerequisite. Usage is inferred from the technique name rather than guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_pngADestructive
Export one frame as a flattened PNG.
Args:
output: Destination .png path.
frame: Frame to export, 1-based (default 1).
scale: Integer upscaling factor (default 1).
overwrite: Replace `output` if it already exists (default False = no-clobber).
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| scale | No | Default: 1. | |
| output | Yes | ||
| filename | Yes | ||
| overwrite | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false, and the description adds concrete behavioral context that annotations don't: overwrite defaults to no-clobber ('Replace output if it already exists') and output is flattened. This clarifies exactly what the destructive flag governs. It doesn't cover error behavior or rate limits, but the no-clobber disclosure is genuinely useful.
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?
Front-loaded purpose sentence followed by a tight args list, with zero filler. Each line earns its place. The structure is standard and readable, though the args block could be folded more compactly.
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 export tool with no output schema, the destination-path and overwrite semantics are covered, but the required 'filename' parameter is undocumented in both schema and description, leaving a real gap for correct invocation. Return/error behavior is also unaddressed.
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 60% (frame/scale/overwrite only carry 'Default: X'), and the description meaningfully extends this: frame is 1-based, scale is an integer upscaling factor, and overwrite's no-clobber default is spelled out. The required 'filename' parameter is never explained in either the schema or the description, which caps the score below 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?
States a specific verb and resource: 'Export one frame as a flattened PNG.' The phrase 'one frame' implicitly distinguishes it from siblings like export_frames and export_spritesheet, so an agent can route reasonably. It stops short of explicitly naming those alternatives, but the purpose is 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?
There is no explicit when-to-use or when-not-to-use guidance relative to the many export siblings (export_gif, export_frames, export_layer, export_spritesheet). The 'one frame' scoping implies a single-frame use case but leaves the agent to infer it against alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_slice_metadataADestructive
Export every slice as engine-agnostic JSON (aseprite_mcp.slice_metadata.v1).
Each slice becomes ``{name, type, id, bounds, pivot, nine_slice, color, data,
raw_data}``. **Type detection:** a slice's user-data JSON ``type`` wins; otherwise the
name convention ``<type>:<id>`` (recognized types: hitbox, hurtbox, collision, interact,
pivot, origin, attach, spawn, nine_slice; anything else becomes ``"custom"``, never an
error). ``id`` comes from the data ``id`` or the name's ``:<id>`` suffix. ``nine_slice``
(Aseprite's 9-patch center) and ``pivot`` are emitted whenever the slice has them. Slice
user-data that is valid JSON is parsed into ``data``; the raw string is kept in ``raw_data``.
Args:
output: Destination .json path. Defaults to ``<sprite>_slices.json`` beside the sprite.
overwrite: Replace an existing file (default False = no-clobber).
Returns a ``workflow_manifest.v1`` manifest (kind ``engine_metadata``).
| Name | Required | Description | Default |
|---|---|---|---|
| output | No | ||
| filename | Yes | ||
| overwrite | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations mark it destructive/not-read-only, and the description earns its keep by disclosing the no-clobber default, the overwrite flag semantics, and the default output path — concrete write-behavior context beyond the annotations. It stops short of stating permissions or failure modes, so not a 5.
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?
Front-loads purpose and output format, then type-detection rules, args, and return. It is dense but every section (type precedence, id derivation, raw_data retention) carries information an agent would otherwise have to guess.
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?
No output schema exists, yet the description describes the returned workflow_manifest.v1 manifest (kind engine_metadata) and the emitted slice object shape, so the agent knows both what is written and what comes back. Minor gaps around permissions/failures 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 coverage is only 33%, but the description documents both output (destination .json path with default) and overwrite (replace existing, default False), adding real meaning. The required filename param is left unexplained, keeping it from 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?
States a specific verb+resource ('Export every slice as engine-agnostic JSON') and names the exact format schema (aseprite_mcp.slice_metadata.v1), which cleanly separates it from siblings like list_slices or export_spritesheet.
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?
Usage is implied by the described output format (engine-agnostic JSON for downstream consumption) but there is no explicit 'use this when / not when' or named alternative. The agent must infer when this beats list_slices or export_game_asset_bundle.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_spritesheetADestructive
Export frames into a single sprite-sheet image.
Args:
output: Destination sheet image (.png).
sheet_type: one of horizontal, vertical, rows, columns, packed.
scale: Integer upscaling factor.
data_output: Optional .json path to also write frame/tag/slice metadata
(JSON-array format) describing each frame's rectangle in the sheet.
padding: Pixels of padding around/between frames.
layer: Only include this layer.
ignore_layer: Exclude this layer (e.g. a "reference" layer).
split_layers: Lay out each layer as separate cels in the sheet.
split_tags: Treat each tag as a separate set in the sheet.
overwrite: Replace existing output(s) (default False = no-clobber). When
data_output is given, both files are checked before anything is written.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | No | ||
| scale | No | Default: 1. | |
| output | Yes | ||
| padding | No | Default: 0. | |
| filename | Yes | ||
| overwrite | No | Default: false. | |
| sheet_type | No | Default: "packed". | packed |
| split_tags | No | Default: false. | |
| data_output | No | ||
| ignore_layer | No | ||
| split_layers | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, so the description carries less burden. It still adds real value beyond them: the no-clobber default (overwrite=False), and the guarantee that when data_output is given 'both files are checked before anything is written,' which is meaningful write-safety context not expressible 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?
Front-loads the purpose in one sentence, then organizes per-argument notes in a consistent docstring style. Essentially every line carries information; only a little verbosity in the overwrite/split entries, but nothing 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 an 11-parameter, destructive export tool with no output schema, the description covers nearly all parameters plus the write-safety semantics. It could still note the return value (paths written) or interaction with split_layers/split_tags and data_output, but it is close to 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 coverage is only 55%, but the description compensates: it enumerates the valid sheet_type values (horizontal, vertical, rows, columns, packed) that the schema lacks as an enum, explains the data_output JSON-array format, and gives an example for ignore_layer. Only filename goes undocumented, a minor gap.
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: 'Export frames into a single sprite-sheet image.' That is clear and unambiguous. However, it never distinguishes this tool from close siblings like export_spritesheet_packed, export_frames, or export_png, so an agent cannot route between them on the description alone.
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 is purely mechanical (what each arg does); it gives no when-to-use context, no prerequisites, and no mention of alternatives despite several overlapping export siblings. An agent gets no help deciding when this tool is the right choice versus export_spritesheet_packed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_spritesheet_packedADestructive
Export a sprite sheet with the controls a game engine needs: extrude, dedupe, trim.
The sibling of `export_spritesheet`, which goes through the Aseprite CLI. This one
drives the editor's own export command, which the CLI flags do not fully reach, and
adds three things that matter when the sheet is going into an engine rather than into
a preview:
Args:
output: Destination sheet image (.png).
sheet_type: one of horizontal, vertical, rows, columns, packed (the default).
trim: Trim each frame to its drawn pixels before packing, so empty margins cost
no sheet space. The frame rectangles in the data file say where each frame
went and how much was trimmed, so an engine can still place it correctly.
extrude: Duplicate each frame's edge pixels one pixel outwards around its cell.
This is the fix for the thin seam or transparent line that appears between
tiles in Unity, Godot or a shader at non-integer zoom: the sampler reads
half a texel past the frame's edge, and without extrude that is whatever the
neighbouring frame or empty space holds. The frame rectangle in the data file
still names the frame itself, not the border.
merge_duplicates: Give identical frames one rectangle in the sheet instead of a
copy each, which is what shrinks a sheet full of held poses. Identical by
pixels, so it catches both a duplicated frame and a linked cel. A packed
sheet does this anyway and the result says so.
padding: Pixels of padding around and between frames, as `export_spritesheet`.
Padding separates frames; extrude fills the gap at the frame's own edge.
They solve different halves of the same bleeding problem and compose.
data_output: Optional .json path for the sheet metadata, which also carries the
layer, tag and slice lists.
data_format: "json-array" (the default when `data_output` is given) or
"json-hash". The array form lists frames in order, which an engine indexing
by frame number wants; the hash form keys them by name, which a loader
looking frames up by name wants. The tag section is called `frameTags` in
both.
overwrite: Replace existing output(s) (default False = no-clobber). When
`data_output` is given, both files are checked before anything is written.
The source sprite is not modified: verified, the file's bytes and frame count are the
same afterwards, including with trim and extrude set.
| Name | Required | Description | Default |
|---|---|---|---|
| trim | No | Default: false. | |
| output | Yes | ||
| extrude | No | Default: false. | |
| padding | No | Default: 0. | |
| filename | Yes | ||
| overwrite | No | Default: false. | |
| sheet_type | No | Default: "packed". | packed |
| data_format | No | ||
| data_output | No | ||
| merge_duplicates | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false, but the description directly addresses this: 'The source sprite is not modified: verified, the file's bytes and frame count are the same afterwards, including with trim and extrude set.' This casts the mutation as output-file-only, which is valuable context beyond annotations. It also explains overwrite's no-clobber default and that both files are checked before writing. Slight tension with destructiveHint is resolved rather than contradicted.
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?
Front-loaded with purpose and the sibling distinction in the first paragraph, which is good. But the argument section is very long and partly prose-essay (Unity sampler half-texel explanation), which is thorough yet heavy for a tool description. Earns its place mostly, but less economical than ideal.
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 a 10-parameter export tool with no output schema: what each control does, the default sheet_type, data_format behavior, no-clobber semantics, and even a non-modification guarantee. Return values aren't described, but metadata is captured via data_output. Nearly complete for the 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 60%, so the description must carry the rest and largely does. It explains the meaning and purpose of trim, extrude, merge_duplicates, padding, data_output, data_format (including the json-array vs json-hash choice and frameTags), and overwrite. It even clarifies how padding and extrude compose. Only sheet_type enum values are fully enumerated.
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 ('Export a sprite sheet') and immediately names its scope ('with the controls a game engine needs'). It explicitly distinguishes itself from the sibling export_spritesheet: 'The sibling of export_spritesheet, which goes through the Aseprite CLI. This one drives the editor's own export command, which the CLI flags do not fully reach.'
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?
Names the alternative (export_spritesheet) and the condition selecting this tool: it drives the editor's own export and reaches flags the CLI doesn't. Also frames the whole tool as for 'sheet going into an engine rather than into a preview,' an explicit use case boundary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_tag_gifBDestructive
Export only the frames of a named animation tag as an animated GIF.
overwrite: Replace `output` if it already exists (default False = no-clobber).
| Name | Required | Description | Default |
|---|---|---|---|
| tag | Yes | ||
| scale | No | Default: 1. | |
| output | Yes | ||
| filename | Yes | ||
| overwrite | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and readOnlyHint=false; the description usefully explains the no-clobber default and that overwrite replaces `output`, which accounts for the destructive trait. However, it omits what gets written on disk (paths, frame-duration handling) and any error behavior when a tag is missing, so it adds only moderate context 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight stanzas, front-loaded with the core action before the overwrite note. No filler sentences, though the overwrite line is formatted as a stray note rather than integrated prose.
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 no output schema and a write operation, the description is adequate but thin: it never explains how scale affects output, where the file lands, or how multiple tagged frames become a GIF. It covers the essentials for a straightforward export but leaves meaningful 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?
Schema coverage is only 40% (just terse 'Default:' notes on scale and overwrite). The description meaningfully explains `overwrite` and references `output` and `tag`, but leaves `filename` and `scale` entirely undefined, so it only partly compensates for the coverage gap.
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 (Export), resource (animation tag frames), and format (animated GIF), with the scope qualifier 'only the frames of a named animation tag' that separates it from generic export_gif/export_frames siblings. It never names a sibling explicitly, but the scoping does the disambiguation 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?
There is no when-to-use vs when-not guidance. Given the dense sibling cluster (export_gif, export_frames, export_tags, export_spritesheet), the description should say when tag-scoped GIF export is preferred over the alternatives, but it leaves that entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_tagsADestructive
Export each animation tag's frames to their own files.
output_pattern must contain "{tag}" (and usually "{frame}"),
e.g. "anim/{tag}_{frame}.png".
overwrite: Replace files the pattern would expand onto (default False = no-clobber).
| Name | Required | Description | Default |
|---|---|---|---|
| scale | No | Default: 1. | |
| filename | Yes | ||
| overwrite | No | Default: false. | |
| output_pattern | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false; the description usefully clarifies the actual behavior that drives that flag - overwrite replaces existing files and defaults to no-clobber. This adds real value beyond the annotation by explaining the clobber semantics rather than just flagging destructiveness.
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?
Front-loaded purpose sentence followed by two short, high-value constraint bullets (pattern tokens, overwrite semantics). No filler, though the formatting as loose lines is slightly ragged.
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 4-parameter mutation tool with no output schema and only 50% parameter coverage, the description covers the two most important parameters but omits scale and filename entirely and never states the return value or whether the operation can be partially applied.
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 50%, with filename and output_pattern undescribed in the schema. The description compensates well for output_pattern by documenting the required "{tag}"/"{frame}" placeholders and for overwrite by giving its default behavior, but filename and scale remain unexplained in both places.
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 (export) and resource (each animation tag's frames) with clear scope: one file per frame per tag. It does not, however, distinguish itself from close siblings like export_frames, export_png, or export_tag_gif, which an agent must resolve on its own.
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 usage by specifying that output_pattern must contain "{tag}" and usually "{frame}", which is actionable but framed as a constraint rather than a when-to-use rule. There is no guidance on when to pick this over export_frames or export_tag_gif, and no prerequisites named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_paletteA
Extract the unique colours used in a sprite (or another image).
Args:
from_image: Optional image/sprite to scan instead of `filename`.
set_as_palette: Apply the extracted colours as `filename`'s palette.
include_alpha: Treat differing alpha as distinct colours (default off).
max_colors: Error out if more unique colours than this are found.
Returns the list of "#RRGGBBAA" colours found.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| from_image | No | ||
| max_colors | No | Default: 256. | |
| include_alpha | No | Default: false. | |
| set_as_palette | No | Default: true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, and the description corroborates this by explaining that set_as_palette (default true) writes the extracted colours into filename's palette — so the mutating behavior is disclosed rather than hidden. It also documents the error path for max_colors, though it says nothing about permissions or how a failure leaves the palette.
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?
One framing sentence, a tight per-argument list, and a return-type line. It is front-loaded and every line earns its place, with only minor redundancy between the arg list and the schema defaults.
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 5-parameter tool with no output schema, the description covers the optional arguments, the mutation semantics, the error condition, and the return format ('#RRGGBBAA' list). Its one substantive gap is routing guidance against the cluster of palette siblings.
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 only 60% and the schema descriptions are boilerplate ('Default: 256.'), so the description does real work: it explains from_image as an override for filename, include_alpha as treating differing alpha as distinct colours, and max_colors as an error threshold. Only filename itself is left without explanation.
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: 'Extract the unique colours used in a sprite (or another image)'. That is clear enough to identify the operation, but it never distinguishes itself from nearby siblings like get_palette, quantize_palette, or list_palette_usage, which an agent must sort out on its own.
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?
Usage is only implied: the from_image and set_as_palette arguments hint at the two modes (scan an external image vs. re-palette the target file), but there is no explicit when-to-use or when-not statement. No alternative tool is named despite get_palette/set_palette/quantize_palette sitting right beside it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fill_areaA
Flood fill (paint bucket): replace the contiguous region of matching
colour starting at (x,y) on the target layer with color.
Coordinates: (0, 0) is the top-left pixel. x grows right, y grows DOWN. A span given as position plus size covers x .. x + width - 1, so width is a count of pixels, not an offset to the far edge.
Centring differs between primitives, so check this when aligning two shapes:
draw_rectangle(x, width) spans x .. x+width-1, centred on x + (width-1)/2. An even width therefore centres on a half pixel.
draw_ellipse(center, radius) spans center-radius .. center+radius, which is always an ODD 2*radius+1 pixels wide and always centred on a whole pixel.
draw_ellipse_in_box(x, y, width, height) takes the same bounding box as draw_rectangle and fills it exactly, so it is the one to use for an even diameter, a disc centred on an even canvas, or a circle that has to line up with a rectangle.
draw_symmetric_pixels mirrors about the canvas, not about either of the above.
Writes falling outside the canvas are dropped rather than raising. Every drawing tool reports pixels_written, and pixels_clipped when anything was dropped, so compare those against what you asked for rather than trusting ok.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | ||
| y | Yes | ||
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the bare annotations (readOnlyHint false, openWorldHint false), it discloses that out-of-canvas writes are silently dropped and that results expose pixels_written/pixels_clipped, advising the agent to verify counts rather than trust 'ok'. That is meaningful behavioral context for a mutation tool with no output 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 opening sentence is precise and front-loaded, but roughly two-thirds of the text is a digression into centring rules for draw_rectangle, draw_ellipse, draw_ellipse_in_box and draw_symmetric_pixels, which are largely irrelevant to a flood-fill start point and dilute the core instruction.
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 mutation tool with minimal annotations and no output schema, the description covers clipping behaviour and return fields well, but it omits the meaning of `frame`/`filename`, any failure modes beyond canvas clipping, and guidance on layer targeting versus the whole-canvas default.
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 only 17%, so the description must compensate, and it partially does: it defines the coordinate origin/direction for x and y and ties colour and 'target layer' to their roles. It says nothing about `frame` or `filename`, leaving two of six parameters undocumented in both places.
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 mechanism: 'Flood fill (paint bucket): replace the contiguous region of matching colour starting at (x,y) on the target layer with color.' It names the exact semantics (contiguous, colour-matching, start point, target layer), which cleanly separates it from whole-layer operations like fill_layer and from the draw_* primitives.
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 flood-fill semantics imply when it applies, but the description never states when to choose it over siblings such as fill_layer, select_by_color, or draw_brush. The centring guidance mentions conditions for aligning shapes but does not route the agent between competing tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fill_checkerboardC
Fill a region with a 2-colour checkerboard of size-pixel squares.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | Default: 0. | |
| y | No | Default: 0. | |
| size | No | Default: 1. | |
| frame | No | Default: 1. | |
| layer | No | ||
| width | No | ||
| color1 | Yes | ||
| color2 | Yes | ||
| height | No | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, so the agent knows this mutates a closed-world resource. The description adds no further behavioral context: it does not say whether existing pixels are overwritten, how the region is bounded, whether a selection or layer is required, or what side effects occur.
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 front-loaded sentence with no filler. It is efficient, though notably sparse for a 10-parameter 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?
With 10 parameters, no output schema, and only minimal annotations, the description is too thin. It omits how the region is defined, which parameters are required, what layer or file is affected, and what happens to existing content.
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 40%, with only default-value notes for x, y, size, and frame. The description only clarifies that `size` is in pixels; it does not explain the coordinate/region parameters, width, height, layer, filename, or color1/color2, so it does not compensate for the low 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?
States a specific verb ('Fill') and resource ('region') plus the distinguishing checkerboard pattern and square size. It does not explicitly differentiate itself from siblings like fill_area, fill_layer, or stamp_pattern, so it falls 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?
Provides no guidance about when to use this tool instead of related fill or pattern tools such as fill_area, fill_layer, or stamp_pattern. It only describes the operation, leaving the agent to infer usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fill_gradientA
Fill a region with a gradient, by default only where pixels already exist.
Args:
colors: 2+ colour stops, e.g. ["#000000", "#ff004d", "#ffec27"], spread
evenly. For dither=True, provide exactly 2 colours.
gradient_type: "linear" or "radial".
angle: Direction in degrees for linear gradients (0 = left->right).
dither: Ordered (Bayer 4x4) dithering between 2 colours instead of smooth
interpolation, great for limited palettes / retro looks.
x, y, width, height: Region (defaults to the whole canvas).
respect_alpha: Leave transparent pixels transparent (default). The gradient
then shades the artwork inside the region rather than filling the region.
Pass False to paint the whole rectangle, background included.
Returns `pixels_written` and `pixels_skipped` so the caller can tell how much of
the region was actually covered.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | Default: 0. | |
| y | No | Default: 0. | |
| angle | No | Default: 0.0. | |
| frame | No | Default: 1. | |
| layer | No | ||
| width | No | ||
| colors | Yes | ||
| dither | No | Default: false. | |
| height | No | ||
| filename | Yes | ||
| gradient_type | No | Default: "linear". | linear |
| respect_alpha | No | Default: true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false; the description goes further by explaining that respect_alpha=True shades existing artwork while False paints the whole rectangle including background, and that the call reports pixels_written/pixels_skipped. It does not mention permissions or layer targeting limits across the 12 params.
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?
Front-loaded one-line summary followed by a tight Args list where each entry adds distinct information; the closing sentence about return values is one line. Slightly long but essentially 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 12-parameter mutation tool with no output schema and thin annotations, the description supplies the missing alpha/dither semantics and even explains the return payload, which compensates for the absent output schema. Only the frame/layer parameters are left unaddressed.
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 only 58% and most schema descriptions are bare 'Default: X', so the description carries real weight: it gives the colors array format with an example, the dither=exactly-2-colours constraint, angle's 0=left->right convention, and the region defaults. It leaves filename, frame, and layer undocumented.
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 ('Fill a region with a gradient') and immediately narrows scope with 'by default only where pixels already exist.' An agent can distinguish this from solid fill_area or palette-gradient gradient_map by the region+gradient framing, though no sibling is named explicitly.
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?
Offers contextual guidance for options ('dither ... great for limited palettes / retro looks') and explains the default alpha behavior, but never states when to prefer this tool over the many neighboring fill/gradient tools (fill_area, gradient_map, dither_band). Usage is implied rather than routed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fill_layerBDestructive
Fill the entire target layer/frame cel with a solid colour.
| Name | Required | Description | Default |
|---|---|---|---|
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=true, so the safety profile is covered. The description contributes the fact that the WHOLE layer/cel is overwritten with a single colour, which corroborates destructiveness, but says nothing about whether the file is saved, whether existing pixels are irrecoverably lost, or what is returned. Adequate but thin given the mutation/destructive 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?
A single sentence with no filler, front-loading the verb and scope. Nothing to trim.
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 destructive mutation with no output schema, 4 parameters at 25% description coverage, and many sibling fill/clear tools, the description is too spare. It omits save semantics, colour format, error cases, and any disambiguation from adjacent fill/clear operations.
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 only 25% and the description adds little: it signals that layer, frame, and color are involved but gives no colour format (hex? named? alpha?), no explanation of which cel on the layer/frame is targeted, and says nothing about the required filename parameter. Low coverage means the description should compensate more than it does.
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 pairs a specific verb ("Fill") with a clear resource ("the entire target layer/frame cel") and the fill material ("solid colour"). It is distinguishable from fill_area (region) and fill_gradient/checkerboard, though it never names those siblings explicitly.
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?
There is no guidance on when to choose this over fill_area, clear_layer, or fill_tile, nor any prerequisite (e.g., layer must exist, file must be loaded). Usage must be inferred from the word "entire".
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fill_tileB
Fill an existing tile's artwork with a solid colour.
Returns `pixels` (the tile's area, all of which is written) so the result says the fill
reached the tile rather than only that the call returned.
| Name | Required | Description | Default |
|---|---|---|---|
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | Yes | ||
| filename | Yes | ||
| tile_index | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is not a read-only operation and is not open-world. The description adds meaningful context by stating that all of the tile's area is written and that the return value reports the filled pixels rather than merely call success.
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 short and front-loads the purpose in the first sentence. The second sentence explains the return value and is useful, though slightly more verbose than strictly necessary.
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?
No output schema exists, and the description does provide some return-value context. However, for a five-parameter mutation tool with only 20% schema description coverage, it leaves most parameter semantics unexplained and is not complete enough for reliable 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 only 20%, with just the frame parameter documented. The description implies color is a solid colour and that tile_index identifies the existing tile, but it does not explain filename, layer, tile_index, or frame 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 states a specific verb and resource: 'Fill an existing tile's artwork with a solid colour.' This distinguishes it from layer-level or tilemap-level fills, though it does not explicitly name the sibling tools it differs from.
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 no when-to-use guidance, no prerequisites, and no comparison to alternatives such as fill_layer, fill_tilemap, or paint_tile_pixels. It only implies that the tile must already exist.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fill_tilemapB
Fill the entire tilemap grid with a single tile index.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | Yes | ||
| filename | Yes | ||
| tile_index | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, so the agent already knows this is a write operation. The description adds that it affects the entire tilemap grid, which usefully signals a bulk overwrite, but it does not disclose whether existing tiles are irreversibly replaced, what permissions are required, or how the optional frame parameter affects scope.
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 front-loaded sentence with no redundant or filler content. It efficiently communicates the core bulk-fill action without repeating schema details or annotations.
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 four-parameter mutation tool with low schema description coverage and no output schema, the description is too thin. It does not explain what filename or layer identify, how frame behaves, or what happens to existing tile data, so an agent lacks enough context to invoke it safely and 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 description coverage is only 25%, and the description mentions only the concept of a single tile index, which maps weakly to the tile_index parameter. It provides no meaning for filename, layer, or frame, leaving three of four parameters semantically unexplained in both schema and description.
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') and resource ('entire tilemap grid') with the tile index constraint, so the core action is clear. However, it does not distinguish this operation from close siblings like fill_layer, fill_tile, set_tile, or set_tiles, leaving an agent to infer the difference from the name alone.
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?
There is no guidance on when to use this tool versus alternatives such as fill_layer, fill_tile, set_tile, or set_tiles. The description implies a bulk fill operation but does not state prerequisites, exclusions, or selection criteria for the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
flatten_spriteBDestructive
Flatten all layers into a single layer (in place).
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, and openWorldHint=false, so the mutation/safety profile is covered structurally. The description adds the useful '(in place)' detail meaning it overwrites the existing sprite rather than producing a new file, but it does not say what is lost (layer structure, groups, blend semantics) or whether the operation is undoable.
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?
A single short sentence with the core action front-loaded and no filler. Nothing could be removed 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 destructive, no-output-schema mutation the description covers the basic effect and the in-place nature, and annotations carry the destructiveness flag. It remains thin on what the destination layer is, how groups/background layers are handled, and how the filename argument should be supplied.
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?
There is one parameter, filename, with 0% schema description coverage, and the description never mentions it. With coverage this low the description is expected to compensate, but it does not say whether filename is a path, a sprite name, or whether it must reference an already-open document.
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 (flatten) and resource (all layers) plus the scope (in place), which is clearly distinct from a partial merge. It does not, however, name or contrast with the closest sibling, merge_layer_down, so the agent must infer the difference.
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?
There is no statement of when to use this versus merge_layer_down, convert_layer_to_background, or other layer-collapsing siblings, and no prerequisites are given. Usage is only implied by the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
flip_spriteB
Flip the entire sprite. direction: "horizontal" or "vertical".
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| direction | No | Default: "horizontal". | horizontal |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=false and openWorldHint=false, so the write nature is known. The description does not add behavioral context such as whether the change is saved automatically, whether the sprite file must exist, or whether the operation is reversible.
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 two short sentences, front-loaded with the core action and followed by the key parameter constraint. It is appropriately sized and contains 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?
For a simple mutation tool with no output schema, the description covers the operation and direction values. It omits file-handling details such as whether the filename refers to an existing sprite or how the result is persisted, which leaves relevant context 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?
Schema description coverage is 50%. The description supplies the allowed direction values ('horizontal' or 'vertical'), which the schema only partially indicates through a default. The required filename parameter is not described in either place, so the description only partially compensates for the coverage gap.
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 (Flip) and resource (entire sprite), and the direction parameter indicates the operation's axis. It does not explicitly distinguish itself from similarly named siblings such as mirror_layer or rotate_sprite, so it falls short of the top score.
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?
No guidance is given on when to use this tool versus alternatives like rotate_sprite or mirror_layer. The implied usage is obvious but not stated explicitly, leaving the agent to infer context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_rampA
Generate a shading ramp from a base colour (dark -> light).
Produces `steps` colours by varying lightness across `light_range`, optionally
rotating hue by `hue_shift` total degrees across the ramp (classic pixel-art
hue shifting: cool shadows / warm highlights) and scaling saturation by
`saturation_shift` percent across the ramp.
Args:
filename: If set with apply, write the ramp into that sprite's palette.
apply: "none" (just return), "append" (add to palette), or "replace".
Returns the ramp as a list of "#RRGGBB" colours (darkest first), with `distinct`, how
many of them are different from each other.
**`distinct` is not always `steps`.** Lightness is clamped at both ends, so a base
already near white or near black spends its outermost steps on the same colour: nine
steps in, eight colours out. The ramp is still returned, because clamping is the honest
result of the inputs and a caller may not care, but `warnings` then names which end
collapsed and the nearest `light_range` that would not.
It is worth caring about at least once. `specular_highlight` needs the ramp's top step
to be brighter than what `shade_region_by_light` spread across the lit side, so a ramp
whose top two entries are both `#ffffff` makes that call refuse, with a message about
the shading pass. The cause is two calls earlier, in this one, which used to report
success either way.
| Name | Required | Description | Default |
|---|---|---|---|
| apply | No | Default: "none". | none |
| steps | No | Default: 5. | |
| easing | No | Default: "linear". | linear |
| filename | No | ||
| hue_shift | No | Default: 0.0. | |
| light_hue | No | ||
| sat_curve | No | Default: "linear". | linear |
| base_color | Yes | ||
| shadow_hue | No | ||
| light_range | No | Default: 0.6. | |
| saturation_shift | No | Default: 0.0. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only readOnlyHint=false and openWorldHint=false available, the description carries the full burden and does so well: it discloses that apply mutates a sprite palette, that lightness clamping can make distinct < steps, that warnings name the collapsed end plus a corrective light_range, and that a degenerate top step makes specular_highlight refuse downstream. That is exactly the non-obvious behavior an agent needs.
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?
Front-loaded purpose and Args block are fine, but the final three paragraphs are discursive and repeat the distinct/steps point multiple times ('It is worth caring about at least once...'). The Args section also partly restates schema fields. Informative, but not tight.
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?
No output schema exists, so the description correctly documents the return value (list of '#RRGGBB', darkest first) plus distinct and warnings. For an 11-parameter mutating tool this is nearly sufficient, with the main gap being the unexplained easing, sat_curve, light_hue, and shadow_hue parameters.
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 64% and the schema's own parameter descriptions are near-useless (mostly just restated defaults). The prose compensates by explaining steps, light_range, hue_shift, saturation_shift, base_color, apply, and filename semantics — 7 of 11. easing, sat_curve, light_hue, and shadow_hue remain undocumented in both places, keeping it short of 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+scope: 'Generate a shading ramp from a base colour (dark -> light).' An agent immediately knows the operation and the direction convention. It does not, however, distinguish itself from close siblings like ramp_between, ramp_from_art, or shift_along_ramp, so sibling selection still requires inference.
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 clarifies the three apply modes (none/append/replace) and filename pairing, and gives a strong downstream caveat about when to care about collapsed ramps feeding specular_highlight. But it never states when to choose this tool over ramp_between or ramp_from_art, so alternative-routing guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_celARead-only
Inspect a cel: whether it exists, its position, bounds, opacity, and links.
`linked_with` lists the other frames sharing this cel's image, so a held pose is
visible as what it is. An edit to any of them changes all of them.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds valuable behavioral context: it lists the returned properties and explains that linked_with reveals shared-image cels, where editing any one changes all of 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 short, front-loaded, and free of filler. Every sentence adds useful information, and the linked-cel caveat is placed immediately after the core 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?
The description adequately covers the read-only inspection purpose and return properties, and it explains the important linked_with semantics. However, with no output schema and only 33% schema parameter coverage, it should do more to explain the filename, layer, and frame parameters needed 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?
Schema description coverage is only 33%, with filename and layer required but undocumented. The description does not explain filename, layer, or frame, so it fails to compensate for the low 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 uses a specific verb (Inspect) and resource (a cel), then enumerates what is returned: existence, position, bounds, opacity, and links. This clearly distinguishes get_cel from mutation siblings such as set_cel_position, set_cel_opacity, and delete_cel.
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 usage by naming the inspection operation and explaining linked cels, but it does not explicitly say when to use get_cel versus alternatives like get_pixels, get_sprite_info, or list_sprites. No when-not conditions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_paletteBRead-only
Return the sprite's palette as a list of "#RRGGBBAA" colours.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds the output format (list of '#RRGGBBAA' colors), which is useful behavioral context, but does not mention ordering, empty palettes, error cases, or other operational 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?
A single front-loaded sentence with no wasted words. It states the action, the resource, and the return format efficiently.
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 read-only tool with one parameter and no output schema, the description adequately states what is returned. However, it leaves the sole parameter undocumented and provides no usage context relative to the many sibling palette tools, so an agent still lacks important operationally relevant 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?
Schema description coverage is 0% and the single parameter 'filename' is not explained at all in the description. The phrase 'the sprite's palette' hints that filename identifies a sprite, but no format, path, or naming convention is provided to compensate for the missing schema documentation.
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 gives a specific verb ('Return') and resource ('the sprite's palette'), and specifies the return format as a list of '#RRGGBBAA' colors. This clearly distinguishes it from sibling palette-mutation tools like set_palette or add_palette_color.
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?
There is no explicit guidance about when to use this tool versus alternatives (e.g., list_palette_usage, extract_palette, set_palette). Usage is only inferred from the tool name and description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_pixelsARead-only
Read the pixel colours of a region.
Args:
layer: Read this layer alone instead of the composite. This matters more than
it sounds: drawing tools write to ONE layer, so the composite is not the
surface your next edit will act on. A fill whose boundary is drawn on a
different layer will flood the whole canvas while the composite looks as
though it should have stopped.
format: "rows" (default) gives rows of "#RRGGBBAA" strings. "map" gives a
`legend` of symbol to colour plus one string per row, which is around a
tenth the size: a 16x16 icon of three colours costs roughly 3,400
characters as rows and 350 as a map, and defects like a one-pixel offset
are visible in it at a glance.
The region is capped at 64x64 (4096 pixels) per call to keep responses small, so
read in tiles for bigger areas.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | Default: 0. | |
| y | No | Default: 0. | |
| frame | No | Default: 1. | |
| layer | No | ||
| width | No | ||
| format | No | Default: "rows". | rows |
| height | No | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say readOnlyHint=true and openWorldHint=false; the description adds the hard 64x64/4096-pixel cap, the composite-vs-layer behavioral trap, and the output-format size tradeoff. These are non-obvious behavioral traits beyond what the structured fields declare.
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?
Front-loaded with a one-line purpose, then focused arg guidance; the length is largely justified by the layer and format explanations. The layer passage is slightly discursive, keeping it from a 5.
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 8-param read tool with no output schema and minimal annotations, it explains the output shapes (rows vs map) and the region cap, which is what an agent most needs. It omits any mention of 'frame' semantics, which is a minor but real 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 coverage is 50%, and the description compensates well for the two semantically tricky params (layer, format) with usage meaning and concrete size examples. It leaves 'frame', x/y, and width/height entirely to the bare schema defaults, so it does not fully close the coverage gap.
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 ('Read the pixel colours of a region'), which is enough for an agent to distinguish it from get_palette, get_cel, or get_sprite_info at a glance. It does not explicitly name or contrast a sibling, so it stops 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?
Gives real decision guidance for two parameters: when to pass 'layer' (because drawing tools write to one layer, so the composite misleads edits) and when to choose 'format: map' (size and defect visibility). It also tells the agent to tile for regions over 64x64. No explicit when-not or alternative-tool routing, 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.
get_propertiesARead-only
Read the custom properties stored on one object inside the sprite.
The counterpart to `set_properties`, and the only way to read that metadata back:
neither `get_sprite_info` nor the sprite-sheet export reports custom properties.
Args:
target, layer, frame, name, tile: Which object, exactly as `set_properties`
takes them.
namespace: Read a named group instead of the unnamed one. Aseprite offers no way
to list the namespaces an object has, so a group can only be read by a caller
who knows its name; an unknown name reads as empty rather than as an error.
Returns `properties` as an object of key to value, each value in the type it was
stored as. A value of a type JSON cannot describe (the editor can store a point or a
rectangle) is reported as text rather than dropped.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| tile | No | ||
| frame | No | ||
| layer | No | ||
| target | Yes | ||
| filename | Yes | ||
| namespace | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations give readOnlyHint=true and openWorldHint=false, so safety is covered. The description goes further with non-obvious edge cases: an unknown namespace reads as empty rather than erroring, and values of types JSON cannot describe (point, rectangle) are returned as text rather than dropped. It does not cover failure behavior for a bad filename/target, which keeps it from a 5.
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?
Front-loads the core purpose, then uses an Args block and a Returns sentence with no filler. Each part earns its place, though the 'counterpart to set_properties' framing repeats the scope point already made in sentence one.
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 no output schema, the description correctly supplies the return shape (key-to-value object, types preserved, unrepresentable types as text) and discloses the namespace-enumeration limitation. Only the required filename parameter and error conditions remain unaddressed.
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 0% across 7 params, so the description must carry the load, and it does: target/layer/frame/name/tile are grouped as the object locator, and namespace gets a full explanation of its grouping semantics and failure mode. The required 'filename' parameter is never explained, and it defers locator semantics to set_properties, so it falls short of full compensation.
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 with scope ('custom properties stored on one object inside the sprite') and distinguishes itself from siblings by naming both its counterpart set_properties and the tools that do NOT surface this data (get_sprite_info, sprite-sheet export). An agent can identify it without opening any schema.
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 frames itself as the counterpart to set_properties and the only way to read that metadata back, and warns that namespaces cannot be enumerated, so a group can only be read by a caller who already knows its name. That is exactly the when/when-not guidance needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_selectionARead-only
Describe the current selection: whether there is one, and what it covers.
Returns `bounds`, the pixel `area` actually inside the selection, and a `map` of
the selected region using `#` for selected and `.` for not, in the same shape
`get_pixels(format="map")` uses. The map is capped, and omitted for a selection
larger than the cap, since a wall of characters is not feedback.
Worth calling before a large edit: a selection you forgot about is the difference
between changing what you meant and changing a corner of it.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and closed-world, so safety is covered. The description adds real behavioral value beyond that by disclosing the returned fields (bounds, area, map), the map character encoding, and the caps/omission behavior for large selections.
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?
Front-loaded with the core purpose followed by return details and a rationale. Generally efficient, though the final motivational sentence is slightly padded rather than strictly informational.
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 no output schema, the description carries the full burden of explaining returns and does so thoroughly, including the map format and its cap behavior. For a simple single-parameter read tool, nothing needed to call it 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 description coverage is 0% and the description never mentions the sole 'filename' parameter, though its meaning is largely self-evident. The baseline 3 applies since the description adds no parameter semantics the schema lacks.
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 (describe) and resource (the current selection), and clarifies scope as 'whether there is one, and what it covers'. This clearly distinguishes it from siblings like modify_selection, invert_selection, and deselect.
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 a concrete usage trigger: 'Worth calling before a large edit'. It explains why it matters but does not explicitly name or exclude alternatives (e.g., contrast with modify_selection or get_pixels), so it stays short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_sprite_infoBRead-only
Return structured info about a sprite: size, colour mode, frames (with durations), the full layer tree (names, opacity, blend mode, visibility), animation tags, and palette size.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the read-only, local safety profile is covered. The description adds useful context about the breadth of returned data (e.g. 'the full layer tree'), but says nothing about error behavior, missing files, or performance. With annotations carrying the safety profile, this is adequate but not rich.
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?
One front-loaded sentence that opens with the action and then lists returned fields with no filler or repetition. Every clause earns its place by describing the output shape.
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?
There is no output schema, so the description carries the burden of describing returns, and it does so thoroughly with an explicit field list. Read-only annotations cover safety and the lone parameter is obvious, leaving only usage guidance as the notable 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?
The single parameter 'filename' has 0% schema description coverage, and the description never mentions it or clarifies whether it is a path, bare name, or extension. The parameter name is self-evident, but the description contributes no additional meaning to compensate for the coverage gap.
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+resource ('Return structured info about a sprite') and enumerates the exact fields returned (size, colour mode, frames, layer tree, tags, palette size), so the agent knows precisely what this produces. It does not, however, differentiate itself from related inspection siblings such as get_pixels, get_properties, or assess_sprite.
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?
There is no indication of when to use this tool versus get_pixels, get_properties, get_cel, or assess_sprite, and no prerequisites or exclusions. Usage is only weakly implied by the fact that it returns metadata rather than pixel data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tilemapBRead-only
Read the tilemap as a 2D grid of tile indices, plus tile size and count.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds useful context that the return is a 2D grid of tile indices plus tile size and count, but it says nothing about the layer/frame scoping behavior or error cases for a missing layer.
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?
A single front-loaded sentence with no wasted words. It is well-sized, though it spends its payload on the return shape rather than the arguments the caller must supply.
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 read-only tool whose annotations carry the safety profile, the description is adequate on the output side but thin on the input side: two required parameters (filename, layer) are unexplained and there is no output schema to fall back on. It leaves a meaningful gap for 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 only 33%: filename and layer — both required — have no descriptions, and only frame ('Default: 1') is documented. The description adds no meaning for any parameter, so it fails to compensate for the undocumented required inputs. An agent cannot tell what a valid 'layer' value is.
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 (read) and resource (tilemap), and even describes the shape of the result: a 2D grid of tile indices plus tile size and count. It is clearly a read operation, distinguishing it implicitly from write-oriented siblings like set_tile or fill_tilemap, though it never names an alternative explicitly.
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?
No when-to-use guidance is given. The description does not state when an agent should call get_tilemap versus related tools (get_pixels, get_cel, list_slices) or what prerequisites apply. Usage is only implied by the word 'read'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
glowA
Halo a shape in rings of ramp steps, so it glows without leaving the palette.
`add_outline` gives one flat ring, which reads as a sticker. A glow is several rings,
each a step further down a ramp: hottest against the artwork, fading outward, with the
outer ring optionally dithered so it ends in something softer than a hard edge.
The ramp is what makes this different from a glow in an image editor. A halo made of
alpha, or of colours interpolated between two others, takes the art off its palette,
and then `palette_conformance` drops and the sprite no longer exports to an indexed
format, reuses a tileset, or matches the sprite beside it. Every pixel this writes is
exactly one of the colours you passed in.
The glow goes on its own layer below the artwork, so the subject's cel is untouched
and deleting one layer removes the effect.
Args:
ramp: Colours darkest first. Ring 1, touching the artwork, takes the top step and
the outermost ring takes `ramp[0]`, so a longer ramp fades more finely. For a
glow that reads as light rather than as a coloured border this usually wants
its own bright ramp (a gem's or a flame's), not the subject's body ramp.
radius: How many rings, in pixels. 2 or 3 reads as a glow; much more reads as fog.
falloff: "linear" spaces the steps evenly. "quadratic" drops away faster, keeping
a hotter core and a dimmer skirt, which is the one that reads as a light
source rather than as an outline.
dither_edge: Dither the outermost ring, so the glow ends in a half-density
scatter instead of a hard line. This is binary coverage, a pixel either drawn
or not, rather than a partial alpha, so every drawn pixel is still exactly a
ramp step and conformance stays at 1.0.
base_color: Glow only around pixels near this colour, which is how a gem glows
while the hand holding it does not. Distance is measured out from those
pixels, but the glow is never painted over any part of the subject layer, so
a body blocks the halo of a gem inside it.
tolerance: How close a pixel must be to `base_color` to be treated as a source,
as a weighted RGB distance. Ignored when `base_color` is omitted.
new_layer: Name for the glow's own layer, created directly below `layer`, or
reused when a previous call of this tool made it and `frame` has no cel on it
yet. That is how one glow layer carries a flickering torch across four frames
rather than needing four layers with one cel each. A second call for the same
layer *and* frame is refused, because two halos composited into one cel are a
picture neither call describes, and so is a layer of that name this tool did
not create.
layer: The layer to glow around (default: top layer). Its cel is never modified.
frame: Target frame, 1-based.
Refuses rather than drawing nothing: no pixel matching `base_color` is an error, and
so is a subject that leaves the glow nowhere to go.
| Name | Required | Description | Default |
|---|---|---|---|
| ramp | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| radius | No | Default: 3. | |
| falloff | No | Default: "linear". | linear |
| filename | Yes | ||
| new_layer | No | Default: "glow". | glow |
| tolerance | No | Default: 24.0. | |
| base_color | No | ||
| dither_edge | No | Default: true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare only readOnlyHint=false and openWorldHint=false, so the description carries the rest and delivers: it writes to a new layer below the artwork, the subject cel is untouched, deleting one layer removes the effect, palette conformance stays at 1.0, layer reuse across frames is allowed but a duplicate layer+frame call is refused, and specific refusal conditions are enumerated. This is unusually rich behavioral disclosure for a mutation 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?
Front-loaded with a one-sentence summary followed by rationale and a dense but well-organized Args section; nearly every sentence carries non-redundant information. It is long for a tool description, but the length is largely earned by the ten parameters and the refusal semantics, with only mild room for trimming in the palette-conformance rationale paragraph.
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 10-parameter mutation tool with no output schema and only two annotation hints, the description covers layer side effects, error/refusal behavior, cross-frame reuse, and palette guarantees. Nothing an agent needs to invoke it correctly appears to be 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 60% and the schema only supplies defaults, yet the description adds genuine meaning for every parameter: ramp ordering and why a separate bright ramp is wanted, radius-as-ring-count, the two falloff modes, dither_edge's binary-coverage semantics, base_color's distance measurement and subject-layer blocking, tolerance's weighted RGB distance and its interaction with base_color, and new_layer's reuse rule. The enum-less falloff string is disambiguated purely by prose.
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 line states a specific verb+resource ('halo a shape in rings of ramp steps') and immediately distinguishes the tool from its closest sibling by contrasting with `add_outline`'s single flat ring. An agent can tell this apart from add_outline, add_drop_shadow, and cast_shadow without opening any schema.
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 names the alternative (`add_outline`) and the condition that separates them, plus contrasts with image-editor glow techniques and explains when falloff='quadratic' vs 'linear' is appropriate and what radius values read as glow vs fog. The when-not case (image-editor alpha interpolation) is also stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gradient_mapA
Put every pixel on a ramp by its brightness, whatever it started as.
The other shading tools all begin with art that is *already* on a ramp:
`shift_along_ramp` moves pixels between steps they already belong to, and
`shade_region_by_light` shades a flat region painted in one of the ramp's colours.
This is the one that brings art onto a ramp in the first place, which is what an
imported image, a photo traced over, or a gradient fill actually needs.
Each pixel's luminance decides its step: darkest to `ramp[0]`, lightest to the last
entry, the rest in between. Afterwards the art uses the ramp's colours and nothing
else, so `assess_sprite(..., ramp=...)` reports a palette conformance of 1.0.
Args:
ramp: The ramp, darkest first. Order is the mapping, so a reversed ramp inverts
the image.
contrast: Stretch the mapping around mid-grey. Above 1.0 pushes pixels toward
the ends of the ramp and drops the middle steps; below 1.0 crowds everything
into the middle. The interesting control is not which colours are used but
how much of the art each step takes.
bias: Shift the whole mapping after contrast, from -1.0 to 1.0. Positive is
lighter. Use it when an image maps too dark to read.
dither: "bayer4", "bayer2" or "checker" to break the bands. A pixel landing
between two steps takes the darker or the lighter one by an ordered pattern,
which reads as a gradient without adding a colour.
x, y, width, height: Restrict the change to a region.
Luminance is weighted 0.299/0.587/0.114, the same weighting the ramp matching uses,
so a saturated red and a dull red of the same weight land on the same step. Alpha is
carried through untouched, so the silhouette does not move and anti-aliased edges
keep their coverage, even though their colour is now a ramp entry.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | Default: 0. | |
| y | No | Default: 0. | |
| bias | No | Default: 0.0. | |
| ramp | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| width | No | ||
| dither | No | ||
| height | No | ||
| contrast | No | Default: 1.0. | |
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false; the description goes far beyond by disclosing the luminance weighting (0.299/0.587/0.114), that alpha is preserved so silhouettes and anti-aliasing are unaffected, that the result yields palette conformance of 1.0, and exactly how contrast/bias/dither manipulate the mapping.
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?
Front-loaded with the core action and the sibling differentiation, then structured into a clear Args block plus a behavior note. Some stylistic prose ('The interesting control is not which colours are used...') is slightly verbose, but almost every sentence carries usable information.
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 11-parameter mutation tool with no output schema, the description is unusually complete on the mapping, region, and alpha behavior. The gaps are the unaddressed frame/layer targeting and return-value expectations, but nothing critical for correct invocation 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 only 45% and the schema descriptions are bare defaults, so the prose carries real weight: it explains ramp ordering and reversal, contrast's effect on step distribution, bias direction, dither modes (bayer4/bayer2/checker), and region restriction for x/y/width/height. It leaves frame, layer, and filename unexplained, which keeps it from 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?
States a specific verb+resource (map every pixel onto a ramp by luminance) and explicitly distinguishes itself from shift_along_ramp and shade_region_by_light, explaining that those assume art already on a ramp while this one brings art onto a ramp. An agent can pick it out of the sibling list without opening any schema.
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 concrete when-to-use cases (imported image, traced photo, gradient fill) and names the alternative tools with the condition that selects them. This is essentially explicit routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gui_availableARead-only
Check whether the Aseprite GUI can be launched (executable resolvable).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish this is a read-only, closed-world probe, so the safety profile is covered. The description adds real value by clarifying that 'available' means the executable is resolvable, but it does not say what the tool returns (boolean? status string?) or what the agent should do when it reports unavailable. With no output schema, that gap matters.
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?
A single, front-loaded sentence with the parenthetical clarifying the criterion. Every word earns its place, and the key information leads.
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 trivial no-argument probe, the description is nearly sufficient: it defines the condition being tested. The only shortfall is the absence of any return-value information, which is not covered by an output schema, so an agent cannot know the result shape in advance.
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 takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a no-parameter tool is 4. Nothing in the text misrepresents the input contract.
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 (check) and a specific subject (whether the Aseprite GUI can be launched), and even defines the check as 'executable resolvable', which removes ambiguity about what 'available' means. It does not differentiate itself from the sibling health_check tool, which is the main gap keeping it from 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?
There is no statement of when to call this versus alternatives — notably the sibling health_check, which sounds like an overlapping diagnostic. The pre-flight use case is only implied by the word 'check'. No exclusions or prerequisites are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
health_checkARead-only
Run a self-test of the server and its Aseprite integration.
Returns whether Aseprite was found, its version, the workspace, the number of
registered tools, and whether a real create-sprite plus export-PNG round-trip
succeeds. `ok` is True only if the round-trip works and the workspace is usable.
`workspace` is the **resolved** path, which is where files land and what every other
tool reports, because paths are canonicalised before the containment check that keeps
them inside the workspace. When the configured value spells the same directory
differently, which is what a junction or a symlink does, it is reported alongside as
`workspace_configured` with a note; the two are one place, not two.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description goes further and discloses the return payload (Aseprite found, version, workspace, tool count, round-trip result) and defines the semantics of `ok` — that it is true only when both the round-trip and workspace usability hold. It also explains the workspace canonicalisation behavior. It stops short of saying whether the self-test is cheap or slow.
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?
Front-loaded with the purpose, then the return breakdown, then the workspace nuance — a sensible order. The final sentence ('the two are one place, not two') restates what the preceding clause already conveyed about workspace vs workspace_configured, adding mild redundancy, but the overall size is defensible given no output schema exists.
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 no input parameters and no output schema, the description carries the full burden of describing the return payload, and it does so — fields, the `ok` condition, and the workspace/workspace_configured relationship. Nothing an agent needs to interpret a health_check result 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?
There are zero parameters, so per the rubric the baseline is 4. No parameter explanation is needed or given, which is correct.
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: 'Run a self-test of the server and its Aseprite integration.' It is immediately distinguishable from roughly 90 sibling tools, including the superficially related gui_available, because it is framed as a server-level diagnostic rather than an editor capability probe.
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 diagnostic intent implies when to call it (before/after operations to verify the integration is live), but there is no explicit statement of when to use this versus alternatives such as gui_available, nor any mention of cost or side effects of the self-test. Usage is inferable but not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_imageADestructive
Create an editable .aseprite sprite from a flat image (.png/.bmp/.jpg/...).
Args:
input_image: Source raster image.
output: Destination .aseprite path.
overwrite: Replace `output` if it already exists (default False = no-clobber).
| Name | Required | Description | Default |
|---|---|---|---|
| output | Yes | ||
| overwrite | No | Default: false. | |
| input_image | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations flag destructiveHint=true and readOnlyHint=false, and the description usefully qualifies that this destruction only occurs when overwrite is true, since the default is no-clobber. That is real added value beyond the flat annotation, though it never says what happens on a no-clobber collision (error vs. skip) or what is returned.
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?
One front-loaded purpose sentence plus a tight three-line args block; nothing is padded and the most important constraint (output must be .aseprite) appears first.
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 low-complexity 3-parameter file-conversion tool with no output schema, the description covers the purpose, both required inputs, formats, and overwrite semantics. The only gap is undefined error behavior when output already exists and overwrite is false, plus no hint about what the call returns.
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 only 33% (just 'Default: false.' on overwrite), so the description must compensate, and it does: it defines input_image as the source raster, output as the destination .aseprite path, and overwrite as the replace-existing flag with its default. The .aseprite constraint on output is information the schema does not carry.
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 ('Create an editable .aseprite sprite from a flat image') and enumerates accepted source formats, so the conversion direction is unambiguous and distinguishable from create_sprite or import_reference_sequence. It stops short of naming a sibling tool explicitly, which keeps it out of the top band.
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?
There is no explicit when-to-use or when-not-to-use statement, nor any named alternative among the many sprite/import siblings. Usage is only implied by the accepted file formats and the no-clobber note, which is the level the rubric defines as 'implied usage'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_reference_sequenceA
Import a sequence of images as per-frame references for rotoscoping.
Each image is placed on its own frame in a single dimmed, locked layer
(frames are created as needed, so `start_frame` may sit past the end). Draw your
animation on a layer above, then exclude this layer at export with
ignore_layer="<layer_name>".
| Name | Required | Description | Default |
|---|---|---|---|
| images | Yes | ||
| opacity | No | Default: 128. | |
| filename | Yes | ||
| layer_name | No | Default: "rotoscope". | rotoscope |
| start_frame | No | Default: 1. | |
| scale_to_fit | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose readOnlyHint=false (a mutation), and the description adds substantial side-effect context: each image goes on its own frame in a single dimmed, locked layer, frames are created as needed, and start_frame may extend past the current end. It does not cover error behavior or layer-name conflicts, but it is well beyond the annotation baseline.
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, then adds just enough behavioral and workflow detail in three compact sentences. Every sentence earns its place, and the backtick usage aids scanning.
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 six-parameter mutation tool with no output schema, the description covers purpose, side effects, and pipeline integration well. However, it omits required-parameter semantics for images and filename and does not describe the return value, leaving meaningful gaps for an agent invoking 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 67%, but descriptions mostly repeat defaults. The tool description adds meaning for start_frame (frames are created as needed) and layer_name (usable for export exclusion), yet it leaves required parameters images and filename undocumented, and does not clarify opacity or scale_to_fit beyond their schema defaults.
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 gives a specific verb and resource ('Import a sequence of images') and scopes it to per-frame references for rotoscoping. It implicitly distinguishes from single-image siblings like import_image, but never names an alternative tool explicitly.
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 the rotoscoping use case and outlines a workflow (draw animation above, exclude at export), which implies when to use it. However, it does not name or contrast alternatives such as import_image or add_reference_layer, nor does it state 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.
invert_colorsB
Invert the RGB colours of a layer's pixels (alpha preserved).
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | No | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false, so the safety profile is thin. The description usefully discloses that only RGB is inverted while alpha is preserved, which is real behavioral information, but it does not say whether the change applies to a single layer or all layers, whether it is reversible, or how it interacts with an active selection.
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?
A single tight sentence with the operation front-loaded and the alpha-preservation caveat parenthetically placed. Zero 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?
There is no output schema, so the description should carry more weight. For a mutation tool with an optional layer parameter, it fails to explain the effect's scope (single layer vs. whole sprite), whether the operation can be undone, or how it differs from related color 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 only 33% (frame has a trivial 'Default: 1.' note, while layer and filename are undocumented). The description gestures at the layer concept with 'a layer's pixels' but never explains what happens when layer is omitted, which is a meaningful ambiguity given only filename is required.
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 ('Invert the RGB colours of a layer's pixels') and adds the scope detail that alpha is preserved. It is clearly distinguishable from the neighboring invert_selection, though the description never names that sibling to close the loop.
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?
No when-to-use guidance, no exclusions, and no alternatives are offered. With siblings like adjust_hue_saturation, desaturate, and invert_selection, the agent gets no help deciding when color inversion is the right operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
invert_selectionB
Swap what is selected for what is not.
Selecting a character's silhouette and inverting gives the background, which is usually easier than describing the background directly.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, indicating a local state-changing operation. The description restates the action but adds no further behavioral details such as prerequisites (e.g., must have an active selection) or side effects, so it adds limited value beyond the structured 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 two sentences, front-loaded with the core action and followed by a brief rationale. Every sentence earns its place with 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?
For a simple selection-inversion tool with no output schema, the description covers the action and a use case. However, it omits any explanation of the required 'filename' parameter and does not state whether an existing selection is a prerequisite, leaving gaps for 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 0% and the description makes no mention of the sole 'filename' parameter. It does not clarify what the filename refers to (e.g., the sprite file) or that it is required, leaving the parameter entirely undocumented.
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: 'Swap what is selected for what is not.' This clearly conveys the action of inverting a selection. It does not explicitly differentiate from siblings like modify_selection or deselect, but the action itself is distinct.
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 second sentence provides a concrete use case: 'Selecting a character's silhouette and inverting gives the background, which is usually easier than describing the background directly.' This gives clear context for when to use the tool, though it does not name alternatives or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
link_celsADestructive
Make several frames share one image, which is how a held pose is authored.
A linked cel is one image appearing on several frames: editing any of them edits all
of them, and the file stores the image once instead of once per frame. Use it for a
pose that genuinely repeats, such as the two extremes of a cycle that return to the
same drawing.
**The first listed frame's image is the one kept.** Every other listed frame loses
whatever was drawn on it and shows the first frame's image instead, which is the point
of linking and is not undoable from here, so check with `get_cel` first if the frames
differ.
To hold a pose for longer rather than to repeat a drawing, lengthen the frame instead
(`set_frame_duration`, or `apply_timing_curve`): a duration costs nothing, while a
repeated frame shifts every tag index.
Returns the layer's link groups: the frames that now share an image, in groups.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | Yes | ||
| frames | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true, but the description adds essential detail: every non-first listed frame loses its drawing, the first frame's image is kept, and the change is 'not undoable from here.' It also suggests a pre-check with get_cel, which is actionable behavioral context beyond the 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 front-loaded with the core purpose, then layers in behavior, alternatives, and return values. Each paragraph earns its place, using bold text and short sections without 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?
For a destructive tool with no output schema and only minimal annotations, the description covers purpose, usage, behavioral consequences, alternatives, and even return values ('Returns the layer's link groups'). The main gap is that it does not document the filename and layer parameters, but otherwise it is complete enough for 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 0%, so the description must compensate for all three parameters. It adds critical meaning for 'frames' by explaining that the first listed frame's image is kept and others are overwritten, but it never defines 'filename' or 'layer', leaving two of three parameters semantically undocumented.
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: 'Make several frames share one image,' and explains the linked-cel concept. It distinguishes the operation from related siblings like set_frame_duration and apply_timing_curve by clarifying that linking repeats a drawing rather than holding a pose.
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 when-to-use guidance ('for a pose that genuinely repeats, such as the two extremes of a cycle') and when-not-to-use guidance ('To hold a pose for longer rather than to repeat a drawing, lengthen the frame instead'), naming the alternative tools set_frame_duration and apply_timing_curve. It also advises checking with get_cel first if frames differ.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_palette_usageARead-only
Which palette indices the art is drawn with, how many pixels each covers, and which runs of them are worth cycling.
Indexed sprites only: an RGB or grayscale pixel carries its own colour rather than an
offset into a palette, so there is no index to count. `extract_palette` lists the
colours such a sprite uses and `assess_sprite` counts them.
The answer `cycle_palette` needs and the answer `get_palette` cannot give. A palette
says what colours exist; this says which of them the picture actually uses, so a
256-entry palette on a sprite painted in nine colours stops being a wall of hex. The
only way to work this out before was to read every pixel through `get_pixels` and
count them by hand.
Args:
frame: Count only this frame. Default: every frame.
layer: Count only this layer. Default: every pixel layer, groups walked through.
Tilemap layers are skipped, because the numbers in their cels are tile
references rather than palette offsets.
Returns `used` (index, colour and pixel count, most pixels first), `unused`, `runs`
(the contiguous spans of used indices, longest first, which is what a cycle rotates),
the transparent index and how many pixels sit on it, and `out_of_range`: pixels
carrying an index past the end of the palette, which is what a palette resized
smaller than its art leaves behind and which no colour can be read for at all.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | ||
| layer | No | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/openWorldHint annotations, the description discloses real behavior: tilemap layers are skipped because their cels hold tile references, defaults apply to frame and layer, and out-of-range indices are reported because no colour can be read for them. That is substantive operational context an agent could not infer from 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?
Purpose is front-loaded and the Args/Returns structure is easy to scan, but the rhetorical asides ('stops being a wall of hex', 'count them by hand') add length without adding selection 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?
No output schema exists, and the description compensates by enumerating every returned field (used, unused, runs, transparent index and its pixel count, out_of_range) with ordering semantics. Nothing needed to call or interpret the tool 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 description coverage is 0%, so the description carries the parameter burden and does: frame and layer both get default behavior (every frame, every pixel layer with groups walked through) plus the tilemap-skip rule. filename is left undocumented, but its meaning as the target sprite is self-evident from context.
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 sentence names the exact resource and the three outputs (used indices, pixel counts, cycleable runs) in a specific verb+resource form. It is immediately distinguishable from get_palette, extract_palette and get_pixels, each of which is named and contrasted.
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 scopes the tool to indexed sprites and tells the agent what to use instead for RGB/grayscale art (extract_palette for colours, assess_sprite for counts). It also frames itself against get_palette and get_pixels, so the when/when-not decision is fully specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_slicesARead-only
List every slice with its bounds, center, pivot, colour and user-data.
User-data comes back two ways, because it is one string that is sometimes a document.
`data` is the string exactly as Aseprite stores it, so it round-trips through
`set_slice` unchanged. `data_parsed` is added only when that string is valid JSON,
which is the shape worth sending: `{"type": "hitbox", "id": "body"}` is what
`export_slice_metadata` reads a slice's type and id from, and what
`build_asset_from_spec` writes. A slice with no user-data has neither field, so "set
and forgot" and "never set" are now distinguishable, which they were not while this
tool reported the same thing for both.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint, so the description carries the return-shape burden and does so well: it explains that `data` is the raw stored string, that `data_parsed` is conditionally present only for valid JSON, and that a slice with no user-data has neither field. This 'set and forgot vs never set' distinction is real behavioral context an agent cannot get from the annotations or schema, though ordering/other field formats remain undisclosed.
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?
It is front-loaded with the one-line purpose before any elaboration, and the JSON example earns its place by making the expected payload concrete. The closing clause about prior behavior ('which they were not while this tool reported the same thing for both') is mildly editorial and could be trimmed, but the overall length is justified by the subtle return semantics.
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 no output schema and no annotation detail, the description must explain the return value, and it thoroughly covers the hardest part (the two forms of user-data and their conditional presence). It stops short of describing the format of the other returned fields (bounds, center, pivot, colour) or any ordering/pagination, which leaves a small but real gap for a list 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 single parameter is a bare `filename: string` with 0% schema description coverage, and the description adds nothing about it (e.g. whether it is a path, an open sprite, or a project-relative name). The parameter is trivially inferable from sibling conventions, so this is adequate but leaves a real gap given the description otherwise has room to say more.
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 sentence gives a specific verb ('List'), an explicit scope ('every slice'), and enumerates the returned fields (bounds, center, pivot, colour, user-data). This is unmistakably distinct from siblings such as list_sprites or get_sprite_info, and it names the companion tools (set_slice, export_slice_metadata, build_asset_from_spec) that consume the data.
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 usage by explaining that `data` round-trips through `set_slice` and that `data_parsed` is 'the shape worth sending' to `export_slice_metadata`/`build_asset_from_spec', which hints at inspecting slices before exporting. However, it never states an explicit when-to-use or when-not-to-use rule, nor does it point to an alternative inspection tool, so the guidance remains inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_spritesARead-only
List sprite/image files in the workspace directory.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered and the bar is lower. The description adds the useful scoping detail that results come from the workspace directory, but says nothing about what is returned (names vs. paths) or whether results are recursive or filtered.
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?
A single front-loaded sentence with no filler, preamble, or redundancy. Every word 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 read-only list with no parameters, the description is nearly sufficient, but since there is no output schema it omits what the listing actually contains (filenames, paths, extensions) and whether the scan is recursive. That gap keeps it at minimum-viable rather than 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?
The tool takes zero parameters and schema coverage is 100%, so there is nothing for the description to disambiguate. A 4 is the baseline for a parameterless tool.
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?
It states a specific verb (List) and resource (sprite/image files) plus a scope (workspace directory), so the agent knows this is a filesystem enumeration of sprites rather than a sprite-object query like get_sprite_info. It does not explicitly contrast itself with sibling listing tools (e.g., list_slices, list_palette_usage), so it falls 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?
Usage is only implied: the agent can infer it should call this to discover what sprite files exist before operating on them. There is no explicit when-to-use, no exclusion, and no named alternative such as get_sprite_info for metadata on a known sprite.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
load_paletteCDestructive
Load a palette from a file (.gpl, .pal, .aseprite, .png, ...) and apply it.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| palette_file | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations flag destructiveHint=true and readOnlyHint=false, but the description never discloses what the operation destroys or replaces (e.g., the existing palette) or which document is affected. 'Apply it' vaguely implies mutation but adds no real behavioral context 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler or redundancy. It is terse, but every word contributes to the action being described.
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 destructive mutation with no output schema and 0% parameter coverage, the description omits the essential facts: which object is modified, whether the existing palette is replaced, and what 'filename' refers to. It is under-specified for the risk level implied by the annotations.
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 0% and neither required parameter is explained. The description clarifies 'palette_file' only by listing example extensions, while 'filename' is left completely unexplained, so the agent cannot tell whether it names the target sprite or something else.
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 concrete verb+resource ('load a palette from a file') and even enumerates supported formats. It does not distinguish itself from palette siblings such as set_palette, extract_palette, or quantize_palette, and 'apply it' leaves the target of the application implicit.
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?
There is no guidance on when to prefer this over set_palette or extract_palette, no statement of prerequisites, and no indication of what 'apply' affects. The agent must infer usage entirely from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
make_4_frame_idle_animationA
Turn a single-frame sprite into a 4-frame idle "bob" loop.
Duplicates frame 1 to 4 frames, nudges `layer` down by `bob_pixels` on frames 2
and 4 for a subtle bob, sets uniform durations, and adds a looping tag.
Returns a ``workflow_manifest.v1`` manifest (sprite summary + animation block).
| Name | Required | Description | Default |
|---|---|---|---|
| layer | No | Default: "body". | body |
| filename | Yes | ||
| tag_name | No | Default: "idle". | idle |
| bob_pixels | No | Default: 1. | |
| frame_duration_ms | No | Default: 150. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false, so the description carries the behavioral burden and does so well: it enumerates the exact mutations (duplicates frame 1 to 4 frames, nudges `layer` down by `bob_pixels` on frames 2 and 4, sets uniform durations, adds a looping tag). It also discloses the return type (workflow_manifest.v1). It stops short of stating what happens to pre-existing frames or whether the operation is reversible/overwriting.
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?
Front-loaded purpose sentence followed by the mechanics and the return value. Every sentence earns its place with no filler or restatement 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?
For a mutating tool with no output schema, the description supplies the transformation steps, the touched parameters, and the return shape, which is enough to call it correctly. A note on interaction with pre-existing frames (overwrite vs. append) would close the remaining 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 coverage is 80% (defaults documented for layer, tag_name, bob_pixels, frame_duration_ms), so baseline is 3. The description adds genuine meaning by tying parameters to behavior: `layer` is the layer that gets nudged, `bob_pixels` is the downward offset amount, and frame_duration_ms maps to the 'uniform durations'. Only `filename` (and the exact effect of tag_name) is left unelaborated.
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 precise verb+resource+outcome: 'Turn a single-frame sprite into a 4-frame idle "bob" loop.' This is clearly distinguishable from generic siblings like add_frame, duplicate_frame, tween_cels, and smear_frame, which do not perform this specific one-shot idle-animation construction.
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 use case (single-frame sprite → idle bob loop) is implied clearly by the first sentence, so an agent can infer when it applies. However, no alternatives are named and no when-not guidance is given (e.g., what to do if the sprite already has frames, or how it differs from add_frame/duplicate_frame).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
make_8_direction_walk_templateA
Scaffold an 8-direction walk-cycle template on an existing sprite: enough frames
for frames_per_direction per direction, with one animation tag per direction
(N, NE, E, SE, S, SW, W, NW by default).
Args:
frames_per_direction: 8 is the convention for a walk, and it is what this
defaults to: contact, down, pass, up for each leg. 6 is the budget option and
4 only reads as a walk mirrored on a side view, which an 8-direction sheet by
definition is not. The default was 4 until this was fixed (#91), so a sprite
scaffolded before then has half the frames a walk needs.
frame_duration_ms: Set on every frame. Shape the timing afterwards with
`apply_timing_curve`: a walk holds its contacts.
directions: Override the eight compass tags.
Frames are placeholders to draw over. Returns a ``workflow_manifest.v1`` manifest
(kind "walk_template") with an animation block listing the directions/tags.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| directions | No | ||
| frame_duration_ms | No | Default: 120. | |
| frames_per_direction | No | Default: 8. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark it as non-read-only and closed-world, so the description carries the useful extra detail: frames are empty placeholders to draw over, timing is set on every frame and should be refined with apply_timing_curve, and it returns a workflow_manifest.v1 (kind "walk_template"). It also discloses the historical default change (#91), which explains why older sprites may lack frames.
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?
Leading sentence front-loads purpose and output shape, and the Args block is scannable. The #91 changelog aside is interesting but not essential for an agent deciding to call the tool, making it slightly longer than it needs to be.
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 mutating scaffolding tool with no output schema, the description covers what is created (placeholders plus tags), the manifest kind it emits, and per-parameter meaning. It lacks any note on prerequisites (sprite size/layer expectations) or what happens if the sprite already has frames or tags of the same name.
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 50% and the two schema-described params only restate their defaults, so the prose does the real work: it explains why 8 is the walk convention, why 6 and 4 are inferior for an 8-direction sheet, what frame_duration_ms applies to, and that directions overrides the default compass tags. The required filename param is never described anywhere.
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 first sentence states a specific verb (scaffold) and resource (8-direction walk-cycle template on an existing sprite) plus the delivered output (a frame per direction with one tag per direction). It is clear enough to separate from siblings like make_4_frame_idle_animation, but it never names or contrasts an alternative such as scaffold_cycle.
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?
Usage is implied rather than stated: it is for a sprite that needs a walk cycle in all eight compass directions, and it operates on an existing sprite. There is no explicit when-to-use / when-not-to-use rule and no routing to scaffold_cycle or add_frame alternatives, so the agent must infer the context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merge_layer_downADestructive
Merge a layer down into the layer directly beneath it.
Refuses rather than doing nothing when there is nothing to merge into. Aseprite's
`MergeDownLayer` is a no-op in five cases, and it raises in none of them, so this used
to report a result indistinguishable from a merge that happened. Measured, naming the
layer stack before and after:
bottom layer of the sprite ['only'] -> ['only']
lowest layer inside a group ['Layer 1', 'grp/a', 'b'] -> unchanged
the layer below is a group ['Layer 1', 'grp', 'a'] -> unchanged
the layer named is a group ['Layer 1', 'grp/a'] -> unchanged
the layer below is a tilemap ['Layer 1', 'tiles', 'px'] -> unchanged
All five returned sprite info describing the stack they had failed to change, which is
the same shape a successful merge returns. Only the ordinary case worked, so an agent
flattening a stack by merging downward in a loop was told the loop had finished when it
had stopped.
Returns `merged_into`, the name of the layer the artwork went into, so the result says
what happened rather than only what the sprite now looks like.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, but the description adds rich behavioral context beyond that: it explains the refusal behavior, lists five no-op cases with measured layer-stack examples, and describes the returned merged_into field. This is exactly the kind of disclosure that helps an agent trust and correctly interpret 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 first sentence front-loads the core operation clearly. The remaining detail is useful for behavioral transparency, though the measured table and extended explanation are somewhat lengthy. Most sentences earn their place, but the definition could be tightened without losing essential 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 destructive tool with no output schema, the description does well by explaining failure modes and the merged_into return value. However, it leaves the two required parameters essentially undocumented despite 0% schema coverage, which is a notable gap for 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 0% for two required parameters (filename and layer). The description discusses the concept of a layer but never explains parameter syntax, accepted layer identifiers, filename format, or any constraints. It does not compensate for the schema's complete lack of parameter documentation.
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, resource, and direction: 'Merge a layer down into the layer directly beneath it.' This is unambiguous and distinguishes the operation from sibling tools like flatten_sprite or duplicate_layer without needing to name them explicitly.
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 when-not guidance by listing five cases where Aseprite's MergeDownLayer is a no-op and explaining that this tool refuses instead. However, it does not explicitly name alternative tools or conditions for choosing them, so it falls short of full when/when-not/alternatives guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mirror_layerB
Mirror one half of a layer onto the other (build symmetric artwork).
Args:
direction: "horizontal" (reflect left<->right) or "vertical" (top<->bottom).
source_side: which half is copied: "first" (left/top) or "second" (right/bottom).
axis: mirror line position (x for horizontal, y for vertical); default = centre.
| Name | Required | Description | Default |
|---|---|---|---|
| axis | No | ||
| frame | No | Default: 1. | |
| layer | Yes | ||
| filename | Yes | ||
| direction | No | Default: "horizontal". | horizontal |
| source_side | No | Default: "first". | first |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and openWorldHint=false, so the agent knows this mutates local state. The description implies the opposite half is overwritten by 'mirror onto the other', but doesn't state what happens to existing pixels on the target side or whether the operation is reversible. Adds some semantic context but not substantially more than the annotations already 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?
One-line summary followed by a compact Args block; the operation is front-loaded and every line earns its place. Slightly verbose in restating default values that the schema already carries.
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 6-parameter mutation tool with no output schema, the description covers the operation and the tricky cosmetic parameters well, but omits frame and the two required params (filename, layer) entirely. Adequate but with a visible gap an agent would want filled.
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 only 50% and the schema provides no value semantics for direction/source_side/axis (just types and defaults). The description supplies the missing meaning: 'horizontal' = left<->right, 'vertical' = top<->bottom, 'first' = left/top, 'second' = right/bottom, and axis = mirror line position. That is real added value over the schema, though filename and layer are undocumented.
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 ('Mirror one half of a layer onto the other') plus the goal (build symmetric artwork), which is clearly distinct from flip_sprite (whole-sprite flip) and draw_symmetric_pixels (pixel drawing). However it never names an alternative explicitly to route the agent, so it stops 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?
There is no explicit when-to-use guidance, no when-not-to-use, and no reference to siblings like flip_sprite or draw_symmetric_pixels. The parenthetical '(build symmetric artwork)' is the only hint of intent, leaving selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
modify_selectionB
Grow, shrink, or outline the current selection.
Args:
op: "expand" grows by `quantity` pixels, "contract" shrinks, "border" replaces
the selection with a band of that width around its edge. A border selection
is how you scope an outline or a contact shadow to where two forms meet.
quantity: How many pixels, at least 1.
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | ||
| filename | Yes | ||
| quantity | No | Default: 1. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only readOnlyHint=false and openWorldHint=false. The description does not state what happens to the prior selection, whether the operation is destructive/irreversible, error conditions (e.g., no active selection), or permission requirements. For a mutating tool, this leaves substantial behavioral gaps.
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?
Front-loaded purpose sentence followed by per-parameter explanation; efficient and organized. The 'Args:' block formatting is slightly verbose but every line carries information.
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 no output schema and thin annotations, the description covers op and quantity adequately but omits filename entirely and says nothing about mutation semantics or post-conditions. It's adequate to invoke the tool but not complete for a mutation on shared state.
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 only 33% (only quantity has a description), so the description must compensate. It does add real meaning: explains that op takes one of three named values and what each does, and that quantity is in pixels with a minimum of 1. It does not document the filename parameter at all, leaving one gap.
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 (grow, shrink, outline) and resource (current selection), and the op semantics are spelled out precisely. It doesn't explicitly differentiate from siblings like select_region, invert_selection, or deselect, but the operation on an existing selection is reasonably distinct.
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 the tool operates on an existing selection ("the current selection") but gives no when-to-use guidance, prerequisites, or alternatives. The note that a border selection 'is how you scope an outline or a contact shadow' hints at usage context without naming or contrasting sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
move_frameA
Move one frame to another position, taking its cels and its duration with it.
Fixing an ordering mistake otherwise means deleting and redrawing. Nothing is copied:
the frame keeps its identity, so linked cels stay linked.
Args:
frame: The frame to move, 1-based.
to: Where it should end up, 1-based, in the numbering *after* the move. Moving
frame 2 to 5 on a six-frame sprite gives 1, 3, 4, 5, 2, 6.
**Tags mark positions, not pictures.** A tag between the two positions keeps its own
range and now covers a different set of drawings. The result names every tag that
overlapped the frames in between, because that is the part worth checking and it is
invisible in the frame count.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | ||
| frame | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint=false annotation by disclosing that nothing is copied, the frame keeps its identity so linked cels stay linked, and that tags mark positions rather than pictures so their ranges shift. It also describes the return behavior (naming every tag that overlapped). This is exactly the mutation-side-effect context annotations cannot 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?
Front-loaded with the core action, then parameter docs, then the tag caveat ordered by importance. Slightly long, and the worked numbering example plus the bolded tag aside push it past the minimum, but each sentence carries information the agent cannot get from the 0%-covered schema.
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 mutating tool with no output schema and no schema descriptions, the description covers the action, the identity/link preservation, the tag-range side effect, and what the result reports. Nothing needed to invoke it 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 description coverage is 0%, yet the description fully compensates: frame and to are documented as 1-based, and crucially 'to' is defined in the post-move numbering with a worked example (moving 2 to 5 on six frames gives 1,3,4,5,2,6). Only filename is left implicit, and that is self-evident.
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 ('Move one frame to another position') and immediately qualifies the scope ('taking its cels and its duration with it'). This cleanly separates it from add_frame, duplicate_frame, remove_frame, and reverse_frames in the sibling list.
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 a clear use context: fixing an ordering mistake that would otherwise require deleting and redrawing. It contrasts against the delete-and-redraw workflow rather than naming a sibling tool, so it stops short of explicit when-to-use-this-vs-that routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
move_layerB
Reorder a layer to a new 1-based stack index (1 = bottom-most).
Note: moves within the layer's current parent group.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | Yes | ||
| filename | Yes | ||
| to_index | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and openWorldHint=false, so the mutation and closed-world nature are known. The description adds useful context about the 1-based indexing and parent-group restriction, but does not cover side effects, error conditions, or required permissions.
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 with no wasted words, and the key behavioral detail (index base) is front-loaded before the parent-group note.
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 mutation with annotations covering safety, the description gives enough to understand the core operation, but it omits parameter semantics for filename and layer, and does not describe what happens on invalid indices or missing layers.
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 0% for all three required parameters. The description explains the meaning of to_index (1-based, bottom-most) but leaves filename and layer entirely undocumented, so it only partially compensates for the missing 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 states a specific verb ('Reorder') and resource ('a layer') and clarifies the target index convention. It is clearly distinct from most siblings, but it does not explicitly differentiate itself from related ordering tools like set_cel_z_index or move_frame.
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 note that the move occurs within the layer's current parent group provides a usage constraint, but there is no explicit guidance on when to use this tool versus alternatives such as set_cel_z_index or set_layer_properties.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
offset_celsA
Move one layer's drawn cel along a path across frames, in one Aseprite launch.
The cel on the first listed frame stays where it is; every later frame is placed
along the way to `(dx, dy)` from it, and the last frame lands exactly there. This is
the same work as one `set_cel_position` per frame, minus the launches and minus
computing the intermediate positions by hand.
Args:
frames: The frames to place, in the order the movement passes through them.
dx, dy: The whole movement, in pixels, from the first frame to the last.
ease: How the movement is *spaced*: `linear`, `ease_in` (starts slow),
`ease_out` (arrives slow), `ease_in_out`, or `gravity` (horizontal speed
stays even while the vertical accelerates, as a thrown object does).
arc_height: Bend the path into an arc this many pixels high at its midpoint,
perpendicular to the straight line between the ends. A jump or a thrown
object needs this; a slide does not.
Easing belongs here, in the spacing, and not in the frame durations. Applying a curve
to both applies it twice, and the result reads as slow motion rather than as weight.
Positions are whole pixels, so it is the running position that gets rounded and not
each step: the leftover fraction carries forward instead of being reintroduced every
frame, which is the difference between spacing that reads as speed and spacing that
reads as a limp. The returned `deltas` are the spacing a viewer actually sees, and
`max_error_px` is how far the furthest frame sits from the ideal curve, which stays
below one pixel.
| Name | Required | Description | Default |
|---|---|---|---|
| dx | No | Default: 0. | |
| dy | No | Default: 0. | |
| ease | No | Default: "linear". | linear |
| layer | Yes | ||
| frames | Yes | ||
| filename | Yes | ||
| arc_height | No | Default: 0.0. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations only declaring readOnlyHint=false and openWorldHint=false, the description carries real load: it discloses that the first frame is anchored, intermediate positions are rounded via carried-forward fractions, and it describes the returned `deltas` and `max_error_px` bound despite there being no output schema. This is genuine behavioral context 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action first, then args, then two short craft notes; each paragraph does work. Slightly verbose in the explanatory asides, but nothing is truly 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 7-param mutation tool with no output schema and partial schema coverage, the description covers the mechanics, the easing/rounding subtleties, and the return values. An agent has everything needed to invoke 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?
Schema coverage is 57% and the description compensates well, defining the frames ordering, the meaning of dx/dy as the total movement, the ease options (linear, ease_in, ease_out, ease_in_out, gravity) that the schema lacks an enum for, and arc_height's perpendicular-midpoint semantics. Only filename and layer are left unexplained in prose.
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 first sentence states a precise verb+resource+scope: moving one layer's cel along a path across frames, and pins it as a single-launch operation. It implicitly distinguishes itself from the sibling set_cel_position by describing itself as the batched equivalent, so an agent can tell them apart without opening schemas.
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 usage context ('the same work as one set_cel_position per frame, minus the launches') and a specific rule for where easing belongs (spacing, not frame durations). However it never explicitly names or excludes the closest siblings, tween_cels and apply_timing_curve, leaving the agent to infer which movement tool to pick.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open_in_editorA
Open a sprite in the Aseprite GUI window (non-blocking) for live viewing.
The window stays open and runs independently of this server. Keep editing the file with the other tools; Aseprite detects the on-disk change and prompts to reload (or reloads automatically, depending on your Aseprite preferences), so you can watch edits land without re-opening.
Returns the launched process id. To stop watching, just close the Aseprite window yourself.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond the annotations: the operation is non-blocking, the window runs independently of the server, on-disk edits are auto-detected and reloaded, the return value is the launched process id, and stopping is done by closing the window. Annotations only give the safety profile, so this is a rich, valuable disclosure.
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, front-loaded sentences: purpose first, then lifecycle behavior, then return value and stopping instructions. Every sentence earns its place and there is no redundant 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 GUI-launching tool with no output schema, the description covers what is needed: non-blocking behavior, process independence, reload semantics, the returned process id, and how to terminate watching. Nothing an agent needs to call it 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 description coverage is 0% and the description never discusses the single 'filename' parameter, its format, or whether paths are relative or absolute. 'Open a sprite' hints that the string should be a sprite file, but this is minimal compensation for a fully undocumented parameter.
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 (open a sprite in the Aseprite GUI window) plus the key distinguishing mode (non-blocking, live viewing). This clearly separates it from headless export/render siblings like render_preview or export_png, so an agent can identify the tool without opening the schema.
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 a clear context for use: live viewing while continuing to edit with other tools, with the reload behavior explained. It does not explicitly name an alternative (e.g., render_preview) or a when-not-to-use condition, so it falls 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.
outline_smartA
Outline a shape in colours drawn from its own ramp, not one flat colour.
`add_outline` paints a single colour all the way round, which reads as a sticker.
Pixel artists vary the outline: darker where the form turns away from the light,
and often dropped entirely on the lit side so the shape breathes.
Args:
ramp: Colours darkest first. Outline pixels come from here.
mode: "colormatched" takes each outline pixel from the adjacent interior colour
shifted `darken_steps` down the ramp. "selective" does the same but leaves
the lit side unoutlined, which needs `light_angle`. "single" uses the
darkest ramp entry all round, the classic look.
darken_steps: How many ramp steps below the neighbouring interior colour.
light_angle: Degrees, required for "selective". 135 is the usual key light.
tolerance: How close an interior pixel must be to a ramp entry to be used as
the source for its outline pixel.
layer: Target layer (default: top layer).
frame: Target frame, 1-based.
The outline is drawn outside the silhouette, into transparency, so it never eats
into the artwork.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Default: "colormatched". | colormatched |
| ramp | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| filename | Yes | ||
| tolerance | No | Default: 32.0. | |
| light_angle | No | ||
| darken_steps | No | Default: 2. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false; the description adds the operationally important fact that the outline is drawn outside the silhouette into transparency 'so it never eats into the artwork' — key for predicting side effects. It still doesn't say whether the operation is destructive to existing outlines or requires an existing ramp/palette on the sprite.
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?
Front-loaded with the purpose, followed by a useful contrast sentence and an Args block; every line carries substance. Slightly long, but no filler that could be cut without losing parameter or behavioral 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 mutation tool with no output schema and thin annotations, the description covers what it does, all parameter meanings, and a key side-effect (draws outside silhouette). Missing only return/error behavior and whether it overwrites existing outlines, which keeps it from a 5.
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 only 50%, and the description fully compensates: it defines ramp ordering ('darkest first'), explains all three mode values with their behavior and the interaction with light_angle, and clarifies darken_steps, light_angle, tolerance, layer default, and frame indexing. This is meaning well 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?
States a specific verb (outline) and a precise, unusual scope: colours drawn from the shape's own ramp rather than one flat colour. It explicitly names and contrasts with the sibling add_outline ('paints a single colour all the way round, which reads as a sticker'), so an agent can distinguish the two without opening either schema.
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?
Strong contextual routing: it explains the pixel-art rationale for varying the outline and when the lit side should be left unoutlined, which effectively tells the agent when to pick each mode. It lacks an explicit 'use this instead of X when Y' statement or prerequisite/permission notes, 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.
paint_tile_pixelsB
Draw individual pixels into a tile's artwork (tile-local coordinates).
pixels: list of {"x", "y", "color"?}; falls back to the shared `color`.
| Name | Required | Description | Default |
|---|---|---|---|
| color | No | ||
| frame | No | Default: 1. | |
| layer | Yes | ||
| pixels | Yes | ||
| filename | Yes | ||
| tile_index | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations supply readOnlyHint=false, so the agent already knows this is a mutating operation, and the description adds the tile-local coordinate semantics plus a color fallback rule. However, it says nothing about preconditions (must the tile already exist?), overwrite behavior, or undo/irreversibility that a paint operation would benefit from.
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, front-loaded segments with no filler; the core purpose leads and the nested pixels detail follows. Efficient and easy to scan, though it leans heavily on terseness rather than 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?
With no output schema and low parameter coverage, the description is only marginally sufficient for a mutating tile-paint operation. It covers the nested pixel payload well but omits preconditions, return behavior, and several parameter meanings.
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 only 17%, so the description carries real weight and does explain the pixels item shape ({x, y, color?}) and the shared color fallback. But filename, layer, tile_index, and frame remain undocumented in both places, leaving a meaningful gap for a 6-parameter tool.
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 individual pixels into a tile's artwork') and adds a scoping qualifier ('tile-local coordinates') that helps distinguish it from the canvas-level draw_pixels sibling. It doesn't explicitly name alternatives, but the tile-scoped framing is clear enough to infer intent.
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?
There is no when-to-use guidance, no statement of prerequisites, and no named alternative (e.g., draw_pixels, set_tile, fill_tile). The tile-local coordinate note implies the use case but the description never tells the agent when this tool is the right choice versus its many drawing/tile siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_asset_specARead-only
Return the ordered build steps for an asset spec without launching Aseprite.
The pure dry-run: each step is ``{tool, args, purpose}`` naming the existing tool that
`build_asset_from_spec` would call. Returns a ``workflow_manifest.v1`` (kind
``asset_spec``) with the steps under `plan` and `dry_run=true`. If the spec is invalid,
returns the validation report instead.
| Name | Required | Description | Default |
|---|---|---|---|
| spec | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and non-open-world behavior, but the description adds significant detail beyond them: no Aseprite launch, pure dry-run execution, each step's shape as {tool, args, purpose}, the returned workflow_manifest.v1 kind with plan and dry_run=true, and the invalid-spec fallback to a validation report.
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 tool's core purpose and dry-run behavior, followed by return and fallback details. It is compact and every sentence adds useful information, though the opening and second sentence overlap slightly in restating the dry-run idea.
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 no output schema, the description usefully explains the returned manifest shape and invalid-spec behavior. However, for a tool whose only parameter is an opaque nested object with 0% schema coverage, the definition remains incomplete because an agent cannot determine how to construct a valid spec from this description alone.
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 0%, and the single nested spec parameter is documented only by the schema type. The description calls it an 'asset spec' but does not describe its accepted fields, expected structure, or format, so it fails to compensate for the absent parameter documentation.
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 gives a specific verb and resource: returning ordered build steps for an asset spec. It explicitly scopes the behavior as a dry-run without launching Aseprite and names build_asset_from_spec as the tool whose calls are being previewed, clearly distinguishing it from build_asset_from_spec.
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 dry-run framing strongly implies the tool is used to preview build steps before invoking build_asset_from_spec, and it notes that invalid specs return a validation report. However, it does not explicitly state when to choose this tool over validate_asset_spec or when not to use it, so usage is implied rather than directly prescribed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
quantize_paletteADestructive
Derive a palette from the art, reduced to at most max_colors entries.
The step between a picture and pixel art. `extract_palette` lists the colours a
sprite already uses but cannot reduce them to a budget, and `set_color_mode` maps art
onto a palette but cannot decide what the palette should be. This asks the editor's
own quantizer for the best `max_colors` colours for this art and installs them, which
is what to do before `set_color_mode("indexed", palette_source="keep")`.
One entry is spent on transparency, at index 0, which is what an indexed sprite needs
there: an opaque colour at the transparent index is in the palette and can never be
drawn.
**`max_colors` is a ceiling and nothing more, and it has a cliff in it.** The
reduction merges whole levels of colour space at a time, so it can stop well short of
what was asked for: measured, four distinct colours with `max_colors=4` came back as
one mid-grey that was the average of all four, while `max_colors=5` on the same art
returned all four exactly. The result therefore reports how many colours the art has,
how many of them the new palette holds exactly, and how many entries can draw at all,
and says in `warnings` when the palette cannot hold the art. Raising `max_colors` by
a little is usually what fixes it.
Refuses an indexed sprite. There a pixel is an offset into the palette rather than a
colour, so replacing the palette changes what every pixel means without touching a
pixel; the error says how to do it in that case.
Past a million pixels the art is not scanned, the palette is still derived, and the
result says the comparison was skipped rather than implying the art is blank.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| max_colors | No | Default: 256. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark it destructive/non-readOnly; the description adds substantial beyond that: it installs the palette, spends index 0 on transparency, refuses indexed sprites with a remediation hint, skips pixel comparison past a million pixels, and surfaces 'warnings' when the palette cannot hold the art. This is rich mutation-behavior disclosure that the annotations alone do not 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?
Front-loaded with purpose and sibling differentiation, then grouped into scannable paragraphs on atomicity, parameter cliffs, refusal, and degradation. Dense and informative, though the transparency-index aside and stylistic phrasing make it longer than strictly necessary.
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 no output schema, the description covers what an agent needs: the mutation performed, refusal conditions, scale limits, and what the result reports (color count, exact-match count, drawable entries, warnings). Nothing essential to calling or interpreting it 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 only 50% ('max_colors' merely says 'Default: 256'), yet the description explains max_colors as a ceiling with a non-obvious quantization cliff, including a concrete measured example (four colors collapsing to one mid-grey at 4, preserved at 5). This meaningfully compensates for the schema gap; 'filename' is self-evident from context.
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+resource ('Derive a palette from the art, reduced to at most max_colors entries') and explicitly distinguishes itself from 'extract_palette' (lists colors, cannot reduce) and 'set_color_mode' (maps onto a palette, cannot decide it). An agent can identify the tool's unique role without opening any schema.
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 explicit when-to-use ('what to do before set_color_mode("indexed", palette_source="keep")'), when-not-to-use (refuses an indexed sprite), failure remedy ('raising max_colors by a little is usually what fixes it'), and the large-image degradation case. Rival tools are named and routed away from.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ramp_betweenA
Build a ramp from its two ends, which is how a ramp is usually decided.
`generate_ramp` grows a ramp outward from one base colour, so reaching a particular
shadow and a particular highlight means guessing at `hue_shift` until the ends land
near what was wanted. This takes the ends directly: pick the cool shadow and the warm
highlight, and the middle is interpolated between them.
Both ends come back **exactly** as given. They were chosen, and a ramp whose endpoints
are approximations of the caller's own colours is not the ramp that was asked for.
Args:
easing: "perceptual" (the default) walks the straight line between the ends in
Oklab, so the middle steps are evenly spaced to the eye and the ramp keeps its
hue. "linear" is the naive sRGB blend, which darkens and greys the middle.
filename, apply: As `generate_ramp`. "append" or "replace" writes the ramp into
that sprite's palette.
Neither mode rotates hue. Interpolating hue between distant colours is what turns a
blue-to-cream ramp magenta in the middle: at that distance both ways round the wheel
are equally short, and neither is the blend anybody wanted.
| Name | Required | Description | Default |
|---|---|---|---|
| apply | No | Default: "none". | none |
| steps | No | Default: 5. | |
| easing | No | Default: "perceptual". | perceptual |
| filename | No | ||
| light_color | Yes | ||
| shadow_color | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false, so the description carries the real burden. It adds meaningful disclosure: endpoints are returned exactly as given, easing choices change the middle's brightness/greyness, neither mode rotates hue, and append/replace writes into the sprite palette. It slightly defers by saying filename/apply behave 'As generate_ramp', and it doesn't clarify what apply='none' (the default) does with the built ramp.
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?
Front-loaded with purpose and the sibling comparison before the Args block, which is the right order. It is slightly verbose — the endpoint-preservation paragraph and the hue-rotation aside both lean on emphasis but each still carries a distinct behavioral point.
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 mutating tool with no output schema and only safety annotations, the description covers purpose, differentiation, key behavior, and most arguments. Remaining gaps are small: the unaddressed 'steps' semantics and the fact that the return value is only implied ('both ends come back').
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 50%, so the description must compensate; it explains easing thoroughly (Oklab 'perceptual' vs naive sRGB 'linear') and partially covers apply ('append'/'replace' writes to palette). However, shadow_color/light_color are only described conceptually and the 'steps' parameter is never addressed anywhere.
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 ('Build a ramp from its two ends') and immediately frames the decision model. It draws an explicit contrast with the sibling generate_ramp, so an agent can distinguish the two without opening either schema.
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?
Names the alternative (generate_ramp) and the condition that selects this tool: when you want to pin both a specific shadow and highlight rather than guessing hue_shift. This is explicit when-to-use guidance against a real sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ramp_from_artA
Recover the ramp an existing sprite is painted with.
`extract_palette` reports the colours a sprite uses as a set. A set is not a ramp: the
shading tools need them ordered dark to light, and an agent asked to add to somebody
else's sprite has no way to get that order today.
The colours are grouped by luminance into `steps` bands, and each band is represented
by the colour most of its pixels use, so every entry is a colour that is actually in
the art and can be matched against it. `coverage` says what share of the drawn pixels
each step covers, which is how to tell a real ramp from one step plus four stragglers.
Says so when the colours are not a ramp: art spanning many hues is several materials
sharing a sprite, and comes back with a warning rather than with a plausible-looking
five colours. Scope the read with `layer` when that happens.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | No | ||
| steps | No | Default: 5. | |
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is unusually rich about behaviour — luminance banding into `steps`, the modal-colour-per-band rule, the `coverage` share, and an explicit warning when the art is not a ramp. However, it frames the whole operation as a read ('Recover', 'scope the read'), while the annotation declares readOnlyHint=false, so the description's read/write framing conflicts with the supplied hint. That mismatch is the main transparency problem; mild credit is retained for the otherwise substantive disclosure.
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 paragraphs, front-loaded with the core action and then rationale. The digression about agents 'adding to somebody else's sprite' is slightly wordy but earns its place by motivating the tool. Nothing is buried.
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?
There is no output schema, so the description carries the return-value burden itself and does so: `steps` bands, per-step `coverage`, and a warning path instead of a plausible-looking five-colour answer. Only the unexplained `frame` parameter and absence of any error/permission detail keep it from a 5.
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 only 50%, so the prose has to compensate. It does meaningfully for `steps` (luminance bands, each represented by its dominant colour) and `layer` (scope the read when a warning fires). `filename` is self-evident; `frame` (default 1) is never explained, which is the only real gap.
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 ('Recover the ramp an existing sprite is painted with') and immediately distinguishes itself from the sibling `extract_palette`, explaining that a colour set is not an ordered ramp. An agent can pick this tool over the palette tools without inspecting either schema.
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 explicit when-to-use (you need colours ordered dark-to-light for the shading tools, or you're adding to someone else's sprite) and names the alternative it supersedes (`extract_palette`, which only reports a set). It also says what to do in the failure case: when the warning about multi-hue art fires, re-run scoped with `layer`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_frameADestructive
Delete a frame (1-based). The sprite must have more than one frame.
`frame` must already exist: an out-of-range number is rejected with the sprite's
valid range rather than clamped to it (which used to delete a different frame).
| Name | Required | Description | Default |
|---|---|---|---|
| frame | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, but the description adds important behavioral detail: frame indexing is 1-based, out-of-range input is rejected with the valid range rather than clamped, and this prevents accidentally deleting a different frame. This goes well beyond the annotation-level safety profile.
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 short, front-loaded with the action, and every sentence earns its place. The parenthetical about the old clamping behavior directly explains the validation behavior rather than adding trivia.
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 low-complexity deletion tool with annotations covering destructiveness, the description covers indexing, preconditions, and error behavior well. Minor gaps remain around the `filename` parameter and any downstream effects on tags or cels, but these are not central for 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 0%, so the description must compensate. It thoroughly explains the `frame` parameter as 1-based, required, and validated against the existing range, though it does not clarify the `filename` parameter beyond the obvious string name.
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 and resource: 'Delete a frame (1-based).' It clearly distinguishes the operation from sibling tools like add_frame, duplicate_frame, and move_frame, and states the key precondition that the sprite must have more than one frame.
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 conditions for use: the sprite must have more than one frame, and the target frame must already exist. It does not explicitly name alternatives, but the deletion context and prerequisites are sufficient to guide correct invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_layerADestructive
Delete a layer (or group, including its children) by name or 1-based index.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description earns credit by extending that: it discloses destructive *scope* — deleting a group also deletes its children — which annotations cannot express. It does not say what happens on a missing/ambiguous layer name, which keeps it from a 5.
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?
A single well-formed sentence with the operation front-loaded, the group/children caveat close behind, and zero filler. Nothing could be trimmed without losing information.
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?
No output schema exists, so the description needn't explain returns, and annotations supply the destructive/safe-read profile. Still, for a destructive two-parameter tool it omits error behavior, index basis, and what 'filename' refers to — enough gaps that an agent may guess on edge cases.
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 0%, so the description must carry the load. It does clarify accepted formats for 'layer' (name or 1-based index), which is meaningful. However, 'filename' is never addressed, and it does not say whether the index counts all layers, top-level layers only, or respects ordering — leaving half the params undocumented.
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 precise verb (Delete) and resource (layer) and immediately resolves the layer-vs-group ambiguity by noting groups and their children go too. That scope distinction separates it from sibling mutations like delete_cel, remove_frame, and remove_tag. It does not explicitly name a sibling, so it lands 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?
There is no when-to-use or when-not-to-use guidance, no note on prerequisites (e.g. whether the layer must exist or be unlocked), and no pointer to alternatives such as clear_layer. The purpose is inferable from the name, but the description itself provides no routing information.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_sliceCDestructive
Delete a slice by name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false, so the write/destructive nature is already known. The description adds nothing beyond 'delete', failing to disclose what deletion entails (permanent? affects file? warnings? error if not found?). With annotations covering the safety profile, the bar is lower, but this still adds no behavioral 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?
Single sentence, front-loaded verb+resource. Very efficient, though perhaps too terse for the scope.
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 destructive mutation tool with 2 undocumented parameters and no output schema, the description is inadequate. It doesn't explain what a slice is, how to reference it, or consequences of deletion.
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 0% and both parameters (name, filename) lack descriptions. The description only implies a 'name' parameter but does not explain what it identifies, how 'filename' relates (which file contains the slice?), or the relationship between them.
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?
Clear verb+resource: deletes a slice by name. Distinct from siblings like add_slice, set_slice, list_slices. But doesn't identify the 'slice' context (e.g., sprite) or how it's identified.
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?
No guidance on when to use this tool versus set_slice, add_slice, or other slice operations. No prerequisites or context beyond the verb.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_stray_pixelsA
Replace pixels that have no neighbour of their own colour with the colour around them.
A stray pixel is one whose eight neighbours are all a different colour. They are what
a shading pass leaves behind at a band boundary, and at any zoom they read as dirt
rather than as texture. `assess_sprite` counts them as `isolated_pixels`; this is what
to do about the count.
Each stray takes the most common colour among its opaque neighbours, so **no new
colour can appear**: the result uses a subset of the colours already there, and art on
a ramp stays on it. Transparent pixels are left alone, so the silhouette does not
change.
A stray with no opaque neighbour at all has no colour to take, so by default it is
skipped: inventing one would be drawing rather than cleaning. That is the right answer
inside the art and the wrong one for the commonest dirt an effects pass leaves, which
is a lone pixel *outside* the art on empty canvas. `erase_isolated` is for that.
Args:
protect: Colours never to replace. A one-pixel eye highlight or a specular dot is
a stray by this definition and is meant to be there, so name its colour. Also
keeps a cluster `erase_isolated` would otherwise erase, if the colour is in it.
erase_isolated: Erase a cluster that stands clear of everything else instead of
skipping it. **Opt-in, because this changes the silhouette**, which is the one
thing the tool otherwise never does: a one-pixel spark, a floating highlight,
the dot of an "i" drawn as its own element and a dither sparser than a
checkerboard are all clusters by this rule and are all meant to be there. What
it erases is reported as `erased`, apart from `replaced`, for the same reason.
min_cluster: How many pixels a detached cluster may have and still count as dirt.
1, the default, is a lone pixel, which is all "isolated" means by itself; 2
catches the two-pixel speck these passes usually leave, where neither pixel is
isolated because each has the other for company. Capped low, and the refusal
names the cap: past a handful of pixels a thing standing clear of the artwork
is a mark somebody drew. Only means anything with `erase_isolated`, and is
refused without it rather than ignored.
Erasure is decided over clusters of **opaque** pixels, connected in all eight
directions, that have nothing but transparency around them. That is what makes it safe
at any `min_cluster`: the artwork is connected to itself, so it is never a cluster, and
only something standing clear of it can go. It is also why the two halves of this tool
barely meet: a cluster touches no other opaque pixel, so nothing else's replacement can
be reading a colour off one. Where they do meet, erasing wins, since recolouring dirt
on its way out is work with no result.
A pixel whose only same-colour neighbour is **diagonal** is part of a dither pattern,
not dirt, and is left alone. `assess_sprite` counts isolation orthogonally, which is
the stricter reading, so a dithered sprite still reports some `isolated_pixels` after
this has run and that count is the dithering rather than anything to fix.
This is not Aseprite's own Despeckle, which is a median filter: that one averages
neighbourhoods, introduces colours that were not in the palette, and on a measured
test left *more* stray pixels than it found. This changes only the pixels that are
strays, and only to colours already next to them.
Returns how many were replaced, so a second call can be skipped when it says 0. With
`erase_isolated` it also returns `erased` and `erased_clusters`, which are absent
otherwise: a count of work nobody asked for reads as a finding.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | No | ||
| protect | No | ||
| filename | Yes | ||
| min_cluster | No | Default: 1. | |
| erase_isolated | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the readOnlyHint=false/openWorldHint=false annotations: it discloses that no new colour can appear, that transparent pixels and the silhouette are untouched by default, that erase_isolated DOES change the silhouette (the one destructive behavior), how clusters are defined (8-connected, opaque, surrounded by transparency), that diagonal-only neighbours are dithering and left alone, and why erased/erased_clusters are reported separately. This is exactly the behavioral context an agent needs for a mutation 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?
Front-loaded and well-organized (opening sentence defines the action, then Args, then edge cases, then return values), but the description is very long — several paragraphs with repeated threading of protect/erase_isolated/min_cluster and multiple parenthetical justifications. It is thorough rather than concise; an agent gets the answer but pays a token cost. Structure is good, size is excessive.
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 mutation tool with no output schema, the description covers operation semantics, destructive boundaries, cluster definitions, sibling routing, defaults, refusal behavior, and return values (replaced, and conditioned erased/erased_clusters). Nothing an agent needs to invoke this correctly appears to be 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 50% (frame and layer have no descriptions; filename none either), so the description must compensate. It richly explains protect, erase_isolated, and min_cluster — their meaning, defaults, interactions, and even refusal conditions ('Capped low, and the refusal names the cap'; 'refused without it rather than ignored'). It does not cover frame/layer/filename, so not a 5, but the semantically tricky parameters are fully illuminated.
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 sentence states a precise verb and operation ('replace pixels that have no neighbour of their own colour with the colour around them'), defines 'stray pixel' operationally, and distinguishes from siblings by naming assess_sprite (which counts them) and erase_isolated (for the outside-canvas case). An agent can tell exactly what this does without opening the schema.
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 it (cleaning dirt left by shading passes at band boundaries), when it's the wrong answer (lone pixels outside the art on empty canvas — use erase_isolated), and the protect/erase_isolated interaction. It also distinguishes itself from a plausible alternative ('This is not Aseprite's own Despeckle'). Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_tagCDestructive
Delete an animation tag by name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare this as destructive and not read-only, so the safety profile is covered. The description adds nothing beyond the action itself — it does not state whether deletion is reversible, what happens to frames or cels associated with the tag, or any permission requirements.
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, front-loaded sentence with no wasted words. It conveys the core action efficiently.
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 destructive mutation tool with two required parameters and no schema descriptions or output schema, the description is insufficient. It omits the meaning of 'filename', any behavioral consequences of deletion, and usage context, leaving significant gaps 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains the 'name' parameter indirectly ('by name'), but the 'filename' parameter is never mentioned or clarified, leaving half the required inputs undocumented.
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 ('Delete') and resource ('animation tag') with a clear scope ('by name'). This is unambiguous on its own, though it does not explicitly distinguish itself from sibling tools like add_tag or set_tag.
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 no when-to-use guidance, no prerequisites, and no alternatives. It only states what the tool does, leaving the agent to infer when deletion is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rename_layerC
Rename a layer.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | Yes | ||
| filename | Yes | ||
| new_name | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose readOnlyHint=false and openWorldHint=false, so the mutation nature is covered structurally. The description adds nothing beyond that: it does not say what happens on name collision, whether the old name is preserved, or what errors can occur. For a mutating tool, this leaves the behavioral profile thin.
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?
A single short sentence with zero waste and the action front-loaded, but the brevity reflects under-specification rather than efficient conciseness.
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 three-parameter mutation tool with no output schema and zero parameter documentation, the description is too thin to be complete. It should at least clarify parameter roles, uniqueness/error behavior, or prerequisites.
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 (filename, layer, new_name) have 0% schema description coverage, so the schema carries no semantics and the description must compensate — but it provides none. The names are largely self-explanatory, which keeps this above a 1, but there is no explanation of format or constraints.
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 (rename) and resource (layer), so the agent knows exactly what operation this performs. However, it offers no differentiation from near-siblings like set_layer_properties or move_layer, which also alter layer metadata.
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 no indication of when to use this tool versus alternatives such as set_layer_properties, nor any preconditions (e.g., layer must exist, name must be unique). Usage is left entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
render_previewARead-only
Render a single frame to a PNG and return it as an image you can view.
Use this to *see* your work. frame is 1-based; scale enlarges small sprites
(default 8x) so individual pixels are visible.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| scale | No | Default: 8. | |
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuine behavioral context beyond that: the 1-based frame indexing and the fact that scale enlarges small sprites so pixels are visible, which tells the agent what output quality to expect.
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, zero filler, and the core action leads immediately ahead of the parameter notes. Every sentence carries information.
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 no output schema, the description correctly states the return is a viewable image, and it covers the two non-obvious parameters. Minor gaps remain (no mention of error behavior for an out-of-range frame or whether a sprite must be loaded), but nothing essential is missing for a low-complexity preview 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 67% and the schema's own descriptions are content-free ('Default: 1.', 'Default: 8.'). The description compensates by explaining that frame is 1-based and that scale magnifies sprites (default 8x), adding real meaning the schema lacks; only filename is left unexplained, though it is self-evident.
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 ('Render a single frame to a PNG') plus the delivery mode ('return it as an image you can view'), which cleanly separates it from the export_* siblings that write files. An agent can identify this as the visual-inspection tool without opening a schema.
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?
'Use this to *see* your work' gives a clear condition for selection, implicitly contrasting with export tools. It stops short of naming an explicit alternative (e.g. export_png) or a when-not case, so it is clear context rather than full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
replace_colorBDestructive
Replace every pixel matching from_color (within tolerance per channel)
with to_color, on the chosen layer + frame.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | No | ||
| filename | Yes | ||
| to_color | Yes | ||
| tolerance | No | Default: 0. | |
| from_color | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, so the write/mutation profile is covered. The description adds the useful scope detail that all matching pixels across the layer/frame are rewritten, but it does not state whether the change is reversible, whether it operates on a saved file or in-memory sprite, or what happens on no matches. Given annotation coverage, a 3 is appropriate.
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?
Single tight sentence with the operation front-loaded and the scope qualifier appended. No waste, though it sacrifices completeness for brevity.
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?
A destructive mutation tool with no output schema, 33% schema coverage, and an undocumented required filename parameter. The description does not cover color format, filename semantics, or the irreversible nature of the pixel rewrite. It should do more given the tool's complexity and destructive annotation.
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 33% – only frame and tolerance have descriptions (defaults). The description names from_color, to_color, tolerance, layer, and frame, giving semantic meaning to the color pair and tolerance that the schema lacks. However, it omits the required filename parameter entirely and gives no format for colors (hex? named? RGBA?), so it only partially compensates for the coverage gap.
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 (Replace) and resource (every pixel matching from_color), plus the exact scope (chosen layer + frame). An agent can distinguish this from select_by_color, fill_area, or recoloring operations without inspecting schemas.
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?
No when-to-use guidance, no mention of alternatives (e.g., select_by_color + fill_area, or how it differs from invert_colors). The description is purely mechanical and does not route the agent to or away from sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resize_canvasADestructive
Resize the canvas WITHOUT scaling the artwork (adds or trims space).
anchor controls where existing content sits in the new canvas:
"top_left" (default) or "center". The new canvas is subject to the same
dimension/area caps as `create_sprite`.
| Name | Required | Description | Default |
|---|---|---|---|
| width | Yes | ||
| anchor | No | Default: "top_left". | top_left |
| height | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, and the description consistently adds real behavioral context: that space is added or trimmed, and that the new canvas is bound by the same dimension/area caps as create_sprite. It does not state effects on existing layers/cels or failure modes, keeping it from a 5.
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, front-loaded sentences; the critical no-scaling constraint and the anchor semantics come first, with no 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?
For a destructive mutation with no output schema this covers the core intent and one constraint, but omits what happens to existing cels/layer positions, whether changes are reversible, and error behavior for missing files — relevant gaps an agent would want.
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 only 25%, so the description must compensate and it does so for anchor, explaining the meaning and values (top_left/center) beyond the schema's bare default note. width, height and filename receive no semantic detail (units, whether the file must exist), so the low-coverage burden is only partly met.
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 (resize) and resource (canvas) and immediately scopes it with 'WITHOUT scaling the artwork (adds or trims space),' which distinguishes it from scale_sprite and crop_sprite without opening any schema.
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 'without scaling' clause gives clear context for when this tool is the right choice versus scaling siblings, and anchor is explained. It stops short of naming the alternative tool or stating when-not (e.g. use scale_sprite to change artwork size).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resize_paletteBDestructive
Resize the palette to size entries (new entries are black).
| Name | Required | Description | Default |
|---|---|---|---|
| size | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, so the risk profile is carried by structured data. The description adds genuinely useful behavior for growth ('new entries are black'), but says nothing about the shrink case — whether colors are truncated, remapped, or an error is raised — which is exactly the destructive scenario the annotation warns about.
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?
One short sentence, front-loaded with the verb and target, with the parenthetical default placed last. Efficient, though the extreme brevity leaves the destructive/shrink behavior unaddressed rather than deliberately trimmed.
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?
This is a destructive mutation with no output schema and zero schema documentation, so the description carries the full burden. It covers growth only; an agent cannot tell what happens to existing palette entries on shrink, whether indices in existing artwork are remapped, or what the call returns.
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 0% for both parameters, so the description must compensate. It explains that `size` is a count of palette entries and how added entries are initialized, which is real value, but `filename` is left entirely unexplained in both schema and description, leaving half the surface undocumented.
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 ('Resize the palette') plus the target dimension (`size` entries), which is enough for an agent to distinguish it from siblings like set_palette, quantize_palette, or sort_palette. It stops short of explicitly contrasting itself with those palette siblings, so it is clear but not fully differentiated.
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?
There is no statement of when to use this versus the many adjacent palette tools (quantize_palette, set_palette, extract_palette, add_palette_color). No prerequisites, no conditions, no exclusions are given; usage must be inferred entirely from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reverse_framesA
Reverse the order of a run of frames, keeping their timing with them.
Reversing a walk to get its mirror, or a grow to get a shrink, is a normal move and
otherwise means re-authoring the whole thing. Whole frames move: every layer's cel
travels together, and each frame keeps its own duration.
Args:
tag: Reverse one tag's frames.
frames: Reverse these frames instead. They must be one unbroken run, because
Aseprite reverses everything between the first and the last: a gapped list
would silently take in the frames in between.
Defaults to the whole sprite when neither is given.
**Tags mark positions, not pictures.** A tag over the reversed frames keeps its own
range and now covers them in their new order, which is usually what was wanted for a
tag that spans the whole run and rarely what was wanted for one that spans part of
it. The result lists every tag that overlapped, so the ones worth revisiting are
named rather than left to be discovered later.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | ||
| frames | No | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only readOnlyHint=false and openWorldHint=false available, the description carries the load and does so well: it discloses that whole frames move as units, that each frame keeps its own duration, that a gapped frame list silently absorbs the frames in between, how tags behave (they mark positions, not pictures), and that the result lists every overlapping tag.
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?
Front-loaded with the core action, then structured into args and a caveat block. Mostly earns its place, though the aside 'otherwise means re-authoring the whole thing' and the tag paragraph are slightly verbose for the payload they carry.
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 mutation tool with no output schema, the description covers input semantics, the gapped-list hazard, tag side effects, and even what the result reports. Remaining gaps are minor: no mention of error conditions or whether changes are undoable.
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 0%, so the description must compensate. It explains what 'tag' targets, what 'frames' means, the unbroken-run constraint and why it matters, and the no-argument default. Only 'filename' is left undocumented, though it is self-evident as the required target.
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?
Starts with a precise verb+resource+scope: 'Reverse the order of a run of frames, keeping their timing with them.' This clearly separates it from siblings like move_frame, duplicate_frame, or flip_sprite, which do not reorder a run while preserving per-frame durations.
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 concrete motivating use cases ('reversing a walk to get its mirror, or a grow to get a shrink') and states the default (whole sprite when neither tag nor frames is given). It does not explicitly name alternative tools for those goals, so it stops short of a 5, but the when-to-use context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rotate_spriteB
Rotate the entire sprite by 90, 180, or 270 degrees (clockwise).
| Name | Required | Description | Default |
|---|---|---|---|
| angle | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, so the mutation nature is already known. The description adds useful scope information ('entire sprite', clockwise direction), but omits whether rotation is in place or saved to a file, and whether 90/270 rotation resizes the canvas.
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?
A single, front-loaded sentence with no waste. Purpose, scope, and accepted values are all in one clause.
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 2-param mutation with no output schema, this covers the essentials. However, it says nothing about whether rotation applies across all cels/frames, whether the canvas is resized for 90/270, or whether results persist — relevant for a write 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 0%, so the description carries the param burden. It usefully constrains 'angle' to 90/180/270 clockwise when the schema only says 'integer' with no enum — a real gap filled. 'filename' is undocumented but self-evident.
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+resource ('Rotate the entire sprite') and adds scope ('entire sprite') plus the accepted angles. This distinguishes it from per-cel operations, though it doesn't explicitly contrast with flip_sprite or offset_cels, which are the nearest 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?
No when-to-use or when-not-to-use guidance. It never mentions flip_sprite, offset_cels, or scale_sprite as alternatives, so the agent must infer that this is the dedicated rotation tool from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_sprite_asADestructive
Save a copy of a sprite under a new path (optionally flattened).
The original file is left untouched. Useful for exporting an editable
.aseprite to another .aseprite, or snapshotting a version.
overwrite: Replace `new_filename` if it already exists (default False = no-clobber).
| Name | Required | Description | Default |
|---|---|---|---|
| flatten | No | Default: false. | |
| filename | Yes | ||
| overwrite | No | Default: false. | |
| new_filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false, and the description adds meaningful context that reduces ambiguity: the original file is never modified, and the destructive path is opt-in via overwrite with a no-clobber default. It does not explain what flatten actually strips or what is returned, and it never reconciles the 'untouched original' claim with the destructive annotation explicitly.
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?
Purpose and the key non-destructive guarantee are front-loaded, and the sentences are short and mostly free of filler. The trailing standalone overwrite note and the hard line wrapping make it slightly less tight than it could be.
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 no output schema and a mutation-ish operation, the description omits what happens on failure and what the result is (e.g., the written path), and leaves flatten undefined. The safety-critical behavior is covered, so it is functional but not complete for a 4-parameter file-writing 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 description coverage is 50% (flatten and overwrite only carry 'Default: false.'), so the description must compensate. It does explain overwrite ('Replace new_filename if it already exists') and gestures at flatten ('optionally flattened'), but never defines what flattening does, and filename/new_filename get no path-format or source-sprite guidance. Adequate but incomplete.
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 ('Save a copy of a sprite under a new path') plus the optional transformation (flatten), and the two use cases (editable .aseprite to another .aseprite, snapshotting a version) separate it from the export_png/export_* siblings that produce different formats.
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 usage context ('exporting an editable .aseprite to another .aseprite, or snapshotting a version'), which tells the agent when this is the right tool versus the format-conversion exporters. There are no explicit when-not rules or named alternatives, 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.
scaffold_cycleA
Scaffold one animation cycle: its frames, a tag per phase, and a shaped timing curve.
`kind` is `walk`, `run`, `idle`, `attack`, `hurt` or `death`, and it settles the four
things a scaffolded animation otherwise gets wrong:
* **The frame count.** walk 8 (6 is the budget option, and 4 only reads as a walk
mirrored on a side view), run 6, idle 4, attack 5, hurt 2, death 6. A count outside
the kind's conventional range is accepted with a warning rather than refused.
* **A tag per phase, named for the pose rather than numbered.** An 8-frame walk gets
`walk_contactL`, `walk_downL`, `walk_passL`, `walk_upL` and the same four for the
right step, plus a `walk` tag over the whole cycle, so the frame you are drawing on
says what it is meant to be.
* **Non-uniform durations from the start**, via `apply_timing_curve`: a cycle holds
its extremes, an attack snaps through the strike, a hurt flashes and then holds the
recovery, a death slows to a stop on a held last pose. Uniform timing is the
placeholder every animation starts with and almost none should keep.
* **Loop versus one-shot.** An attack, a hurt and a death do not wrap, so every tag
they get is written with `repeats=1` instead of being left at 0 ("play forever").
That field is what `validate_loop` reads, so a one-shot tagged as a loop makes the
checker report a duplicated seam frame on an animation that has no seam.
Frames are copies of frame 1, there to draw over. Nothing already in the sprite is
deleted, but Aseprite inserts a copied frame rather than appending it, so on a sprite
that already has several frames the new ones land at the front and the existing ones
end up at the end of the cycle; the manifest warns when that happens. Frames past the
cycle are left untagged and untimed, with a warning saying which.
Args:
kind: walk | run | idle | attack | hurt | death.
frames: Override the kind's default frame count.
base_ms: The duration of a passing frame; every other duration is a multiple of
it. Defaults per kind, because a run passes through its poses faster than an
idle breathes.
Returns a ``workflow_manifest.v1`` manifest (kind ``animation_cycle``) whose
`animation` section lists every phase with the frame, tag, duration, timing role and
repeat count it ended up with, read back off the saved sprite rather than restated
from what was asked for.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | ||
| frames | No | ||
| base_ms | No | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare mutation (readOnlyHint=false) and openWorldHint=false; the description adds substantial behavior: frames are copies of frame 1, nothing existing is deleted, Aseprite inserts copies at the front so existing frames shift to the end, warnings are emitted for odd frame counts and untagged tail frames, and out-of-range counts are accepted with a warning rather than refused.
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?
Front-loaded one-line summary followed by four tight bullets that each cover a distinct behavioral dimension, with args and returns clearly demarcated. It is long, but for a tool that mints frames, tags, timing and loop flags in one call, nearly every sentence carries information an agent needs.
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?
No output schema exists, so the description explains the return value (a workflow_manifest.v1 with kind animation_cycle, listing phase, frame, tag, duration, timing role and repeat count read back off the saved sprite). Combined with the mutation behavior and warning disclosures, an agent has everything needed to invoke and interpret 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 0%, so the description must carry parameter meaning. It does: enumerates the six valid kind values, explains frames as an override of the kind's default count, and explains base_ms as the duration of a passing frame with per-kind defaults. Only filename is undocumented, which is self-evident.
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: 'Scaffold one animation cycle: its frames, a tag per phase, and a shaped timing curve.' This distinguishes it clearly from narrow siblings like add_frame, add_tag, and apply_timing_curve, which each do only one of the three things this tool bundles.
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 strong context on when each kind applies and which defaults are conventional, and explains the interaction with validate_loop (tagging one-shots with repeats=1 so the checker doesn't report a duplicated seam). It doesn't explicitly say when to prefer this over manually calling add_frame/add_tag/apply_timing_curve, so it stops short of full when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scale_spriteADestructive
Scale the whole sprite (artwork included).
Provide either `factor` (e.g. 2.0 to double) OR explicit `width`/`height`.
method: "nearest" (crisp pixels, default) or "bilinear" (smooth).
The scaled canvas is subject to the same dimension/area caps as `create_sprite`.
With `factor` the result depends on the sprite's current size, so that check runs
inside Aseprite and reports the size it would have produced.
| Name | Required | Description | Default |
|---|---|---|---|
| width | No | ||
| factor | No | ||
| height | No | ||
| method | No | Default: "nearest". | nearest |
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With destructiveHint=true already declared, the description adds real context: the scaled canvas is subject to the same dimension/area caps as `create_sprite`, and with `factor` the check runs inside Aseprite and reports the resulting size. That explains a non-obvious failure mode, 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then parameter guidance, then caveats. Four short lines with no repetition, though the closing sentence about the cap check is slightly longer than needed.
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 5-parameter mutation tool with no output schema and sparse schema descriptions, the definition covers purpose, parameter alternatives, method semantics, and the size-cap constraint. It does not describe the return payload other than the size report, but that is minor.
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 only 20% (just `method`), so the description must compensate, and it does: it explains `factor` semantics (2.0 = double), the width/height alternative, mutual exclusivity, and the meaning of 'nearest' vs 'bilinear'. Only the `filename` parameter goes unexplained, which is self-evident.
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+resource ('Scale the whole sprite') and clarifies scope with '(artwork included)', which implicitly separates it from resize_canvas. It doesn't name resize_canvas or flip_sprite/rotate_sprite explicitly, so the differentiation from siblings is left to inference.
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 operating context: use either `factor` OR explicit `width`/`height`, and explains the two `method` choices. It doesn't state when to prefer this over resize_canvas or when scaling is inappropriate, but the invocation conditions are unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
select_by_colorA
Select every pixel of one layer matching a colour, the magic-wand selection.
The usual way to scope an edit to one material: select the armour's base colour and
every later operation touches only the armour. Pair it with `shift_along_ramp` to
shade one material without disturbing its neighbours.
Args:
color: The colour to match.
tolerance: 0 matches exactly. Higher values also catch nearby colours, which is
useful on artwork that was anti-aliased or converted from a photo.
frame: Which frame to sample, 1-based.
layer: Which layer to match on. Defaults to the top layer, which is the layer the
drawing and shading tools also default to, so a selection made here scopes
the call that follows it.
**One layer, not the composite**, and that is deliberate for the same reason
`get_pixels` takes a layer: the tools this selection is for write to one layer, so a
pixel selected on a different one is selected and unreachable. Select on the layer you
are about to edit.
This used to run Aseprite's `MaskByColor` without saying which layer it meant, and the
layer it got was whichever one Aseprite made active on opening the file, which is the
*bottom* one. Measured on an 8x8 sprite with red on the bottom layer and an opaque
blue square over half of it on the layer above: matching red selected all 64 pixels,
including the 32 nothing can see, and matching blue (32 pixels, plainly visible, and
on the layer every drawing tool writes to) selected nothing at all.
Refuses when no pixel matches, rather than reporting a success with no selection. The
old behaviour cleared the sidecar on the way through, so a mistyped colour silently
unscoped every edit that followed it, which is the opposite of what asking for a
selection means. A refusal leaves the previous selection as it was.
| Name | Required | Description | Default |
|---|---|---|---|
| color | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| filename | Yes | ||
| tolerance | No | Default: 0. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false; the description goes well beyond that, disclosing that the tool refuses rather than reporting a false success, that a refusal preserves the previous selection, and the exact layer-defaulting behavior (top layer, matching drawing tools) with an explicit account of the legacy MaskByColor bug. For a state-mutating selection tool this is unusually complete.
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?
Front-loaded and clearly sectioned (summary, Args, rationale), so structure is good, but the two final paragraphs are lengthy historical narration about the old MaskByColor behavior. That detail explains a real behavioral change, yet it is duplicated across the 'One layer, not the composite' paragraph and the bug story, costing more words than the agent needs to invoke the 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?
With no output schema, no annotations covering mutation semantics, and 5 parameters, the description carries most of the burden and does so competently: it covers selection scope, refusal semantics, layer defaults, and side effects on prior selections. It does not say what is returned on success (e.g. whether selection bounds or a count comes back), which is the main remaining 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 coverage is only 40% (frame and tolerance carry just a default; color/filename have none). The description compensates by explaining color, the tolerance scale including the anti-aliasing/photo rationale for higher values, the 1-based frame, and the layer default plus why it matters. Only `filename` is left unmentioned, which is self-evident, so the gap is nearly closed.
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 sentence names a specific verb+resource+scope: 'Select every pixel of one layer matching a colour, the magic-wand selection.' This is immediately distinguishable from siblings like select_region, modify_selection, and invert_selection, and even names the conceptual analogue (magic wand).
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 a concrete use case (scoping an edit to one material) and names a companion tool (`shift_along_ramp`) for the follow-up operation, plus an operational rule ('Select on the layer you are about to edit'). It gives no explicit comparison to select_region or get_selection, so it stops short of full when-not-to-use routing, but the 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.
select_regionA
Select a region, so later edits only affect that area.
The selection persists until `deselect`, and every pixel-writing tool honours it.
There is no per-call override: to draw outside the selection, clear it first. Tools
that wrote fewer pixels than asked report `selection_applied` and
`pixels_outside_selection`, so a forgotten selection shows up in the result rather
than as a mysteriously incomplete edit.
Args:
shape: "rect", "ellipse" (both use x/y/width/height) or "polygon" (uses points).
x, y, width, height: The region. width/height default to the rest of the canvas.
points: For "polygon", a list of {"x": int, "y": int}, at least 3.
mode: "replace" the selection, or "add"/"subtract"/"intersect" with the current
one. Building a selection from several shapes is how you scope an edit to
an awkward area, such as everything except a character's eyes.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | Default: 0. | |
| y | No | Default: 0. | |
| mode | No | Default: "replace". | replace |
| shape | No | Default: "rect". | rect |
| width | No | ||
| height | No | ||
| points | No | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false, so the description carries the real burden and delivers: selection persistence, cross-tool effect on every pixel-writing tool, no per-call override, and self-reporting via selection_applied/pixels_outside_selection so a stale selection is visible rather than silent. This is exactly the behavioral context annotations cannot express.
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?
Front-loaded with purpose and persistence semantics, then a structured Args block. Every sentence adds information (override behavior, failure reporting, composition motivation); 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?
No output schema exists, and the description compensates by naming the result fields (selection_applied, pixels_outside_selection) returned by affected tools. Combined with full coverage of selection lifecycle and modes, an agent has everything needed to call and interpret 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?
Schema coverage is 50% and its descriptions are trivial ('Default: 0'), so the description does the heavy lifting: it maps shape values to their coordinate requirements ('polygon' uses points), explains that width/height default to the rest of the canvas, and defines what mode does. The required 'filename' parameter is never mentioned, a minor gap.
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 ('Select a region') plus its scope consequence ('so later edits only affect that area'), which cleanly separates it from siblings like modify_selection, invert_selection, and deselect. An agent can identify the tool without opening the schema.
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 persistence ('until deselect'), the absence of a per-call override, and the corrective action ('clear it first'). It also names the mode values and describes the composition workflow (add/subtract/intersect) with a concrete motivating example.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_all_frame_durationsA
Set every frame's duration in milliseconds (uniform animation speed).
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| duration_ms | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations (readOnlyHint=false, openWorldHint=false) already tell the agent this is a local mutation, so the bar is lower. The description adds the semantic rationale ('uniform animation speed'), but omits that it overwrites all existing per-frame delays and does not say whether the change is persisted to disk or only to the in-memory sprite.
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?
A single front-loaded sentence with the scope, unit, and intended effect, and no filler. Nothing can be trimmed without losing information.
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-param mutation tool with no output schema this is minimally sufficient, but the filename argument is undocumented, the overwrite semantics are unstated, and the relationship to the single-frame sibling is left implicit.
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 0% and the schema only types duration_ms as an integer, so the description's disclosure of the millisecond unit is genuinely additive. The required 'filename' parameter, however, has no explanation in either the schema or the description, leaving the compensation incomplete.
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 (set) and resource (every frame's duration) with an explicit scope qualifier ('every frame') that implicitly distinguishes it from the sibling set_frame_duration. However, it never names that sibling, so the differentiation relies on the agent noticing the singular/plural contrast on its own.
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?
Usage is only implied: the 'every frame' wording suggests bulk application versus the single-frame variant, but there is no explicit guidance on when to prefer this over set_frame_duration or whether it belongs to a specific animation workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_cel_opacityC
Set a cel's opacity (0-255).
| Name | Required | Description | Default |
|---|---|---|---|
| frame | Yes | ||
| layer | Yes | ||
| opacity | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare it's a non-read-only, closed-world mutation. The description adds the 0-255 range constraint, which is useful behavioral context beyond annotations, but doesn't explain effects on linked cels, clamping, or persistence.
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?
One front-loaded sentence with no wasted words. For a simple setter, this is concise, though it could arguably afford a bit more detail on parameters without becoming verbose.
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 4-parameter mutation with no schema descriptions and no output schema, the description is far too sparse. It identifies the operation and one parameter range but leaves the agent without necessary context on how to identify the target cel or interpret the other parameters.
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 0%, so the description must compensate. It only clarifies the 'opacity' parameter's range (0-255), leaving filename, layer, and frame completely undocumented—the agent has no semantic guidance for three of four required parameters.
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 ('Set') and resource ('cel's opacity'), clearly distinguishing it from sibling setters like set_cel_position or set_cel_z_index by naming the property. It stops short of 5 because it doesn't explicitly reference alternatives or scope (e.g., which cel).
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?
No guidance on when to use this tool versus alternatives such as set_properties or set_cel_position, nor any prerequisites. The simple setter nature implies usage, but no explicit context is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_cel_positionC
Move a cel's image to position (x, y) within the canvas.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | ||
| y | Yes | ||
| frame | Yes | ||
| layer | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations establish this is a write operation (readOnlyHint=false) in a closed world, so the safety profile is partly covered. Beyond that the description says nothing: it does not reveal whether the position is relative to the layer, canvas, or tilemap origin, what happens to pixels pushed past the canvas edge, or whether linked cels are affected.
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?
A single tight sentence with the action front-loaded and no filler. It is efficient, though it is efficient partly because it omits necessary content rather than by trimming 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?
This is a mutation tool with no output schema, 0% parameter documentation, and only two terse annotations. The description leaves the coordinate frame, cel identification (filename/layer/frame), and out-of-bounds behavior entirely unaddressed, which is inadequate for a 5-required-parameter write 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 0% across 5 parameters, so the description carries the full burden. It only surfaces x and y (implicitly, as the positional pair) and says nothing about filename, layer, or frame, leaving three of five required parameters with no semantic explanation anywhere.
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 ('Move') and resource ("a cel's image") with a clear positional target, so the core action is unambiguous. It does not differentiate itself from neighboring tools such as offset_cels, move_layer, or set_cel_z_index, which all involve repositioning, so an agent gets no help disambiguating.
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?
There is no when-to-use guidance, no mention of prerequisites (a cel must already exist given filename/layer/frame), and no named alternative. The reader must infer from the name alone that this is a direct absolute-position setter rather than a relative offset.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_cel_z_indexA
Reorder one cel against the other cels in its frame, without moving any layer.
This is the fix for "the arm is in front of the body this frame and behind it the
next". The alternatives are to restructure the layer stack, which changes every other
frame too, or to duplicate the arm onto a second layer and hide one of them per
frame; a z-index is per cel, so it says exactly what it means and only where it
applies.
`z` is an offset, not a position: 0 (the default for every cel) means "wherever this
cel's layer sits in the stack", a positive number moves the cel towards the front and
a negative one towards the back. A cel draws at its layer's stack position plus `z`,
and when two cels land on the same number the one with the larger `z` draws in front.
So `z=1` on a cel one layer below another is enough to put it in front of that one.
The ordering is scoped to the layer's siblings: a layer inside a group is ordered
against that group's other layers, and the group as a whole keeps its place. Returns
`order`, the frame's competing cels back to front, which is the part a caller cannot
see for themselves.
A z-index is per cel even when the cel is linked: two frames sharing one image share
their opacity and their properties, and do not share this. Verified against the
editor, because the opposite is the reasonable guess.
`z` must be between -32768 and 32767. The editor accepts a larger number in memory
and then stores it in a 16-bit field, so saving and reopening would silently turn it
into a different one, usually of the opposite sign.
| Name | Required | Description | Default |
|---|---|---|---|
| z | Yes | ||
| frame | Yes | ||
| layer | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark it as a mutation (readOnlyHint=false). The description adds crucial behavioral depth: z is an offset not a position, default 0, positive/negative movement, tie-breaking rule, scoping to sibling layers, per-cel behavior even when linked, the exact numeric range -32768 to 32767, and why larger values cause silent corruption on save. This is far beyond structured fields.
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 alternatives, then systematically explains z semantics, scoping, and edge cases. Every sentence adds value, though the overall length is substantial; it could be trimmed slightly without losing critical information.
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 mutation tool with four required parameters, no output schema, and minimal annotations, the description covers the tool's behavior, constraints, return value (`order`), and scoping rules in full. An agent has everything needed to invoke 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?
Schema description coverage is 0%, so the description must carry the full load. It thoroughly explains the `z` parameter (meaning, range, tie-breaking) but leaves `filename`, `layer`, and `frame` without explicit definition, relying on the reader's inference from context. This is adequate for an expert but leaves clear gaps.
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: 'Reorder one cel against the other cels in its frame, without moving any layer.' It distinguishes from sibling tools by explaining the exact problem it solves and why alternative approaches (restructuring layers, duplicating cels) are inferior.
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 ('the fix for the arm in front of the body this frame and behind it the next') and names the concrete alternatives (restructure layer stack, duplicate layer) along with their downsides. The agent can confidently select this tool over the alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_color_modeADestructive
Convert a sprite between colour modes ("rgb", "indexed", "gray").
Converting **to indexed** builds the palette from the sprite's own colours first,
which is what the editor does and what makes the art survive. Mapping art against
whatever palette the sprite happened to carry is how this tool used to empty a
sprite: a saved RGB sprite carries a single transparent entry, so every pixel
resolved to it and the whole image became transparent while the call reported ok.
Args:
color_mode: "rgb", "indexed", or "gray".
dithering: "none" (default), "ordered", or "old". How a colour between two
palette entries is resolved. Indexed conversions only.
palette_source: "from_art" (default) quantizes the sprite's colours into a new
palette and maps onto that, so flat colours convert exactly. "keep" maps
against the palette the sprite already has, for when you loaded or built one
deliberately; snapping the art to that palette is the point, so expect
colours to shift, and expect two art colours to merge where the palette has
only one entry near them. Indexed conversions only; the other modes have no
palette to choose.
**Refuses** a conversion to indexed that would make drawn pixels disappear, naming
how many, and leaves the file untouched when it does. Losing colour accuracy is what
indexed mode is for and is allowed; losing pixels is not recoverable and is the one
thing a mode change must never do quietly. `set_palette` or `add_palette_color` fix a
palette that has nothing to draw with.
That check counts every pixel of every frame, twice. Past `MAX_VERIFY_PIXELS` the
conversion still runs and reports `verified: false` with the reason, rather than
being refused: a capability that declines to work on a large sheet because the check
is unaffordable is worse than one that works and says what it did not check.
`diff_sprites` against a copy taken beforehand answers the same question by hand.
Returns the sprite's structured info, plus `drawn_pixels` and `verified` (whether
that count was actually compared across the conversion) and the `palette_source`
used, for indexed targets.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| dithering | No | Default: "none". | none |
| color_mode | Yes | ||
| palette_source | No | Default: "from_art". | from_art |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true, and the description goes well beyond that: it documents the refusal precondition (indexed conversions that would erase drawn pixels, with a count reported and the file left untouched), the large-sheet fallback where MAX_VERIFY_PIXELS is exceeded and the call proceeds with verified:false, and the historical failure mode that motivates the check. This is exactly the kind of behavioral context annotations cannot carry.
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?
It is front-loaded with the conversion itself and then uses a clear Args block, so structure is good. It runs long, however, and the aside about how the tool 'used to empty a sprite' plus the doubled pixel-count detail could be trimmed without losing the operational guarantee.
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 no output schema present, the description still specifies the return payload (structured sprite info plus drawn_pixels, verified, palette_source for indexed targets) and covers the refusal path, the unverified-large-sheet path, and the palette_source default. Nothing an agent needs to call it safely 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 50% - filename and color_mode have no schema descriptions and dithering/palette_source only carry a default string. The description compensates fully, documenting each value of color_mode, the three dithering behaviours and their indexed-only scope, and the two palette_source strategies including when colours will shift or merge.
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 first sentence gives a specific verb (Convert) and resource (a sprite between colour modes) and enumerates the three target modes, which pins the operation precisely against palette-oriented siblings like set_palette, quantize_palette and cycle_palette. An agent can tell what changes and what the input domain is without opening the schema.
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 real guidance on option selection - dithering applies to indexed only, palette_source=from_art vs keep with the consequences of each - and routes agents to set_palette/add_palette_color when a palette is unusable and to diff_sprites for manual verification. It never states explicitly when to choose this tool over a sibling conversion/quantization tool, so it stops short of full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_frame_durationA
Set a single frame's duration in milliseconds (1-based frame).
`frame` must already exist: an out-of-range number is rejected with the sprite's
valid range rather than clamped to it (which used to report the requested number
while changing frame 1).
| Name | Required | Description | Default |
|---|---|---|---|
| frame | Yes | ||
| filename | Yes | ||
| duration_ms | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say it is not read-only and not open-world. The description adds meaningful behavioral detail: out-of-range frames are rejected with the valid range rather than clamped, and the historical bug is called out so the agent understands the current contract.
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 short, front-loads the operation, and keeps the key precondition in the first sentence. The parenthetical historical note is useful but slightly more detail than strictly needed for selection.
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 three-parameter mutation tool with no output schema and minimal annotations, the description covers indexing, units, existence constraint, and error behavior. It is nearly complete, though filename semantics and whether changes are persisted remain implicit.
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 0%, so the description must compensate. It explains that duration is in milliseconds and that frame is 1-based and must already exist, but it says nothing about the filename parameter, leaving one of three required parameters semantically undocumented.
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 verb and resource: set a single frame's duration, with units and indexing. The word 'single' distinguishes it from the sibling set_all_frame_durations without requiring the schema to be opened.
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 an important precondition ('frame' must already exist) and error behavior, but does not explicitly say when to choose this tool over set_all_frame_durations or other frame-duration tools. Usage is implied by the single-frame scope rather than stated as routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_layer_propertiesC
Update one or more layer properties. Only the arguments you pass are changed.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| layer | Yes | ||
| opacity | No | ||
| visible | No | ||
| editable | No | ||
| filename | Yes | ||
| blend_mode | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, so the agent knows this is a mutation, and the description usefully adds that unset properties are left untouched. It is silent on permissions, behavior when the layer or filename is invalid, and whether failing mid-update rolls back, which matters for a multi-field writer.
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 with zero padding, and the primary action is front-loaded. It is efficient but verges on under-specification rather than dense information delivery.
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 7-parameter write tool with no output schema and only minimal annotations, the description is far too thin. An agent still cannot tell which properties are settable, what values blend_mode accepts, or what happens on partial failure, so key operational knowledge 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 description coverage is 0% across 7 parameters, and the description contributes no meaning for any of them. It never maps the verb 'properties' to the fields name, opacity, visible, editable, or blend_mode, nor explains that filename/layer are the addressing keys, leaving the agent to guess from bare 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?
States a specific verb and resource ('Update one or more layer properties'), so the core action is unambiguous. However, it fails to distinguish itself from overlapping siblings like rename_layer and move_layer, which also mutate per-layer attributes, and it never clarifies which properties are in 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?
The second sentence ('Only the arguments you pass are changed') describes partial-update semantics rather than when to choose this tool. There is no guidance on when to use it versus rename_layer, move_layer, or set_properties, nor any prerequisites such as the file needing to be open or the layer existing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_paletteCDestructive
Replace the entire palette with the given list of colours.
colors: list of colour strings, e.g. ["#000000", "#ffffff", "255,0,0"].
| Name | Required | Description | Default |
|---|---|---|---|
| colors | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, and the description's 'Replace the entire palette' largely restates that rather than adding context. It says nothing about what 'filename' scopes to (which sprite/palette file), whether the previous palette is recoverable, or what happens to palette indices already in use.
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 lines, front-loaded with the destructive action and then the one non-obvious parameter format. The trailing fragment 'colors: ...' is slightly terse but not wasteful.
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 destructive, file-scoped mutation with no output schema, the description is minimally adequate: it conveys the overwrite semantics and the colour format. It omits what 'filename' refers to and any recoverability/permission note, which matters given destructiveHint=true.
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 0%, so the description must compensate. It does document the 'colors' parameter with concrete format examples (hex and 'r,g,b' strings), which is genuinely useful, but the required 'filename' parameter is never explained, leaving half the inputs ambiguous.
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 ('Replace') plus resource ('palette') and scope ('entire'), which distinguishes it from partial mutators like add_palette_color or set_palette_color. It does not explicitly name those siblings, but the scoping word 'entire' carries the 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?
No when-to-use guidance and no mention of alternatives, despite a dense sibling cluster (set_palette_color, add_palette_color, resize_palette, load_palette, quantize_palette). The agent is left to infer that this is the whole-palette overwrite variant.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_palette_colorA
Set a single palette entry by index (0-based). Grows the palette if needed.
The index is bounded by the palette ceiling: the Lua below resizes the palette to
`index + 1`, so the index *is* a palette size.
| Name | Required | Description | Default |
|---|---|---|---|
| color | Yes | ||
| index | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false, so the description carries real weight by disclosing that the palette grows if the index exceeds its size — a mutation side-effect the agent would otherwise not anticipate. It does not explain return values, error behavior, or whether color must be a specific format, which keeps it from a 5.
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?
Front-loaded with the core action and two sentences of genuinely relevant constraint, with no filler. The dangling reference to 'the Lua below' is a minor structural flaw since no such code is present in the visible definition.
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 no output schema and thin annotations, the description covers the mutation and index semantics but leaves the color encoding and filename target unspecified. It is adequate to call the tool safely but not 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?
Schema coverage is 0%, so the description must compensate for three parameters. It usefully clarifies that index is 0-based and effectively defines the resulting palette size, but it says nothing about the color string format or the filename parameter's role, leaving meaningful gaps.
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+resource (set a single palette entry) and scope (by index, one entry at a time), which distinguishes it from bulk siblings like set_palette and resize_palette. It never names an alternative explicitly, so it falls short of a 5 but the operation is 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?
Usage is only implied: an agent can infer this is for writing one entry rather than the whole palette or appending a new one, but the description never states when to prefer it over add_palette_color, set_palette, or resize_palette. The growth note hints at a use case but no explicit routing guidance is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_propertiesADestructive
Store a custom property on an object inside the sprite, in the .aseprite file.
This is where game metadata belongs: a hitbox on a slice, an anchor point on a layer,
"this frame deals damage" on a cel, a surface kind on a tile. It travels with the art
instead of living in a sidecar file that the next edit desynchronises, and the editor
shows it and keeps it.
Args:
target: Which kind of object: "sprite", "layer", "cel", "tag", "slice" or "tile".
key: The property name, e.g. "hitbox".
value: What to store. Text by default, so value="7" stores the two-character
string "7". Pass as_json=True to store a number, a boolean or a structure:
then "7" stores the number 7, "true" stores a boolean, and
'{"x": 8, "y": 15}' stores a table. A value that begins like a JSON object or
array is read as JSON either way, since there is no other reading of one.
layer: The layer's name. Needed for target "layer", "cel" and "tile".
frame: 1-based frame number, for target "cel" (default: the first frame).
name: The tag's or slice's name, for target "tag" and "slice".
tile: An index into the layer's tileset, for target "tile". 0 is the empty tile.
namespace: Keep the property in a named group rather than in the unnamed one the
editor's own property panel uses. Two tools can then both use the key
"anchor" without colliding. Namespaces cannot be listed back, so a caller has
to know the name to read one again.
as_json: Parse `value` as JSON before storing it (see `value`).
delete: Remove the property instead of setting it. `value` is then ignored, and
removing a key that was not there is not an error.
A selector the target does not use is refused rather than ignored, because the
property would otherwise land on a different object than the one that was named.
Properties live on the record that linked cels share, so setting one on a held pose
sets it on every frame of the hold. The result says which frames those were.
Returns the whole property group after the write, so the stored value is visible as
the type it was stored as.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | ||
| name | No | ||
| tile | No | ||
| frame | No | ||
| layer | No | ||
| value | No | ||
| delete | No | Default: false. | |
| target | Yes | ||
| as_json | No | Default: false. | |
| filename | Yes | ||
| namespace | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the annotations: discloses that unused selectors are refused rather than ignored, that properties live on shared cel records so a held pose sets every frame, that namespaces prevent key collisions but cannot be listed back, and that deleting a nonexistent key is not an error. These are precisely the behaviors an agent cannot derive from destructiveHint=true.
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?
Front-loaded with the purpose before the Args block, and every sentence carries information. It is long, but the length is justified by the 11-parameter surface and the storage-type subtleties; little could be cut 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?
Despite no output schema, it describes the return (the whole property group after the write, so the stored value is visible as the type it was stored as) and notes the result identifies which frames were affected. Complete for a destructive multi-parameter mutation 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 only 18%, so the description carries the load, and it does: every meaningful parameter (target, key, value, layer, frame, name, tile, namespace, as_json, delete) is explained with types and defaults. The value/as_json interaction ("7" vs 7, JSON-shaped strings parsed either way) is documented far beyond what the schema states.
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 (store) and resource (custom property on an object in the .aseprite file) and immediately scopes the intent with a concrete example list (hitbox on a slice, anchor on a layer). An agent can distinguish this from the sibling get_properties, which is the read counterpart.
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 context for when this is the right tool (game metadata that should travel with the art rather than a sidecar file) and covers the delete case explicitly. It never names the sibling get_properties as the read path, so an agent must infer the read/write split.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_sliceB
Update an existing slice's bounds, name, colour, or data.
data: a string is stored as it arrives; a dict or list is JSON-encoded, so structured
user-data round-trips through export_slice_metadata.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | ||
| y | No | ||
| data | No | ||
| name | Yes | ||
| color | No | ||
| width | No | ||
| height | No | ||
| filename | Yes | ||
| new_name | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, confirming this is a mutation on closed local data. The description adds useful detail on data encoding behavior (strings pass through, dicts/lists are JSON-encoded and round-trip via export_slice_metadata) which goes beyond annotations. However, it doesn't say whether undefined fields are left alone or cleared, whether the name change via new_name vs name behaves how, or what happens if the slice doesn't exist.
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 paragraphs; the first sentence front-loads purpose and the second adds targeted detail on the data param. No wasted words, though the encoding note could be trimmed slightly.
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?
9 parameters with 0% schema coverage, no output schema, no annotations beyond safety flags, and description only covers one parameter's behavior. For a 9-param mutation tool the description leaves substantial gaps — how bounds interact, what new_name vs name does, and error behavior are all unstated.
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 0% — no parameter is documented in the schema. The description explains data encoding semantics for the 'data' param but says nothing about x/y/width/height/fileName semantic constraints, nor the difference between 'name' (required) and 'new_name'. Partial compensation at 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?
Clearly states 'Update an existing slice's bounds, name, colour, or data' — specific verb (update) plus resource (slice) plus enumerable fields. Distinguishes itself from siblings add_slice/remove_slice/list_slices, though it doesn't explicitly name them.
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?
No guidance about when to use this vs add_slice or remove_slice, no mention of prerequisites like whether the slice must already exist, and no exclusions. The 'existing' implies the slice must pre-exist but this is only weakly inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_tagA
Update an existing tag. Only the arguments you pass are changed.
Note: changing from_frame/to_frame recreates the tag in place to update its
range reliably across Aseprite versions. A frame that does not exist is rejected
with the sprite's valid range rather than clamped into it.
`repeats` is how many times the tag plays, with 0 meaning forever. It survives the
recreate above along with the name, direction and colour.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| color | No | ||
| repeats | No | ||
| filename | Yes | ||
| new_name | No | ||
| to_frame | No | ||
| direction | No | ||
| from_frame | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say readOnlyHint=false, so the description carries the disclosure burden and does it well: it warns that changing from_frame/to_frame recreates the tag in place, that an out-of-range frame is rejected with the sprite's valid range rather than clamped, that repeats=0 means forever, and that name/direction/colour survive the recreate. These are non-obvious, operationally important behaviours an agent could not infer.
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?
Purpose is front-loaded in the first sentence, followed by a scoped note block; every sentence carries information. Slightly over-fragmented with the mid-sentence line breaks and the parenthetical aside about Aseprite versions, but no 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?
No output schema and minimal annotations mean the description is the main source of truth. It covers the tricky behavioural cases well, but for an 8-parameter, 0%-coverage mutation tool it leaves direction (an enum-less string with no hint of forward/reverse/pingpong), colour format, and the identifier-vs-rename roles of name/new_name undocumented.
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 0% across 8 parameters, so the description must compensate. It adds real meaning for repeats (0 = forever) and for from_frame/to_frame (recreation and validation), and generalises partial-update semantics, but it says nothing about the name vs new_name distinction, the colour format, or the legal values for direction.
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?
"Update an existing tag" is a specific verb+resource and clearly scopes it to mutation of a tag that already exists, distinguishing it in spirit from add_tag and remove_tag in the sibling list. It does not name those siblings explicitly, so it falls 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?
"Only the arguments you pass are changed" implies partial-update usage and the phrase "Update an existing tag" implies it is not the tool for creating a tag, but no alternative (add_tag) is named and no conditions or exclusions are given. Usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_tileC
Place a tile (by tileset index, 0 = empty) at grid cell (column, row).
| Name | Required | Description | Default |
|---|---|---|---|
| row | Yes | ||
| frame | No | Default: 1. | |
| layer | Yes | ||
| column | Yes | ||
| filename | Yes | ||
| tile_index | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and openWorldHint=false, so the agent knows this mutates local state. The description adds only the "0 = empty" clearing behavior; it says nothing about whether the tileset/file must already exist, whether the change persists, or error 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?
A single tight sentence with the key index semantics parenthesized inline; nothing is wasted and the operation is front-loaded. It is efficient, though very sparse for a 5-required-parameter mutation.
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 6-parameter mutation tool with no output schema and 17% schema coverage, the definition is too thin: filename/layer semantics, save behavior, and failure modes are all unaddressed, so an agent cannot reliably call it without guessing.
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 only 17%, so the description carries heavy burden. It usefully explains tile_index (tileset index, 0 = empty) and maps column/row to a grid cell, but leaves the required filename, layer, and the optional frame parameter completely unexplained.
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+resource ("Place a tile") and a precise target ("grid cell (column, row)"), and clarifies tile_index semantics ("0 = empty"). However, it does not distinguish itself from the cluster of highly similar siblings (add_tile, set_tiles, fill_tile, paint_tile_pixels), leaving the agent to infer the difference.
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?
There is no when-to-use guidance, no prerequisites, and no mention of the near-identical tile siblings. With add_tile, set_tiles, fill_tile and fill_tilemap all in scope, the absence of any routing guidance is a clear gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_tilesC
Place many tiles at once. tiles: list of {"column", "row", "index"}.
| Name | Required | Description | Default |
|---|---|---|---|
| frame | No | Default: 1. | |
| layer | Yes | ||
| tiles | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, so the write nature is already covered. The description adds nothing beyond that: it doesn't say whether existing tiles are overwritten, whether 'index' refers to a tileset index or -1 for empty, or whether filename/layer must pre-exist.
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, front-loaded with the action and followed by the payload shape, with no filler. It is lean almost to the point of being terse, 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?
A mutation tool on a tilemap layer with four parameters, 25% schema coverage, no output schema, and dense tile siblings — the description should do much more. It omits what the operation mutates, overwrite behavior, and how it differs from the other tile 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 coverage is only 25% (only 'frame' is documented), so the description must compensate. It partially does by disclosing the tile object shape {column, row, index}, which is genuinely useful since the schema types 'tiles' items as an opaque object. But filename, layer, and frame semantics remain unexplained.
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 ('Place many tiles at once'), and the plural quantity implicitly distinguishes it from the singular set_tile. However, it never names or contrasts with the nearby siblings set_tile, add_tile, fill_tile, or fill_tilemap, leaving the agent to infer which tile-writing tool applies.
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?
There is no when-to-use guidance, no exclusions, and no alternatives named, despite four tile-manipulation siblings (set_tile, add_tile, fill_tile, fill_tilemap) whose boundaries an agent needs resolved. The agent gets no signal about batch-vs-single or paint-vs-place selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_transparent_colorB
Set which palette index is treated as transparent (indexed sprites only).
| Name | Required | Description | Default |
|---|---|---|---|
| index | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false (mutation) and openWorldHint=false, consistent with the 'Set' wording, so no contradiction. The description adds the meaningful constraint that this applies only to indexed sprites, but does not explain what happens to the previously transparent index, validation of the index, or reversibility.
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?
A single sentence with the scope qualifier front-loaded and zero filler; every element 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 narrow mutation tool with no output schema, the scope constraint plus annotation-driven safety profile is minimally sufficient. Missing prerequisites (indexed mode check) and error behavior keep it from being fully 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?
With 0% schema description coverage, the description carries the full burden. It clarifies that 'index' refers to a palette index, but gives no detail on the 'filename' parameter or valid index ranges, leaving half the parameters effectively undocumented.
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+resource: sets which palette index is treated as transparent, and clarifies scope with '(indexed sprites only)'. An agent can distinguish it from color-editing siblings like set_palette_color, though no sibling is named explicitly.
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 parenthetical 'indexed sprites only' implies a precondition (sprite must be in indexed color mode), giving implied usage context. However, it offers no when-to-use framing, no alternatives, and no explanation of behavior on non-indexed sprites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shade_region_by_lightA
Shade a flat region as a lit form, using a ramp and a light direction.
Turns a flat fill into a shaded one: an asymmetric terminator, a darker core away
from the light, and optional rim light. Every output pixel comes from `ramp`.
Scope this to one material. Shading a whole layer flattens materials together: a
sword shaded in one pass turns steel, brass and leather into the same colours, where
three scoped calls keep all three. Scope it by passing `base_color`, by making a
selection first (`select_by_color` is the usual way), or both.
What it cannot do: a distance field measures depth inside a silhouette, so it cannot
invent form boundaries that are not in the outline. An overlapping head and torso
drawn as one flat shape become one mass. Shade them as separate regions.
Args:
ramp: Colours darkest first, as from `generate_ramp`. Output uses only these.
base_color: Only shade pixels near this colour. Defaults to every opaque pixel
in scope, which is usually what you want once a selection is active.
light_angle: Degrees. 0 is from the right, 90 from above, 135 from the upper
left, which is the conventional pixel-art key light.
light_z: How much the light comes from the viewer, 0 to 1. Higher flattens the
terminator and lights more of the form.
bulge: How rounded the form reads. 1.0 is sphere-like; lower is flatter, which
suits cloth and flat panels; higher exaggerates the curvature.
ambient: Floor brightness in shadow, 0 to 1. Pixel art rarely wants true black
in shadow, so this sits well above zero by default.
rim: Light wrapping the edge away from the key, 0 to 1. A little reads as a
bounce; a lot reads as backlight.
bias: Shift the whole result along the ramp, in steps. Use this when the result
is uniformly a shade too dark or light, rather than re-tuning the lighting.
fill_angle: Degrees, a second light. Omitted by default, which leaves the result
exactly as it was before this argument existed. Set it opposite `light_angle`
for the fill or bounce light that keeps a shadow side readable instead of
letting it go flat dark: the shadow side is where a sprite stops describing
its form, and one light can only ever leave it at `ambient`.
fill_strength: How strong the fill is next to the key, 0 to 1 and capped below 1.
A fill that matches the key cancels the form entirely, because the two
terminators land on opposite sides of the same shape and sum to a flat fill,
so the cap refuses the value that destroys what the tool is for. A third to a
half is the conventional choice.
tolerance: How close a pixel must be to `base_color` to count as part of the
region, as a weighted RGB distance. Ignored when `base_color` is omitted.
**A distance between colours, not between materials.** Two ramps of different
materials are routinely closer than the default 24: every step of a gold ramp
generated by `generate_ramp` is within 24 of a step of a brass one, so a pass
scoped to the brass matched the gold as readily. Art whose fills came from
`generate_ramp` is exact, so scope it with a tolerance near zero and keep the
wide default for hand-drawn art that varies.
layer: Target layer (default: top layer).
frame: Target frame, 1-based.
The two lights are summed and clamped, not averaged: averaging would dim the key side
as the fill came up, so adding a fill light would make the whole sprite darker and
quietly cost the ramp's top step. Clamping leaves the key side as it was and lightens
only what the key did not reach, which is what a fill light is.
`per_step` in the result counts pixels per ramp entry, which is how to check a fill
actually lightened the shadow side rather than trusting that it did.
`region_components` and `region_bounds` say whether the pass went where it was meant
to, which `region_pixels` cannot: it counts matches without saying whether they are in
one place or four. A call scoped to a 27px coin that comes back with a box spanning 200
pixels of canvas has matched something else as well, and that is the mistake
`tolerance` invites.
Refuses a region with no interior to shade: below roughly 6px across, the distance
field never exceeds a pixel and there is no form to describe. The honest answer
there is two hand-placed pixels, which `draw_pixels` already does.
| Name | Required | Description | Default |
|---|---|---|---|
| rim | No | Default: 0.0. | |
| bias | No | Default: 0.0. | |
| ramp | Yes | ||
| bulge | No | Default: 1.0. | |
| frame | No | Default: 1. | |
| layer | No | ||
| ambient | No | Default: 0.35. | |
| light_z | No | Default: 0.45. | |
| filename | Yes | ||
| tolerance | No | Default: 24.0. | |
| base_color | No | ||
| fill_angle | No | ||
| light_angle | No | Default: 135.0. | |
| fill_strength | No | Default: 0.35. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say it is a mutating, non-open-world call. The description goes well beyond: it refuses regions below ~6px, caps fill_strength below 1 and explains why, explains that the two lights are summed and clamped rather than averaged, and describes result fields (per_step, region_components, region_bounds) that reveal intent failures. Rich disclosure for a mutation 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?
Front-loaded and every section carries real decision-relevant content, but the prose is unusually long for a tool description and a few sentences restate a point already made ('which is what a fill light is'). Dense rather than padded, yet trimming would help scanning.
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?
No output schema exists, and the description compensates by explaining what the result fields mean and how to use them to verify the pass. It also covers refusal conditions and multi-light interaction. For a 14-parameter mutation tool, nothing an agent needs to call it 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?
At 64% schema coverage the schema itself only supplies defaults. The prose documents all 14 parameters with units, ranges, defaults, and intent — light_angle's degree convention, light_z's flattening effect, bulge's per-material guidance, the tolerance warning about gold vs brass ramps, and fill_angle's omission semantics. This far exceeds what the schema 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?
Opens with a specific verb+resource+mechanism: 'Shade a flat region as a lit form, using a ramp and a light direction.' It then names the resulting visual artifacts (asymmetric terminator, darker core, rim light) and constrains the output palette, which separates it from neighbours like gradient_map, specular_highlight and shift_along_ramp.
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 scope guidance ('Scope this to one material') with a concrete failure mode (sword/steel/brass/leather flattening), three named ways to scope (base_color, making a selection, naming select_by_color as the usual route, or both), an explicit 'What it cannot do' section, and an alternative for the refused case (draw_pixels). This is close to ideal when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shift_along_rampA
Move pixels along a colour ramp, keeping every one of them on the palette.
This is the operation to use for "put this in shadow", "make the night variant" or
"deepen the shadow side". Each pixel is matched to its nearest ramp entry, moved
`steps` along the ramp, and clamped at the ends, so the result uses only colours
that were already on the ramp.
Prefer this over `adjust_brightness_contrast` for anything that should still look
like pixel art: that tool does colour arithmetic and lands almost every pixel
between palette entries.
Args:
ramp: The ramp, darkest first, as produced by `generate_ramp`. Order matters:
negative `steps` moves toward the front of this list.
steps: How far to move. Negative darkens (toward the front of `ramp`), positive
lightens. Pixels already at an end stay there rather than wrapping.
x, y, width, height: Restrict the change to a region. Defaults to the whole
canvas. Scope this when a sprite has several materials: one ramp applied to
everything flattens steel, brass and leather into the same colours.
tolerance: How far a pixel may be from a ramp entry and still be treated as
belonging to it, as a weighted RGB distance. Pixels further away than this
are left alone and counted in `pixels_skipped`, so shading one material does
not disturb its neighbours.
layer: Target layer (default: top layer).
frame: Target frame, 1-based.
Returns `pixels_written` and `pixels_skipped`. A high skip count usually means the
ramp does not match the artwork, not that the sprite was already correct.
`pixels_matched` counts the pixels that both matched the ramp and were written, so it
agrees with `pixels_written` rather than counting matches an active selection then
refused.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | Default: 0. | |
| y | No | Default: 0. | |
| ramp | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| steps | Yes | ||
| width | No | ||
| height | No | ||
| filename | Yes | ||
| tolerance | No | Default: 48.0. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply readOnlyHint=false and openWorldHint=false, so the description carries most of the load. It discloses real behavior beyond the safety profile: per-pixel nearest-entry matching, clamping at ramp ends rather than wrapping, the tolerance-based skip rule, that skipped pixels are left untouched and counted, and the default target (top layer, whole canvas). The note that a high skip count usually signals a ramp mismatch rather than correct artwork is genuinely useful diagnostic 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 purpose and the alternative-tool guidance are front-loaded before the Args block, which is the right order. The final paragraph on pixels_matched is convoluted — it introduces a third return field not listed in the preceding 'Returns' sentence and references 'an active selection', a concept not otherwise raised. Minor redundancy costs it a point, but the rest is dense and 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?
With no output schema, the description takes on return-value documentation (pixels_written, pixels_skipped, pixels_matched) and does so adequately, and it covers the region/tolerance semantics that the thin schema omits. For a 10-parameter mutation tool at 40% schema coverage this is close to sufficient; only the persistence target implied by filename and any undo/permission behavior go unmentioned.
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 only 40% (10 params, mostly undocumented in the schema), so the description must compensate and largely does: ramp ordering and its effect on negative steps, the sign convention for steps with clamp-at-end semantics, region scoping for x/y/width/height, tolerance as a weighted RGB distance with its skip consequence, layer default (top layer), and frame being 1-based. Only filename is left implicit, which is self-evident.
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 sentence states a specific verb and resource ('Move pixels along a colour ramp, keeping every one of them on the palette') and immediately names the sibling it is not: 'Prefer this over `adjust_brightness_contrast`'. An agent can distinguish this from the many other colour/ramp tools (generate_ramp, ramp_between, ramp_from_art) without opening any schema.
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 use-case triggers ('put this in shadow', 'make the night variant', 'deepen the shadow side') and an explicit when-not with a named alternative ('anything that should still look like pixel art' → use this, not adjust_brightness_contrast, because that tool lands pixels between palette entries). It also advises scoping x/y/width/height when a sprite has multiple materials.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
smear_frameA
Draw one frame's subject along its own path, so fast movement reads as speed.
Between two frames of a fast movement the eye expects a **smear**: one frame where the
subject is stretched along where it came from, or drawn several times faintly, so the
movement reads as speed rather than as teleportation. `offset_cels` produces the
movement; this describes one frame of it.
The movement vector is taken from the sprite rather than restated by the caller: it is
the shift between the centre of the drawn content on `from_frame` and on `frame`. The
*content* box, not `cel.position`, because any tool here that writes a whole canvas
back leaves the position at (0, 0) on every frame, and a position diff would then read
zero while the drawing plainly moved.
Args:
frame: The frame to smear. Its own cel is the subject and stays on top, unchanged;
the trail is drawn behind it. Only this frame is written.
from_frame: The frame the movement came from. Defaults to the one before `frame`.
mode: `stretch` draws the subject once, elongated back along the vector and
thinning to a single pixel at the tip, which is the classic one-frame smear.
`echo` draws it `steps` times along the vector, each copy a step further down
the ramp, which is the multiple-exposure smear.
strength: How far back the smear reaches, as a fraction of the movement. 0.6 is a
trail that clearly trails; 1.0 reaches all the way to the previous position;
above 1 it overshoots, which is a real choice an animator makes.
steps: How many copies `echo` draws. Defaults to 3, and is refused with
`mode="stretch"` rather than silently ignored.
ramp: The colours, darkest first, the trail is allowed to use, as `generate_ramp`
returns them. **Pass this.** Each pixel of the trail is the nearest ramp entry
to the subject's own colour there, stepped toward the dark end and clamped
(never wrapped), so `palette_conformance` stays at 1.0, which is the property
every shading tool here holds to and what a pixel artist actually draws.
Without it the fallback is opacity, and the fallback **leaves the palette**:
the trail is then made of colours that are not in the sprite, which is motion
blur rather than a smear. On an *indexed* sprite the ramp is required rather
than preferred, and the call is refused without one: an indexed pixel is an
offset into a palette and carries no alpha, so the fallback would snap every
copy back to the subject's own colour and draw a solid blob.
Refuses rather than producing a blur of nothing: a frame with no movement to smear
(the two content boxes sit at the same place, and the message says where they are), a
movement too short to smear at this strength (it names the pixels and the length that
would result), `frame` 1 with no earlier frame, `from_frame` equal to `frame`, either
frame undrawn, a group or tilemap layer, a ramp of fewer than two colours or one given
as palette indices, `steps` with `stretch`, and a frame that shares its image with
another frame, since a linked cel would put the smear on every frame in the group and
the whole point is that the unsmeared frames are untouched.
Returns the vector it measured and where it came from, the plots it drew, and the
cel's bounds before and after, so the claim that the smear lies along the movement can
be checked. On an indexed sprite it also returns `trail_on_palette`: what the trail's
own target colours resolve to on this palette, and a warning naming the copies that
will come out the same colour because two of those targets landed on one entry. That
is a different finding from the ramp headroom one above it, which measures the art.
`validate_loop` will now report this frame as breaking the spacing series, which is
correct: a smear frame is one that legitimately does.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Default: "stretch". | stretch |
| ramp | No | ||
| frame | Yes | ||
| layer | Yes | ||
| steps | No | ||
| filename | Yes | ||
| strength | No | Default: 0.6. | |
| from_frame | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are sparse (readOnlyHint=false, openWorldHint=false), so the description must carry behavioral detail, and it does: it discloses the fallback behavior (opacity leaves the palette), the indexed-sprite refusal, the non-destructive nature (only this frame is written, unsmeared frames untouched), linked-cel refusal, and the return contents. This is far richer than the annotations. No contradiction with readOnlyHint=false (it writes).
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?
Well structured and front-loaded with the core purpose, then Args, refusals, and returns. It is long but the length is earned by the number of semantic traps (ramp requirement, indexed sprites, refusals). Some repetition exists but it is largely informative.
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 8 params, no output schema, and sparse annotations, the description covers purpose, modes, required args, fallback behavior, refusals, return contents, and interaction with validate_loop. Nothing essential for correct invocation 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 description coverage is only 25%, so the description must compensate, and it does for mode, strength, steps, and ramp, explaining semantics and edge cases (steps refused with stretch, ramp required on indexed sprites). It also explains how the vector is derived (content box, not cel.position). However, filename and layer are not addressed, and the frame/from_frame descriptions are brief.
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 the verb and resource ("Draw one frame's subject along its own path") and distinguishes this tool from its closest sibling: ``offset_cels`` produces the movement; this describes one frame of it. An agent can tell immediately this is a smear-frame tool, not a movement tool, and it references the sibling that creates the movement being smeared.
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 names the alternative (`offset_cels`) and distinguishes its role, states which mode to use when (`stretch` vs `echo`), requires a ramp, and describes refusal conditions that effectively serve as when-not-to-use guidance. It explicitly calls out the indexed-sprite case. Usage conditions are well specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sort_paletteA
Sort the palette by "hue", "luminance" (default), "saturation", or "value".
For indexed sprites the pixel indices are remapped so the image looks identical.
| Name | Required | Description | Default |
|---|---|---|---|
| by | No | Default: "luminance". | luminance |
| reverse | No | Default: false. | |
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=false signalling a mutation, the description adds a genuinely useful behavioral detail beyond annotations: indexed sprites have pixel indices remapped so the image appearance is preserved. It does not say whether the file is modified in place or what happens on non-indexed sprites, keeping it short of a 5.
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 tight sentences; the sort keys and default are front-loaded, and the indexed-sprite caveat follows with zero 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 mutation tool with no output schema, the description covers the options and the key side effect. It leaves minor ambiguity about mutation target/in-place behavior, but is otherwise complete enough to call 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 67% and the schema's 'by' field only states the default. The description supplies the actual valid values (hue, luminance, saturation, value), adding real meaning beyond the schema. 'reverse' remains undocumented in both, so not quite 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?
States a specific verb (sort) and resource (the palette) plus the sort keys available. It is clearly distinct from siblings like resize_palette, cycle_palette, or load_palette, though it does not explicitly name any alternative for contrast.
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 lists valid sort modes and the default, implying the operation's context, but gives no guidance on when to use it versus sibling palette tools or any prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
specular_highlightA
Place a small specular highlight where the light actually reflects at the viewer.
`shade_region_by_light` spreads the ramp's top step over the whole lit side, which is
what a matte surface does and why its output reads as plastic. A specular is the other
thing at the top of the ramp: a two or three pixel glint on the one part of the form
whose normal sends the light straight back at you. It is the difference between a
stone and a gem, and it is small by definition.
Run this **after** `shade_region_by_light`, on the same region and the same light: it
reuses that tool's region mask, distance field and surface normals, so the glint lands
inside the highlight rather than beside it.
**Reserve the top step for it.** Shade the form with the ramp *minus its last entry*
and then call this with the whole ramp:
shade_region_by_light(f, ramp[:-1], light_angle=135)
specular_highlight(f, ramp, light_angle=135, size=2)
Shading with the full ramp spreads its top step over the entire lit side, which leaves
nothing above it for a glint to be: the specular then paints pixels the colour they
already are, and that call is refused rather than reported as a success that changed
nothing. The refusal says this and names the way out, so it is a reminder rather than
a puzzle.
Where it goes: on the normal closest to the half-vector between the light and the
viewer, not on the normal closest to the light. That offset toward the viewer is what
makes a specular sit inside the lit side instead of out on its shoulder, and it is the
whole reason this is a separate tool rather than a brighter `bias`.
What it will not do: touch an edge pixel. A specular on the silhouette's border reads
as a hole punched in the form rather than as a shine, so only pixels with all eight
neighbours inside the region are candidates. On a region with no such pixel there is
nothing to put a glint on, and the call is refused with the same message
`shade_region_by_light` gives for a region too thin to shade.
Args:
ramp: Colours darkest first, the same ramp the form was shaded with.
light_angle: Degrees, and it must match the shading pass or the glint contradicts
the form. 0 is from the right, 90 from above, 135 from the upper left.
light_z: How much the light comes from the viewer, 0 to 1. Match the shading pass.
size: How many pixels the glint covers. A count, not a radius: a specular is two
or three pixels on most sprites, and the point of this tool is that it stays
that small. The pixels are grown outward from the brightest one and stay
touching, so the result is one glint rather than scattered dots.
tightness: How narrowly the surface has to face the reflection to count, 0 to 1,
as a threshold on the normal against the half-vector. High is a tiny hard
glint on a polished surface; low lets a broader shoulder qualify, from which
`size` still takes only the best pixels. If nothing clears it the call is
refused and the message names the best alignment the form actually offers, so
the number to lower it to is in the error rather than a guess.
bulge: How rounded the form reads. Match the shading pass, or the normals this
works from are not the normals the shading used.
highlight_color: The glint's colour, defaulting to the ramp's top step so
`palette_conformance` stays at 1.0. This is the flag for metal, which is the
one material whose specular is genuinely brighter than its own ramp: name a
near-white there. A colour that is not on `ramp` will drop conformance against
that ramp, which is the honest trade rather than a bug, and the result says
whether it happened.
base_color: Only consider pixels near this colour, as for `shade_region_by_light`.
Scope it the same way you scoped the shading.
tolerance: How close a pixel must be to `base_color` to count as part of the
region. Ignored when `base_color` is omitted.
layer: Target layer (default: top layer).
frame: Target frame, 1-based.
Returns `specular_pixels` (how many were placed, which is below `size` when the
eligible area is smaller than the budget), `pixels` (where they went, so a later
`remove_stray_pixels` can be told to protect them), `pixels_changed` (how many were
not already that colour) and `peak_alignment`, the best normal against the
half-vector found anywhere in the region.
Also `region_components` and `region_bounds`, which say whether the region is where it
was meant to be. Worth reading on this tool in particular: the normals come from the
*whole* region, so scoping a glint to a compound object rather than to one of its parts
puts it wherever that object's overall mass bulges. A sword scoped by its whole cell
got its only glint on the leather grip, with none on the blade, and
`specular_pixels: 2` said nothing about that.
| Name | Required | Description | Default |
|---|---|---|---|
| ramp | Yes | ||
| size | No | Default: 2. | |
| bulge | No | Default: 1.0. | |
| frame | No | Default: 1. | |
| layer | No | ||
| light_z | No | Default: 0.45. | |
| filename | Yes | ||
| tightness | No | Default: 0.7. | |
| tolerance | No | Default: 24.0. | |
| base_color | No | ||
| light_angle | No | Default: 135.0. | |
| highlight_color | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=false; the description carries the rest richly — pixel-mutating behavior, refusal semantics for full-ramp and thin-region cases, the no-edge-pixel rule, and palette-conformance tradeoffs. This is far more behavioral context than the 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?
Front-loaded with purpose and structured with headers, code example, and a param list, so it is navigable. It is nonetheless very long (~700 words) for a single tool; some prose, such as the stone/gem and sword anecdotes, could be trimmed without losing actionable guidance.
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?
No output schema exists, but the description fully documents return keys (`specular_pixels`, `pixels`, `pixels_changed`, `peak_alignment`, `region_components`, `region_bounds`) and warns about the compound-object scoping pitfall. An agent has everything needed to call and interpret the result.
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 only 58% and most schema entries are bare defaults, so the description compensates by defining every parameter — units (degrees), ranges (0 to 1), matching requirements against the shading pass, count-vs-radius for `size`, and how `base_color`/`tolerance` interact. This adds substantial meaning 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?
States a specific verb and resource ('Place a small specular highlight') and immediately distinguishes itself from the sibling `shade_region_by_light` and from `bias`. An agent can tell exactly what this tool does and what it is not, without opening a schema.
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 ordering rule ('Run this **after** `shade_region_by_light`, on the same region and the same light'), prerequisites (reserve the top step of the ramp), and named alternatives. It also routes failure cases clearly, telling the agent when the call is refused and why.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stamp_fileB
Composite another image/sprite file onto a layer at (x, y).
Args:
source: Path to a .aseprite/.png/.bmp/... to stamp in.
x, y: Top-left placement on the target canvas.
source_frame: Which frame of the source to use (1-based).
opacity: 0-255.
blend_mode: Blend mode for compositing (normal, multiply, …).
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | ||
| y | Yes | ||
| frame | No | Default: 1. | |
| layer | No | ||
| source | Yes | ||
| opacity | No | Default: 255. | |
| filename | Yes | ||
| blend_mode | No | Default: "normal". | normal |
| source_frame | No | Default: 1. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and openWorldHint=false, so the mutation profile is partly covered, and the description confirms it composites onto a layer. It adds useful detail (opacity 0-255, blend_mode options) but never says whether existing pixels are overwritten or blended, nor whether the target layer must exist.
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 opening sentence is front-loaded and the Args block is compact, with every line earning its place. Minor redundancy in listing x, y and source_frame that the schema exposes, but overall efficient.
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 9-parameter mutating tool with no output schema, the description should explain the layer/filename targets and the source_frame vs frame distinction. It covers most compositing knobs but leaves enough gaps that an agent could call it incorrectly.
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 only 44%, and the description compensates by explaining x/y as top-left placement and giving opacity range and blend_mode examples. However, it omits the role of filename, layer, and frame, and it documents source_frame without clarifying its relation to the also-present frame parameter.
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 (composite/stamp) and resource (another image/sprite file onto a layer at x,y), which clearly differentiates it from siblings like import_image and draw_image_base64. It is clear what the tool does, though it doesn't explicitly name the nearest sibling (stamp_pattern).
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?
No guidance on when to use this versus alternatives such as stamp_pattern, draw_image_base64, import_image, or add_reference_layer, nor any prerequisites. The agent must infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stamp_patternB
Tile an image/sprite across a region to fill it with a repeating pattern.
Args:
source: Image/sprite to tile.
x, y, width, height: Region to fill (defaults to the whole canvas).
spacing_x, spacing_y: Gap between tiles.
opacity, blend_mode: Compositing of each tile.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | Default: 0. | |
| y | No | Default: 0. | |
| frame | No | Default: 1. | |
| layer | No | ||
| width | No | ||
| height | No | ||
| source | Yes | ||
| opacity | No | Default: 255. | |
| filename | Yes | ||
| spacing_x | No | Default: 0. | |
| spacing_y | No | Default: 0. | |
| blend_mode | No | Default: "normal". | normal |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply readOnlyHint=false and openWorldHint=false. The description does not disclose that existing pixels in the region are overwritten, that it operates on a specific file/layer/frame context (three params it never mentions), or how compositing accumulations behave. It adds little beyond the write hint.
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?
Purpose sentence is front-loaded and the arg list is compact with no wasted prose. Structure is clean, though the args block reads more like a schema echo than value-adding guidance.
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 12-param mutation tool with no output schema, the description covers most parameters and the core behavior, but leaves the file/layer/frame targeting context and the overwrite semantics unaddressed. Adequate but with clear 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?
Schema coverage is 58% and much of it is trivial ('Default: 0.'), so the description carries real weight here: it explains source, the region defaults, spacing, and per-tile opacity/blend. It still omits filename, layer, and frame, which are inferred rather than explained.
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 ('tile') and resource ('image/sprite'), and clarifies the result ('fill it with a repeating pattern'). This broadly distinguishes it from stamp_file, but it never explicitly contrasts the two (single vs repeating stamp), so differentiation relies on inference.
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 lists arguments but gives no when-to-use guidance, no when-not-to-use conditions, and no pointer to alternatives like stamp_file, fill_area, or fill_checkerboard. An agent must guess which fill/tiling sibling to pick.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
trim_spriteBDestructive
Auto-crop the canvas to the bounding box of all non-transparent content (across every frame).
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false, so the safety profile is already covered by structured data. The description adds real behavioral context by specifying that trimming spans every frame and is driven by non-transparent content, but it omits the critical consequence for a destructive op: that cropped-away pixels and canvas regions are discarded and any frame offsets shift.
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?
A single front-loaded sentence with the core verb first and the parenthetical scope qualifier second; 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?
For a destructive, single-parameter mutation with no output schema, the description covers the operation and its frame-wide scope adequately but leaves out the consequences of the destructive annotation (data loss, positional shifts) and any hint about the filename argument. Adequate but with visible 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?
With one parameter at 0% schema description coverage, the description carries the burden but says nothing about 'filename' — not whether it is a path, a sprite name, or relative to the loaded document. The parameter is conventional enough to be guessed, so this is a gap rather than a failure.
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 ('Auto-crop the canvas to the bounding box of all non-transparent content') with a clear scope qualifier ('across every frame'), so the effect is unambiguous. It implicitly differentiates from the sibling crop_sprite by being automatic rather than manual, but never names or contrasts that alternative explicitly.
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 explains what the tool does but gives no guidance on when to use it versus crop_sprite or resize_canvas, no prerequisites, and no exclusions. An agent must infer the use case entirely from the mechanism described.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tween_celsADestructive
Scale, turn and fade one drawn cel across frames, in one Aseprite launch.
`offset_cels` moves a cel along a path, which is one of the four things an inbetween
does. This is the other three. The cel on the **first listed frame is the source**,
and every listed frame becomes that one drawing resampled by its share of the change:
frame nine is sampled from the original and not from frame eight, so the rounding
never compounds.
**It interpolates a transform, not pixels.** Blending two different drawings gives a
double exposure, two silhouettes at half strength, which reads as a mistake rather
than as motion. So this takes one drawing, and when two cels genuinely differ in shape
there is no honest automatic inbetween: draw the second pose and tween each one out
from its own extreme, or express the difference as a scale and a turn, which most of
them are.
Args:
frames: The frames to write, in the order the change passes through them. The
first is the source, and it is rewritten too when `scale_from`, `rotate_from`
or `opacity_from` is not the identity.
scale_from, scale_to: The scale at the first and last frame, on both axes.
scale_y_from, scale_y_to: Override the vertical scale, for squash and stretch,
where the two axes go opposite ways (0.7 tall against 1.25 wide is a squash
that keeps its volume). Unset means the same as the horizontal, which is a
zoom and not a squash.
rotate_from, rotate_to: Clockwise degrees at the first and last frame, snapped to
whole degrees. Quarter turns are exact and lose nothing; sampling within about
15 degrees of one shuffles the edge pixels rather than turning the shape, and
the result says so in `warnings` instead of pretending otherwise.
opacity_from, opacity_to: Cel opacity, 0 to 255. This sets the cel's own opacity
and never bakes alpha into the pixels: a baked fade invents colours that are
not on the palette. It is the per-frame `set_cel_opacity` done in one call.
ease: How the change is *spaced*: `linear`, `ease_in` (starts slow), `ease_out`
(arrives slow), `ease_in_out`, or `gravity` (accelerating, as a falling object
does). Easing belongs in one place at a time, and `apply_timing_curve` carries
the durations.
anchor: The point the transform holds still, taken from the cel's own drawn
bounds: `center`, `top`, `bottom`, `left` or `right`. This matters more than it
looks. A scale about the centre makes a ball grow in every direction; a scale
about `bottom` makes it squash *onto the ground*, which is the one that reads
as weight, and `validate_loop`'s contact-edge check then confirms that the
contact row did not move.
Refuses rather than doing something approximate: fewer than two frames, a frame listed
twice, a from and to that are identical on every channel (each frame would be
rewritten with the drawing the source already holds), a scale of zero or below, a
group or tilemap layer, a source frame with no cel or nothing drawn on it, a frame
whose transform lands entirely off the canvas, and any frame that shares its image
with another frame. That last one is the sharp edge: linked cels share one image, one
position and one opacity, so a tween written into a link group would change every
frame in it. The refusal names the frames and points at `unlink_cels`.
Every listed frame after the first is **overwritten** with the transformed source
rather than blended with what was there. `steps[].bounds` is the written cel's own
content box, so a scale series can be checked instead of trusted: `rendered_monotone`
is that check, and it is omitted while the cel is also rotating, because a turning
shape's bounding box oscillates by design. `steps[].drawn_pixels` is how many opaque
samples that frame took; `pixels_written` is what landed, and the two differ only when
an active selection masked part of it, which `pixels_outside_selection` then reports.
Sampling is nearest-neighbour and copies the source pixel whole, so no colour appears
that the drawing did not already contain and `palette_conformance` is unchanged.
| Name | Required | Description | Default |
|---|---|---|---|
| ease | No | Default: "linear". | linear |
| layer | Yes | ||
| anchor | No | Default: "center". | center |
| frames | Yes | ||
| filename | Yes | ||
| scale_to | No | Default: 1.0. | |
| rotate_to | No | Default: 0.0. | |
| opacity_to | No | Default: 255. | |
| scale_from | No | Default: 1.0. | |
| scale_y_to | No | ||
| rotate_from | No | Default: 0.0. | |
| opacity_from | No | Default: 255. | |
| scale_y_from | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnly=false, and the description substantiates the mutation profile in depth: every listed frame after the first is overwritten, the source frame is rewritten when the from-values are non-identity, and a long list of refusal conditions is given (fewer than two frames, duplicate frames, identical from/to, zero scale, group/tilemap layer, linked cels sharing one image, off-canvas transforms). It even discloses backward-looking behavior like warnings on near-quarter rotations and palette_conformance being unchanged. Far beyond what annotations 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?
Front-loaded with the core purpose before the args, and the parentheticals (squash example, contact-edge reference) earn their space. It is long, but the length is largely justified by 13 parameters with non-obvious transform semantics and a large refusal surface; a few clauses could be tightened without loss.
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?
No output schema exists, so the description carries the full return burden and does: steps[].bounds, rendered_monotone (and why it is omitted while rotating), drawn_pixels vs pixels_written, and pixels_outside_selection. Combined with the refusal list and mutation semantics, an agent has everything needed to call and interpret 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?
With 62% schema coverage and 13 parameters, the description compensates heavily: it defines frames ordering and source semantics, the scale_y_from/to override for squash-and-stretch, rotate snapping behavior, opacity as per-cel non-baked alpha, the ease enumeration with meanings, and anchor with the bottom-anchor weight argument. This adds substantial meaning the bare 'Default: 1.0' schema entries do not.
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 triple (scale, turn, fade) on a specific resource (one drawn cel) across frames, and explicitly positions itself against the sibling offset_cels ('this is the other three' inbetweens). An agent can distinguish this from offset_cels, set_cel_opacity, and apply_timing_curve without opening any schema.
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?
Not only says when to use it but when NOT to: interpolating two genuinely different drawings is refused because it produces a double exposure, and the description routes the agent to draw the second pose or express the delta as scale/turn. It also names the boundary with apply_timing_curve (easing vs durations) and offset_cels explicitly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unlink_celsA
Give frames their own copy of a shared image again, so they can differ again.
The reverse of `link_cels`: each listed frame keeps what it currently shows and stops
following the others. Nothing is lost; the image is copied rather than moved.
Returns the layer's link groups afterwards.
| Name | Required | Description | Default |
|---|---|---|---|
| layer | Yes | ||
| frames | Yes | ||
| filename | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give readOnlyHint=false and openWorldHint=false, so safety and side-effects are largely the description's job. It discloses the key behavioral trait — 'Nothing is lost; the image is copied rather than moved' — which reassures the agent this mutation is non-destructive, and notes the return (link groups). Could say more about scope/permissions but adds real value beyond 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?
Front-loads the core action, uses a short clarifying sentence, then states the return — three tight blocks with no 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?
For a mutation tool with no output schema, the description covers purpose, non-destructiveness, and return value. The main shortfall is parameter explanation, but overall it gives an agent enough 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?
Schema coverage is 0% for all 3 required params. The description loosely references 'the layer's link groups' and 'each listed frame', hinting at layer and frames, but never clarifies filename, frame format, or the relationship between the three params. It does not adequately compensate for the coverage gap.
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+resource (unlink cels) and immediately names the sibling it reverses (`link_cels`) and the effect (each frame keeps what it shows and stops following others). An agent can select this without opening the schema.
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?
Frames the when: 'so they can differ again' and explicitly identifies itself as the reverse of link_cels, which routes the agent between the two. No explicit when-not condition, but the intent is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_asset_specARead-only
Validate an aseprite_mcp.asset_spec.v1 document (does the spec make sense?).
Checks the schema, kind, canvas, per-kind fields, palette, layers, animations
(`frame_count`, not `frames`), slices, export formats, and that the work the plan
would produce fits one build. `name` may already carry a `.aseprite`/`.ase`
extension: it is normalised, not doubled, so `hero` and `hero.aseprite` name the same
file. Returns a ``workflow_manifest.v1`` (kind ``asset_spec``) with a `validation` block
`{passed, checks, errors, warnings}`. This does **not** check a finished sprite against
the spec - that's a separate future tool.
| Name | Required | Description | Default |
|---|---|---|---|
| spec | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the side-effect profile is covered. The description adds real value beyond that: it names the return artifact (workflow_manifest.v1 with a {passed, checks, errors, warnings} block) and the filename normalisation rule for `.aseprite`/`.ase` extensions.
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?
Front-loaded with the core action and the parenthetical 'does the spec make sense?' anchors intent immediately, followed by the check list, return shape, and the exclusion. It is dense but each clause carries information; the parenthetical is the only mildly expendable element.
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 read-only validation tool with a generic nested object parameter and no output schema, the description supplies both the checks performed and the return structure. The only gap is how errors are surfaced (returned in the validation block vs raised), which an agent invoking on invalid input might want to know.
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 0% and the single `spec` parameter is an unrestricted nested object, so the description must carry the burden - and it does, enumerating the spec's constituent parts (schema, kind, canvas, per-kind fields, palette, layers, animations, slices, export formats). It could still be clearer on the frame_count vs frames nuance as an input field.
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 (validate) and resource (aseprite_mcp.asset_spec.v1 document) plus the concrete scope of checks performed. It also distinguishes itself from adjacent tools like plan_asset_spec/build_asset_from_spec and explicitly excludes the 'validate a finished sprite' case.
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 closing sentence draws a clear boundary ('does not check a finished sprite against the spec - that's a separate future tool'), giving useful when-not guidance. However, it never routes the agent among existing siblings such as validate_sprite_for_game_export or validate_loop, so context is clear but alternatives are not fully enumerated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_loopARead-only
Measure an animation and report what is wrong with it, without playing it.
Renders each frame once (one Aseprite launch), then reports per-frame hashes, content
bounding boxes, centroids, the bottom row of the drawn content, the spacing series
between frames, and the durations. On top of the numbers it checks for: a last frame
identical to the first (a loop's wrap showing one image twice), identical adjacent
frames (a pose held by repeating a frame instead of lengthening one), uniform frame
durations, a spacing series that wobbles rather than eases, a contact edge that moves,
and frames with nothing drawn on them.
Args:
tag: Limit the check to one animation tag's frames. Its repeat setting also
decides whether the seam is treated as a loop's wrap.
layer: Measure one layer's cels instead of the flattened frame, so a moving
character can be measured without the background it sits on.
loops: Override whether these frames are a cycle. One-shots (attack, hurt, death)
do not wrap, so a repeated last frame is only a warning for them.
jitter_tolerance: Pixels of spacing wobble to ignore. Integer cel positions make
1px unavoidable, so that is the default; pass 0 to see every reversal.
Returns a ``workflow_manifest.v1`` manifest (kind "validation") whose `validation`
section is `{passed, checks[], errors[], warnings[]}` and whose `animation` section
carries every measurement. `validation.passed` is the verdict and is false only for
faults that are wrong whatever the animation is doing; the rest are warnings, because
a bouncing ball is meant to leave the ground and a flicker is meant to go blank.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | ||
| layer | No | ||
| loops | No | ||
| filename | Yes | ||
| jitter_tolerance | No | Default: 1.0. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint=false, but the description adds substantial behavioral detail: it renders each frame once via a single Aseprite launch, enumerates the measurement series produced, and critically explains the pass/warning verdict semantics ('passed is false only for faults that are wrong whatever the animation is doing'). This is exactly the context annotations cannot carry.
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?
It is front-loaded with the purpose and cleanly sectioned into behavior, Args, and Returns. The prose is dense but each sentence (measurements listed, checks listed, verdict rule) earns its place; a slight trim of the enumeration would tighten it further.
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?
There is no output schema, so the description compensates by specifying the returned workflow_manifest.v1 shape and its validation.animation/validation sections in detail. Combined with the arg semantics and check list, an agent has everything needed to call and interpret 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?
With only 20% schema coverage, the description does the heavy lifting: tag (frame subset plus seam semantics), layer (isolate cels from background), loops (cycle override), and jitter_tolerance (1px default rationale) all get meaningful explanation beyond the schema. Only filename is left implicit, but it is self-evident.
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 ('Measure an animation and report what is wrong with it, without playing it') and enumerates the concrete faults it detects (duplicate last frame, held frames, uniform durations, wobbling spacing, moving contact edge, empty frames). This distinguishes it clearly from generic siblings like validate_asset_spec or assess_sprite without needing to open any schema.
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 the args (when to pass a tag, when to measure a layer, when loops should be overridden) and notes that one-shot animations turn some faults into warnings. However, it never names an alternative tool or states explicit when-not-to-use conditions relative to the many other validate_/assess_ siblings, so usage is implied rather than routed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_minecraft_textureARead-only
Check a sprite against Minecraft's texture rules before it ships.
Always checks that frames are square and power-of-two. Optionally checks the declared
size, frame count and palette budget; if `tiling` is set, measures the wrap-around
seams of every frame; if `pack_root` is given, confirms an animated texture has its
``.png.mcmeta`` sidecar.
**The seam check** does not require the first and last columns to match - that is only
true of a texture with no variation, and would reject most real block art. It compares
the wrap transition against the texture's own interior column-to-column transitions and
reports the ratio, so a borderline verdict can be judged rather than taken on faith.
`warn_ratio` / `error_ratio` set where "suspect" and "seam" begin.
Returns a ``workflow_manifest.v1`` manifest (kind ``validation``) whose `validation`
block is ``{passed, checks, errors, warnings}``, plus per-frame seam measurements
under `tiling` when the seam check ran.
| Name | Required | Description | Default |
|---|---|---|---|
| tiling | No | Default: false. | |
| category | No | ||
| filename | Yes | ||
| namespace | No | Default: "minecraft". | minecraft |
| pack_root | No | ||
| warn_ratio | No | Default: 2.0. | |
| error_ratio | No | Default: 4.0. | |
| texture_name | No | ||
| texture_size | No | ||
| expected_frames | No | ||
| max_palette_size | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this a safe read (readOnlyHint true, openWorldHint false), so the bar is low, and the description still adds substantial behavioral context: it explains the seam-check methodology, why a naive first/last column match is wrong, how warn_ratio/error_ratio thresholds are interpreted, and what the returned manifest contains. This is unusually rich disclosure for a read-only 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 content is front-loaded with the core purpose, then a compact list of always-on versus optional checks, then a focused explanation of the seam metric. The bolded seam paragraph is longer than strictly necessary but each sentence carries behavioral weight, so little 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?
With no output schema and 11 parameters, the description carries heavy burden and does describe the return manifest shape ('validation' block with passed/checks/errors/warnings, plus per-frame seam measurements). It is nearly complete, missing only semantics for the identity/scope params (filename, category, namespace, texture_name).
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 only 36%, so the description must compensate, and it does for the most consequential params: the declared size, frame count and palette budget (texture_size, expected_frames, max_palette_size), tiling, pack_root, and the two ratio thresholds. It leaves filename, category, namespace and texture_name undocumented, so it is not fully complete.
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 ('Check a sprite against Minecraft's texture rules') and enumerates the exact invariants enforced (square power-of-two frames, declared size, frame count, palette budget, tiling seams, .mcmeta sidecar). This clearly separates it from sibling validators like validate_loop or validate_sprite_for_game_export, which target different rule sets.
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 context ('before it ships') and states precisely when each optional check activates: 'if `tiling` is set', 'if `pack_root` is given', and which checks are always-on versus conditional. It does not name an alternative validator to use instead, so it stops short of full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_sprite_for_game_exportARead-only
Check whether a sprite is game-ready against the criteria you specify.
Runs a series of checks: does the file open, do dimensions match (exactly or as
a tile multiple), is the colour mode allowed, are frame counts / required animation
tags present, is the background transparent, is the palette within budget, do
expected export files exist, and is sprite-sheet metadata readable, plus soft
warnings for oversized canvases, missing tags, and default/blank layer names.
All criteria are optional; only the ones you pass are enforced. Returns a
``workflow_manifest.v1`` manifest (kind "validation") with a `validation` section
`{passed, checks[], errors[], warnings[]}`. `validation.passed` is the verdict;
`ok` just means the check ran.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| max_frames | No | ||
| min_frames | No | ||
| required_tags | No | ||
| tile_multiple | No | ||
| expected_width | No | ||
| expected_height | No | ||
| expected_exports | No | ||
| max_palette_size | No | ||
| spritesheet_data | No | ||
| allowed_color_modes | No | ||
| require_transparent_background | No | Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered, yet the description goes further by enumerating the actual checks performed, noting which produce hard errors versus 'soft warnings', and clarifying that `ok` means the check ran while `validation.passed` is the real verdict. That is meaningful behavioral context 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two paragraphs, front-loaded with the purpose before the checklist, and the verdict semantics are stated at the end where the reader needs them. It is somewhat dense with the check list, but every item describes a real behavior rather than 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?
There is no output schema, and the description compensates by describing the returned workflow_manifest.v1 structure (kind 'validation', a validation section with passed/checks/errors/warnings) and disambiguating `ok` from `passed`. Combined with the check enumeration and optional-criteria rule, an agent has everything needed to call and interpret 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?
With only 8% schema description coverage across 12 parameters, the description carries most of the semantic load, and it does: dimensions (exact or tile multiple), colour mode, frame counts, required tags, transparency, palette budget, expected exports, and spritesheet metadata are all described in prose. It compensates well for the schema gap, though it does not map each check to a specific parameter name.
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 ('Check') plus resource ('sprite') and scope ('game-ready against the criteria you specify'), and the enumerated checklist pins down exactly what 'validate' means here. It is clearly distinguishable from neighboring validators like validate_minecraft_texture or validate_asset_spec, which have narrower or different targets.
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 clarifies that all criteria are optional and only supplied ones are enforced, which is useful calling guidance, but it never states when to choose this over validate_asset_spec, validate_minecraft_texture, or assess_sprite. Usage is implied by the 'game export' framing 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.
write_pack_mcmetaADestructive
Write <pack_root>/pack.mcmeta - the file that makes a directory a resource pack.
Args:
pack_root: Directory to become the pack root (created if needed).
mc_version: A known Minecraft version (e.g. "1.21.1") to look the format up from.
Defaults to 1.21.1.
pack_format: The format number, overriding `mc_version`. Required for versions
outside the known table - an unverified guess produces a pack the game
rejects as incompatible, so it is refused rather than guessed.
supported_min, supported_max: Optional inclusive `supported_formats` range,
letting one pack load across several game versions.
Returns a ``workflow_manifest.v1`` manifest (kind ``minecraft_pack``).
| Name | Required | Description | Default |
|---|---|---|---|
| overwrite | No | Default: false. | |
| pack_root | Yes | ||
| mc_version | No | ||
| description | No | Default: "Generated by aseprite-mcp". | Generated by aseprite-mcp |
| pack_format | No | ||
| supported_max | No | ||
| supported_min | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, openWorldHint=false. The description adds context beyond that: the directory is created if needed, an unverified format guess is refused rather than written, and the return is a `workflow_manifest.v1` (kind `minecraft_pack`). It stops short of describing overwrite behavior for an existing pack.mcmeta, which is the main gap.
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?
Front-loaded with the one-line purpose, then a clean Args block and a return note. The 'unverified guess... rejected as incompatible... refused rather than guessed' clause is slightly verbose but carries real behavioral weight, so most sentences earn their 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 destructive file-writing tool with no output schema, the description covers creation side effects, the format-resolution failure mode, cross-version support, and the return manifest. The only meaningful omission is the `overwrite` and `description` parameters, leaving the truncation story incomplete.
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?
With only 29% schema coverage the description must compensate, and it does for 5 of 7 params: pack_root (created if needed), mc_version (a known version, defaults to 1.21.1), pack_format (overrides mc_version, required outside the known table and why), and supported_min/max (inclusive supported_formats range with its effect on cross-version loading). It omits any mention of `overwrite` and `description`, which is why it isn't 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?
States a specific verb (write) and exact artifact (`<pack_root>/pack.mcmeta`), then explains what that artifact does ('makes a directory a resource pack'). This lets an agent distinguish it from the sibling write_texture_mcmeta and the other mcmeta tools without opening the schema.
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?
There is partial conditional guidance ('pack_format required for versions outside the known table'), but no explicit when-to-use vs alternatives, no mention of when to prefer write_texture_mcmeta, and no prerequisites or exclusions. Usage is largely implied by the mount path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_texture_mcmetaADestructive
Write the <texture>.png.mcmeta sidecar for an animated texture.
``export_minecraft_texture`` writes this automatically for a multi-frame sprite; use
this to add or repair one beside a PNG that already exists.
Args:
texture_path: Path to the ``.png`` (the sidecar goes beside it, same name + .mcmeta).
frametime: Ticks each frame is shown for (1 tick = 50 ms).
interpolate: Blend between frames - smooth for gradients, blurry for pixel art.
frame_order: Optional playback order: frame indices (0-based) or
``{"index": i, "time": t}`` objects to hold individual frames longer.
frame_width, frame_height: Only for non-square frames, which the game otherwise
infers from the strip's width.
Returns a ``workflow_manifest.v1`` manifest (kind ``minecraft_texture``).
| Name | Required | Description | Default |
|---|---|---|---|
| frametime | No | Default: 1. | |
| overwrite | No | Default: false. | |
| frame_order | No | ||
| frame_width | No | ||
| interpolate | No | Default: false. | |
| frame_height | No | ||
| texture_path | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=true, so the write/destructive profile is covered. The description adds useful behavior: the file lands beside the PNG with a derived name, and it returns a workflow_manifest.v1. It does not explain the ``overwrite`` behavior that makes the call destructive, which is the one meaningful omission.
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?
Front-loaded with the purpose, then a routing sentence pointing at the alternative, then structured Args. The per-argument lines all add semantic value rather than restating names; slightly long but 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?
No output schema exists, and the description compensates by stating the return type (workflow_manifest.v1, kind minecraft_texture). Destination file naming and parameter semantics are complete; the only gap is the unmentioned ``overwrite`` flag, which matters given destructiveHint=true.
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?
With only 43% schema coverage, the description carries the load well: it explains frametime units (1 tick = 50 ms), the practical meaning of interpolate (smooth gradients vs. blurry pixel art), the ``frame_order`` format including 0-based indices and {"index", "time"} hold objects, and that frame_width/height are only needed for non-square frames. Only ``overwrite`` goes undocumented.
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 artifact: write the ``<texture>.png.mcmeta`` sidecar for an animated texture. It explicitly distinguishes itself from ``export_minecraft_texture`` (which writes it automatically for multi-frame sprites) and from the sibling ``write_pack_mcmeta`` by naming the texture-level sidecar.
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 an explicit when-to-use: 'add or repair one beside a PNG that already exists,' and names the alternative tool that already does this automatically. The condition that selects this tool over export_minecraft_texture is unambiguous.
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.
156 tool updates
v0.10.0- Changed
add_drop_shadow13 fields changed- added
Input schema / properties / color / descriptionAdded value: +"Default: \"#00000080\"." - removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / offset_x / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / offset_x / titleRemoved value: -"Offset X" - added
Input schema / properties / offset_y / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / offset_y / titleRemoved value: -"Offset Y" - added
Input schema / properties / opacity / descriptionAdded value: +"Default: 255." - removed
Input schema / properties / opacity / titleRemoved value: -"Opacity" - removed
Input schema / titleRemoved value: -"add_drop_shadowArguments"
- Changed
add_frame8 fields changed- removed
Input schema / properties / copy_from / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / copy_from / defaultRemoved value: -null - removed
Input schema / properties / copy_from / titleRemoved value: -"Copy From" - added
Input schema / properties / copy_from / typeAdded value: +"integer" - added
Input schema / properties / duration_ms / descriptionAdded value: +"Default: 100." - removed
Input schema / properties / duration_ms / titleRemoved value: -"Duration Ms" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"add_frameArguments"
- Changed
add_group_layer3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / titleRemoved value: -"add_group_layerArguments"
- Changed
add_layer13 fields changed- added
Input schema / properties / blend_mode / descriptionAdded value: +"Default: \"normal\"." - removed
Input schema / properties / blend_mode / titleRemoved value: -"Blend Mode" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / group / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / group / defaultRemoved value: -null - removed
Input schema / properties / group / titleRemoved value: -"Group" - added
Input schema / properties / group / typeAdded value: +"string" - removed
Input schema / properties / name / titleRemoved value: -"Name" - added
Input schema / properties / opacity / descriptionAdded value: +"Default: 255." - removed
Input schema / properties / opacity / titleRemoved value: -"Opacity" - added
Input schema / properties / visible / descriptionAdded value: +"Default: true." - removed
Input schema / properties / visible / titleRemoved value: -"Visible" - removed
Input schema / titleRemoved value: -"add_layerArguments"
- Changed
add_outline15 fields changed- removed
Input schema / properties / color / titleRemoved value: -"Color" - added
Input schema / properties / connectivity / descriptionAdded value: +"Default: 8." - removed
Input schema / properties / connectivity / titleRemoved value: -"Connectivity" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / thickness / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / thickness / titleRemoved value: -"Thickness" - added
Input schema / properties / where / descriptionAdded value: +"Default: \"outside\"." - removed
Input schema / properties / where / titleRemoved value: -"Where" - removed
Input schema / titleRemoved value: -"add_outlineArguments"
- Changed
add_palette_color3 fields changed- removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"add_palette_colorArguments"
- Changed
add_reference_layer15 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / image_file / titleRemoved value: -"Image File" - added
Input schema / properties / layer_name / descriptionAdded value: +"Default: \"reference\"." - removed
Input schema / properties / layer_name / titleRemoved value: -"Layer Name" - added
Input schema / properties / opacity / descriptionAdded value: +"Default: 128." - removed
Input schema / properties / opacity / titleRemoved value: -"Opacity" - added
Input schema / properties / scale_to_fit / descriptionAdded value: +"Default: false." - removed
Input schema / properties / scale_to_fit / titleRemoved value: -"Scale To Fit" - added
Input schema / properties / x / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / x / titleRemoved value: -"X" - added
Input schema / properties / y / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"add_reference_layerArguments"
- Changed
add_slice39 fields changed- removed
Input schema / properties / center_height / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / center_height / defaultRemoved value: -null - removed
Input schema / properties / center_height / titleRemoved value: -"Center Height" - added
Input schema / properties / center_height / typeAdded value: +"integer" - removed
Input schema / properties / center_width / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / center_width / defaultRemoved value: -null - removed
Input schema / properties / center_width / titleRemoved value: -"Center Width" - added
Input schema / properties / center_width / typeAdded value: +"integer" - removed
Input schema / properties / center_x / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / center_x / defaultRemoved value: -null - removed
Input schema / properties / center_x / titleRemoved value: -"Center X" - added
Input schema / properties / center_x / typeAdded value: +"integer" - removed
Input schema / properties / center_y / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / center_y / defaultRemoved value: -null - removed
Input schema / properties / center_y / titleRemoved value: -"Center Y" - added
Input schema / properties / center_y / typeAdded value: +"integer" - removed
Input schema / properties / color / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / color / defaultRemoved value: -null - removed
Input schema / properties / color / titleRemoved value: -"Color" - added
Input schema / properties / color / typeAdded value: +"string" - removed
Input schema / properties / data / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / data / defaultRemoved value: -null - removed
Input schema / properties / data / titleRemoved value: -"Data" - added
Input schema / properties / data / typeAdded value: +"string" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / height / titleRemoved value: -"Height" - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / properties / pivot_x / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / pivot_x / defaultRemoved value: -null - removed
Input schema / properties / pivot_x / titleRemoved value: -"Pivot X" - added
Input schema / properties / pivot_x / typeAdded value: +"integer" - removed
Input schema / properties / pivot_y / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / pivot_y / defaultRemoved value: -null - removed
Input schema / properties / pivot_y / titleRemoved value: -"Pivot Y" - added
Input schema / properties / pivot_y / typeAdded value: +"integer" - removed
Input schema / properties / width / titleRemoved value: -"Width" - removed
Input schema / properties / x / titleRemoved value: -"X" - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"add_sliceArguments"
- Changed
add_tag12 fields changed- removed
Input schema / properties / color / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / color / defaultRemoved value: -null - removed
Input schema / properties / color / titleRemoved value: -"Color" - added
Input schema / properties / color / typeAdded value: +"string" - added
Input schema / properties / direction / descriptionAdded value: +"Default: \"forward\"." - removed
Input schema / properties / direction / titleRemoved value: -"Direction" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / from_frame / titleRemoved value: -"From Frame" - removed
Input schema / properties / name / titleRemoved value: -"Name" - added
Input schema / properties / repeatsAdded value: +{ + "default": 0, + "description": "Default: 0.", + "type": "integer" +} - removed
Input schema / properties / to_frame / titleRemoved value: -"To Frame" - removed
Input schema / titleRemoved value: -"add_tagArguments"
- Changed
add_tile9 fields changed- removed
Input schema / properties / color / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / color / defaultRemoved value: -null - removed
Input schema / properties / color / titleRemoved value: -"Color" - added
Input schema / properties / color / typeAdded value: +"string" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / titleRemoved value: -"add_tileArguments"
- Changed
adjust_brightness_contrast12 fields changed- added
Input schema / properties / brightness / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / brightness / titleRemoved value: -"Brightness" - added
Input schema / properties / contrast / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / contrast / titleRemoved value: -"Contrast" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / titleRemoved value: -"adjust_brightness_contrastArguments"
- Changed
adjust_hue_saturation14 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - added
Input schema / properties / hue / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / hue / titleRemoved value: -"Hue" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / lightness / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / lightness / titleRemoved value: -"Lightness" - added
Input schema / properties / saturation / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / saturation / titleRemoved value: -"Saturation" - removed
Input schema / titleRemoved value: -"adjust_hue_saturationArguments"
- Changed
apply_operations5 fields changed- added
Input schema / properties / dry_run / descriptionAdded value: +"Default: false." - removed
Input schema / properties / dry_run / titleRemoved value: -"Dry Run" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / operations / titleRemoved value: -"Operations" - removed
Input schema / titleRemoved value: -"apply_operationsArguments"
- Added
apply_timing_curve - Added
assess_sprite - Changed
build_asset_from_spec4 fields changed- added
Input schema / properties / overwrite / descriptionAdded value: +"Default: false." - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - removed
Input schema / properties / spec / titleRemoved value: -"Spec" - removed
Input schema / titleRemoved value: -"build_asset_from_specArguments"
- Added
cast_shadow - Changed
clear_layer8 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / titleRemoved value: -"clear_layerArguments"
- Added
contact_shadow - Changed
convert_background_to_layer2 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"convert_background_to_layerArguments"
- Changed
convert_layer_to_background3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / titleRemoved value: -"convert_layer_to_backgroundArguments"
- Changed
copy_cel5 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / from_frame / titleRemoved value: -"From Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / to_frame / titleRemoved value: -"To Frame" - removed
Input schema / titleRemoved value: -"copy_celArguments"
- Changed
create_character_sprite10 fields changed- added
Input schema / properties / base_color / descriptionAdded value: +"Default: \"#3878c8\"." - removed
Input schema / properties / base_color / titleRemoved value: -"Base Color" - added
Input schema / properties / height / descriptionAdded value: +"Default: 32." - removed
Input schema / properties / height / titleRemoved value: -"Height" - removed
Input schema / properties / name / titleRemoved value: -"Name" - added
Input schema / properties / width / descriptionAdded value: +"Default: 32." - removed
Input schema / properties / width / titleRemoved value: -"Width" - added
Input schema / properties / with_placeholder / descriptionAdded value: +"Default: true." - removed
Input schema / properties / with_placeholder / titleRemoved value: -"With Placeholder" - removed
Input schema / titleRemoved value: -"create_character_spriteArguments"
- Changed
create_icon_set10 fields changed- removed
Input schema / properties / columns / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / columns / defaultRemoved value: -null - removed
Input schema / properties / columns / titleRemoved value: -"Columns" - added
Input schema / properties / columns / typeAdded value: +"integer" - added
Input schema / properties / count / descriptionAdded value: +"Default: 4." - removed
Input schema / properties / count / titleRemoved value: -"Count" - added
Input schema / properties / icon_size / descriptionAdded value: +"Default: 16." - removed
Input schema / properties / icon_size / titleRemoved value: -"Icon Size" - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / titleRemoved value: -"create_icon_setArguments"
- Changed
create_rpg_item_sheet13 fields changed- removed
Input schema / properties / columns / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / columns / defaultRemoved value: -null - removed
Input schema / properties / columns / titleRemoved value: -"Columns" - added
Input schema / properties / columns / typeAdded value: +"integer" - added
Input schema / properties / item_size / descriptionAdded value: +"Default: 16." - removed
Input schema / properties / item_size / titleRemoved value: -"Item Size" - removed
Input schema / properties / items / anyOfRemoved value: -[ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } -] - removed
Input schema / properties / items / defaultRemoved value: -null - added
Input schema / properties / items / itemsAdded value: +{ + "type": "string" +} - removed
Input schema / properties / items / titleRemoved value: -"Items" - added
Input schema / properties / items / typeAdded value: +"array" - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / titleRemoved value: -"create_rpg_item_sheetArguments"
- Changed
create_sprite12 fields changed- removed
Input schema / properties / background / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / background / defaultRemoved value: -null - removed
Input schema / properties / background / titleRemoved value: -"Background" - added
Input schema / properties / background / typeAdded value: +"string" - added
Input schema / properties / color_mode / descriptionAdded value: +"Default: \"rgb\"." - removed
Input schema / properties / color_mode / titleRemoved value: -"Color Mode" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / height / titleRemoved value: -"Height" - added
Input schema / properties / overwrite / descriptionAdded value: +"Default: false." - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - removed
Input schema / properties / width / titleRemoved value: -"Width" - removed
Input schema / titleRemoved value: -"create_spriteArguments"
- Changed
create_tilemap_layer17 fields changed- removed
Input schema / properties / columns / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / columns / defaultRemoved value: -null - removed
Input schema / properties / columns / titleRemoved value: -"Columns" - added
Input schema / properties / columns / typeAdded value: +"integer" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / properties / rows / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / rows / defaultRemoved value: -null - removed
Input schema / properties / rows / titleRemoved value: -"Rows" - added
Input schema / properties / rows / typeAdded value: +"integer" - added
Input schema / properties / tile_height / descriptionAdded value: +"Default: 16." - removed
Input schema / properties / tile_height / titleRemoved value: -"Tile Height" - added
Input schema / properties / tile_width / descriptionAdded value: +"Default: 16." - removed
Input schema / properties / tile_width / titleRemoved value: -"Tile Width" - removed
Input schema / titleRemoved value: -"create_tilemap_layerArguments"
- Changed
create_tileset_project13 fields changed- added
Input schema / properties / columns / descriptionAdded value: +"Default: 4." - removed
Input schema / properties / columns / titleRemoved value: -"Columns" - removed
Input schema / properties / name / titleRemoved value: -"Name" - added
Input schema / properties / rows / descriptionAdded value: +"Default: 4." - removed
Input schema / properties / rows / titleRemoved value: -"Rows" - added
Input schema / properties / tile_size / descriptionAdded value: +"Default: 16." - removed
Input schema / properties / tile_size / titleRemoved value: -"Tile Size" - removed
Input schema / properties / tiles / anyOfRemoved value: -[ - { - "items": { - "additionalProperties": true, - "type": "object" - }, - "type": "array" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tiles / defaultRemoved value: -null - added
Input schema / properties / tiles / itemsAdded value: +{ + "additionalProperties": true, + "type": "object" +} - removed
Input schema / properties / tiles / titleRemoved value: -"Tiles" - added
Input schema / properties / tiles / typeAdded value: +"array" - removed
Input schema / titleRemoved value: -"create_tileset_projectArguments"
- Changed
crop_sprite6 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / height / titleRemoved value: -"Height" - removed
Input schema / properties / width / titleRemoved value: -"Width" - removed
Input schema / properties / x / titleRemoved value: -"X" - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"crop_spriteArguments"
- Added
cycle_palette - Changed
delete_cel4 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / titleRemoved value: -"delete_celArguments"
- Changed
desaturate10 fields changed- added
Input schema / properties / amount / descriptionAdded value: +"Default: 100." - removed
Input schema / properties / amount / titleRemoved value: -"Amount" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / titleRemoved value: -"desaturateArguments"
- Added
deselect - Added
diff_sprites - Added
dither_band - Changed
draw_brush13 fields changed- added
Input schema / properties / anchor / descriptionAdded value: +"Default: \"center\"." - removed
Input schema / properties / anchor / titleRemoved value: -"Anchor" - removed
Input schema / properties / brush / titleRemoved value: -"Brush" - removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / properties / points / titleRemoved value: -"Points" - removed
Input schema / titleRemoved value: -"draw_brushArguments"
- Changed
draw_curve17 fields changed- removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / control_x / titleRemoved value: -"Control X" - removed
Input schema / properties / control_y / titleRemoved value: -"Control Y" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / steps / descriptionAdded value: +"Default: 32." - removed
Input schema / properties / steps / titleRemoved value: -"Steps" - removed
Input schema / properties / x0 / titleRemoved value: -"X0" - removed
Input schema / properties / x1 / titleRemoved value: -"X1" - removed
Input schema / properties / y0 / titleRemoved value: -"Y0" - removed
Input schema / properties / y1 / titleRemoved value: -"Y1" - removed
Input schema / titleRemoved value: -"draw_curveArguments"
- Changed
draw_ellipse17 fields changed- added
Input schema / properties / antialias / descriptionAdded value: +"Default: false." - removed
Input schema / properties / antialias / titleRemoved value: -"Antialias" - removed
Input schema / properties / center_x / titleRemoved value: -"Center X" - removed
Input schema / properties / center_y / titleRemoved value: -"Center Y" - removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / filled / descriptionAdded value: +"Default: false." - removed
Input schema / properties / filled / titleRemoved value: -"Filled" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / properties / radius_x / titleRemoved value: -"Radius X" - removed
Input schema / properties / radius_y / titleRemoved value: -"Radius Y" - removed
Input schema / titleRemoved value: -"draw_ellipseArguments"
- Added
draw_ellipse_in_box - Changed
draw_image_base6415 fields changed- added
Input schema / properties / blend_mode / descriptionAdded value: +"Default: \"normal\"." - removed
Input schema / properties / blend_mode / titleRemoved value: -"Blend Mode" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / image_base64 / titleRemoved value: -"Image Base64" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / opacity / descriptionAdded value: +"Default: 255." - removed
Input schema / properties / opacity / titleRemoved value: -"Opacity" - removed
Input schema / properties / x / titleRemoved value: -"X" - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"draw_image_base64Arguments"
- Changed
draw_line17 fields changed- added
Input schema / properties / antialias / descriptionAdded value: +"Default: false." - removed
Input schema / properties / antialias / titleRemoved value: -"Antialias" - removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / pixel_perfect / descriptionAdded value: +"Default: false." - removed
Input schema / properties / pixel_perfect / titleRemoved value: -"Pixel Perfect" - removed
Input schema / properties / x1 / titleRemoved value: -"X1" - removed
Input schema / properties / x2 / titleRemoved value: -"X2" - removed
Input schema / properties / y1 / titleRemoved value: -"Y1" - removed
Input schema / properties / y2 / titleRemoved value: -"Y2" - removed
Input schema / titleRemoved value: -"draw_lineArguments"
- Added
draw_pixel_map - Changed
draw_pixels13 fields changed- removed
Input schema / properties / color / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / color / defaultRemoved value: -null - removed
Input schema / properties / color / titleRemoved value: -"Color" - added
Input schema / properties / color / typeAdded value: +"string" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / properties / pixels / titleRemoved value: -"Pixels" - removed
Input schema / titleRemoved value: -"draw_pixelsArguments"
- Changed
draw_polyline14 fields changed- added
Input schema / properties / closed / descriptionAdded value: +"Default: false." - removed
Input schema / properties / closed / titleRemoved value: -"Closed" - removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / pixel_perfect / descriptionAdded value: +"Default: false." - removed
Input schema / properties / pixel_perfect / titleRemoved value: -"Pixel Perfect" - removed
Input schema / properties / points / titleRemoved value: -"Points" - removed
Input schema / titleRemoved value: -"draw_polylineArguments"
- Changed
draw_rectangle15 fields changed- removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / filled / descriptionAdded value: +"Default: false." - removed
Input schema / properties / filled / titleRemoved value: -"Filled" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / height / titleRemoved value: -"Height" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / properties / width / titleRemoved value: -"Width" - removed
Input schema / properties / x / titleRemoved value: -"X" - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"draw_rectangleArguments"
- Changed
draw_symmetric_pixels20 fields changed- removed
Input schema / properties / axis_x / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / axis_x / defaultRemoved value: -null - removed
Input schema / properties / axis_x / titleRemoved value: -"Axis X" - added
Input schema / properties / axis_x / typeAdded value: +"integer" - removed
Input schema / properties / axis_y / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / axis_y / defaultRemoved value: -null - removed
Input schema / properties / axis_y / titleRemoved value: -"Axis Y" - added
Input schema / properties / axis_y / typeAdded value: +"integer" - removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / mode / descriptionAdded value: +"Default: \"horizontal\"." - removed
Input schema / properties / mode / titleRemoved value: -"Mode" - removed
Input schema / properties / pixels / titleRemoved value: -"Pixels" - removed
Input schema / titleRemoved value: -"draw_symmetric_pixelsArguments"
- Changed
draw_text24 fields changed- removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / font_path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / font_path / defaultRemoved value: -null - removed
Input schema / properties / font_path / titleRemoved value: -"Font Path" - added
Input schema / properties / font_path / typeAdded value: +"string" - added
Input schema / properties / font_size / descriptionAdded value: +"Default: 16." - removed
Input schema / properties / font_size / titleRemoved value: -"Font Size" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / scale / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - added
Input schema / properties / spacing / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / spacing / titleRemoved value: -"Spacing" - removed
Input schema / properties / text / titleRemoved value: -"Text" - added
Input schema / properties / threshold / descriptionAdded value: +"Default: 128." - removed
Input schema / properties / threshold / titleRemoved value: -"Threshold" - removed
Input schema / properties / x / titleRemoved value: -"X" - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"draw_textArguments"
- Changed
duplicate_frame3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / titleRemoved value: -"duplicate_frameArguments"
- Changed
duplicate_layer3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / titleRemoved value: -"duplicate_layerArguments"
- Changed
export_frames6 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / output_pattern / titleRemoved value: -"Output Pattern" - added
Input schema / properties / overwriteAdded value: +{ + "default": false, + "description": "Default: false.", + "type": "boolean" +} - added
Input schema / properties / scale / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - removed
Input schema / titleRemoved value: -"export_framesArguments"
- Changed
export_game_asset_bundle10 fields changed- removed
Input schema / properties / bundle_name / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / bundle_name / defaultRemoved value: -null - removed
Input schema / properties / bundle_name / titleRemoved value: -"Bundle Name" - added
Input schema / properties / bundle_name / typeAdded value: +"string" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / overwrite / descriptionAdded value: +"Default: false." - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - added
Input schema / properties / scale / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - removed
Input schema / titleRemoved value: -"export_game_asset_bundleArguments"
- Changed
export_gif7 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / output / titleRemoved value: -"Output" - added
Input schema / properties / overwrite / descriptionAdded value: +"Default: false." - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - added
Input schema / properties / scale / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - removed
Input schema / titleRemoved value: -"export_gifArguments"
- Changed
export_godot_spriteframes17 fields changed- added
Input schema / properties / default_loop / descriptionAdded value: +"Default: true." - removed
Input schema / properties / default_loop / titleRemoved value: -"Default Loop" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / output / titleRemoved value: -"Output" - added
Input schema / properties / overwrite / descriptionAdded value: +"Default: false." - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - added
Input schema / properties / scale / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - removed
Input schema / properties / sheet_output / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / sheet_output / defaultRemoved value: -null - removed
Input schema / properties / sheet_output / titleRemoved value: -"Sheet Output" - added
Input schema / properties / sheet_output / typeAdded value: +"string" - removed
Input schema / properties / texture_res_path / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / texture_res_path / defaultRemoved value: -null - removed
Input schema / properties / texture_res_path / titleRemoved value: -"Texture Res Path" - added
Input schema / properties / texture_res_path / typeAdded value: +"string" - removed
Input schema / titleRemoved value: -"export_godot_spriteframesArguments"
- Changed
export_layer9 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / output / titleRemoved value: -"Output" - added
Input schema / properties / overwriteAdded value: +{ + "default": false, + "description": "Default: false.", + "type": "boolean" +} - added
Input schema / properties / scale / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - removed
Input schema / titleRemoved value: -"export_layerArguments"
- Changed
export_layers8 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / include_hidden / descriptionAdded value: +"Default: false." - removed
Input schema / properties / include_hidden / titleRemoved value: -"Include Hidden" - removed
Input schema / properties / output_pattern / titleRemoved value: -"Output Pattern" - added
Input schema / properties / overwriteAdded value: +{ + "default": false, + "description": "Default: false.", + "type": "boolean" +} - added
Input schema / properties / scale / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - removed
Input schema / titleRemoved value: -"export_layersArguments"
- Added
export_minecraft_texture - Changed
export_onion_skin13 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - added
Input schema / properties / ghost_opacity / descriptionAdded value: +"Default: 80." - removed
Input schema / properties / ghost_opacity / titleRemoved value: -"Ghost Opacity" - added
Input schema / properties / next / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / next / titleRemoved value: -"Next" - removed
Input schema / properties / output / titleRemoved value: -"Output" - added
Input schema / properties / overwriteAdded value: +{ + "default": false, + "description": "Default: false.", + "type": "boolean" +} - added
Input schema / properties / previous / descriptionAdded value: +"Default: 2." - removed
Input schema / properties / previous / titleRemoved value: -"Previous" - added
Input schema / properties / scale / descriptionAdded value: +"Default: 4." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - removed
Input schema / titleRemoved value: -"export_onion_skinArguments"
- Changed
export_png9 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / output / titleRemoved value: -"Output" - added
Input schema / properties / overwrite / descriptionAdded value: +"Default: false." - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - added
Input schema / properties / scale / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - removed
Input schema / titleRemoved value: -"export_pngArguments"
- Changed
export_slice_metadata8 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / output / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / output / defaultRemoved value: -null - removed
Input schema / properties / output / titleRemoved value: -"Output" - added
Input schema / properties / output / typeAdded value: +"string" - added
Input schema / properties / overwrite / descriptionAdded value: +"Default: false." - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - removed
Input schema / titleRemoved value: -"export_slice_metadataArguments"
- Changed
export_spritesheet27 fields changed- removed
Input schema / properties / data_output / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / data_output / defaultRemoved value: -null - removed
Input schema / properties / data_output / titleRemoved value: -"Data Output" - added
Input schema / properties / data_output / typeAdded value: +"string" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / ignore_layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / ignore_layer / defaultRemoved value: -null - removed
Input schema / properties / ignore_layer / titleRemoved value: -"Ignore Layer" - added
Input schema / properties / ignore_layer / typeAdded value: +"string" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / properties / output / titleRemoved value: -"Output" - added
Input schema / properties / overwrite / descriptionAdded value: +"Default: false." - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - added
Input schema / properties / padding / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / padding / titleRemoved value: -"Padding" - added
Input schema / properties / scale / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - added
Input schema / properties / sheet_type / descriptionAdded value: +"Default: \"packed\"." - removed
Input schema / properties / sheet_type / titleRemoved value: -"Sheet Type" - added
Input schema / properties / split_layers / descriptionAdded value: +"Default: false." - removed
Input schema / properties / split_layers / titleRemoved value: -"Split Layers" - added
Input schema / properties / split_tags / descriptionAdded value: +"Default: false." - removed
Input schema / properties / split_tags / titleRemoved value: -"Split Tags" - removed
Input schema / titleRemoved value: -"export_spritesheetArguments"
- Added
export_spritesheet_packed - Changed
export_tag_gif8 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / output / titleRemoved value: -"Output" - added
Input schema / properties / overwrite / descriptionAdded value: +"Default: false." - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - added
Input schema / properties / scale / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - removed
Input schema / properties / tag / titleRemoved value: -"Tag" - removed
Input schema / titleRemoved value: -"export_tag_gifArguments"
- Changed
export_tags6 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / output_pattern / titleRemoved value: -"Output Pattern" - added
Input schema / properties / overwriteAdded value: +{ + "default": false, + "description": "Default: false.", + "type": "boolean" +} - added
Input schema / properties / scale / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - removed
Input schema / titleRemoved value: -"export_tagsArguments"
- Changed
extract_palette12 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / from_image / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / from_image / defaultRemoved value: -null - removed
Input schema / properties / from_image / titleRemoved value: -"From Image" - added
Input schema / properties / from_image / typeAdded value: +"string" - added
Input schema / properties / include_alpha / descriptionAdded value: +"Default: false." - removed
Input schema / properties / include_alpha / titleRemoved value: -"Include Alpha" - added
Input schema / properties / max_colors / descriptionAdded value: +"Default: 256." - removed
Input schema / properties / max_colors / titleRemoved value: -"Max Colors" - added
Input schema / properties / set_as_palette / descriptionAdded value: +"Default: true." - removed
Input schema / properties / set_as_palette / titleRemoved value: -"Set As Palette" - removed
Input schema / titleRemoved value: -"extract_paletteArguments"
- Changed
fill_area11 fields changed- removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / properties / x / titleRemoved value: -"X" - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"fill_areaArguments"
- Changed
fill_checkerboard24 fields changed- removed
Input schema / properties / color1 / titleRemoved value: -"Color1" - removed
Input schema / properties / color2 / titleRemoved value: -"Color2" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / height / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / height / defaultRemoved value: -null - removed
Input schema / properties / height / titleRemoved value: -"Height" - added
Input schema / properties / height / typeAdded value: +"integer" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / size / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / size / titleRemoved value: -"Size" - removed
Input schema / properties / width / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / width / defaultRemoved value: -null - removed
Input schema / properties / width / titleRemoved value: -"Width" - added
Input schema / properties / width / typeAdded value: +"integer" - added
Input schema / properties / x / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / x / titleRemoved value: -"X" - added
Input schema / properties / y / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"fill_checkerboardArguments"
- Changed
fill_gradient28 fields changed- added
Input schema / properties / angle / descriptionAdded value: +"Default: 0.0." - removed
Input schema / properties / angle / titleRemoved value: -"Angle" - removed
Input schema / properties / colors / titleRemoved value: -"Colors" - added
Input schema / properties / dither / descriptionAdded value: +"Default: false." - removed
Input schema / properties / dither / titleRemoved value: -"Dither" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - added
Input schema / properties / gradient_type / descriptionAdded value: +"Default: \"linear\"." - removed
Input schema / properties / gradient_type / titleRemoved value: -"Gradient Type" - removed
Input schema / properties / height / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / height / defaultRemoved value: -null - removed
Input schema / properties / height / titleRemoved value: -"Height" - added
Input schema / properties / height / typeAdded value: +"integer" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / respect_alphaAdded value: +{ + "default": true, + "description": "Default: true.", + "type": "boolean" +} - removed
Input schema / properties / width / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / width / defaultRemoved value: -null - removed
Input schema / properties / width / titleRemoved value: -"Width" - added
Input schema / properties / width / typeAdded value: +"integer" - added
Input schema / properties / x / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / x / titleRemoved value: -"X" - added
Input schema / properties / y / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"fill_gradientArguments"
- Changed
fill_layer9 fields changed- removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / titleRemoved value: -"fill_layerArguments"
- Changed
fill_tile7 fields changed- removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / tile_index / titleRemoved value: -"Tile Index" - removed
Input schema / titleRemoved value: -"fill_tileArguments"
- Changed
fill_tilemap6 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / tile_index / titleRemoved value: -"Tile Index" - removed
Input schema / titleRemoved value: -"fill_tilemapArguments"
- Changed
flatten_sprite2 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"flatten_spriteArguments"
- Changed
flip_sprite4 fields changed- added
Input schema / properties / direction / descriptionAdded value: +"Default: \"horizontal\"." - removed
Input schema / properties / direction / titleRemoved value: -"Direction" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"flip_spriteArguments"
- Changed
generate_ramp20 fields changed- added
Input schema / properties / apply / descriptionAdded value: +"Default: \"none\"." - removed
Input schema / properties / apply / titleRemoved value: -"Apply" - removed
Input schema / properties / base_color / titleRemoved value: -"Base Color" - added
Input schema / properties / easingAdded value: +{ + "default": "linear", + "description": "Default: \"linear\".", + "type": "string" +} - removed
Input schema / properties / filename / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / filename / defaultRemoved value: -null - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / filename / typeAdded value: +"string" - added
Input schema / properties / hue_shift / descriptionAdded value: +"Default: 0.0." - removed
Input schema / properties / hue_shift / titleRemoved value: -"Hue Shift" - added
Input schema / properties / light_hueAdded value: +{ + "type": "string" +} - added
Input schema / properties / light_range / descriptionAdded value: +"Default: 0.6." - removed
Input schema / properties / light_range / titleRemoved value: -"Light Range" - added
Input schema / properties / sat_curveAdded value: +{ + "default": "linear", + "description": "Default: \"linear\".", + "type": "string" +} - added
Input schema / properties / saturation_shift / descriptionAdded value: +"Default: 0.0." - removed
Input schema / properties / saturation_shift / titleRemoved value: -"Saturation Shift" - added
Input schema / properties / shadow_hueAdded value: +{ + "type": "string" +} - added
Input schema / properties / steps / descriptionAdded value: +"Default: 5." - removed
Input schema / properties / steps / titleRemoved value: -"Steps" - removed
Input schema / titleRemoved value: -"generate_rampArguments"
- Changed
get_cel5 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / titleRemoved value: -"get_celArguments"
- Changed
get_palette2 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"get_paletteArguments"
- Changed
get_pixels18 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / formatAdded value: +{ + "default": "rows", + "description": "Default: \"rows\".", + "type": "string" +} - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / height / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / height / defaultRemoved value: -null - removed
Input schema / properties / height / titleRemoved value: -"Height" - added
Input schema / properties / height / typeAdded value: +"integer" - added
Input schema / properties / layerAdded value: +{ + "type": "string" +} - removed
Input schema / properties / width / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / width / defaultRemoved value: -null - removed
Input schema / properties / width / titleRemoved value: -"Width" - added
Input schema / properties / width / typeAdded value: +"integer" - added
Input schema / properties / x / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / x / titleRemoved value: -"X" - added
Input schema / properties / y / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"get_pixelsArguments"
- Added
get_properties - Added
get_selection - Changed
get_sprite_info2 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"get_sprite_infoArguments"
- Changed
get_tilemap5 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / titleRemoved value: -"get_tilemapArguments"
- Added
glow - Added
gradient_map - Changed
gui_available1 field changed- removed
Input schema / titleRemoved value: -"gui_availableArguments"
- Changed
health_check1 field changed- removed
Input schema / titleRemoved value: -"health_checkArguments"
- Changed
import_image4 fields changed- removed
Input schema / properties / input_image / titleRemoved value: -"Input Image" - removed
Input schema / properties / output / titleRemoved value: -"Output" - added
Input schema / properties / overwriteAdded value: +{ + "default": false, + "description": "Default: false.", + "type": "boolean" +} - removed
Input schema / titleRemoved value: -"import_imageArguments"
- Changed
import_reference_sequence11 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / images / titleRemoved value: -"Images" - added
Input schema / properties / layer_name / descriptionAdded value: +"Default: \"rotoscope\"." - removed
Input schema / properties / layer_name / titleRemoved value: -"Layer Name" - added
Input schema / properties / opacity / descriptionAdded value: +"Default: 128." - removed
Input schema / properties / opacity / titleRemoved value: -"Opacity" - added
Input schema / properties / scale_to_fit / descriptionAdded value: +"Default: false." - removed
Input schema / properties / scale_to_fit / titleRemoved value: -"Scale To Fit" - added
Input schema / properties / start_frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / start_frame / titleRemoved value: -"Start Frame" - removed
Input schema / titleRemoved value: -"import_reference_sequenceArguments"
- Changed
invert_colors8 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / titleRemoved value: -"invert_colorsArguments"
- Added
invert_selection - Added
link_cels - Added
list_palette_usage - Changed
list_slices2 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"list_slicesArguments"
- Changed
list_sprites1 field changed- removed
Input schema / titleRemoved value: -"list_spritesArguments"
- Changed
load_palette3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / palette_file / titleRemoved value: -"Palette File" - removed
Input schema / titleRemoved value: -"load_paletteArguments"
- Changed
make_4_frame_idle_animation10 fields changed- added
Input schema / properties / bob_pixels / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / bob_pixels / titleRemoved value: -"Bob Pixels" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame_duration_ms / descriptionAdded value: +"Default: 150." - removed
Input schema / properties / frame_duration_ms / titleRemoved value: -"Frame Duration Ms" - added
Input schema / properties / layer / descriptionAdded value: +"Default: \"body\"." - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / tag_name / descriptionAdded value: +"Default: \"idle\"." - removed
Input schema / properties / tag_name / titleRemoved value: -"Tag Name" - removed
Input schema / titleRemoved value: -"make_4_frame_idle_animationArguments"
- Changed
make_8_direction_walk_template12 fields changed- removed
Input schema / properties / directions / anyOfRemoved value: -[ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } -] - removed
Input schema / properties / directions / defaultRemoved value: -null - added
Input schema / properties / directions / itemsAdded value: +{ + "type": "string" +} - removed
Input schema / properties / directions / titleRemoved value: -"Directions" - added
Input schema / properties / directions / typeAdded value: +"array" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame_duration_ms / descriptionAdded value: +"Default: 120." - removed
Input schema / properties / frame_duration_ms / titleRemoved value: -"Frame Duration Ms" - changed
Input schema / properties / frames_per_direction / defaultPrevious value: -4New value: +8 - added
Input schema / properties / frames_per_direction / descriptionAdded value: +"Default: 8." - removed
Input schema / properties / frames_per_direction / titleRemoved value: -"Frames Per Direction" - removed
Input schema / titleRemoved value: -"make_8_direction_walk_templateArguments"
- Changed
merge_layer_down3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / titleRemoved value: -"merge_layer_downArguments"
- Changed
mirror_layer13 fields changed- removed
Input schema / properties / axis / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / axis / defaultRemoved value: -null - removed
Input schema / properties / axis / titleRemoved value: -"Axis" - added
Input schema / properties / axis / typeAdded value: +"integer" - added
Input schema / properties / direction / descriptionAdded value: +"Default: \"horizontal\"." - removed
Input schema / properties / direction / titleRemoved value: -"Direction" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / source_side / descriptionAdded value: +"Default: \"first\"." - removed
Input schema / properties / source_side / titleRemoved value: -"Source Side" - removed
Input schema / titleRemoved value: -"mirror_layerArguments"
- Added
modify_selection - Added
move_frame - Changed
move_layer4 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / to_index / titleRemoved value: -"To Index" - removed
Input schema / titleRemoved value: -"move_layerArguments"
- Added
offset_cels - Changed
open_in_editor2 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"open_in_editorArguments"
- Added
outline_smart - Changed
paint_tile_pixels11 fields changed- removed
Input schema / properties / color / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / color / defaultRemoved value: -null - removed
Input schema / properties / color / titleRemoved value: -"Color" - added
Input schema / properties / color / typeAdded value: +"string" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / pixels / titleRemoved value: -"Pixels" - removed
Input schema / properties / tile_index / titleRemoved value: -"Tile Index" - removed
Input schema / titleRemoved value: -"paint_tile_pixelsArguments"
- Changed
plan_asset_spec2 fields changed- removed
Input schema / properties / spec / titleRemoved value: -"Spec" - removed
Input schema / titleRemoved value: -"plan_asset_specArguments"
- Added
quantize_palette - Added
ramp_between - Added
ramp_from_art - Changed
remove_frame3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / titleRemoved value: -"remove_frameArguments"
- Changed
remove_layer3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / titleRemoved value: -"remove_layerArguments"
- Changed
remove_slice3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / titleRemoved value: -"remove_sliceArguments"
- Added
remove_stray_pixels - Changed
remove_tag3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / titleRemoved value: -"remove_tagArguments"
- Changed
rename_layer4 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / new_name / titleRemoved value: -"New Name" - removed
Input schema / titleRemoved value: -"rename_layerArguments"
- Changed
render_preview6 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - added
Input schema / properties / scale / descriptionAdded value: +"Default: 8." - removed
Input schema / properties / scale / titleRemoved value: -"Scale" - removed
Input schema / titleRemoved value: -"render_previewArguments"
- Changed
replace_color12 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / from_color / titleRemoved value: -"From Color" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - removed
Input schema / properties / to_color / titleRemoved value: -"To Color" - added
Input schema / properties / tolerance / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / tolerance / titleRemoved value: -"Tolerance" - removed
Input schema / titleRemoved value: -"replace_colorArguments"
- Changed
resize_canvas6 fields changed- added
Input schema / properties / anchor / descriptionAdded value: +"Default: \"top_left\"." - removed
Input schema / properties / anchor / titleRemoved value: -"Anchor" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / height / titleRemoved value: -"Height" - removed
Input schema / properties / width / titleRemoved value: -"Width" - removed
Input schema / titleRemoved value: -"resize_canvasArguments"
- Changed
resize_palette3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / size / titleRemoved value: -"Size" - removed
Input schema / titleRemoved value: -"resize_paletteArguments"
- Added
reverse_frames - Changed
rotate_sprite3 fields changed- removed
Input schema / properties / angle / titleRemoved value: -"Angle" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"rotate_spriteArguments"
- Changed
save_sprite_as7 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / flatten / descriptionAdded value: +"Default: false." - removed
Input schema / properties / flatten / titleRemoved value: -"Flatten" - removed
Input schema / properties / new_filename / titleRemoved value: -"New Filename" - added
Input schema / properties / overwrite / descriptionAdded value: +"Default: false." - removed
Input schema / properties / overwrite / titleRemoved value: -"Overwrite" - removed
Input schema / titleRemoved value: -"save_sprite_asArguments"
- Added
scaffold_cycle - Changed
scale_sprite16 fields changed- removed
Input schema / properties / factor / anyOfRemoved value: -[ - { - "type": "number" - }, - { - "type": "null" - } -] - removed
Input schema / properties / factor / defaultRemoved value: -null - removed
Input schema / properties / factor / titleRemoved value: -"Factor" - added
Input schema / properties / factor / typeAdded value: +"number" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / height / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / height / defaultRemoved value: -null - removed
Input schema / properties / height / titleRemoved value: -"Height" - added
Input schema / properties / height / typeAdded value: +"integer" - added
Input schema / properties / method / descriptionAdded value: +"Default: \"nearest\"." - removed
Input schema / properties / method / titleRemoved value: -"Method" - removed
Input schema / properties / width / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / width / defaultRemoved value: -null - removed
Input schema / properties / width / titleRemoved value: -"Width" - added
Input schema / properties / width / typeAdded value: +"integer" - removed
Input schema / titleRemoved value: -"scale_spriteArguments"
- Added
select_by_color - Added
select_region - Changed
set_all_frame_durations3 fields changed- removed
Input schema / properties / duration_ms / titleRemoved value: -"Duration Ms" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"set_all_frame_durationsArguments"
- Changed
set_cel_opacity5 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / opacity / titleRemoved value: -"Opacity" - removed
Input schema / titleRemoved value: -"set_cel_opacityArguments"
- Changed
set_cel_position6 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / x / titleRemoved value: -"X" - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"set_cel_positionArguments"
- Added
set_cel_z_index - Changed
set_color_mode6 fields changed- removed
Input schema / properties / color_mode / titleRemoved value: -"Color Mode" - added
Input schema / properties / dithering / descriptionAdded value: +"Default: \"none\"." - removed
Input schema / properties / dithering / titleRemoved value: -"Dithering" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / palette_sourceAdded value: +{ + "default": "from_art", + "description": "Default: \"from_art\".", + "type": "string" +} - removed
Input schema / titleRemoved value: -"set_color_modeArguments"
- Changed
set_frame_duration4 fields changed- removed
Input schema / properties / duration_ms / titleRemoved value: -"Duration Ms" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / titleRemoved value: -"set_frame_durationArguments"
- Changed
set_layer_properties23 fields changed- removed
Input schema / properties / blend_mode / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / blend_mode / defaultRemoved value: -null - removed
Input schema / properties / blend_mode / titleRemoved value: -"Blend Mode" - added
Input schema / properties / blend_mode / typeAdded value: +"string" - removed
Input schema / properties / editable / anyOfRemoved value: -[ - { - "type": "boolean" - }, - { - "type": "null" - } -] - removed
Input schema / properties / editable / defaultRemoved value: -null - removed
Input schema / properties / editable / titleRemoved value: -"Editable" - added
Input schema / properties / editable / typeAdded value: +"boolean" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / name / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / name / defaultRemoved value: -null - removed
Input schema / properties / name / titleRemoved value: -"Name" - added
Input schema / properties / name / typeAdded value: +"string" - removed
Input schema / properties / opacity / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / opacity / defaultRemoved value: -null - removed
Input schema / properties / opacity / titleRemoved value: -"Opacity" - added
Input schema / properties / opacity / typeAdded value: +"integer" - removed
Input schema / properties / visible / anyOfRemoved value: -[ - { - "type": "boolean" - }, - { - "type": "null" - } -] - removed
Input schema / properties / visible / defaultRemoved value: -null - removed
Input schema / properties / visible / titleRemoved value: -"Visible" - added
Input schema / properties / visible / typeAdded value: +"boolean" - removed
Input schema / titleRemoved value: -"set_layer_propertiesArguments"
- Changed
set_palette3 fields changed- removed
Input schema / properties / colors / titleRemoved value: -"Colors" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"set_paletteArguments"
- Changed
set_palette_color4 fields changed- removed
Input schema / properties / color / titleRemoved value: -"Color" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / index / titleRemoved value: -"Index" - removed
Input schema / titleRemoved value: -"set_palette_colorArguments"
- Added
set_properties - Changed
set_slice31 fields changed- removed
Input schema / properties / color / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / color / defaultRemoved value: -null - removed
Input schema / properties / color / titleRemoved value: -"Color" - added
Input schema / properties / color / typeAdded value: +"string" - removed
Input schema / properties / data / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / data / defaultRemoved value: -null - removed
Input schema / properties / data / titleRemoved value: -"Data" - added
Input schema / properties / data / typeAdded value: +"string" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / height / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / height / defaultRemoved value: -null - removed
Input schema / properties / height / titleRemoved value: -"Height" - added
Input schema / properties / height / typeAdded value: +"integer" - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / properties / new_name / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / new_name / defaultRemoved value: -null - removed
Input schema / properties / new_name / titleRemoved value: -"New Name" - added
Input schema / properties / new_name / typeAdded value: +"string" - removed
Input schema / properties / width / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / width / defaultRemoved value: -null - removed
Input schema / properties / width / titleRemoved value: -"Width" - added
Input schema / properties / width / typeAdded value: +"integer" - removed
Input schema / properties / x / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / x / defaultRemoved value: -null - removed
Input schema / properties / x / titleRemoved value: -"X" - added
Input schema / properties / x / typeAdded value: +"integer" - removed
Input schema / properties / y / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / y / defaultRemoved value: -null - removed
Input schema / properties / y / titleRemoved value: -"Y" - added
Input schema / properties / y / typeAdded value: +"integer" - removed
Input schema / titleRemoved value: -"set_sliceArguments"
- Changed
set_tag24 fields changed- removed
Input schema / properties / color / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / color / defaultRemoved value: -null - removed
Input schema / properties / color / titleRemoved value: -"Color" - added
Input schema / properties / color / typeAdded value: +"string" - removed
Input schema / properties / direction / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / direction / defaultRemoved value: -null - removed
Input schema / properties / direction / titleRemoved value: -"Direction" - added
Input schema / properties / direction / typeAdded value: +"string" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / from_frame / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / from_frame / defaultRemoved value: -null - removed
Input schema / properties / from_frame / titleRemoved value: -"From Frame" - added
Input schema / properties / from_frame / typeAdded value: +"integer" - removed
Input schema / properties / name / titleRemoved value: -"Name" - removed
Input schema / properties / new_name / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / new_name / defaultRemoved value: -null - removed
Input schema / properties / new_name / titleRemoved value: -"New Name" - added
Input schema / properties / new_name / typeAdded value: +"string" - added
Input schema / properties / repeatsAdded value: +{ + "type": "integer" +} - removed
Input schema / properties / to_frame / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / to_frame / defaultRemoved value: -null - removed
Input schema / properties / to_frame / titleRemoved value: -"To Frame" - added
Input schema / properties / to_frame / typeAdded value: +"integer" - removed
Input schema / titleRemoved value: -"set_tagArguments"
- Changed
set_tile8 fields changed- removed
Input schema / properties / column / titleRemoved value: -"Column" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / row / titleRemoved value: -"Row" - removed
Input schema / properties / tile_index / titleRemoved value: -"Tile Index" - removed
Input schema / titleRemoved value: -"set_tileArguments"
- Changed
set_tiles6 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - removed
Input schema / properties / tiles / titleRemoved value: -"Tiles" - removed
Input schema / titleRemoved value: -"set_tilesArguments"
- Changed
set_transparent_color3 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / index / titleRemoved value: -"Index" - removed
Input schema / titleRemoved value: -"set_transparent_colorArguments"
- Added
shade_region_by_light - Added
shift_along_ramp - Added
smear_frame - Changed
sort_palette6 fields changed- added
Input schema / properties / by / descriptionAdded value: +"Default: \"luminance\"." - removed
Input schema / properties / by / titleRemoved value: -"By" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / reverse / descriptionAdded value: +"Default: false." - removed
Input schema / properties / reverse / titleRemoved value: -"Reverse" - removed
Input schema / titleRemoved value: -"sort_paletteArguments"
- Added
specular_highlight - Changed
stamp_file17 fields changed- added
Input schema / properties / blend_mode / descriptionAdded value: +"Default: \"normal\"." - removed
Input schema / properties / blend_mode / titleRemoved value: -"Blend Mode" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / opacity / descriptionAdded value: +"Default: 255." - removed
Input schema / properties / opacity / titleRemoved value: -"Opacity" - removed
Input schema / properties / source / titleRemoved value: -"Source" - added
Input schema / properties / source_frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / source_frame / titleRemoved value: -"Source Frame" - removed
Input schema / properties / x / titleRemoved value: -"X" - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"stamp_fileArguments"
- Changed
stamp_pattern29 fields changed- added
Input schema / properties / blend_mode / descriptionAdded value: +"Default: \"normal\"." - removed
Input schema / properties / blend_mode / titleRemoved value: -"Blend Mode" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - added
Input schema / properties / frame / descriptionAdded value: +"Default: 1." - removed
Input schema / properties / frame / titleRemoved value: -"Frame" - removed
Input schema / properties / height / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / height / defaultRemoved value: -null - removed
Input schema / properties / height / titleRemoved value: -"Height" - added
Input schema / properties / height / typeAdded value: +"integer" - removed
Input schema / properties / layer / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / layer / defaultRemoved value: -null - removed
Input schema / properties / layer / titleRemoved value: -"Layer" - added
Input schema / properties / layer / typeAdded value: +"string" - added
Input schema / properties / opacity / descriptionAdded value: +"Default: 255." - removed
Input schema / properties / opacity / titleRemoved value: -"Opacity" - removed
Input schema / properties / source / titleRemoved value: -"Source" - added
Input schema / properties / spacing_x / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / spacing_x / titleRemoved value: -"Spacing X" - added
Input schema / properties / spacing_y / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / spacing_y / titleRemoved value: -"Spacing Y" - removed
Input schema / properties / width / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / width / defaultRemoved value: -null - removed
Input schema / properties / width / titleRemoved value: -"Width" - added
Input schema / properties / width / typeAdded value: +"integer" - added
Input schema / properties / x / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / x / titleRemoved value: -"X" - added
Input schema / properties / y / descriptionAdded value: +"Default: 0." - removed
Input schema / properties / y / titleRemoved value: -"Y" - removed
Input schema / titleRemoved value: -"stamp_patternArguments"
- Changed
trim_sprite2 fields changed- removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / titleRemoved value: -"trim_spriteArguments"
- Added
tween_cels - Added
unlink_cels - Changed
validate_asset_spec2 fields changed- removed
Input schema / properties / spec / titleRemoved value: -"Spec" - removed
Input schema / titleRemoved value: -"validate_asset_specArguments"
- Added
validate_loop - Added
validate_minecraft_texture - Changed
validate_sprite_for_game_export47 fields changed- removed
Input schema / properties / allowed_color_modes / anyOfRemoved value: -[ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } -] - removed
Input schema / properties / allowed_color_modes / defaultRemoved value: -null - added
Input schema / properties / allowed_color_modes / itemsAdded value: +{ + "type": "string" +} - removed
Input schema / properties / allowed_color_modes / titleRemoved value: -"Allowed Color Modes" - added
Input schema / properties / allowed_color_modes / typeAdded value: +"array" - removed
Input schema / properties / expected_exports / anyOfRemoved value: -[ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } -] - removed
Input schema / properties / expected_exports / defaultRemoved value: -null - added
Input schema / properties / expected_exports / itemsAdded value: +{ + "type": "string" +} - removed
Input schema / properties / expected_exports / titleRemoved value: -"Expected Exports" - added
Input schema / properties / expected_exports / typeAdded value: +"array" - removed
Input schema / properties / expected_height / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / expected_height / defaultRemoved value: -null - removed
Input schema / properties / expected_height / titleRemoved value: -"Expected Height" - added
Input schema / properties / expected_height / typeAdded value: +"integer" - removed
Input schema / properties / expected_width / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / expected_width / defaultRemoved value: -null - removed
Input schema / properties / expected_width / titleRemoved value: -"Expected Width" - added
Input schema / properties / expected_width / typeAdded value: +"integer" - removed
Input schema / properties / filename / titleRemoved value: -"Filename" - removed
Input schema / properties / max_frames / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / max_frames / defaultRemoved value: -null - removed
Input schema / properties / max_frames / titleRemoved value: -"Max Frames" - added
Input schema / properties / max_frames / typeAdded value: +"integer" - removed
Input schema / properties / max_palette_size / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / max_palette_size / defaultRemoved value: -null - removed
Input schema / properties / max_palette_size / titleRemoved value: -"Max Palette Size" - added
Input schema / properties / max_palette_size / typeAdded value: +"integer" - removed
Input schema / properties / min_frames / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / min_frames / defaultRemoved value: -null - removed
Input schema / properties / min_frames / titleRemoved value: -"Min Frames" - added
Input schema / properties / min_frames / typeAdded value: +"integer" - added
Input schema / properties / require_transparent_background / descriptionAdded value: +"Default: false." - removed
Input schema / properties / require_transparent_background / titleRemoved value: -"Require Transparent Background" - removed
Input schema / properties / required_tags / anyOfRemoved value: -[ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } -] - removed
Input schema / properties / required_tags / defaultRemoved value: -null - added
Input schema / properties / required_tags / itemsAdded value: +{ + "type": "string" +} - removed
Input schema / properties / required_tags / titleRemoved value: -"Required Tags" - added
Input schema / properties / required_tags / typeAdded value: +"array" - removed
Input schema / properties / spritesheet_data / anyOfRemoved value: -[ - { - "type": "string" - }, - { - "type": "null" - } -] - removed
Input schema / properties / spritesheet_data / defaultRemoved value: -null - removed
Input schema / properties / spritesheet_data / titleRemoved value: -"Spritesheet Data" - added
Input schema / properties / spritesheet_data / typeAdded value: +"string" - removed
Input schema / properties / tile_multiple / anyOfRemoved value: -[ - { - "type": "integer" - }, - { - "type": "null" - } -] - removed
Input schema / properties / tile_multiple / defaultRemoved value: -null - removed
Input schema / properties / tile_multiple / titleRemoved value: -"Tile Multiple" - added
Input schema / properties / tile_multiple / typeAdded value: +"integer" - removed
Input schema / titleRemoved value: -"validate_sprite_for_game_exportArguments"
- Added
write_pack_mcmeta - Added
write_texture_mcmeta
113 tool updates
v0.7.0- First observed
add_drop_shadow - First observed
add_frame - First observed
add_group_layer - First observed
add_layer - First observed
add_outline - First observed
add_palette_color - First observed
add_reference_layer - First observed
add_slice - First observed
add_tag - First observed
add_tile - First observed
adjust_brightness_contrast - First observed
adjust_hue_saturation - First observed
apply_operations - First observed
build_asset_from_spec - First observed
clear_layer - First observed
convert_background_to_layer - First observed
convert_layer_to_background - First observed
copy_cel - First observed
create_character_sprite - First observed
create_icon_set - First observed
create_rpg_item_sheet - First observed
create_sprite - First observed
create_tilemap_layer - First observed
create_tileset_project - First observed
crop_sprite - First observed
delete_cel - First observed
desaturate - First observed
draw_brush - First observed
draw_curve - First observed
draw_ellipse - First observed
draw_image_base64 - First observed
draw_line - First observed
draw_pixels - First observed
draw_polyline - First observed
draw_rectangle - First observed
draw_symmetric_pixels - First observed
draw_text - First observed
duplicate_frame - First observed
duplicate_layer - First observed
export_frames - First observed
export_game_asset_bundle - First observed
export_gif - First observed
export_godot_spriteframes - First observed
export_layer - First observed
export_layers - First observed
export_onion_skin - First observed
export_png - First observed
export_slice_metadata - First observed
export_spritesheet - First observed
export_tag_gif - First observed
export_tags - First observed
extract_palette - First observed
fill_area - First observed
fill_checkerboard - First observed
fill_gradient - First observed
fill_layer - First observed
fill_tile - First observed
fill_tilemap - First observed
flatten_sprite - First observed
flip_sprite - First observed
generate_ramp - First observed
get_cel - First observed
get_palette - First observed
get_pixels - First observed
get_sprite_info - First observed
get_tilemap - First observed
gui_available - First observed
health_check - First observed
import_image - First observed
import_reference_sequence - First observed
invert_colors - First observed
list_slices - First observed
list_sprites - First observed
load_palette - First observed
make_4_frame_idle_animation - First observed
make_8_direction_walk_template - First observed
merge_layer_down - First observed
mirror_layer - First observed
move_layer - First observed
open_in_editor - First observed
paint_tile_pixels - First observed
plan_asset_spec - First observed
remove_frame - First observed
remove_layer - First observed
remove_slice - First observed
remove_tag - First observed
rename_layer - First observed
render_preview - First observed
replace_color - First observed
resize_canvas - First observed
resize_palette - First observed
rotate_sprite - First observed
save_sprite_as - First observed
scale_sprite - First observed
set_all_frame_durations - First observed
set_cel_opacity - First observed
set_cel_position - First observed
set_color_mode - First observed
set_frame_duration - First observed
set_layer_properties - First observed
set_palette - First observed
set_palette_color - First observed
set_slice - First observed
set_tag - First observed
set_tile - First observed
set_tiles - First observed
set_transparent_color - First observed
sort_palette - First observed
stamp_file - First observed
stamp_pattern - First observed
trim_sprite - First observed
validate_asset_spec - First observed
validate_sprite_for_game_export
TDQS
Scored across 156 tools
Many tools target clearly distinct resources and actions, and the descriptions sharply differentiate most overlaps (e.g. add_outline vs outline_smart vs glow, or add_drop_shadow vs cast_shadow). However, with 156 tools the set has several neighboring export, shading, and drawing families whose boundaries require careful reading, increasing misselection risk.
The tool names overwhelmingly use a consistent snake_case verb_noun pattern, such as export_png, add_layer, set_frame_duration, and validate_loop. A few names depart from the pattern or use noun/adjective forms (health_check, gui_available, outline_smart), but the convention remains predictable.
156 tools is far beyond any reasonable scoped surface and falls into the extreme mismatch band (50+ tools). Even for a complex Aseprite integration, this many tools overwhelms selection and context management despite the high quality of individual descriptions.
The surface covers the domain extremely thoroughly: sprite creation, layers, frames, tags, palettes, tilemaps, selections, drawing primitives, shading, animation timing, validation, and many export targets including game-engine and Minecraft formats. There are no obvious dead ends for core Aseprite editing or asset-export workflows.
Maintenance
Related MCP Connectors
Generate authentic pixel art - sprites, animations, and tilesets - from any MCP client
Official MCP server for Agentwork — delegate tasks to AI agents with human-in-the-loop
MCP server for NanoBanana AI image generation and editing
Generate game-ready 3D models, textures, and audio from natural language, over MCP.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server for programmatically creating and editing Aseprite sprites, enabling AI agents to draw, manage layers and frames, and iterate until the desired result is achieved.MIT
- AlicenseBqualityDmaintenanceMCP server for Aseprite — create, edit, and export pixel art sprites, animations, and sprite sheets from any AI assistant.437MIT
- AlicenseAqualityDmaintenanceA pixel art animation MCP server for AI agents, enabling scene generation, sprite drawing, and PNG export with zero latency.1921 npm3MIT
- FlicenseAqualityDmaintenanceAn MCP server that enables AI coding agents to create pixel art programmatically by providing canvas manipulation tools and PNG export.1030 npm7-