Skip to main content
ClaudeWave

An API for an LLM to create images via brush strokes

SubagentsRegistry oficial0 estrellas0 forksPythonMITActualizado today
ClaudeWave Trust Score
87/100
Trusted
Passed
  • Open-source license (MIT)
  • Actively maintained (<30d)
  • Clear description
  • Documented (README)
Last scanned: 9/13/2026
Install as a Claude Code subagent
Method: Clone
Terminal
git clone https://github.com/Gemberkoekje/EaselAPI && cp EaselAPI/*.md ~/.claude/agents/
1. Clone the repository and copy the agent .md definitions into ~/.claude/agents (or .claude/agents inside a project).
2. Start a new Claude Code session to load the agents.
3. Delegate work to them with the Task/Agent tool or by name.
Casos de uso

Resumen de Subagents

# Easel

**Can an LLM paint with real brush strokes, rather than draw with pixels? Yes — this is
the API for it.**

Easel is a headless painting engine for AI agents: brushes, paint load, wet blending
and canvas texture, driven from Python, from a shell, or over MCP. A brush carries a
finite load of paint and runs out along a stroke. Paint lands wet and mixes with what
is already there, in a pigment model where blue and yellow make green rather than grey.
The canvas has tooth, and a brush low on paint catches only the high points — so dry
brush is not a special effect, it is what happens when you run out of paint on rough
canvas. Between strokes you look at your own work, which is the whole point: the engine
is built for an agent that can see what it just did.

It is not a drawing library, not a rasteriser, and not an image generator — nothing
here turns a prompt into a picture. You choose and make every mark. There are no
layers, and no undo that costs nothing: you work in passes, and when something is wrong
you paint over it.

