Skip to content

Install Aseprite AI Artist

You need Aseprite 1.3 or later and Node.js 22.6 or later, on macOS, Linux or Windows. Three commands, about a minute.

  1. Install the Aseprite extension

    This puts the bridge into Aseprite. Quit and reopen Aseprite afterwards. Run it again to update.

    npx @pebbly/aseprite-ai-artist install-extension
  2. Connect your agent

    Pick the agent you use.

    Claude Code

    Type these in a Claude Code session.

    /plugin marketplace add with-pebbly/aseprite-ai-artist
    /plugin install aseprite@aseprite-ai-artist

    omp

    Run these in your shell.

    omp plugin marketplace add with-pebbly/aseprite-ai-artist
    omp plugin install aseprite@aseprite-ai-artist

    Codex, Gemini CLI, Cursor, VS Code, Windsurf

    Swap codex for gemini or cursor, or pass --all. Your config is backed up first; --dry-run shows the change.

    npx @pebbly/aseprite-ai-artist install codex
  3. Check it

    Restart your agent, then run the doctor. All ticks means you are ready.

    npx @pebbly/aseprite-ai-artist doctor

Your first drawing

Open a sprite in Aseprite and ask your agent for something, for example "Draw me a 32×32 knight in the PICO-8 palette, then give him a 4-frame idle." In Claude Code, /aseprite:studio runs the whole job.

Full install guide

View on GitHub

Every agent, project scope, headless mode, troubleshooting and uninstalling.

Install

Two pieces: an Aseprite extension (so Aseprite can be driven) and an MCP server (so your agent can drive it). The extension is the same in every case; only the agent wiring differs.

Requirements

  • Aseprite 1.3 or newer. The Lua WebSocket API this depends on does not exist in 1.2.
  • Node 22.6 or newer.
  • Aseprite must have been run at least once, so its config directory exists.

1. Install the Aseprite extension

npx @pebbly/aseprite-ai-artist install-extension

Then restart Aseprite. It connects on startup.

If the config directory cannot be found, the command prints where it looked; pass --dir <path> to override. On macOS it is ~/Library/Application Support/Aseprite, on Windows %APPDATA%\Aseprite, on Linux ~/.config/aseprite.

2. Wire up your agent

Everything at once

npx @pebbly/aseprite-ai-artist install --all --agents

Writes config for Claude Code, Codex, Gemini CLI, Cursor, VS Code and Windsurf, and adds an AGENTS.md section for the clients that read one. Existing config files are backed up first (.bak-<timestamp>), and --dry-run prints the change without making it.

Workflow names

Every client sees the same fourteen workflows under the same names: aseprite:studio (the front door — give it any request and it picks and runs the rest), aseprite:brief, aseprite:concept, aseprite:new, aseprite:palette, aseprite:draw, aseprite:shade, aseprite:rig, aseprite:animate, aseprite:tileset, aseprite:review, aseprite:fix, aseprite:export, aseprite:submit.

Client How they appear
Claude Code (plugin) /aseprite:draw — plugin skills
omp (plugin) /aseprite:draw — commands from the omp extension
Gemini CLI, Cursor, other prompt-aware MCP clients MCP prompt aseprite:draw
Codex, and any client without prompts resource skill://draw; the server instructions list the names

Claude Code

The plugin is the better route — it brings the /aseprite:* workflows, the specialist subagents and the hooks, not just the tools:

/plugin marketplace add with-pebbly/aseprite-ai-artist
/plugin install aseprite@aseprite-ai-artist

Installed before the rename, as aseprite-ai-artist? Uninstall that one first (/plugin uninstall aseprite-ai-artist) — the plugin ID changed so the commands could be aseprite:*, and both copies would start a server.

Or wire the server alone:

npx @pebbly/aseprite-ai-artist install claude

omp (oh-my-pi)

omp installs the same plugin from its own marketplace:

omp plugin marketplace add with-pebbly/aseprite-ai-artist
omp plugin install aseprite@aseprite-ai-artist

The skills, subagents and MCP server come from the same tree Claude Code reads. omp does not run Claude's hooks/hooks.json, so the plugin ships the two hooks again as an omp extension (omp/aseprite-ai-artist.mjs, declared in package.json under omp.extensions): the bridge status on the first prompt and the once-per-session nudge to look after a mutating call.

omp lists plugin skills as /skill:<name>, so the same extension registers the /aseprite:* commands itself, from the same SKILL.md files. They inject the skill as a prompt, with anything typed after the command as the request.

omp also imports Claude Code's plugins. Install it in omp under the same ID as in Claude Code — omp's registry wins for a shared ID, so this replaces the imported copy instead of starting a second server. For the same reason, do not also run install claude: omp reads ~/.claude.json too, and you would load every tool twice.

From a checkout, point the marketplace at the directory instead:

omp plugin marketplace add /path/to/aseprite-ai-artist
omp plugin install aseprite@aseprite-ai-artist

