Repository avatar
AI Tools
v0.3.0
active

threesmith

io.github.laaielichter/threesmith

three.js for coding agents: version-pinned API and review, assets, headless runs, perf, 3D models.

Documentation

Threesmith logo

Threesmith

Less debugging. More dimension.
MCP server, CLI and Claude Code plugin. Works with Claude Code, Codex, Cursor, VS Code, Gemini CLI and any MCP client.

CI Tested on three.js r187 MIT license Install in VS Code Install in Cursor Add to Claude Code

Website · Install in your agent · 3D models · Example · Changelog

Threesmith: less debugging, more dimension; a real model built from code
Explore the interactive model preview, toolkit and real before-and-after demo.

Left: the black canvas of a scene a coding agent wrote. Right: the same scene after the fixes Threesmith listed, a lit crate and a character model
Real run on examples/agent-mistakes: as the agent wrote it (3 review errors, 2 asset paths that 404, a black canvas), and after threesmith fix plus the fixes threesmith doctor listed (100/100, check passes).

three.js ships a release almost every month and removes old APIs. Coding agents learned it from years of code that used THREE.Geometry, outputEncoding, three/examples/js and import paths that no longer exist, and they cannot see the canvas they draw on. Threesmith is the check between the agent and your project: the API of the three version you have installed, a scored review, the assets and decoders the code needs, the live scene in headless Chromium, and safe, undoable edits. Everything runs locally; nothing leaves the machine.

Without and with

Your agent...On its ownWith Threesmith
writes three.jsGeometry, outputEncoding, BoxBufferGeometry, examples/js: old habits97 rules pinned to the installed release flag each line with the fix; fix does the 23 pure renames
calls an APIguesses a name or an import path from memorythree_api reads node_modules/three: signature, deprecation and the right three/addons/... path
writes a shader#include <encodings_fragment>, gl_FragColor with GLSL3, a .replace() on a chunk that is goneincludes checked against the installed ShaderChunk, patches that silently do nothing found, renames fixed
loads a model/models/Car.glb that is a 404 on Linux, Draco without a decoderthree_assets resolves every path like the server does and names the missing decoder setup
says "it works"never opened the pagethree_check opens it headless: errors with causes, blank frames, a screenshot, baselines
gets a black screenguesses: more light? move the camera?three_inspect reads the live scene and says why each object is not visible
fixes a bugcannot show it was there, or that it is gonethree_play runs steps and judges claims frame by frame; three_scenario keeps it as a regression test
makes it fastchanges things and hopesthree_perf counts draw calls, triangles and programs against a budget and the last run; three_leaks names what is never disposed
ships itbuilds once, deploys, sees a 404three_build builds, finds two copies of three, missing assets and sub-path URLs, then opens the built page
needs a 3D modelneeds Blender or a placeholder cubethree_model_build makes a clean .glb from one of 110 kinds, then shows it as text views and lints it
does not know the projectreads twenty filesthree_scan and three_doctor give the map and the order to fix things in one call

A car, an airship, a wizard tower, an excavator, a treasure chest, a dragon, a lighthouse, a mech, a longship, a stone golem, a hot-air balloon and a castle, built by Threesmith and rendered by three.js
3D models from code, no Blender: 110 ready-made kinds, from cars and airships to swords, teapots and golems, rendered here by three.js itself. See all

Quickstart

1. See what is wrong. Nothing to install but the package:

npx -y threesmith doctor          # what is wrong, grouped by cause, most urgent first, with next steps
npx -y threesmith review          # score 0-100, `file:line severity [rule] message Fix: ...`
npx -y threesmith check .         # open the page headless, errors and a screenshot

2. Give it to your agent. In Claude Code:

/plugin marketplace add laaielichter/Threesmith
/plugin install threesmith@threesmith

3. Ask for something. "Find out why the scene is black and fix it." Every three.js file Claude edits is reviewed right after the edit, its errors and broken asset paths go straight back to Claude, and the session starts with a brief of the project.

Install in your agent

ClientHow
Claude Code/plugin install threesmith@threesmith after /plugin marketplace add laaielichter/Threesmith (MCP server, hooks incl. protected paths, 8 skills, 2 subagents, settings for tool sets and read-only)
Claude Code, MCP onlyclaude mcp add threesmith -- npx -y threesmith mcp
Codexcodex mcp add threesmith -- npx -y threesmith mcp --tier premium
Cursor, VS Codethe buttons at the top
Gemini CLIgemini extensions install https://github.com/laaielichter/Threesmith
Cline and othersllms-install.md, or { "mcpServers": { "threesmith": { "command": "npx", "args": ["-y", "threesmith", "mcp"] } } }
DockerDockerfile

Run the agent from the project folder, or pass --project <path>. Needs Node.js 22.12+ and three installed in the project. The browser tools need playwright-core and a Chromium (npx playwright-core install chromium); threesmith doctor --env shows what is missing.

Made for agents: cheap calls, exact answers

  • Two profiles. --tier cheap (the default) gives short, capped output and numbered step-by-step instructions, so small models follow the right order; --tier premium gives full detail for large models.
  • Tool sets. --tools core loads 14 tools; add run, live, build, model when you need them, or name single tools. A tool list the client pays for in every turn stays small. The server instructions only ever name tools that are loaded.
  • Fix loops that cost less. three_review with only_new: true shows new findings in full, the ones the agent already saw as one short line, and how many are fixed. code + file reviews code before it is saved.
  • Structured results. Review, check and doctor return structuredContent with an output schema next to the text.
  • One line per finding. file:line severity [rule] message Fix: ..., the same in the CLI (--compact), MCP and hooks.
  • Safe writes. Every write (fix, model build, scenario save) is one journal entry that three_undo takes back; a file changed by hand since is left alone. "protect" in threesmith.json (or THREESMITH_PROTECT) names folders no write may touch. --read-only leaves out the tools that always write and refuses write options.
  • It learns, locally. A finding marked as a false alarm with three_feedback is hidden from then on; lessons kept with three_lesson_add come back under the same error. Only hashes, counters and scrubbed text, on this machine.

The 31 tools

All MCP tools (most are also CLI commands)
SetToolWhat it does
corethree_doctorStart here when something is broken: versions and imports, why the scene shows nothing, assets that will not load, removed APIs, colour, performance and cleanup, grouped by cause, most urgent first, with what three_fix does and numbered next steps
corethree_scanMap the project: bundler and framework, three vs @types/three vs package.json, the libraries around it, pages and import maps, every file that uses three with what it creates and where its loop is, renderer settings, assets
corethree_apiExact API of a class, member or constant in the installed three: signature, deprecation, import path; did-you-mean for unknown names
corethree_searchFind classes, constants and members by part of a name
corethree_reviewScored review (0-100) with 97 rules pinned to the installed release; code + file for unsaved code, only_new in a fix loop, files to focus
corethree_typesThe project's own tsc --noEmit, with each three.js type error answered from the installed release (the member that exists, the real import path)
corethree_fixThe renames that mean exactly the same, dry run first, undoable
corethree_explainCause and fix of a console, build or test message (35 kinds), with the right import path for the installed release
corethree_lessons100 lessons from real three.js and react-three-fiber projects (symptom, cause, fix, test) by error message, words, rule or topic
corethree_lesson_addKeep a lesson learned here, scrubbed of names, paths and code; it comes back under the same error
corethree_rulesEvery review rule with its category, release gating and fix
corethree_feedbackMark a finding as a false alarm (hidden from then on) or right
corethree_undoUndo the last Threesmith writes, newest first
corethree_versionWhich three release is installed
runthree_checkHeadless Chromium (software WebGL 2): console and page errors with causes, shader errors at your file and line, failed requests, no context, lost context, blank frames, screenshot, baselines with a diff, interaction steps
runthree_inspectThe live scene graph, camera, draw calls, GPU memory growth, and why each object is not visible
runthree_playSteps (click, press, hold, drag, wheel, frames, eval, until), watched values per frame and step, claims judged at the end, any moment or every frame
runthree_scenarioKeep a passing play run as a regression test in .threesmith/scenarios/; ci runs them and writes JUnit
runthree_perfDraw calls, triangles, programs, geometries, textures (exact) and frame-time percentiles with the slowest frames and their cause, against a budget and the last run
runthree_leaksRepeat a cycle of steps with garbage collection and report what grows per cycle, down to the GPU resources never disposed, by type
livethree_sessionKeep a headless page open between calls (start, status, stop)
livethree_pageDrive that page without reloading: eval JS against the live scene, steps, frames, until, screenshot, inspect, reload, new errors after every answer
buildthree_assetsEvery asset path resolved like the dev server and a static host: missing files, wrong capitals, decoder folders, glTF decoders the code never sets up, huge textures, unused files
buildthree_buildRun the build, check the output (copies of three, missing assets, sub-path URLs, decoders) and open the built page headless
modelthree_model_briefOne page before you build a model: the nearest ready-made kind, parts, real size, rules, the order of tools
modelthree_model_identifyWhat a thing is (English or Dutch): parts, pivots, typical size, variants, usual mistakes
modelthree_model_specThe JSON model spec, an example, and the 110 ready-made kinds
modelthree_model_buildBuild a clean, deterministic .glb from a kind or a spec, and lint it
modelthree_model_viewA .glb as text: front, side and top views, parts with sizes, parts that do not touch
modelthree_model_lintScore a .glb for the web (geometry, materials, triangles, draw calls, texture memory, loading), and against what it should be
modelthree_model_inspectWhat is in a .glb and which loaders and decoders three.js needs, with the setup code, checked against the project's code