**Read the guide before you paint.** The engine is only the brush;
[`PAINTER.md`](https://github.com/Gemberkoekje/EaselAPI/blob/main/PAINTER.md) is the method, and six measured runs say the method
is the half that matters. It ships inside the package, so there is nothing to go and
find: **`easel guide`** prints its first page — the whole workflow, under a thousand
words — and `easel guide --full` prints the rest.

```python
from easel import Session, blob, cell

s = Session(1024, 768, texture="linen", ground="toned_grey", seed=7)
s.palette["shadow"] = s.palette.mix("ultramarine", "burnt_umber", 0.4)

s.block_in(blob(cell("D5")), brush="bristle", color="shadow", density=0.8)
s.look(values=True)                       # check the value structure
s.stroke([(0.2, 0.6), (0.6, 0.55), (0.9, 0.62)], "bristle", "yellow_ochre")
s.export("painting.png")
```

## Three paintings, made this way

![Inside a car wash seen from the driver's seat: a magenta foam arch overhead, a bloom
of white light down the tunnel, a red stop light, and a foam-covered side brush
swinging in from the right, past a steering wheel and rear-view mirror](https://raw.githubusercontent.com/Gemberkoekje/EaselAPI/main/paintings/car_wash/painting.png)

*[**Inside a car wash, from the driver's seat**](https://github.com/Gemberkoekje/EaselAPI/blob/main/paintings/car_wash/NOTES.md) — 206
strokes of a 300 budget, 1152×720 linen, no reference photograph. The nineteen pass
scripts beside it reproduce that PNG byte for byte.*

![Three ripe pears on a kitchen windowsill in late-afternoon light, a chipped blue
enamel mug behind them and a half-drawn curtain at the right](https://raw.githubusercontent.com/Gemberkoekje/EaselAPI/main/paintings/windowsill_pears/painting.png)

*[**Three pears on a kitchen windowsill**](https://github.com/Gemberkoekje/EaselAPI/blob/main/paintings/windowsill_pears/NOTES.md) — 224
strokes, 1024×768 linen, no reference photograph.*

![A lighthouse on a rocky headland at dusk: a white tower with a red band standing in
dark rock on the left, its lamp lit, an orange afterglow along the right-hand horizon
reflected in a calm sea, and a crescent moon in the upper right](https://raw.githubusercontent.com/Gemberkoekje/EaselAPI/main/paintings/lighthouse_dusk/painting.png)

*[**A lighthouse on a rocky headland at dusk**](https://github.com/Gemberkoekje/EaselAPI/blob/main/paintings/lighthouse_dusk/NOTES.md) — 184
strokes of a 300 budget, 1024×768 linen, no reference photograph. Eighteen rehearsals,
none of them charged; the ten pass scripts beside it reproduce that PNG byte for byte.*

All three were painted by a language model working from [`PAINTER.md`](https://github.com/Gemberkoekje/EaselAPI/blob/main/PAINTER.md),
one call to this API at a time, with no human hand on the canvas and nothing traced.
Every stroke is in the log, every time-lapse was rebuilt from it, and the notes beside
each painting say what went wrong as well as what went right.
[`PAINTINGS.md`](https://github.com/Gemberkoekje/EaselAPI/blob/main/PAINTINGS.md) gathers the record, and *The worked examples* below
says what each one is made of.

**If you are about to paint from the guide yourself: have you decided what to paint?**
If you have, these are yours to study and the scripts beside them are the best thing
here. If you have not, do not look — a worked example names a subject and a named
subject chooses for you, as six of six fresh sessions once demonstrated by painting a
noun the guide had merely listed in passing. Decide first, then look.

## The brushes themselves

![Brush sampler: every brush at three sizes and three pressure profiles, on smooth, linen and rough canvas](https://raw.githubusercontent.com/Gemberkoekje/EaselAPI/main/samples/brushes.png)

*Every brush, size and pressure profile, on each canvas texture. Regenerate with
`python scripts/make_brush_sampler.py` — this sheet is the project's primary test
artefact, and looking at it catches what the test suite cannot.*

![Shape sampler: five ways to build a mass, each filled along four sweep directions, with the bounding box in the last column](https://raw.githubusercontent.com/Gemberkoekje/EaselAPI/main/samples/shapes.png)

*A mass does not have to be a rectangle. Each row is one way of building a shape,
each column a way of sweeping it; the last column is the box that mass would have
been. Regenerate with `python scripts/make_shape_sampler.py`.*

## Install

Requires Python 3.12 or newer. Only numpy and Pillow — nothing that is painful to
build on Windows.

```bash
pip install easel-paint          # the engine, the CLI and the Python API
pip install "easel-paint[mcp]"   # and the MCP server
```

From a checkout, `pip install -e .` and `pip install -e ".[mcp]"` do the same two
things.

Either installs an `easel` command. Pip puts it in the interpreter's scripts
directory, which is often not on `PATH` (it warns when it is not), so
`python -m easel ...` is always available as the same command by another name.

The MCP server is an opt-in extra because nothing else in the engine imports it.
See *MCP server* below.

## If you are an LLM agent, read PAINTER.md

[`PAINTER.md`](https://github.com/Gemberkoekje/EaselAPI/blob/main/PAINTER.md) is the guide written for you. It teaches the *workflow* —
tone the ground, paint back to front, check values, refine, edges, highlights
last — rather than listing functions, and it opens with *the first hour*: the whole
method on one page, so the eight warm-up exercises come before anything else.

It is one file of five, split by what you do with each rather than by subject, because
three painters each said the same two things — the guide is long, and the essay in it is
what made the rules stick. Nothing was cut to shorten it; it was moved, and `PAINTER.md`
is now held to a word budget by the test suite.

| | |
|---|---|
| [`PAINTER.md`](https://github.com/Gemberkoekje/EaselAPI/blob/main/PAINTER.md) | the method: the order of work, the mistakes, the exercises, the checklist. Held in your head |
| [`PAINTING.md`](https://github.com/Gemberkoekje/EaselAPI/blob/main/PAINTING.md) | the reasons: colour, wet paint, the brushes, working from a reference. Read once |
| [`RECIPES.md`](https://github.com/Gemberkoekje/EaselAPI/blob/main/RECIPES.md) | the procedures: the calls in order for a kind of thing, and what it looks like when it goes wrong |
| [`REFERENCE.md`](https://github.com/Gemberkoekje/EaselAPI/blob/main/REFERENCE.md) | the facts: units, defaults, what each argument does |
| [`CALIBRATION.md`](https://github.com/Gemberkoekje/EaselAPI/blob/main/CALIBRATION.md) | the numbers behind the rules, each with what it was measured on |

The engine is designed around one habit:

> Look every five to fifteen strokes. A stroke you did not look at was a guess.

[`llms.txt`](https://raw.githubusercontent.com/Gemberkoekje/EaselAPI/main/llms.txt) is
the same signpost in the format a model fetching this repository is increasingly told
to look for: the summary, what to know before reading further, and where each document
is, in about 850 words.

## What is in the box

| Piece | What it does |
|---|---|
| `Session` | The one object you hold. Canvas, palette, seed, history, `look()`. |
| `Canvas` | Linear-light RGB plus `wetness`, `thickness`, `sketch` (graphite) and canvas `height` (tooth). |
| Brushes | `round_soft`, `round_hard`, `liner`, `flat`, `bristle`, `knife`, `smudge`. Procedural tips, and `tip_wobble` gives a round one a silhouette of its own, redrawn per mark. |
| `Palette` | A limited pigment set with no black. Mix, tint, shade, and name your mixes. |
| Regions | `region("top-left")`, `cell("D6")`, `horizon(0.4)`, `below(...)`, `between(...)`. |
| Shapes | A mass that is not a box: `blob`, `ellipse`, `hull`, `union`, `ribbon`, `polygon`, and `s.circle()` for one that is round in pixels on any canvas. `smooth()` cuts the corners off an outline. Any of them goes where a region goes. |
| Masses | `block_in(place, ...)` fills a rectangle *or a shape* with overlapping passes, stopping at the silhouette, or drawing its contour with `edge="clean"`; `solid=True` when it has to be solid paint, because density spaces the passes rather than filling them. `sweep(edge, ...)` lays a mass as passes along its own boundary, stepped inward. Both emit ordinary strokes. |
| Passages and repairs | `scumble(band, a, b, n)` lays a soft passage as `n` overlapping passes stepping between two values — the thing a gradient tool would be for, as paint — and `direction="inward"` runs them round a patch instead of across it, for a value falling off from a centre. `cover(place, color)` buries a mistake with every clause of the correction recipe already set. `smudge(edge, ...)` loses an edge along its own shape: points, or a mass whose outline it walks. |
| `look()` | Grid overlay, greyscale values, region crop, side-by-side, diff, landmarks, and a fine grid of labelled tenths inside a crop. |
| Draw

Lo que la gente pregunta sobre EaselAPI

¿Qué es Gemberkoekje/EaselAPI?

+

Gemberkoekje/EaselAPI es subagents para el ecosistema de Claude AI. An API for an LLM to create images via brush strokes Tiene 0 estrellas en GitHub y su última actualización registrada es del 2026-09-12.

¿Cómo se instala EaselAPI?

+

Puedes instalar EaselAPI clonando el repositorio (https://github.com/Gemberkoekje/EaselAPI) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar Gemberkoekje/EaselAPI?

+

Nuestro agente de seguridad ha analizado Gemberkoekje/EaselAPI y le ha asignado un Trust Score de 87/100 (tier: Trusted). Revisa el desglose completo de comprobaciones superadas y flags en esta página.

¿Quién mantiene Gemberkoekje/EaselAPI?

+

Gemberkoekje/EaselAPI es mantenido por Gemberkoekje. La última actividad registrada en GitHub es del 2026-09-12, con 1 issues abiertos.

¿Hay alternativas a EaselAPI?

+

Sí. En ClaudeWave puedes explorar subagents similares en /categories/agents, ordenados por popularidad o actividad reciente.

Despliega EaselAPI en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: Gemberkoekje/EaselAPI
[![Featured on ClaudeWave](https://claudewave.com/api/badge/gemberkoekje-easelapi)](https://claudewave.com/repo/gemberkoekje-easelapi)
<a href="https://claudewave.com/repo/gemberkoekje-easelapi"><img src="https://claudewave.com/api/badge/gemberkoekje-easelapi" alt="Featured on ClaudeWave: Gemberkoekje/EaselAPI" width="320" height="64" /></a>

Más Subagents

Alternativas a EaselAPI