Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
ASEPRITE_PATHNoOptional path to the Aseprite executable, only used for verify_with_aseprite.
ASE_STUDIO_LIVENoSet to 0 to turn off the built-in Studio Live viewer.
ASE_STUDIO_ROOTSNoFolders the server may read and write, separated by ; on Windows and : elsewhere. Default: the working directory.
ASE_STUDIO_LIVE_PORTNoPort for the built-in Studio Live viewer (default: 7790).7790

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
sprite_newC

Create a new transparent RGBA .aseprite sprite. layers are created bottom to top (default one layer named "Layer 1").

sprite_infoB

Structure of a sprite: size, frame durations, layer tree (with which frames have cels and which are linked), tags, slices, palette size and warnings.

applyA

Run edit operations on a sprite as ONE transaction: if any op fails nothing is saved and the error names the op. ops_list items are {"op": name, ...arguments}. Frames are 1-based; drawing ops take frame (one) or frames (list, "all", "2-6", "1,3,5-8"); layer defaults to the top image layer. Pixels drawn past the canvas edge are kept in the cel, never clipped. dry_run=true runs everything and reports, but saves nothing.

Ops (name(arguments), ? = optional): add_frames(count?=1, at? (1-based position to insert before; default: append), duration?=100, copy_from?) add_group(name, group?) add_layer(name, group?, opacity?=255, blend?=normal, visible?=true, reference?=false) add_slice(name, x, y, w, h, frame?=1, pivot? [x,y], center? [x,y,w,h], data?) add_tag(name, from, to, direction?=forward, repeat?=0 (0 = loop forever), color?) blink_flash(layer?, frames, color?=#ffffff (white flash) — alternates flash on/off across the frames) clean(specks?=2 (max size of detached islands to delete), orphans?=true, protect? [colors], layer?, frames?) clear(layer?, frames?, region? [x,y,w,h]) copy_cel(layer, from, to (frames), to_layer?, linked?=false, dx?=0, dy?=0) curve(points (3 = quadratic, 4 = cubic Bezier control points), color, layer?, frames?) damage_number(text, x, y (where it pops: its bottom centre), frames, rise?=10, layer?=damage, color?=#fff1a8, bottom_color?=#ff5a3c, outline?=#3a0c14, font?=bold, pop?=true, fade_frames?=2) duplicate_frame(frame, linked?=false) duplicate_layer(layer, name) ellipse(x, y, w, h (bounding box, even sizes fine), color, fill?=true, layer?, frames?, lock_alpha?) erase(x, y, w, h, layer?, frames?) fade(layer, frames, from?=255, to?=0, ease?=linear) fill(x, y, color, tolerance?=0, diagonal?=false, layer?, frames?) fix_glitches(kinds?=[stray, spur, hole, cut, block], master_frame?=1, master_frames? (key drawings), layer?, frames?) flash(color?=#ffffff, amount?=1.0 (1 = solid silhouette), layer?, frames? (hit flash)) flip(axis?=h|v, center? (canvas x for h, y for v; default canvas middle), layer?, frames?) line(x0, y0, x1, y1, color, perfect?=true, layer?, frames?, lock_alpha?) link_cels(layer, source (frame), frames) map(rows (one string per row), legend {char: color}, x?=0, y?=0, layer?, frames?, lock_alpha? ('.' = leave)) move_cel(layer, dx, dy, frames?) move_frame(frame, to) move_layer(layer, to (1 = bottom among its siblings)) outline(color, where?=outside|inside, diagonal?=false, layer?, frames?) palette_lock(palette? [colors] or source? (.aseprite/.png whose colours to use), layer?, frames?) pixels(points [[x,y],...] or [[x,y,color],...], color?, layer?, frames?, lock_alpha?) polyline(points [[x,y],...], color, closed?=false, perfect?=true, layer?, frames?) rect(x, y, w, h, color, fill?=false, layer?, frames?, lock_alpha?) remap(mapping {from_color: to_color}, tolerance?=0, layer?, frames?) remove_frames(frames) remove_layer(layer) remove_slice(name) remove_tag(name) replace_color(from, to, tolerance?=0, layer?, frames?) reverse_frames(frames (an unbroken range)) rotate(degrees (clockwise), pivot [x,y] (canvas), method?=rotsprite|nearest, layer?, frames?) scale(factor (or sx, sy), anchor?=topleft|center|bottom, layer?, frames? (nearest neighbour)) seal_cuts(master_frame?=1, color? (default: the master's darkest colour), layer?, frames? (outline what animating cut open)) set_cel(layer, frames?, opacity?, z?) set_duration(ms, frames?=all) set_durations(durations (list of ms, one per frame from frame 1)) set_layer(layer, name?, opacity?, blend?, visible?, editable?) set_palette(colors [list], replace?=true) shake(layer, frames, amplitude?=1, axis?=x|y|both) squash_stretch(amount (0.2 = squash 20%, -0.2 = stretch), anchor?=bottom|top|left|right, layer?, frames?) stamp(source (png/aseprite path), x?=0, y?=0, source_frame?=1, source_layer?, blend?=true, layer?, frames?) text(text, x, y, color, font?=tiny|bold, bottom_color?, outline?, shadow?, scale?=1, anchor?=topleft|center|bottom|topright, layer?, frames?) tween_move(layer, frames (in order), dx?, dy?, ease?=linear|ease_in|ease_out|ease_in_out|back_out, arc?=0) unlink_cels(layer, frames)

undoB

Undo the last edits made through this server to a file (up to 50 per file).

redoC

Redo edits that were undone.

viewB

Look at frames: one image with up to 16 frames side by side, each on a checkerboard with a pixel grid (darker every 8 px), rulers in sprite coordinates and its number and duration. frames: 1-based list, "all" or "2-6". region [x,y,w,h] zooms into a detail. mode: color, value (lightness only: do the forms read without hue?) or silhouette. onion=true shows the previous frame in red and the next in blue under each frame.

read_pixelsA

Pixels as a character map: {"legend": {char: colour}, "rows": [...]} ('.' = transparent). Edit the rows and send them back with the map op: a read-edit-write round trip. Without layer it reads the flattened frame. Region capped at 128x128.

lintB

Find what is easy to miss, with coordinates: orphan pixels (unlike all 8 neighbours), lone pixels, detached parts, colour count, darkest colour share and pixels past the canvas. Use a layer for one object; the flattened frame touches everything else.

check_animationB

Measure an animation without playing it: per-frame bounds, ground row, centroid, height, repeated frames, colour drift and spacing. kind: "loop" (walk, idle: must close), "oneshot" (attack, hurt, death: may hold poses) or "scene" (several actors: report only).

find_glitchesA

Find what animating broke, frame by frame, with an onion-skin view of every frame that has a problem (previous frame red, next blue, each problem boxed and labelled). Each frame is compared with its previous and next frame (loop=true wraps round) and with the master (default: the first frame), so the design's own details are not reported. Kinds: cut (a part sliced open: interior colours on the outer edge), block (a flat fill larger than the master has), blip (a small patch unlike both neighbour frames), stray (a detached speck), spur (a single pixel sticking out), hole (an enclosed gap), orphan (a pixel unlike all its neighbours). Run it after every animate/edit pass; fix until ok. master_frames: several frames of this sprite that are real drawings (a transition's start and end keys); what any of them contains is design.

