Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
PAPRIKA3D_CHROMENoPath to Chrome or Chromium. Optional: found automatically on PATH (chromium, google-chrome) or at the usual install path.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
openA

Opens a three.js, React Three Fiber or WebGL page (a game, viewer, configurator, simulation or shader demo) in headless Chrome (or the browser given) on a paused, seeded clock, closing any page already open under the same game name, and lists the asset files (models, textures, sounds) it fetched and any fetch that failed, what a dev-server command printed as an error or warning, a canvas with no height, and the page's text outside the canvas. Open once: after an edit, the next interact, look, observe, eval or feel reloads the page by itself. Use it when such a page has been written or changed. Give a file or folder to serve (url, relative to cwd), an http URL, or a dev-server command run in cwd. Up to 4 games can be open at once, each under its own game name: a subagent opens its own (game: "tester") and passes that name to every call.

observeA

Reads the open page's state as JSON (window.__game.observe(), or its named three.js objects), renderer counts, new console errors and what changed since the last observe.

evalA

Runs JavaScript in the open page and returns what it returns, as JSON, then up to 5 lines it logged (console.log, warn, info) and up to 5 console errors. In scope: scene, camera, renderer, find(name), stats(target) (vertices, triangles, bounds, closed, volume, genus per mesh), realNow(), window, and THREE on a page that loads three through an import map. performance.now, Date and timers run on the harness's paused clock (code that awaits a timer or frame steps it until done), so to time code here use realNow() (real milliseconds), and end GPU work before reading it (a 1-pixel gl.readPixels; on WebGPU, await renderer.backend.device.queue.onSubmittedWorkDone()). Use it to inspect the scene, try a change before writing it into the source, measure an imported model, or check procedural geometry with stats after each step; changes vanish on reload. A thrown error names where it threw: a line of this code or of the page's own files. Code that keeps the page busy for 30 s (longer on a busy host) is stopped and the page kept: split long work across calls, or await a 0 ms timer every few hundred iterations.

interactA

Plays the open page: keyboard, mouse, touch, wheel, scroll, resize and clock steps sent frame by frame (steps lists the kinds), and returns what changed in the state (its new values; the whole state when nothing changed), the console log/warn/info lines and errors the steps raised, a Motion line when the subject (window.__game.subject, or where the state puts its player) turned, or stopped while a key was still held, a Sound line with how many sounds the steps started on a page that makes sound, and with look: true look's picture and list after the steps, in the same reply. Every mouse and touch step says which named object in the scene is under it, and its distance. Use it to play an interaction the request names and read the state it leaves, to set a moment up ({ state }) and step to it ({ until }), or to keep a play as a check (save).

lookA

