Skip to content

trebeljahr/sprite-tools

v0.1.0

Generate video with your local provider keys and export transparent sprite sheets with collision metadata.

sprite-tools

npm CI Web app License Node

A batteries-included toolkit for turning AI-generated or hand-drawn sprites into game-ready 2D assets: background removal, duplicate-frame removal, collision polygons, pivot anchors, animation tags with per-frame timings, nine-slice borders, pixel-art conversion and upscaling, normal maps, outlines and drop shadows, palette and shading-ramp recoloring, atlas packing, GIF export, .aseprite file import, and engine-native export for Godot, Unity, Aseprite, and Phaser.

Three surfaces, one shared pipeline:

  • Web app — interactive browser-based tools at sprites.trebeljahr.com for local sprite editing. Video generation uses the local companion and your provider key.
  • CLI (sprite-tools) — Composable subcommands. Pipe-friendly, JSON on stdout, stdin on -.
  • MCP server (sprite-tools-mcp) — exposes every tool over Model Context Protocol so Claude Desktop (and any MCP client) can drive the pipeline directly.

All three surfaces call the same algorithm modules and emit the same JSON shapes. Mix them freely.

Try it online

Open sprites.trebeljahr.com to use the tools in your browser. Images stay local to the page unless you opt into an AI-powered flow that explicitly calls an external service.

Good starting points:

  • Sheet Lint — the one to open first: what a sheet is, and what is wrong with it, drawn onto the sheet.
  • Sheet Builder — turn video, GIF, loose frames, or an .aseprite file into a clean sheet.
  • Background Removal — chroma-key a flat background out of every frame.
  • Collision — trace tight polygons for physics engines.
  • Pixelate — convert sprites into limited-palette pixel art, or upscale existing pixel art with Scale2x, Scale3x, Eagle, or xBR.
  • Outline & Shadow — add an outline and a drop shadow to a sprite or a sheet.
  • Atlas — pack loose sprites into one PNG plus JSON.
  • Export — turn that metadata into a Godot, Unity, Aseprite, or Phaser file.
  • Docs — quickstart, CLI reference, MCP setup, schemas, and algorithm notes.

Project status

sprite-tools is actively maintained. The npm package ships the CLI and MCP server; the deployed web app is the interactive reference implementation for the same algorithms. Issues, bug reports, and focused pull requests are welcome.

Quick taste

# Start here on a sheet you know nothing about: detected grid, frame count, findings
sprite-tools lint unknown-sheet.png --format text

# Gate CI on it — exit 1 on error-severity findings, full JSON report still on stdout
sprite-tools lint hero.png > lint-report.json

# Auto-detect grid, generate collision polygons + pivots + tags in one shot
sprite-tools meta hero.png \
  --collision --tolerance 4 \
  --pivot bottom-center \
  --tag idle=0-3 \
  --tag run=4-7:12:pingpong \
  --tag attack=8-11 \
  -o hero.json

# Slice a tileset that has a 1px border and 2px gutters between cells
sprite-tools slice tileset.png --cols 8 --rows 6 --margin 1 --spacing 2 --out-dir tiles

# Read an .aseprite file: one tag as a sheet PNG, plus tags, frame durations, layers, and palette as JSON
sprite-tools ase hero.aseprite --tag run -o run-sheet.png --json run.json
# That JSON is sheet metadata, so export reads it and keeps Aseprite's frame durations
sprite-tools export run.json --format godot -o run.tres

# Chroma-key a flat background out and crop to the content
sprite-tools chroma hero.png --color '#00ff00' --trim -o hero-cut.png

# Guess nine-slice borders for a UI panel, then check them with a stretched preview
sprite-tools nine-slice panel.png --preview panel-stretched.png -o panel-9s.json

# Drop repeated frames from a video extraction and rewrite the tag ranges to match
sprite-tools dedupe walk-sheet.png --cols 8 --rows 4 --threshold 1 \
  --tags walk-tags.json --tags-out walk-tags-deduped.json \
  --sheet walk-deduped.png -o dedupe.json

# Hand that metadata to an engine — Godot 4 SpriteFrames, Unity .meta, Aseprite, Phaser
sprite-tools export hero.json --format godot -o hero.tres

# Turn any sprite into Game Boy pixel art
sprite-tools pixelate hero.png --pixel-size 4 --palette gameboy --dither -o hero-gb.png

# Add a 2px outline and a soft drop shadow
sprite-tools outline hero.png --width 2 --shadow --shadow-blur 2 -o hero-fx.png

# Upscale existing pixel art 4x with Scale2x (no downscale, no quantization)
sprite-tools pixelate hero.png --pixel-size 1 --colors 0 --upscale-algo scale2x --upscale-factor 4 -o hero-4x.png

# Derive a normal map for 2D lighting
sprite-tools normal-map hero.png -o hero-normal.png

# Re-tint a whole shading ramp, then spin out 8 enemy color variants + a manifest
sprite-tools palette hero.png --ramp '#4d7faf=#af4d4d' --image hero-red.png
sprite-tools palette hero.png --hue-variants 8 --out-dir variants --manifest variants/hero.json