check_identityB

Compare every frame with a master image (png or .aseprite): share of pixels that are master colours (within a just-noticeable difference), colours the master lacks, and height/width drift. The check that a character is still itself after animating.

compareA

Pixel difference between two frames (of one sprite, or of two files): changed pixel count and the box that changed. 0 changed pixels proves a part did not move.

pixelizeA

Convert an image into real pixel art and save it as a native-resolution .aseprite.

Finds the fake pixel grid of image-model "pixel art" (cell size, drifting grid lines) and turns each cell into one pixel by perceptual majority; a real illustration (no grid) or an explicit target_height is downscaled by majority vote instead. Palette reduced in OKLab (small distinct accents kept), specks and orphan pixels cleaned. cell: force the cell size in source px. target_height: the native height wanted. background: auto (remove a flat background if there is no transparency) | remove | keep. outline: none, "auto" (darkest palette colour) or a colour, adds a 1 px keyline. palette_from: lock to another image's colours (e.g. the character's master). Returns the report and a preview: source | result enlarged.

import_stripA

Bring a strip of poses (drawn by hand or generated) into a sprite as frames, at the master's scale: every frame is pixelized on one shared cell size (taken from the master's height unless cell is given), locked to the master's colours, and stood on the master's ground line with its feet (or centre) on the master's axis. Frames are added as needed. count: frames in the strip (default: split at transparent gaps). Returns a preview.

rig_previewA

Check a rig before animating: which pixels each part got (tinted), each pivot (white dot), pixel counts and bounding boxes. Parts claim pixels in list order; leftovers form "rest". rig = {"parts": [{"name", "mask": {"rect"|"polygon"|"rows"|"colors"|"union"|"minus"}, "pivot": [x,y], "parent"?, "z"?}], "overlap"?: 1}. Name parts head, torso, arm_front, arm_back, leg_front, leg_back, weapon, tail, hair to use the motion presets.

animate_rigA

Pose a rigged character over several frames and write them to out_layer.

