Skip to main content
Glama

PixelSmith

Pixel art as text. Claude draws sprites by writing rows of characters and drawing commands through an MCP connector; every save returns a zoomed preview with coordinates, real-size copies, a silhouette and automatic checks. Humans view and paint the same sprites in a web page from any device.

Try it: https://pixelsmith.aleksanderbryhnreitan.no — a painter anyone can use (it keeps everything in your own browser) and a step-by-step setup guide in Norwegian.

Run your own

Free on the free plans of GitHub, Vercel, Upstash and Claude; no programming.

  1. Make a secret: a long random password, e.g. openssl rand -base64 32, or the generator on the setup page. Keep it somewhere safe.

  2. Deploy: Deploy to Vercel. Vercel copies this repository to your GitHub, creates a free Upstash for Redis database (pick the Free plan and a region near you) and asks for MCP_SECRET: paste the secret.

  3. Find your address: the short one under Domains on the project's page, e.g. pixelsmith-you.vercel.app. The long per-deployment addresses sit behind Vercel's login and Claude can't reach them.

  4. Connect Claude: in claude.ai or the Claude app, **Customize → Connectors →

    • → Add custom connector**. Name PixelSmith, URL https://YOUR-ADDRESS/api/mcp?k=YOUR-SECRET, authentication No sign-in. Switch it on in a chat under + → Connectors. For Claude Code:

    claude mcp add --transport http --scope user pixelsmith "https://YOUR-ADDRESS/api/mcp?k=YOUR-SECRET"
  5. Paint by hand: open https://YOUR-ADDRESS/?k=YOUR-SECRET once per browser. It swaps the secret for a year-long cookie and removes it from the address bar.

The secret travels in the address because custom connectors on most Claude plans can't send any other kind of password yet, so treat both links like passwords. To change it: edit MCP_SECRET in the Vercel project's settings, redeploy, and update the connector's URL.

Settings

Variable

Needed

What it does

MCP_SECRET

yes

The one secret that guards the connector, the painter and the HTTP API.

KV_REST_API_URL / KV_REST_API_TOKEN

yes, on Vercel

The Upstash Redis database; set by Vercel when the database is connected. Any *_KV_REST_API_* or *_REDIS_REST_* pair works. Without one, a local run keeps everything in memory.

PUBLIC_HOST

no

An address (e.g. pixelsmith.example.com) whose front page shows the public showcase from public/site/ instead of the private painter.

Pages

  • / — your painter (behind the secret), or the showcase on PUBLIC_HOST.

  • /tegn — the public painter: no secret, everything kept in the visitor's own browser, no connection to your sprites.

  • /oppsett — the setup guide (Norwegian).

Related MCP server: aseprite-mcp

The sprite format

A sprite is w × h rows of single-character colour keys; . is transparent. Keys come from the project's palette plus the sprite's own colors. Projects hold palettes, colour swaps (named recolourings, e.g. rarity tiers) and sprites. The guide tool returns the full reference, including every drawing command.

A palette can also hold ramps: named runs of its keys from dark to light (steel = 12345). The shading commands work along them — shade turns a flat area into a lit, rounded form; gradient, dither and texture (wood grain, stones, grit, bricks, cloth) add surface; selout colours the outline on the lit side. Any command can be limited to certain existing colours (in=, not=) or a rectangle (box=), so a shape becomes a brush that only paints onto, say, the metal of a blade.

For animation, stamp can paste a part turned by any angle and lift can move or turn a piece of the sprite in place (both RotSprite-style), and arc draws curved strokes such as motion streaks. Turning pixel art by an odd angle still roughens it, so for poses that matter the better way is to draw the moving part again at its new angle. The animate tool plays sprites in order at 12 ticks a second, lined up by their feet, and returns a filmstrip, an onion skin and a looping GIF.

Tools

guide, projects, project, create_project, set_palette, set_swap, put_sprite, edit_sprite, view_sprite, sheet, mockup, animate, rename_sprite, copy_sprite, delete_sprite, history, restore_sprite, export.

The same tools are available over plain HTTP at POST /api/tool/<name> (JSON arguments in, { ok, text, images[] } out), which is what the helper uses.

The PC helper

node scripts/ps.mjs tools
node scripts/ps.mjs view_sprite '{"project":"demo","name":"potion"}'
node scripts/ps.mjs edit_sprite < args.json
node scripts/ps.mjs pull <project> "<game folder>"      # PNGs + manifest into a game

Images come back as files in %TEMP%\pixelsmith (or $PIXELSMITH_OUT). pull only ever deletes files a previous pull wrote (tracked through manifest.json), plus Godot's .import file next to a removed PNG.

Export layout

png/NAME.png (1x), png/NAME@SWAP.png for each swap that applies to the sprite, src/NAME.json (the source), project.json (palettes and swaps), and manifest.json listing every sprite with its size, tags and files.

How it's built

  • Next.js 15 on Vercel; mcp-handler for the connector (single secret, 403 on failure so MCP clients don't start an OAuth flow).

  • app/painter.tsx — the web painter, in two modes (lib/painter/backend.ts): your sprites on the server behind the secret, with live updates while Claude draws, or the public /tegn one that keeps everything in the browser's local storage.

  • public/site/ — the showcase and setup guide, plain HTML built by scripts/build_site.py from the art in brand/ (scripts/brand.ts, scripts/brand_preview.py).

  • lib/core/ — sprite model, drawing commands, checks. No Node-only imports; the web painter uses the same code.

  • lib/render/ — raster drawing, a 3x5 label font, PNG and GIF encoders, and the preview / sheet / mockup / animation images.

  • lib/store.ts — Upstash Redis (connected through the Vercel project's Storage tab). Chosen over Vercel Blob because Blob's free tier allows 2,000 writes a month shared with every other connector on the account and locks them all for 30 days when exceeded. Falls back to an in-memory store when run locally.

  • Every sprite keeps its last 20 versions, including after deletion.

  • Server functions run in Frankfurt (vercel.json → fra1), next to the database and close to Norway. Keep the two in the same region.

Working on it

npm test                   # offline checks of the drawing core; images in out-local/
npx next build             # production build
npx vercel@latest deploy --prod

Test locally against the production build only (next build then MCP_SECRET=... npx next start -p 3123), never the dev server.

Related MCP Connectors

Related MCP Servers