Skip to main content
Glama

Paint Cost Lab

One Paint application. One reference photo. Claude Code draws it twice: with its usual setup and with a cost-control framework. Compare drawing quality, completion time and the full cost of each drawing session.

Status: working prototype. A local paired portrait pilot has been recorded; experiment images, transcripts and its report are maintained separately. Building the editor is a separate development cost, not one of the two drawing runs.

Live editor: https://kajetanmazur.github.io/paint-cost-lab/

Try the editor

Serve the web directory with any static server:

python3 -m http.server 8080 --directory web --bind 127.0.0.1

Open http://127.0.0.1:8080. Upload a portrait or use the included original demo illustration. Draw, erase, undo/redo, export a PNG or save the stroke log. The editor has no auto-tracer, image generator, API key field or fake AI chat. The run selector only labels exports; it does not enable the framework.

All assets use relative URLs. The web folder is suitable for GitHub Pages, including deployment at a repository subpath. Photos stay in browser memory; reloading clears the session. Export your work before closing it.

Related MCP server: the-mogiyoon-mcp

Connect your own Claude Code locally

The public editor does not provide a hosted Claude. Use your own Claude Code installation/account, Python 3.11+ and the local MCP server in this repository. It launches a separate visible browser window with the same editor. An existing GitHub Pages tab is not automatically connected.

From this project's directory:

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python -m playwright install chromium
claude mcp add --scope local paint-cost-lab -- "$PWD/.venv/bin/python" "$PWD/server.py"

On Windows use the corresponding .venv\\Scripts\\python.exe path. If using an installed Google Chrome instead of downloading Chromium, register with:

claude mcp add --scope local paint-cost-lab -e PAINT_BROWSER_CHANNEL=chrome -- "$PWD/.venv/bin/python" "$PWD/server.py"

Choose one registration command. Start a new Claude Code session in the same project directory. Ask it to call studio_view and wait for you to upload the reference in the opened window. Then ask it to draw the portrait.

The server exposes four tools: view, one brush stroke, undo/redo and export. Strokes use the real color/size controls and mouse input; there is no arbitrary JavaScript, direct pixel replacement, source-image copying or auto-tracing tool. A view sends a screenshot containing your reference and drawing to your Claude. You decide which photos to use. Server action logs and outputs are local under artifacts/ and excluded from Git. CLI usage/cost logs must be collected separately.

For independent sessions, exit the previous CLI so its MCP process closes, then start a new CLI with a fresh MCP process and upload the same photo. Each process gets an isolated browser and artifact directory. Do not use the label selector as a session reset.

Drawing experiment

  1. Freeze the editor/server revision, photo, model version, effort, prompt, screenshot size, limits and evaluation rubric before running.

  2. Use the same four painting tools in both arms. Both can see the reference, choose colors, draw, inspect, correct and export. No source reading or image processing scripts as alternate drawing channels in the controlled test.

  3. Standard arm: record the actual CLI configuration. Framework arm: record all policy/tool/context differences. Integrate this MCP server explicitly: the existing cost-lab controller disables MCP by default and cannot run this experiment unchanged. Do not silently drop the painting tools.

  4. Start from a blank canvas for each run. The app itself applies no artistic improvements. The model chooses every stroke.

  5. Include screenshot calls, reasoning, retries, repairs and helper calls in cost. Report input/cache-read/cache-write/output separately; don't add thinking to output twice. CLI USD is an estimate, not a subscription bill.

  6. Compare anonymous drawings against the same reference: likeness, facial proportions, colors, completeness. A cheap unfinished drawing is not a win.

  7. Pilot one pair, then repeat at least three pairs if the budget permits. Alternate order and retain failures. Fresh sessions can still share cache.

Default test should not assume a reset every three final replies saves money. Prior coding experiments found it increased cost. Painting is a new workload; measure the selected framework policy without assuming it transfers.

Common drawing prompt

Use only the Paint Cost Lab tools to draw the uploaded reference portrait on the blank canvas. Aim for a recognizable, stylized likeness: face shape, proportions, hair, main colors and distinctive features. Choose your own brush strokes. Inspect your progress and correct mistakes when useful. Do not trace/copy the image with code, access files, or use other image tools. Finish by exporting the drawing with studio_save. Follow the shared limits supplied with this experiment.

Exact cost/time/tool-call limits must be supplied by the runner before starting, not invented by the model. Freeze them equally for both arms.

GitHub Pages

Publish only the contents of web/. Keep server.py, README and tests in the source repository for people who want to connect their own Claude. Do not publish artifacts, portraits, credentials or CLI transcripts. This repository publishes web/ to the gh-pages branch. GitHub Pages is configured to serve the root of that branch. After committing changes to main, update the deployed branch with:

git subtree push --prefix web origin gh-pages

Local checks

.venv/bin/pip install pytest
PAINT_HEADLESS=1 PAINT_BROWSER_CHANNEL=chrome .venv/bin/python -m pytest -q

Tests exercise the editor in Chrome and the MCP connection without paid model calls. If you installed Playwright Chromium, omit PAINT_BROWSER_CHANNEL.

Recording a controlled experiment

The MCP server accepts optional environment settings for an experiment runner: PAINT_REFERENCE (local image path), PAINT_OUT (new output directory), PAINT_LABEL (standard or framework), PAINT_RECORD=1, PAINT_MAX_STROKES and PAINT_MAX_VIEWS. These configure the shared environment; they do not change the model's painting logic. With recording enabled the server uses a fixed studio layout and writes a native browser capture.webm on shutdown. Action logs include canvas bounds and a recording timestamp so a video editor can crop the drawing and align it with CLI events. In recording mode, studio_save finishes the run and finalizes the video before replying; subsequent drawing calls require a new MCP process.

Cost and token usage still come from the Claude CLI transcript. A recording alone cannot measure model cost. The local pilot is separate from this public editor; no portraits or raw CLI transcripts are uploaded by the app.

Related MCP Connectors

Related MCP Servers