Open source • MIT • Python

LenkRaster

I built LenkRaster to give my own pixel art a second read before I call a sprite finished. It runs on your machine and looks at your files. What comes back is a structured finding with the measurement attached, so you get a specific thing to go and check. It does not draw for you, and it does not sign off on your work.

View on GitHub ▸ See the examples
The LenkRaster banner. The name LENKRASTER runs across it in heavy black type, above a yellow bar reading Bounded pixel-art tools and five colored chips labeled Critique, Palettes, Motion, Aseprite and MCP. On the right a pixel-art anvil throws pink and yellow sparks beside a panel of pixel tool icons. A line along the bottom reads: a Ryan Lenk open source tool, ryanlenk.com.
LenkRasterAn open source pixel-art toolkit from Ryan Lenk. It is bounded on purpose: every check has a limit, every output is additive, and every report is advisory.

What it does

Craft critique

It scores a PNG sprite against pixel-craft checks and hands back structured findings with retry hints attached. Every finding tells you what it measured. That was the part I cared about most, because a number you can see is a number you can argue with.

Palette and contrast

It reports palette structure and contrast, and it builds hue-shifted color ramps in OKLCH. I treat what comes back as a starting point for a readable palette. Which colors are correct for your game is taste, and your taste is not something I want to automate.

Quantization and dithering

It maps your artwork onto a controlled palette, with ordered dithering available when you want it. Your original file stays exactly where it was, so you can put the two side by side and keep whichever one you actually prefer.

Animation-cycle QA

It measures frame-to-frame motion, timing and loop consistency with rendered-pixel math, which is how it surfaces the frames worth another look. Whether your cycle reads correctly to a person watching it is still your call, and it always will be.

Aseprite bridge

An optional bridge to the Aseprite command line reads .ase and .aseprite files directly. I kept it optional on purpose, so nothing in the toolkit breaks for anyone who does not have Aseprite installed.

Python, CLI and MCP

You can use it as a Python API, from the command line, or through a local stdio MCP server, which is what lets an agent run the same bounded checks I run by hand. Install it with pip install lenkraster on Python 3.10 or newer.

Examples

Three views out of the repository. Every image below is a real output. I measured the numbers in the captions from the files themselves rather than copying them out of the README.

Four frames of a brass blacksmith automaton swinging a hammer, side by side left to right: hammer raised overhead, mid-swing, striking in a burst of orange sparks, then back at rest. This is the artwork before any palette work, and its shading blends through thousands of near-identical colors.
Before: the source cycleA four-frame hammer cycle as drawn. Measured straight from the file, it carries 77,766 distinct colors. That is what you would expect from artwork that has been through a program that blends or scales.
The same four hammer-swing frames after mapping to one fixed 48-color palette. The poses, the sparks and the timing are unchanged, and the shading now steps through a small set of flat colors that every frame shares.
After: one fixed paletteThe same four frames mapped to a single fixed palette of 48 colors, down from 77,766. Your source file is untouched and sits right beside it, so this is deliberate palette exploration and not an automatic improvement. Which version ships is a decision you make by looking at both of them.
One cycle, two jobs.
Those two images are the same artwork doing double duty on this page. Read as a pair they show quantization against a fixed palette, and read as four frames of one swing they are also what the animation checks work on, measuring the motion between frames and whether the loop closes cleanly.

Built for

Pixel artists

A second pass over your sprite before you call it done, with the reasoning shown so that you can disagree with it on the evidence.

Indie game developers

Consistent palettes and readable sprites across an asset folder that keeps growing, all of it checkable from the command line.

Tool builders

A Python API and a documented command line, so that these checks can sit inside your own pipeline instead of beside it.

Local AI-agent workflows

A stdio MCP server that lets an agent run the same bounded checks on your own machine, with no key to manage and no network call to trust.

Safety and scope

What the boundaries actually are

  • Local stdio only, which means the MCP server talks over stdio and nothing else. There is no network listener, no HTTP transport and no authentication layer, because there is nothing exposed that would need authenticating.
  • An explicit trusted workspace, so paths get resolved and then contained to a root that you name yourself, which keeps the tool from wandering around the rest of your disk.
  • Bounded workloads, with limits on encoded bytes, decoded pixels, frames, discovery, and total work per request. A file that is too large gets refused, so nothing runs away with your machine while you are looking at something else.
  • Create-only outputs, meaning generated files are written as new files and your originals stay exactly as you left them.
  • Advisory results, so a report points at things worth looking at and stops there, because it is not approval and was never built to be.
What it will not do.
LenkRaster does not produce finished artwork, it does not stand in for an artist, and it does not guarantee that anything is good. It has no opinion on whether you own the art it reads. Human art direction, provenance review and your own release gates all still apply, and I would not hand any of those three to a script.

Under the hood

  • Python
  • Aseprite
  • MCP
  • Pixel art
  • Image processing
  • Local-first
  • Open source
  • MIT
  • NumPy
  • Pillow
  • OKLCH
  • CLI

Questions

Does LenkRaster make pixel art for me?

No, it reads art you already have and reports back on it. The one thing it writes is a converted copy, such as a palette-mapped version sitting beside your original. Even that is a starting point for you to judge, not a finished asset.

Does it send my artwork anywhere?

Nothing leaves your machine, because there is nowhere for it to go. The MCP server speaks over stdio with no network listener and no HTTP transport, and the toolkit itself needs no API key and no account.

Do I need Aseprite to use it?

You do not, because the Aseprite command-line bridge is optional and only matters when you want to read .ase or .aseprite files directly. Everything on the PNG path needs nothing beyond the install itself.

Will it overwrite my original files?

No, and that is the one guarantee I will make. Outputs are create-only. A generated file lands as a new file rather than on top of the one you handed it, which is why both images further up this page still sit side by side in the repository.

What does an advisory report mean in practice?

It means a finding is a thing to go and look at, with the measurement attached, and nothing more than that. Passing every check is not approval, and a flagged frame is not proof of a mistake. I keep the judgement with whoever is responsible for the art, which on your project is you.

How do I install it?

It is on PyPI. pip install lenkraster gets you the library, the command line tools and the MCP server, on Python 3.10 or newer. The repository carries the current instructions and I would just trust those over this page, since I update the repo first.

Can I use it in a commercial project?

The code is MIT licensed, and the repository carries separate notices covering the example assets and the third-party components. Read those before you reuse anything out of the repo itself. The license on a piece of code and the license on an image are two different questions.

View on GitHub ▸ All side projects

LenkRaster is one of the open source tools I build and use in the open. The repository is the source of truth for installation, the Python API, the command line, the MCP server, the security policy and the examples. When this page and the code disagree, the repository wins: github.com/itsryanlenk/lenkraster. Every image on this page comes straight out of that repository. The rest of what I build in the open is over on side projects.