omp copies the tree into its plugin cache, so after changing it run omp plugin marketplace update aseprite-ai-artist and omp plugin install --force aseprite@aseprite-ai-artist, then restart the session.

Codex CLI

npx @pebbly/aseprite-ai-artist install codex

Writes [mcp_servers.aseprite-ai-artist] into ~/.codex/config.toml. Codex uses TOML — the JSON config from other clients will not work, which is a common source of "it silently does nothing".

Codex does not expose MCP prompts, so the skills do not appear as commands there. It does read MCP resources, which is where the same skill content lives (skill://draw and friends), and in practice it finds and follows them on its own — verified against Codex CLI 0.145.0.

Gemini CLI

npx @pebbly/aseprite-ai-artist install gemini

Cursor

npx @pebbly/aseprite-ai-artist install cursor

Project scope instead of user scope

npx @pebbly/aseprite-ai-artist install codex cursor --project

Writes into the current directory (.codex/config.toml, .cursor/mcp.json) so the setup travels with the repository.

Headless: no Aseprite window

npx @pebbly/aseprite-ai-artist install codex --headless --aseprite /path/to/aseprite

Writes ASEPRITE_AI_HEADLESS=1 (and ASEPRITE_PATH) into the client config. The server then runs one batch Aseprite (aseprite -b) itself; neither the extension nor the bridge is involved. For the Claude Code and omp plugins, set ASEPRITE_AI_HEADLESS=1 — and ASEPRITE_PATH if Aseprite is not in a standard place — in the environment the agent is started from.

Without --aseprite/ASEPRITE_PATH the server looks in the standard and Steam install locations, then on PATH. doctor prints the one it would use:

✓ Aseprite executable   /Applications/Aseprite.app/Contents/MacOS/aseprite (used by --headless)

Documents live in memory until saved (sprite_manage save/save_as) or exported — the agent is told so by preflight.

3. Check it

npx @pebbly/aseprite-ai-artist doctor
aseprite-ai-artist 0.1.0

✓ Aseprite config dir   /Users/you/Library/Application Support/Aseprite
✓ Bridge                 ws://127.0.0.1:9932
✓ Aseprite extension     0.1.0 on Aseprite 1.3.17-arm64
  features               draw_batch, recolor, validate, tileset, reference, filmstrip
✓ Active sprite          knight.aseprite

Then restart your agent so it picks up the new server, and ask it to call preflight.

Troubleshooting

"Aseprite extension not connected" — Aseprite is closed, or the extension is not installed, or it was installed while Aseprite was running. Install, then restart Aseprite. Check Edit ▸ Preferences ▸ Extensions for Aseprite AI Artist.

To tell "never loaded" apart from "loaded but could not connect", look for the marker the extension writes on startup:

<Aseprite config dir>/aseprite-ai-artist.status

No file at all means Aseprite never ran the script — the extension is not installed or not enabled. "state": "loaded" means it ran but never reached the bridge. "state": "connected" means the link is up and the problem is elsewhere.

A dialog is blocking startup — Aseprite gates script access to the network and filesystem, and a brand-new config directory also shows a first-run dialog. Either will stop the extension from connecting until dismissed. If this is the very first time Aseprite has run on this machine, open it once and dismiss whatever it asks before installing.

The agent draws nothing and reports success — it is editing files on disk instead of the live window. That should be impossible: every tool refuses with not_connected and doNotFallBackToDisk. If you see it, please open an issue with the transcript.

Ports already in use — something else owns 9931/9932. Move both:

npx @pebbly/aseprite-ai-artist install --all --plugin-port 9941 --control-port 9942

and set ASEPRITE_AI_PLUGIN_PORT in Aseprite's environment to match.

A reconnect is not happening — the extension's reconnect timer runs on Aseprite's UI loop. Click the Aseprite window once. A connection that is already live keeps working unfocused; only re-establishing a dropped one needs focus.

Running from a checkout

git clone https://github.com/with-pebbly/aseprite-ai-artist
cd aseprite-ai-artist
pnpm install && pnpm run build
node dist/cli.js install --all
node dist/cli.js install-extension

Use node dist/cli.js, not npx @pebbly/aseprite-ai-artist, and only inside this checkout. npm sees that the current project is that package, so it skips fetching it and looks for the binary in node_modules/.bin — where a package's own bin is never linked. You get:

sh: aseprite-ai-artist: command not found

which reads like a broken package and is only ever a wrong working directory. The npx form is correct everywhere else.

Uninstall

Delete the aseprite-ai-artist directory from Aseprite's extensions folder, remove the server entry from your agent's config (in omp: omp plugin uninstall aseprite@aseprite-ai-artist), and stop any running bridge:

pkill -f "aseprite-ai-artist bridge"    # macOS / Linux

On Windows there is no pkill — end the node process running aseprite-ai-artist bridge from Task Manager, or:

Get-CimInstance Win32_Process |
  Where-Object CommandLine -like '*aseprite-ai-artist*bridge*' |
  ForEach-Object { Stop-Process -Id $_.ProcessId }