← Discover MCPs and Agents
a
MCPAPIs & IntegrationsGitHub

aseprite-mcp

MCP server for interacting with the Aseprite API

Links

README

From the repo.

Aseprite MCP Tools

A Python MCP server that gives AI assistants full control over Aseprite for creating pixel art and animated sprites.

104 tools across 17 categories — canvas, drawing, layers, animation, palettes, effects, slices, tilemaps, exports, visual-feedback/analysis tools, and a raw Lua escape hatch. The tool set is designed so an LLM has everything it needs to produce good pixel art, not just primitives: shading ramps with hue shifting, ordered dithering, outlines, retro palette presets with quantization, onion-skin renders, and frame diffing for animation work.

Example: a swordsman, drawn and animated by Claude

Pixel-art swordsman drawn by Claude Fable 54-frame sword slash animation by Claude Fable 5
Task 1"Draw me a pixel art of a swordsman."
32×32 still, exported at 10×.
Task 2"…a sword slash attack sequence, from windup to follow-through."
4-frame animation, exported with export_tag.
Slash sequence spritesheet: windup, extension, swing, follow-through
The same slash as a spritesheet (export_spritesheet): windup → extension → swing → follow-through.

Both were created end-to-end by Claude Fable 5 through this server's MCP tools — drawing, checking its own work with scaled export_frame previews and render_onion_skin, then exporting. The tasks recreate the benchmark from Draw Me a Swordsman by Lj Miranda, whose findings inspired this server's expanded toolset.

Tool Categories

CategoryToolsDescription
Canvas6Create sprites, manage layers/frames, set the active state
Drawing14Pixels, lines, rectangles, circles, ellipses, polygons, paths, fills, gradients
Text3Draw and measure text with bitmap sprite-sheet or TrueType fonts
Layers7Delete, rename, duplicate, reorder, blend modes, merge, flatten
Selection & Regions4Move, copy, and erase rectangular regions or colors
Effects5Outlines, color replacement, HSL adjustment, ordered dithering
Animation24Frames, cels, tags, tweening with easing, propagation
Palette8Get/set palettes, retro presets, color ramps, quantization, color modes
Transform4Flip, rotate, resize, crop
Slices5Named regions, 9-patch centers, pivot points
Tilemap5Tilemap layers, tileset editing, tile placement
Export & Import7PNG, GIF, sprite sheets, per-layer/per-tag export, image import
Inspection3Read pixels and sprite metadata
Analysis & Visual Feedback3Onion-skin renders, frame diffing, color statistics
Quality4Validate and sanitize animation consistency
Scene1Copy layers between sprite files
Preview & Guide3Local HTTP preview server, workflow guide
Scripting1Raw Lua escape hatch for anything not covered above

Canvas

ToolDescription
create_canvasCreate a new sprite with the given dimensions
add_layerAdd a new layer, optionally inside a named group
add_groupAdd a new (optionally nested) group layer
add_frameAppend a new frame
set_frameSet the active frame
set_frame_durationSet one frame's duration in ms
set_layerSet the active layer (optionally creating it)

Drawing

All _at variants target a specific layer/frame and can create the cel on demand. Coordinates are sprite-global.

ToolDescription
draw_pixelsPlot individual pixels with per-pixel colors
draw_pixels_atPlot pixels on a specific layer/frame
draw_line / draw_line_atLines with thickness
draw_rectangle / draw_rectangle_atOutlined or filled rectangles
draw_circle / draw_circle_atOutlined or filled circles
draw_ellipse_atOutlined or filled ellipses with separate x/y radii
draw_polygonOutlined or filled polygons from a point list
draw_pathPolyline through a point list with thickness
fill_area / fill_area_atPaint-bucket flood fill
apply_gradient_rectSmooth linear gradient fill in a rectangle

Text

Aseprite's Lua API has no text drawing, so glyphs are rasterised on the server and composited into the sprite. Two font backends are supported: bitmap sprite-sheet fonts (the right choice for pixel art — glyphs are already pixels and size scales them by whole numbers) and TrueType .ttf/.otf files, rendered without antialiasing unless you ask for it.

Fonts are discovered in ~/.aseprite-mcp/fonts: a bitmap font is a directory containing font.json plus its sheet PNGs; a TrueType font is just the font file. Installed system fonts are listed too. font also accepts a direct path.

ToolDescription
list_text_fontsList the bitmap and TrueType fonts available to draw_text
measure_textWidth, height, advance and baseline extents — size a panel or centre a label without redrawing to find out
draw_textDraw text with anchors, faux bold, outline, drop shadow and letter spacing

Call measure_text first when the layout depends on the text: it returns the same metrics draw_text will use, so a label can be centred or a plate sized in one pass.

measure_text(text="MODERATOR", font="minecraft", size=2, bold=1)
  -> width=115 height=15 advance_width=117 above_baseline=14 below_baseline=1 left_bearing=0