Motion comes from a preset (idle, walk_side, attack, hurt, death; strength scales it) or from keys: [{"frame": 1, "pose": {"arm_front": {"rotate": -30}, "torso": {"dy": 1}, "root": {"dx": 2, "rotate": 5, "pivot": [x,y]}}}, ...] interpolated over frames (ease: ease_in_out | linear | hold). Parts turn with RotSprite about their pivots, children follow parents, and joint gaps are filled from the source (rig "overlap"). feet [x,y] is the pivot for whole-body rotations (default bottom centre). clean removes specks and orphan pixels the rotation left. Frames are added if needed; the source layer is hidden. Returns a summary and a view with onion skin.

tween_posesA

In-betweens between two drawn key poses of one character (pose-to-pose).

rig_start / rig_end cut each drawing into parts with the SAME names (same masks syntax as rig_preview); put each pivot on the same joint in both drawings (neck, shoulder, hip, grip). For every part the rotation and position that carry it from one drawing to the other are fitted; in-betweens in the first half move the start drawing's parts, those in the second half move the end drawing's parts back, so every frame is made of real drawn pixels. Writes out_layer from first_frame: the start drawing, inbetweens frames, the end drawing. ease: ease_in_out | ease_in | ease_out | linear. extra: one pose per in-between added on top (e.g. anticipation [{"torso": {"dy": 3}}, {}, ...]); parts of both rigs, plus "root". Returns the fit per part (angle, match 0..1; under 0.4 = shape changes too much: split it at its joint, e.g. a leg into thigh + shin, or redraw it), bone_stretch (joints whose limb is over 2 px longer or shorter in one drawing: joints stay closed in every in-between, and the length changes where the frames switch drawings), and an onion-skin view. Parts that carry others turn by their bones (pivot -> children's pivots).

exportB

Export without Aseprite. kind (default from the extension): "gif" (real transparency or a background, global palette, per-frame durations, loop or play once), "png" (one frame), "frames" (output must contain {frame}: one png per frame), "sheet" (layout horizontal | vertical | grid with columns, padding, optional JSON frame data). Reference layers and hidden layers are left out; layers restricts to some layers.

make_rampC

A shading ramp around one colour, darkest first, built in OKLCh: even lightness steps, hue leaning warm in the lights and cool in the shadows, chroma tapering at both ends.

verify_with_asepriteA

Open the file with the real Aseprite (if installed: ASEPRITE_PATH or the usual install folder), render every frame there and compare with this server's renderer. Proves the file is valid and that previews here match what Aseprite shows.

live_openA

Studio Live: the built-in web viewer (local only). Plays frames at their real durations, onion skin, compare two frames (side by side / difference / blink), versions of every save with a before/after difference, and find_glitches boxes over the frames. The user selects wrong frames and paints the exact wrong pixels with a brush, adds quick tags and a note; read those with review_notes. Returns the URL (open it in the browser pane); with path it opens that file.

review_notesA

What the user marked in Studio Live: wrong frames, painted pixels, tags and text. Without path, every sprite with notes under the allowed folders. status: open | resolved | all. Each note gives its frames (1-based), tags (hole, stray, cut, limb, flicker, stiff, pose, color, shape, timing), the user's text and per marked frame the pixel bbox and the pixels themselves (sprite coordinates). The picture of each note shows the previous frame, the marked frame with the user's marks in pink, and the next frame. Fix, then resolve_note.

resolve_noteA

Answer a Studio Live note: say what was fixed (the user sees it under the note) and mark it resolved, or reopen it with status="open".

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

B3.3/5.0

Scored across 23 tools

Disambiguation4/5

Most tools have clearly distinct purposes across creation, editing, rigging, verification, and review. The main overlap is the diagnostic cluster (lint, check_animation, find_glitches, check_identity, compare), but their descriptions define separate scopes well enough for an agent to choose correctly.

Naming Consistency3/5

All names use snake_case, which keeps them readable. However, the word order is mixed: many are verb_noun (check_animation, find_glitches, animate_rig) while several are noun_verb or adjective_verb (sprite_new, sprite_info, rig_preview, live_open), so the pattern is not fully predictable.

Tool Count3/5

The 23-tool surface is heavy, though the broad studio scope justifies many capabilities. Still, the set sits in the borderline-heavy range, and some diagnostic or review tools could feel like extra surface area for an agent to manage.

Completeness5/5

The server covers the full lifecycle: sprite creation and inspection, extensive transactional editing via apply, rigging and animation, import/pixelization, linting and glitch checks, export, real-Aseprite verification, and user review notes. No obvious CRUD or workflow dead ends are apparent for the stated pixel-art studio purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues