aseprite-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| ASEPRITE_PATH | No | Aseprite executable. Otherwise found on PATH or in common install/Steam locations (macOS, Windows, Linux). | |
| ASEPRITE_MCP_DIR | No | Base directory for relative paths (default: the server's working directory). | |
| ASEPRITE_MCP_WORKER | No | Set to 0 to disable the persistent worker (one Aseprite process per call). | |
| ASEPRITE_TIMEOUT_MS | No | Per-call timeout, default 60000. | |
| REPLICATE_API_TOKEN | No | Replicate API token used by the generate tool to run models. | |
| ASEPRITE_MCP_ALLOW_IMAGE_WRITES | No | Set to 1 to allow saving edits over existing PNG/GIF/... files. |
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
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| prompts | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| create_spriteC | New sprite file. Or import an image with |
| sprite_infoB | Size, mode, layers, frame durations, tags. palette=true adds palette colors. |
| drawB | Draw on a layer, in order: shapes, rows, pixels. shapes: [kind,x1,y1,x2,y2,color,fill?] kind line|rect|ellipse (fill = interior color); ["curve",[[x,y],...],color,w0?,w1?] smooth spline through points, tapering width (1 = crisp pixel-perfect line); ["blob",[[x,y],...],fill,outline?] smooth closed silhouette through points (heads, bodies, snouts); a point [x,y,1] is a sharp corner (brims, hems, ears); ["tube",[[x,y],...],[dark..light],w0,w1?,{light?,contrast?,bias?}] shaded tapered cylinder (limbs, hair locks, horns, necks, tails; w1=0 for a point); ["form",[[x,y(,1)],...],[dark..light],{light?,shrink?=0.18,shift?=0.5}] blob silhouette shaded with clean crescents (heads, snouts, bodies, rocks); ["eye",cx,cy,w,h,{fill,lid,lower?,pupil?,glint?},{nose:"right"|"left",arch?=0.4,flat?=0.7,tilt?,lidWidth?,pupil:{w,h,dx,dy},light?}] an eye with anatomy: flat lower lid, angular inner corner toward the nose, upper lid arching to a round outer corner, pupil under the lid (mirror nose for the pair); w,h <= 3 draws a tiny eye (dark block, glint on the light side, same for both eyes). Use eye for every eye so glints agree; ["lobe",cx,cy,rx,ry,[dark..light colors],{light?,shift?=0.45,shrink?=0.2,bumps?=7,bumpiness?=0.12,seed?}] shaded form: each lighter tone a smaller copy shifted toward the light, scalloped clump edges (tree = ~3 lobes, back first; bushes, clouds, round bodies); or ["gradient",x1,y1,x2,y2,[colors...],"v"|"h"|"r"] (Bayer-dithered). rows: char grid, legend maps char->color, '.'/space skipped; x,y offset rows. pixels: [[x,y,color]...]. |
| editB | fill{x,y,color,contiguous?} | replace{from,to} (all cels unless layer/frame) | mirror{mode:left_to_right|right_to_left|top_to_bottom|bottom_to_top|flip_h|flip_v} | outline{color?="auto" (darker hue-shifted neighbor), mode?:outside|inside, corners?} | shade{light?:top_left|top|...|bottom_right, depth?, highlightDepth?, shadow?/highlight?: color|"auto"|false, ignore?: colors (e.g. outline), strength?} | copy{x,y,width,height,toX,toY,fromLayer?,fromFrame?,flip?:h|v} | shift{dx,dy,wrap?} | split{toLayer, rects?:[[x1,y1,x2,y2]], rows?(mask, x,y), below?, backfill?=1} (cut a part onto its own layer for rigging: head, torso, arm_l, arm_r, leg_l, leg_r) | separate{colors?(default: border colors), seeds?:[[x,y]], toLayer?="background"|false, islands?=6, fillHole?=true} (split background from subject) | quantize{palette?: hex list|preset|"sprite", dither?:none|bayer|fs, strength? 0-1, setPalette?} (pull colors to a palette) | finishing: round{colors?,passes?} (cut box corners) | selout{outline?,light?,strength?} (outline tinted from what it borders) | aa{outline?,amount?=0.5} (soften stair-steps) | pixel_perfect{colors?} (remove doubled line corners); outline defaults to darkest color | simplify{minSize?=2,passes?=2,keep?:colors} (merge orphan pixels/tiny clusters: removes shading noise; run before 1px details) | volume{colors?,ramp?(dark->light)|bands?=4,light?,elevation?=1.2,ambient?=0.15,dither?=0..1,roundness?} (shade each region as a lit rounded form) | scatter{pattern?:clumps|leaves|grass|bark|scales|stone|speck | rows (h lighter,m base,s darker,d dark), tones?:{h,m,s,d: color} (fixed colors), maskLayer? (place only over that layer), lightBias?=0..1 (denser on the lit side), density?=0.6, spacing?=3, strength?=0.4, colors?, rect?, seed?, breakEdge?=true} (detail clusters following the light) |
| paletteA | Read/extract/generate/set palettes. extract{max}: dominant colors of the sprite or any image path. ramps:[{base,steps?=5,hueShift?=20,contrast?=1}]: hue-shifted shading ramps. colors: hex list/preset. set=true writes colors+extracted+ramps to the sprite palette. No args: current palette. |
| read_pixelsB | Pixels as char grid + legend (draw rows format, '.'=transparent). Flattened unless layer. Optional region. |
| previewB | See the sprite: zoomed, checkerboard transparency, pixel grid. frames="all" contact sheet; tags=true one row per animation; tag=name. reference=image path (+referenceRect [x,y,w,h]) shows a target image beside it at the same height: check every pass against it. |
| layerC | add{name,group?,parent?,below?,opacity?} | update{layer,rename?,visible?,opacity?} | delete{layer} | clear{layer,frame?} | merge_down{layer} |
| framesD | add{count?,after?,copyFrom?,durationMs?} | duration{durationMs,frames?} | delete{frames} | tag{name,from,to,direction?} |
| resizeC | scale{factor|width,height} nearest-neighbor | canvas{width,height,anchor?:center|top_left|top|...} |
| exportC | Export png/gif/sequence, or a spritesheet + Aseprite JSON (tags) when sheet is set. Frames 1-based. |
| animateA | Static art -> animations. Reads |
| ingestA | Turn frames from anything (diffusion/image models, video, hand-drawn) into clean pixel-art animation: removes background, pulls colors to a palette, snaps to the pixel grid (block majority), drops specks, aligns frames, adds a tag. Appends to path if it exists (one tag per call). Source: frames (image paths, gif ok) | sheet{path,cols,rows,count?} | video{path,fps?,start?,duration?} (needs ffmpeg). Size: height (art px) | scale (source px per art px) | reference sprite (matches its height, palette, canvas, feet). align: sequence (shared transform, keeps source motion; video) | feet (per frame: independent poses) | center. |
| generateA | Generate frames with any Replicate model (env REPLICATE_API_TOKEN), then clean them into pixel art with ingest. describe=true: list the model's inputs first. image: your sprite rendered upscaled on a solid background, sent as the model's image input (auto-detected field). prompts: one prediction per prompt (e.g. per pose), run in parallel. Raw outputs are kept in outDir so you can re-ingest without paying again. Videos need ffmpeg. Ideas: retro-diffusion/rd-animation (pixel animation), black-forest-labs/flux-kontext-pro (pose edit per prompt), image-to-video models. |
| characterB | Build a chibi character (~44px at scale 1, feet at x,y) from organic parts on its own layer: body, simplify, outline, then eyes. spec: {skin, eyes, glowEyes, hair:{style:long|bob|spiky|bun|ponytail|none,color}, hat:{type:witch|wizard|top|hood|beret|crown,color,band,height,bend,droop,brim}, top:{type:robe|dress|tunic|coat|armor,color,inner,trim,hem:straight|zigzag|ragged|flared}, sleeves:{type:fitted|puffed|bell,color}, cape:{type:flowing|ragged|tendrils,color}, legs, boots:{type:short|tall|pointy,color}, belt, extras:[halo,catEars,elfEars,foxTail,goggles,horns,aura,spikes,staff], extraColor}. Colors: ramp names (red crimson orange gold green emerald teal blue navy purple violet pink magenta brown tan gray steel black white cream pale light skinTan dark skinGreen skinBlue) or [shadow,base,light] hex. Batch op: person. |
| batchA | Many steps on one sprite in one call (one open, one save, all-or-nothing). Step = {op, ...that tool's args minus path/preview}. e.g. [{"op":"create_sprite","width":16,"height":16,"palette":"pico8"},{"op":"draw","rows":["kk"],"legend":{"k":"#000"}},{"op":"edit","action":"outline"}] |
| run_luaB | Run Aseprite Lua (API 1.3). Globals: sprite (from path), params. Returns the script's return value. Saves unless save=false. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| pixel_art_passes | The multi-pass method for drawing a sprite or prop that looks hand-made instead of assembled from primitives. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 17 tools
Most tools target clearly distinct operations (draw vs edit vs animate vs generate vs character), with detailed descriptions that help separate them. Minor overlap exists between create_sprite's image import and ingest's frame import, and palette colors can also be read via sprite_info, but these are edge confusions rather than core ambiguity.
Mixed conventions: some tools use verb_noun (create_sprite, read_pixels, run_lua), many are bare verbs (draw, edit, resize, export, animate), and others are nouns (palette, layer, frames, character, batch). It's readable and each name hints at its domain, but there's no single predictable pattern.
17 tools is slightly above the ideal 3-15 range, but each tool bundles a coherent family of operations (edit, animate, character) rather than being a redundant one-off. The breadth of the pixel-art workflow (create, edit, animate, AI-generate, export) justifies the count.
The surface covers creation, editing, animation, AI ingestion/generation, and export with good lifecycle depth. Some gaps remain (no dedicated text, selection/tilemap, or undo/redo tooling), but run_lua serves as an escape hatch for arbitrary Aseprite Lua operations.