draw_text(filename="badge.aseprite", text="MODERATOR", x=64, y=17,
          font="minecraft", size=2, anchor="baseline", bold=1,
          color="#FFFFFF", shadow_color="#14237A")

Anchors are topleft/top/topright, left/center/right, bottomleft/bottom/bottomright, plus baselineleft/baseline/baselineright for pinning several labels to one baseline. Outline and shadow grow the stamp but never move the glyphs.

font.json

{
  "name": "my-font",
  "letter_gap": 1,
  "space_width": 3,
  "sheets": [{
    "file": "sheet.png",
    "cell_w": 8, "cell_h": 8,
    "ascent": 7,
    "chars": [" !\"#$%&'()*+,-./", "0123456789:;<=>?"]
  }],
  "overrides": {
    "86": {"ascent": 7, "rows": ["#...#", "#...#", ".#.#.", "..#.."]}
  }
}

Each sheet carries its own ascent, so sheets with different cell sizes still share a baseline — that is how a compact ASCII sheet and a taller accented sheet combine into one run. origin shifts the cell grid when the sheet has a margin, ink_rule: "dark" reads sheets that use an opaque white background to delimit variable-width glyph boxes, and advance: "box" takes the advance from the box rather than the ink. overrides replaces individual glyphs with hand-drawn rows, which is useful when a sheet ships a glyph that is off-centre or too tall to sit on the line.

Layers

ToolDescription
delete_layerDelete a layer by name
rename_layerRename a layer
duplicate_layerDuplicate a layer with all cels, opacity, and blend mode, optionally into a group
reorder_layerMove a layer to a position in the stack
set_layer_blend_modeSet blend mode (multiply, screen, overlay, ... 19 modes)
merge_layer_downMerge a layer into the one below it
flatten_spriteFlatten all layers into one

Selection & Regions

ToolDescription
move_regionCut a rectangle of pixels and paste it elsewhere
copy_regionCopy a rectangle to another position, layer, or frame
erase_regionMake a rectangle transparent
erase_colorMagic-eraser: make all pixels of a color transparent (with tolerance)

Effects

The pixel-art toolbox: clean outlines, palette-respecting blends, and shading variants.

ToolDescription
outline_celAdd a 1px outline around all opaque pixels
replace_colorReplace one color with another (with tolerance), preserving alpha
adjust_hslShift hue/saturation/lightness of a cel — palette swaps, night scenes, shadows
apply_dither_gradientTwo-color gradient using Bayer 4×4 ordered dithering
apply_dither_patternUniform dithered mix of two colors at a given density

Animation

ToolDescription
add_framesAppend N frames with optional duration
delete_frameDelete a frame
set_frame_duration_allSet every frame's duration
duplicate_frame_rangeDuplicate a frame range N times
copy_frame / propagate_frame_to_rangeCopy all cels of a frame to other frames
create_cel / clear_cel / copy_celCel lifecycle on a layer/frame
propagate_celsCopy selected layers' cels across a frame range
set_cel_positionPlace a cel at x,y
set_cel_opacitySet a single cel's opacity
offset_cel_positionsShift cels by a delta across frames
tween_cel_positionsLinear position tween across frames
tween_cel_positions_easedPosition tween with easing (ease_in/out, smoothstep)
tween_cel_opacity_easedOpacity tween with easing
tween_cel_scale_easedScale tween with easing and anchor
oscillate_cel_positionsSine-wave motion (bobbing, breathing, hovering)
set_tag / delete_tagAnimation tags with direction (forward/reverse/pingpong)
set_layer_visibility / set_layer_opacityLayer-level visibility and opacity
set_onion_skinConfigure onion-skin UI prefs (see render_onion_skin for batch use)
get_sprite_infoSprite metadata: size, layers, frames, durations, tags

Palette

ToolDescription
get_paletteRead the palette as hex colors
set_paletteSet the palette from a list of hex colors
list_palette_presetsList built-in retro palettes
apply_palette_presetApply a preset: gameboy, pico8, c64, cga, dawnbringer16, dawnbringer32, grayscale_4, monochrome
generate_color_rampBuild a dark→light shading ramp with hue shifting from a base color
quantize_to_paletteSnap every pixel to the nearest palette color
remap_colors_in_cel_rangeRemap specific colors across a frame range
set_color_modeConvert between RGB, grayscale, and indexed

Transform

ToolDescription
flip_layerFlip a cel horizontally or vertically
rotate_layerRotate a cel 90/180/270°
resize_canvasScale the sprite to new dimensions
crop_canvasCrop to a rectangle

Slices

ToolDescription
create_sliceCreate a named rectangular region
set_slice_centerSet the 9-patch stretchable center
set_slice_pivotSet the pivot point
list_slicesList all slices with bounds, centers, pivots as JSON
delete_sliceDelete a slice

Tilemap