CLI: threesmith doctor | scan | api | search | review | types | fix | rules | undo | lessons | assets | check | inspect | play | scenario | perf | leaks | build | model <inspect|needs|view|lint|identify|brief|spec|kinds|recipes|build> | explain | ci | hook | mcp. threesmith <command> --help lists the options.

The review

Rules are pinned to the installed release: a removed API is an error on a release that removed it and a warning on an older one; a rule whose replacement does not exist yet in your release stays quiet. The categories:

  • api (28): removed or renamed APIs and their releases, symbols that do not exist in the installed version, TSL names imported from the wrong entry, three/src imports, deprecations read from three's own source.
  • correctness (48): code that renders nothing or the wrong thing — no lights, shadows off, renderer never attached, render(camera, scene), scene.add(gltf), a mixer never updated, getElapsedTime() and getDelta() on one clock, instance and attribute updates without needsUpdate, raycasting with window instead of canvas coordinates, controls bound to document, decoders created but never attached; shaders: #include chunks that do not exist in the installed release, onBeforeCompile patches that do nothing, GLSL3 mistakes, redeclared built-ins, uniforms without { value }, GLSL materials under WebGPU and node materials under WebGL; React Three Fiber: state set in useFrame, objects made in render.
  • performance (10): allocations and heavy objects per frame, scene traversal per frame, uncapped pixel ratio, huge shadow maps, many meshes that should be instanced.
  • lifecycle (3): no resize handling, removed objects never disposed, dispose() without super.dispose().
  • color (8): colour textures without colorSpace, colour management off, EffectComposer without OutputPass or with double gamma, envMapIntensity that has no effect.

It reads text, not types (three_types adds the type checker for TypeScript). The rules are tested against three's own examples and addons for false alarms. If a finding is wrong: three_feedback, --disable <rule>, or // threesmith-disable-next-line <rule> (also -disable-line, -disable-file); an issue with the snippet is the most useful bug report.

GitHub Action

- uses: laaielichter/Threesmith@main
  with:
    min-score: 85
    check: dist          # folder with the built index.html; omit to skip the browser
    baseline: home       # screenshot baseline in .threesmith/baselines/home.png
    comment: true        # post the receipt on the pull request

The receipt (review, check, scenarios) appears in the job summary and optionally as a PR comment. Locally or in any CI: threesmith ci --check dist --junit junit.xml --sarif threesmith.sarif. Commit .threesmith/baselines/ and .threesmith/scenarios/; the rest of .threesmith/ is local state and ignored by its own .gitignore.

Limits

  • WebGL 2 in headless Chromium works in GitHub Actions (SwiftShader software rendering). WebGPU is best effort (--webgpu), depending on the runner having an adapter.
  • Frame times come from software rendering: compare them before and after on the same machine. Draw calls, triangles, programs and resource counts are exact.
  • Baselines should be made in the environment that checks them (CI), with the default tolerance.
  • The API lookup parses the JSDoc in three/src; it is tested on r187, older releases give thinner answers.
  • The review is heuristic; the asset check follows paths written as text, not paths built at run time.

Benchmarks

bench/ has tasks and a deterministic grader for comparing an agent with and without Threesmith. No results are published yet; see bench/README.md for the method.

Sister tools

From the same author, local and open source: ReversePort (reverse engineer and port games between engines), Godotwright (check the Godot code your agent writes), Stashpad (agent memory you can trust) and agentdisk (clean up after agents).

Develop

npm ci
npm run check     # typecheck, tests (incl. headless Chromium), build

Try the Claude Code plugin from this checkout, before a release: npm run build && npm run plugin:local, then start Claude Code with the claude --plugin-dir ... line it prints.

See AGENTS.md and CONTRIBUTING.md. Threesmith follows the design of its sister project for Godot, Godotwright. MIT licensed, made by laaielichter.