paprika3d

Three.js MCP server and Claude Code plugin paprika3d turns your coding agent into a game studio.

It pulls references from the web, writes a look and character sheets and a design doc with the creative calls left to you, builds the game, then runs loops that keep improving it, all in one lean package of tools.

$ claude plugin marketplace add paprika3d/paprika3d
$ claude plugin install paprika3d@paprika3d
$ npx -y paprika3d serve

As an MCP server in the client's settings (.cursor/mcp.json, Windsurf, VS Code): the JSON entry.

$ codex mcp add paprika -- npx -y paprika3d serve

Needs Google Chrome and Node 20.11 or later; the Claude Code plugin needs Claude Code 2.1.118 or later.

Or hand this to your coding agent

Install paprika3d (https://paprika3d.com/docs/install) and make me a small three.js game: <one line about it>. In Claude Code, run /paprika3d:paprika-make with that line and answer its questions with me. Before you say it’s done, play its controls with paprika3d, look for objects that never appear, and time a frame against the desktop budget.

01 · Research references paprika-make · reference · sheet

Research references.

Once you say yes, it searches the whole web, YouTube included, for how the look, camera and sound are done. The pictures the game is built from are ones you keep, each with its licence.

How it works

In Claude Code, /paprika3d:paprika-make asks first whether to search the web. On a yes, subagents read trailers, gameplay and the makers' own posts into refs/study/ and its notes (they stay on your machine and are never published), and look for free CC0 and CC BY models whose licence they read on the model's own page. When you bring no pictures, another one finds some on Wikimedia Commons and Openverse and you keep the ones you want, each as refs/01.jpg, refs/02.jpg, … with its role and whether to match it.

Real lines from the BRIEF.md of Kaeru Flip, a live game built with paprika3d; cut to the CC BY pictures shown on this page. The style references, screenshots of other games, stay reference only and are not shown here.
## References
…
refs/04.jpg · layout (village → countryside: poles, wires, paddies, mountains) · inspiration · flickr.com/photos/88664052@N00/2708207172 (CC BY)
refs/05.jpg · layout (narrow town alley, clutter, bikes) · inspiration · flickr.com/photos/16877319@N07/4635633228 (CC BY)
refs/06.jpg · layout (straight paddy road, open countryside) · inspiration · flickr.com/photos/86424983@N00/4770701716 (CC BY)
…

sheet {"pictures": [refs/04.jpg, refs/05.jpg, refs/06.jpg], "title": "Kaeru Flip · references", "out": "refs/sheets/refs.png"}

Saved refs/sheets/refs.png (1248 × 402): 3 pictures, numbered as given, and 0 swatches. Made here, free; nothing was sent anywhere.
Three reference photos side by side, numbered 1 to 3: a narrow country road winding past rice paddies and power poles toward a village under wooded hills; a narrow town alley with bicycles and potted flowers; a straight road through green paddies to distant mountains. Each is labelled with its file, role layout, inspiration and CC BY 2.0.
Kaeru Flip's layout references on one sheet, made by sheet for free. Photos: 1 “miyanotsuka landscape” by Molly Des Jardin, 2 “Back Alley” by Guwashi999, 3 “Vanishing point” by Ghost of Kuji, each CC BY 2.0, cropped.

02 · Design spec sheet · reference · asset_search

Write the design spec.

A style sheet with a palette sampled from the references, character sheets, and a design doc that leaves the creative calls to you. You pick where each key model comes from.

A look board titled Look: Kaeru Flip: the three reference photos in a row, then nine colour swatches with their hex codes (sky #6ec9bb, shadow #72928e, wall grey #828b82, off-white #f1f4ec, foliage #397852, orange #b58749, teal #4ab0c2, red #9e5753, charcoal #555555) and one line of notes.
Kaeru Flip's free LOOK.png from sheet: the CC BY photos above and a palette of colours sampled with reference from its style references (the colours only; those pictures are not shown).
How it works

From the tagged pictures and your answers it writes LOOK.md (palette, light, materials, shapes, camera, UI, sound, and three to five checks a look can verify), CHARACTERS.md for characters and key props, and for a game DESIGN.md, which asks you up to two calls that change what the game is (tone, how it progresses, how it is won) and leaves the rest to the builder with a recommendation. Every line names the picture behind it. sheet composes refs/sheets/LOOK.png for free; with your own fal, OpenAI or Gemini key it also draws a look board and character turnarounds, and with a fal, Meshy or Tripo key it can make a model. Then one question per key item: the library, a free model from the web, your key, or code. A one-line request takes a quick path of about four questions, and nothing paid is used unasked.

Real lines from Kaeru Flip's BRIEF.md, cut to the lines shown, and the real replies that made the board above
## Must have
…
3. **The road is the highway**: five coloured lanes on a downhill road, with a strike line just ahead of the toad. **Keyboard**: frets A S D F G, strum Enter / ↑ / ↓. **Touch**: tap a lane (no strum).
…
## Left to the builder
- The toad's exact outfit, the trick animations, the camera, the demo song, and the HUD typography.

reference {"file": "refs/09.png", "sample": [[144, 144], [1440, 480], [240, 600], [600, 264]]}

Colours (5 × 5 mean): (144, 144) #6ec9bb, (1440, 480) #f1f4ec, (240, 600) #9e5753, (600, 264) #397852.

sheet {"pictures": [refs/04.jpg, refs/05.jpg, refs/06.jpg], "palette": [9 sampled colours], "title": "Look: Kaeru Flip"}

Saved refs/sheets/LOOK.png (1248 × 538): 3 pictures, numbered as given, and 9 swatches. Made here, free; nothing was sent anywhere.
An example of LOOK.md's format (skills/paprika-make/sheets.md), written for this page from Kaeru Flip's brief; the hexes are the samples above
# Look: Kaeru Flip
Board: refs/sheets/LOOK.png
## Palette
sky #6ec9bb · shadow #72928e · wall grey #828b82 · off-white #f1f4ec · accents #b58749 #9e5753   (refs/09.png style match: sampled at (144, 144), (1440, 480), (240, 600))
## Camera
low behind the rider, the road running to the horizon   (refs/06.jpg, layout, inspiration)
## Checks
1. Sky sampled at top centre of the opening look within 30/255 of #6ec9bb.
2. The toad is the warmest object on screen (look's Subject line names it).
A character sheet titled KAERU: a tall, lanky mint-green frog in a burnt-orange hoodie, black shorts and white-and-teal sneakers, shown front, side, back (a red pepper printed on the back of the hoodie) and three-quarter, holding a white skateboard; below, seven head close-ups of expressions, and a close-up of the white earbud wire running into the hoodie pocket.
Kaeru's character sheet: a turnaround drawn by fal's image model on the owner's own key (about $0.15), one of several the owner chose between.

03 · Build paprika-make · asset_search · model_run · geo.js · fx.js

Build it, with a critic.

paprika-make builds from the brief and the sheets. Then a critic reads the pictures and lists what is broken or falls short of the look.

How it works

The first version is written from BRIEF.md and the sheets: LOOK.md's palette and camera as written, each key item from the source you picked, and DESIGN.md's controls and core loop as what gets played. Once the page runs, a critic subagent reads the newest look pictures and lists glitches (z-fighting, objects through each other, floating or clipped things), each LOOK.md check the pictures fail and what a viewer would notice first; they are closed one at a time. open also puts two helper files in the project, geo.js (procedural geometry) and fx.js (sound, textures, particles, a lighting setup). asset_search (preview) finds a ready-made model, PBR texture or HDRI sky in a hosted library of 57,732 models, 3,545 textures and 1,430 skies, and model_run builds a model in code and saves it as a .glb. The board behind this text pulls apart into what made it: the gates are geo.js booleans, the pebbles fx.js placement, the duck one asset_search pick.

Real replies that put the duck in this page, 2026-10-28; cut to the lines shown. model_audit's shrink then capped its textures at 256 px (74 KB to 46 KB).
asset_search {"query": "rubber duck", "maxTris": 6000}

2. f1de4fc390db4266a509b9739350512a · Rubber duck · stylized · 3458 tris · 0.075 MB · about 0.1 m tall · CC-BY-4.0 · …

asset_search {"pick": "f1de4fc3", "height": 1.2}

Picked f1de4fc390db4266a509b9739350512a, the one shown id that starts with "f1de4fc3".
Saved assets/rubber-duck-f1de4f.glb (Rubber duck, CC-BY-4.0); credited in assets/CREDITS.md
If the import map has no `three/addons/`, map it to three's `examples/jsm/` folder.

04 · Iterate paprika-loop

Keep improving it for hours.

paprika-loop runs a builder and a judge session each round, scores the game against the brief and commits it, until the time you gave it is up.

How it works

/paprika3d:paprika-loop <request> for <time> writes the brief with you, then starts fresh claude -p sessions: a builder makes as many improvements as fit, a read-only judge scores the page against the brief's Must have list and writes the next three improvements, and each round is committed, with the best tagged paprika-loop/best. You can edit paprika-loop/PROMPT.md while it runs. It starts only when you type it, each round is two Claude Code sessions billed as such, and it needs claude and git on PATH. The bars behind this text are the six rounds below, each car lap one round.

Real report from a paprika-loop run on Night Shift Toss, 2026-10-28 (the run's second hour; its rounds are numbered on from the first)
# paprika-loop report

6 iterations in 57 minutes, $11.90.

| n | min | turns | tokens | commit | score |
|---|---|---|---|---|---|
| 18 | 8.3 | 45 | 3699609 | b6a2ba6 | 7.3 |
| 19 | 7.5 | 38 | 2951642 | 789479e | 7.4 |
| 20 | 3.4 | 16 | 931095 | 07e4879 | 7.4 |
| 21 | 30 | 20 | 1060576 | 61f2ff4 | 7.6 |
| 22 | 4.5 | 14 | 786807 | 246cab0 | 7.8 |
| 23 | 3.7 | 18 | 750452 | 4529600 | 7.8 |

Best: iteration 22 at 246cab0 (score 7.8), tagged paprika-loop/best; the latest is 4529600.

05 · See and play open · look · interact · observe · eval · feel

See it and play it, frame by frame.

Every object gets a box, and anything missing gets a reason. Keys, clicks and touches land on exact frames, so every run comes out the same.

How it works

Your agent sees what is on screen, what never appears and why (behind the camera, outside the view, too small), which files failed to load, and which lighting and surface faults show. In the scene behind this text, every named object gets its box in page pixels, the way look lists them, and the screw on the mat is too small to see. Then it presses keys, clicks, touches and scrolls on exact frames of a paused, seeded clock and reads the state after each input: scroll on and the car drives one lap, frame by frame, its trace drawn behind it.

Real replies from the guides Find out why a three.js model is not visible, 2026-10-14, and Test a three.js game with Claude Code, 2026-10-16
look {}

Picture: <project>/paprika3d/runs/2026-10-14T07-50-50-163Z/look-1.png
ID image: <project>/paprika3d/runs/2026-10-14T07-50-50-163Z/look-1-ids.png
On screen (2):
ground 68.0% [0, 241, 1279, 799]
car 0.0% [638, 346, 641, 347]
Never visible: lamp (3 units, behind the camera)

eval {"code": "return stats(\"car\")"}

total  1 meshes  24 v  12 tri
car  24 v  12 tri  closed  vol 0  genus 0  size 0.04×0.014×0.02  [position, normal, uv]

interact {"steps": [{"key": "ArrowRight", "frames": 30}, {"key": "ArrowRight", "down": false}]}

{"changed":{"x":1.5}}

interact {"steps": [{"key": " "}, {"key": " ", "down": false}, {"wait": 18}], "look": true}

{"changed":{"y":0.95,"jumps":1}}
Picture: <project>/paprika3d/runs/2026-10-16T23-20-52-829Z/look-2.png
Pixels: brightness 14%, colour saturation 50%, 0% near black, 0% blown out; 2% of the picture changed since the last look.
Hues: blue 90%, green 9%.
On screen (2):
floor 8.8% [0, 614, 1279, 689]
ball 0.71% [735, 452, 831, 547]
Never visible: none

06 · Test and measure interact save · test · perf

Turn a play into a test, and time every frame.

Saved plays rerun after every edit. Each frame is timed against a desktop, phone or Quest budget, with the objects that cost the most.

This page, measured in your browser: the numbers appear once the scene runs.

How it works

A play your agent saves reruns from a fresh reload with test, and the after-edit hook reruns every saved check after each edit, speaking only when one starts or stops failing: on the second lap each gate turns green as the car passes it. perf times the frame against a desktop, mobile, Quest or site budget, finds what costs it, and with optimize: true keeps only the speed-ups that leave the picture unchanged. The bars that rise next are this scene's own named groups, counted in your browser the way perf's cost table counts them (the height is the square root of the triangles); the line above is this page's frame time.

Real replies from the guides Unit test a three.js app in a real browser, 2026-10-28 (the second test ran after a refactor broke the wall rule), and Measure three.js draw calls and FPS, 2026-10-28, on a server with no GPU (the reply says so); cut to the lines shown
interact {"steps": [{"state": {"player": {"x": 3, "z": 0}}}, {"key": "ArrowRight"}], "expect": {"player.x": 4, "score": 10, "coins.0.x": 1}, "save": "far-coin"}

{"changed":{"player":{"x":4},"coins":[{"x":1,"z":1}],"score":10,"moves":1}}
Expect: player.x 4 ✓ · score 10 ✓ · coins.0.x 1 ✓
Saved check "far-coin" in game-tests.json (3 checks now); `test` reruns them all, each from a fresh reload.

test {}

✓ coin-pickup
✗ wall-blocks: player.x 2, expected 1; moves 2, expected 1
✓ far-coin
2 of 3 saved checks passed in 0.5 s

perf {"costs": true}

248.3 ms median frame (p95 273 ms, 4 fps on average), 1797 draw calls, 54298 triangles, 0 MB assets; over budget: frameMs 248.3 of 16.7 ms; desktop budget; software renderer (no GPU): frame time is no budget signal, do not optimize for it
…
  statue: 16384 triangles, 16384 casting shadows, 1 draw calls, 0 MB of textures
  crates: 10800 triangles, 10800 casting shadows, 900 draw calls, 0 MB of textures
  floor: 2 triangles, 0 casting shadows, 1 draw calls, 0 MB of textures

07 · Tools 16 MCP tools, in any MCP client

The 16 tools, by stage.

paprika-make and paprika-loop are Claude Code skills; the tools work in any MCP client.

References and spec

reference
Reads a picture at full resolution: a crop with a pixel grid, colours at points; with the page open, compares the two.
sheet
Names the image and 3D keys set, composes a free LOOK.png, and with your key draws boards and turnarounds or starts a model job.

Build

asset_search
Finds a model, PBR texture or HDRI sky in the hosted CC BY and CC0 library, and downloads the pick with its loading code and credit.
model_run
Builds a model in code with three.js and Manifold, and saves a .glb the page loads.
model_look
Shows that model from four sides against a grid, with each object's size and triangles.
model_audit
Checks .glb, .gltf and USD files: size, triangles, textures, compression; shrink makes one smaller.

See

open
Runs the page in headless Chrome on a paused, seeded clock and lists what loaded and what failed.
look
A screenshot, every object on screen with its box, and what never appears and why.
observe
Reads the game state as JSON, with renderer counts and new console errors.
eval
Runs JavaScript in the page, with the scene, camera and mesh stats in scope.

Play and test

interact
Plays keys, mouse, touch and scroll on exact frames and reports what changed; save keeps the play as a check.
feel
Measures whether a hit, pickup or win shows on screen: shake, pops, flashes, particles, sounds.
test
Reruns every saved check from a fresh reload, one pass or fail line each.

Measure

perf
Times the frame against a budget with what costs it; optimize: true keeps only the speed-ups that leave the picture the same.

Share

publish
Puts the game on https://<name>.paprika3d.app when you ask (preview, invite-only).
send_feedback
Sends the paprika3d team a bug or criticism, with the last tool call.

How it works, stage by stage · Every tool, skill and hook

Built with paprika3d

From the intro reel

Watch the 46-second reel ↗

Results

paprika3d vs Playwright MCP and Blender MCP

Featurepaprika3dPlaywright MCPBlender MCP
Sees the scene: named objects, sizes, what never appearsYesNoNo
Same inputs give the same frames (paused, seeded clock)YesNot built inNo
Input on an exact frame, with the game state backYesNoNo
Frame time against a budget, plus an optimizerYesNoNo
Names lighting and z-fighting faultsYesNoNo
Flickering faces found in 133 finished objects (Sonnet 5.5)
75% vs 44% paprika3d vs Playwright MCP with a QA skill and a measuring script.
Clean objects correctly passed (Sonnet 5.5)
80% vs 66% Same 133 objects, paprika3d vs Playwright MCP.

3JSBench

3JSBench by General Context Labs checks the 3D objects a model builds from one-line requests. In our run of its checks, more objects pass with paprika3d:

Sonnet 5.5: objects that pass every check
66% → 86% +20 points (95% interval +11 to +29), 150 runs per arm
Opus 5.5: objects that pass every check
63% → 78% +15 points (95% interval +4 to +26), 150 runs per arm
Sonnet 5.5: objects with no flickering faces
68% → 88% +20 points (95% interval +11 to +29), 150 runs per arm
Opus 5.5: objects with no flickering faces
69% → 89% +21 points (95% interval +11 to +31), 150 runs per arm

More results

Imported glTF model loaded and shown at the right size (Sonnet 5.5)
1 → 9 of 11 runs Without vs with paprika3d.
Draco-compressed model loaded (Sonnet 5.5)
0 → 3 of 3 runs Without vs with paprika3d.
Main-thread time per frame, ~2,000 physics crates (Opus 5.5)
7–11 → 1.3–2.0 ms With game-state, which runs physics in a worker. 18 of 18 game checks pass.

All results

This page was built and checked with paprika3d

We tested it with paprika3d at desktop and phone sizes.

Desktop frame
4.8 ms
Phone frame (390 × 844, JS 4× slower)
7.5 ms
Draw calls
79
First scene frame, fast 4G
1.6 s
Bytes to first frame
0.28 MB