# Pack a folder of loose sprites into an atlas + TexturePacker manifest
# (sprite edges are extruded 1px into the gutter by default — no filtering halos)
sprite-tools atlas sprites/*.png -o atlas.png --json atlas.json

# Pipe stdin to stdout
cat hero.png | sprite-tools trim - -o - | sprite-tools collision -

Install

Published on npm as @trebeljahr/sprite-tools. One install ships both the sprite-tools CLI and the sprite-tools-mcp server.

# Global install — both binaries on your PATH
npm install -g @trebeljahr/sprite-tools

# Or run any command one-off without installing
npx @trebeljahr/sprite-tools meta hero.png --collision -o hero.json

Requires Node 20+. PNG I/O is pure JS. Video Studio additionally requires ffmpeg and ffprobe on your PATH. Full install options (pnpm, MCP client config, building from source) live in the install docs.

Local Video Studio

Run sprite-tools studio, open its private setup link, and add a Google or xAI key to the encrypted local vault. Set a total and per-job spending limit before generating. The default budget is zero.

The local Web UI accepts prompts, concept art, and supported first/end frame controls. One job generates video, removes the background, and exports a sprite sheet with timing, pivots, collision polygons, and bounding hitboxes. Existing video can be imported or reprocessed without generation charges.

Local MCP clients use the same running companion through five sprite_video_* tools. Keys stay out of chat and tool arguments. See the runtime and security contract.

MCP in Claude Desktop

Add to claude_desktop_config.json (macOS path: ~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "sprite-tools": { "command": "sprite-tools-mcp" }
  }
}

Restart Claude Desktop — the sprite tools appear under the MCP menu. If sprite-tools-mcp isn't on the PATH Claude sees (common with nvm/fnm), set command to the absolute path printed by which sprite-tools-mcp.

What's in the box

Web app: /spritesheet, /background-removal, /lasso, /lint, /collision, /pivot, /tags, /nine-slice, /pixelate, /normal-map, /outline, /palette, /atlas, /gif, /export, /generate (AI Character), and /animate (AI Animation).

CLI: lint, info, detect, slice, trim, aseprite (alias ase), dedupe, chroma (alias remove-bg), collision, pivot, tags, nine-slice, meta, palette, pixelate, normal-map, outline, atlas, gif, export.

MCP: Tools with typed Zod input schemas (outline splits into sprite_add_outline and sprite_add_shadow; palette adds sprite_detect_ramps and sprite_palette_variants; aseprite is sprite_read_aseprite).

Docs

Full docs live in the app at sprites.trebeljahr.com/docs. Highlights:

  • Quickstart — 5 minutes end-to-end.
  • Install — web app, CLI, MCP, npm, and source setup.
  • Web app guide — Sheet Builder, Background Removal, Lasso, metadata tools, transforms, exports, and AI flows.
  • CLI reference — every flag + output shape.
  • JSON schemas — the canonical data contract shared across all surfaces.
  • Aseprite files — what the .ase / .aseprite reader supports, what it skips, and the warnings it reports.
  • Engine export — what the Godot / Unity / Aseprite / Phaser files contain, and where each one is lossy.
  • Algorithm notes — how grid detection / contour tracing / duplicate detection / bin packing work.
  • Contributing — how to add a new tool.

Or run the app locally: pnpm install && pnpm dev, then open http://localhost:3471/docs.

Community and maintenance

Architecture

src/lib/**             # pure algorithm modules (ImageData in, JSON/ImageData out)
cli/commands/**        # CLI wrappers via commander + pngjs
mcp/tools.ts           # MCP server (Zod schemas)
src/app/**/page.tsx    # web app routes (static export, served by a Cloudflare Worker)
src/app/docs/**        # MDX docs
packages/server/**     # accounts API under /api (Better Auth + PostgreSQL)
tests/**.test.ts       # vitest on every algorithm

Every tool has the same shape: a pure function, a CLI wrapper, an MCP tool, a React page. Adding new functionality means mirroring that pattern once.

Development

git clone https://github.com/trebeljahr/sprite-tools.git
cd sprite-tools
pnpm install

# Web app (Next.js) on :3471 and the accounts API on :3472
pnpm dev                # http://localhost:3471

# CLI / MCP — run uncompiled against TS source
pnpm cli:dev -- detect my-sheet.png
pnpm mcp:dev

# CLI / MCP — build, then symlink as global commands
pnpm install-local      # cli:build + mcp:build + npm install -g .

# Tests / typecheck / lint
pnpm test
pnpm typecheck
pnpm lint

Releasing

@trebeljahr/sprite-tools ships from the repo root. The published tarball is scoped via the files field in package.json and contains dist/cli/, dist/mcp/, the compiled dist/src/lib/ algorithm modules, the README, and the LICENSE — none of the Next.js app code or its dependencies.

pnpm release           # patch bump (default)
pnpm release:minor
pnpm release:major

Each command runs in this order:

  1. release-prep — refuses to release if the working tree is dirty or if the local version is behind what's already on npm.
  2. release-bump — bumps package.json, commits, and tags atomically.
  3. _release:finish — builds the CLI + MCP, typechecks, npm publishes, and pushes the tag.

prepublishOnly re-runs the CLI + MCP builds as a final safety net before npm uploads the tarball.

License

MIT. See LICENSE.