ToolDescription
create_tilemap_layerAdd a tilemap layer with its own tileset and tile grid
draw_on_tilePaint pixels into a tileset tile (auto-appends new tiles)
set_tilesPlace tiles on the map by grid position
get_tile_atRead which tile occupies a grid cell
get_tilemap_infoTile size, tile count, and map dimensions as JSON

Export & Import

ToolDescription
export_spriteExport to PNG, GIF, JPG, ...
export_frameExport one frame as PNG with integer upscaling — the core visual-feedback loop: draw, export at 8×, look, iterate
export_spritesheetSprite sheet (horizontal/vertical/rows/columns/packed) with optional JSON metadata and per-tag filtering
export_layersOne PNG per layer
export_tagExport an animation tag as GIF or PNG sequence
import_image_as_layerImport a PNG into a layer (references, premade parts)
copy_spriteDuplicate the .aseprite file

Inspection

ToolDescription
get_pixel_colorRead one pixel's RGBA
get_pixels_rectRead a rectangle of pixels as JSON
get_sprite_infoSprite metadata (also listed under Animation)

Analysis & Visual Feedback

Batch-mode equivalents of what a human artist gets from the Aseprite UI.

ToolDescription
render_onion_skinRender a frame over translucent ghosts of neighboring frames — check motion continuity without opening Aseprite
compare_framesDiff two frames: changed pixel count, percentage, bounding box
get_color_statsColor histogram of a frame — catches palette drift and near-duplicate colors

Quality

ToolDescription
ensure_layers_presentCreate missing cels for layers across a frame range
validate_sceneReport missing layers/cels as JSON
audit_animationAudit frames for overlaps and out-of-range layer activity
animation_sanitizeNormalize layer order, coverage, and overlaps

Scene

ToolDescription
copy_layers_between_spritesCopy layers by name from one .aseprite file to another

Preview & Guide

ToolDescription
start_preview_server / stop_preview_serverServe exported files over local HTTP
animation_workflow_guideReturns a step-by-step workflow guide for the LLM

Scripting

ToolDescription
run_lua_scriptExecute arbitrary Aseprite Lua (API docs) in batch mode. The escape hatch when no dedicated tool fits: one script can batch many operations into a single Aseprite launch. Remember to spr:saveAs(spr.filename) and print() your results. ⚠️ Runs unrestricted code on the host — only pass scripts you trust.

Recommended Workflow for LLMs

  1. Plan the palette first: generate_color_ramp for each material (skin, armor, blade), or apply_palette_preset for a retro look.
  2. Build in layers: background / body / equipment / effects, so parts can be animated and edited independently.
  3. Draw coarse to fine: silhouette with draw_rectangle_at / draw_ellipse_at / fill_area_at, then refine with draw_pixels_at.
  4. Look at your work: export_frame at 8×, inspect, fix, repeat. Use get_color_stats to keep the palette tight.
  5. Shade with intent: adjust_hsl for shadow layers, apply_dither_gradient for blends, outline_cel for readability.
  6. Animate with the cel tools: propagate_cels, then tween_cel_positions_eased / oscillate_cel_positions; verify with render_onion_skin and compare_frames; export with export_tag.

Docker Usage

Quick Start

Build and run the Docker image:

docker build -t aseprite-mcp:latest .
docker run -it --rm aseprite-mcp:latest

Or use the provided build scripts:

  • Linux/macOS: chmod +x build-docker.sh && ./build-docker.sh
  • Windows: .\build-docker.ps1

Using Docker Compose

# Production
docker-compose up aseprite-mcp

# Development mode
docker-compose --profile dev up aseprite-mcp-dev

See DOCKER.md for detailed Docker setup instructions.

Optional: Install Aseprite via Steam

To have the container install Aseprite via SteamCMD at startup, provide Steam credentials:

# Create a .env with STEAM_USERNAME/STEAM_PASSWORD (and optional STEAM_GUARD_CODE)
# Then
docker run --rm -i --env-file .env aseprite-mcp:latest

If installed, the binary will be at /opt/steamapps/common/Aseprite/aseprite and ASEPRITE_PATH will be picked up automatically.

Local Installation

Prerequisites

  • Python 3.13+
  • uv package manager
  • Aseprite (set ASEPRITE_PATH in .env if it is not on your PATH)

Installation:

{
  "mcpServers": {
      "aseprite": {
          "command": "/opt/homebrew/bin/uv",
          "args": [
              "--directory",
              "/path/to/repo",
              "run",
              "-m",
              "aseprite_mcp"
          ]
      }
  }
}

Collected info

  • 572 stars
  • 61 forks
  • Language: Python
  • Source updated: 9/19/2026

Config for your environment

Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.

Tool

OS

Config file: ~/.cursor/mcp.json

{
  "mcpServers": {
    "mcp-server": {
      "url": "{MCP_ENDPOINT_URL}"
    }
  }
}

Paste into mcpServers in the config file. Restart Cursor after saving.

If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.