Screenshot of the open page, returned in the reply (no file to read), with an ID image saved beside it (one colour per object, the picture's path with -ids before .png), and a list of what is on screen and the named objects no look has seen, with their size and where they are: it catches a model at the wrong scale, out of view or never loaded, which a screenshot alone misses. One mode per field: cameras, target, sheet, zoom, at, opening, viewports, scroll, save and compare, camera; on a software renderer (no GPU) each sheet cell reloads and replays the page at roughly a second per drawn frame. Each look ends with the lines the skill's references/lighting.md explains: the subject and whether it stands out, depth, hues, the Lighting: and Surfaces: setup faults, the largest surface's texture, the canvas size, what shows through a transparent canvas, and the HTML over the canvas with the ones that overlap or are cut off by the screen edge. Use it to see what a viewer sees. A page drawn in passes (post-processing) is pictured as it drew its last frame, so state set since then shows after a step.

feelA

Measures game feel, how the page reacts to an event: on a fresh reload, sends the steps, then watches the next frames for camera shake or one camera move out and back (a hit's lurch), scale pops, smooth moves versus teleports, colour flashes, particles (a Points pool's or an InstancedMesh's count), spawned objects, HUD text ticks and sounds, each with the watched frame it came on. Leading { state } steps set the scene up (the player next to the coin), and nothing is measured until they and one frame have run; what moved during the other steps is listed as a fact on its own line, and teleports are jumps between two watched frames, so a setup or a walk in the steps is never one. It shows whether each event a feel brief names (hits, clears, explosions, pickups, deaths, wins) reacts on screen, and whether anything teleports. It measures and saves nothing: to keep the play as a check, send the same steps to interact with expect and save.

perfA

Measures the open page's frame time (fps), draw calls, triangles and asset size against a budget (desktop by default): it is for a frame a reply reports over budget, or a user who asks about performance (stutter, low fps). To find what costs the frame, give variants: each is measured on a fresh page against the baseline, in this one call, with named objects hidden, a pixel ratio, code run with renderer and scene (shadows or antialias off, a material swapped), or a query the page loads with ("noshadow&pr=0.5", for switches the game reads at load); no reopening or reload code needed. Sampling waits until no element covers the canvas (a loading screen), up to 5 s of the page running, and the load line says what it waited for or sampled under.

optimizeA

Speeds up the open page: measures the frame time (no perf needed first), tries the @paprika3d/three-runtime switches, keeps those that help without changing the picture, writes game-runtime.json, and ends with the final test of game-tests.json when the project has one. It is for a frame a reply reports over budget, or a user who asks about performance.

model_auditA

Inspects 3D model files (.glb, .gltf, and USD: .usd, .usda, .usdc, .usdz): megabytes, triangles, materials, each texture's size and format, and whether it uses Draco, meshopt and KTX2, for one file or every one under a folder (path, relative to cwd; the whole project when left out), read from the file itself with no decoder, so Draco and meshopt files report too. Then a one-line verdict on what a website or a Shopify listing judges a model on, against target: site (the site budget: 4 MB of assets, 200,000 triangles, 2048 px textures by area) or shopify (a GLB of about 4 MB with textures at most 2048 px on a side). shrink rewrites one .glb or .gltf smaller, without its textures or with each capped at a size (WebP), and replies with before and after (a USD file is converted to GLB first); a failing file gets the shrink call that fixes it: save a look first (look save), shrink, point the page at the new file, then look compare.

model_runA

Runs JavaScript against the modelling scene: a three.js scene this server keeps between calls, apart from any page, for building a model in code as in Blender, then saving it as a .glb the page loads. The code is an async function body with THREE, scene, geo (Manifold, started: geo.Manifold, geo.CrossSection, geo.toGeometry(manifold), geo.toManifold(geometry), geo.boolean(op, a, ...b)), scatter, find(name), stats(target) (vertices, triangles, bounds, closed, volume, genus per mesh), load(path) (a .glb from the project, an asset_search pick included, added to the scene and returned), save(path, object = scene) (a GLB under cwd; replies with its size and the line that loads it) and clear() in scope, and returns what it returns, as JSON, with up to 5 lines it logged. What it adds to scene stays for the next call and is saved to paprika3d/model/scene.glb after each run that changed it, so a restart loads it back; variables (a Manifold) do not last between calls. Manifold works in metres with Z up and angles in degrees; three is Y up. Name every object you make: model_look lists them by name.

model_lookA

Shows the modelling scene that model_run builds: one picture of it (or of object) from the front, right and top (orthographic, so sizes read true against the grid) and a three-quarter view, under a neutral studio light with a ground grid whose step it states, and one line per object: name, type, place, turn and scale, material (colour, roughness, metalness) and, for a mesh, triangles, size, whether it is closed, its volume and genus. With object, that object in full; with cameras, those views instead of the four.

testA

Reruns every check saved with interact save (game-tests.json), each from a fresh reload at frame 0, one line each: ✓ pickup or ✗ jump: player.y 1.4, expected ≥ 2. Use it after an edit that could break earlier features.

referenceA

Reads a reference picture the page should match (a photo, artwork, mockup or screenshot in the project, e.g. refs/01.jpg) at full resolution, in one call and with no page open: crop [left, top, right, bottom] in the picture's pixels, enlarged up to 4× to fit 1280 px, with grid lines every N px labelled in the picture's own pixel coordinates (positions read off it go straight into the next call or the scene), and sample points, each answered as #rrggbb. With the page open, compare: true puts the picture, the page's look (from camera when given) and a difference picture side by side and says what share of pixels differ, overall and in a grid of regions (cells per side, 4 by default), with each sample point's colour on both, or that the canvas aspect is not the picture's. Use it to read a picture the page should match and to check the page against it.

asset_searchA

Searches the hosted paprika3d asset library over the network (assets.keeno.dev) for a ready-made model (57k, CC BY or CC0, as GLB and some as USD), PBR texture or HDRI sky, and puts the one you pick in the project with its loading code. A search answers one numbered line per hit (id, name, size, licence, preview image) and a contact sheet: the hits' thumbnails in one row, numbered as the lines are. pick an id from it (or its start, when no other hit shown in this project starts so) to download the file into assets/ (public/assets/ with vite) and get the code that loads it, a model at real size (or height units tall) and credited in CREDITS.md. not lists ids that missed, which the library learns from, and searches again without them; more searches the same query again for the next hits. image (a picture in the project, with crop to cut one thing out of it) ranks models by how alike they look, for the thing a reference picture shows that words miss. The library logs model searches, picks and rejections with the agent's name.

publishA

Publishes the project at https://.paprika3d.app (public; preview, invite-only), only when the person asks; never for another host. Never read or print ~/.config/paprika3d/credentials.json: this tool reads the key.

send_feedbackA

Sends the paprika3d team a bug, feedback or criticism about the harness itself (not about the user's page): a reply that was wrong or unclear, a tool that hung, errored or got in your way, a check you disagree with, or something you needed and no tool gave. It attaches the last tool call's name, options and error, never the page's code or files. One line back; carry on with the task after it.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.8/5.0

Scored across 16 tools

Disambiguation3/5

Several tools have overlapping boundaries: perf and optimize both target performance, interact and feel both replay input steps, and look and reference compare both handle visual comparison. The descriptions explain the distinctions, but an agent could still misselect when deciding whether to measure or optimize, or whether to use interact versus feel.

Naming Consistency3/5

Names are all lowercase snake_case, but the conventions are mixed: single verbs or nouns such as open, look, feel, eval, perf, and test sit alongside compound names like model_audit, asset_search, and send_feedback. The names remain readable, but there is no predictable verb_noun pattern throughout.

Tool Count4/5

Sixteen tools is slightly above the typical 3-15 range, but the server covers a broad 3D game-development harness from opening pages to modelling, testing, asset search, and publishing. Each tool mostly earns its place, though a few overlaps make the surface feel larger than necessary.

Completeness4/5

The set covers a strong lifecycle: opening pages, inspecting and interacting, visual checks, performance measurement and optimization, model creation and audit, tests, reference comparison, asset search, and publishing. Minor gaps exist, such as no explicit close/list management for open pages, but core workflows are well covered.

Maintenance

ActivityMaintained
ResponsivenessOutdated data