@nodi3d/agent
v0.1.5
Published
CLI bridge that lets a coding agent (Claude Code, Cursor, Codex, …) drive the Nodi desktop app — list the node catalog, look up node specs, apply graph edits, evaluate, and capture viewport screenshots.
Readme
@nodi3d/agent
CLI + skills that let a local coding agent (Claude Code, Cursor, Codex, Gemini CLI, …) drive Nodi for desktop to build and edit procedural 3D models — no Nodi UI interaction required. Edits appear live on the canvas.
For the Nodi desktop app only. This works with the downloadable desktop version, not the web editor — the control server it talks to is embedded in the desktop build. Get it at https://nodi3d.com/desktop.
Full setup & usage guide: https://nodi3d.com/agents/
This package is just the CLI and the agent skill; the control server is embedded in the Nodi desktop app and starts automatically when the app is running.
Install
npx @nodi3d/agent setupInstalls the Nodi instructions for each coding agent it detects:
- Claude Code — the
nodiskill under~/.claude/skills/and~/.agents/skills/ - Codex — appended to
~/.codex/AGENTS.md(a re-runnable, non-destructive block) - Gemini CLI — appended to
~/.gemini/GEMINI.md - Cursor — a project rule at
<your project>/.cursor/rules/nodi.mdc(Cursor has no global rules dir, so run setup inside your project — or pass--cursorto force it)
(setup --all forces all of them even if not detected.) Then open Nodi for
desktop (download: https://nodi3d.com/desktop) and ask your agent to model
something — it drives the app through the nodi-agent CLI.
Re-run setup after upgrading the package: installed skills only update when
setup runs, and nodi-agent status / open warn when the installed skill is
older than the CLI.
Skills
Everything ships as one skill, nodi, living in
skills/; setup copies it into each detected agent's skills
directory. You don't invoke it directly — it triggers from what you ask for.
SKILL.md stays small (the CLI workflow: catalog → docs → apply →
evaluate → screenshot) and the depth sits in references/, which the agent
reads on demand. That's progressive disclosure: a one-line "make a box"
never pays for the replication playbook, and a task that needs it gets the
whole thing.
| Reference | Read when… |
|-----------|------------|
| shape-replication.md | you hand the agent reference images (photos, renders, technical drawings, spec sheets) and want that shape reproduced — "model this from the image", "recreate this part", "この画像の形状を再現して". A gated, verify-driven workflow: evidence → dimensioned shape brief → per-part B-rep recipes → build-and-screenshot each part → compose → self-critique each view against the reference |
| evidence-and-brief.md | writing that shape brief — the template, and how to pull dimensions off a drawing or photo |
| brep-recipes.md | building the parts — copy-paste recipes R1–R4 and an error-string → one-line-fix pitfall table |
| solids-and-fillet.md | Loft / Sweep / Extrude / FilletEdge — watertight solids and the native-vs-sewn fillet fidelity caveat |
| data-trees.md | Merge / FlattenTree / list inputs behave unexpectedly per branch |
| rhai-scripting.md | scripting an Expression / Function node |
| implicit-modeling.md | building with the Implicit* (SDF) node family — CSG, lattices, TPMS, ImplicitExpression — recipes and primitive gotchas |
| immersed-analysis.md | running any Immersed*Solver analysis (stress / thermal / flow / topology optimization) — the shared core, routing to a per-type analysis-*.md file |
| turntable.md | handing over a finished model — a looping 360° GIF via nodi-agent turntable: when to shoot one, framing and background, every option, and the ffmpeg-vs-bundled encoder |
Shape replication deliberately avoids Implicit/SDF nodes, which round off the
crisp edges of machined and printed parts. To force that path explicitly,
invoke /nodi replicate <image path>. Everything here requires Nodi for
desktop to be running.
Earlier versions shipped a separate
nodi-shape-replicatorskill. It's nowreferences/shape-replication.md;setupdeletes the old skill directory for you.
How it works
coding agent ──► @nodi3d/agent CLI ──HTTP──► control server (in the Nodi desktop app)The app writes a discovery file (<tmpdir>/nodi-agent.json) with the server
port + a per-launch token; the CLI reads it. Localhost only.
Commands
nodi-agent open # launch the desktop app (if needed) and wait until ready
nodi-agent status # discovery + server health + skill freshness
nodi-agent catalog [--section impl] # list available nodes
nodi-agent docs ImplicitSphere # a node's inputs/outputs/properties
nodi-agent graph # current nodes, edges, aliases
nodi-agent apply -f ops.json # apply graph edits (--evaluate to eval after)
nodi-agent apply -e '<json>' # …or inline / via stdin
nodi-agent evaluate # evaluate and return per-node feedback
nodi-agent import part.step # load a geometry file (STEP/IGES/STL/OBJ/…)
nodi-agent wait-eval # wait until the graph evaluation is idle
nodi-agent state thinking --note '…' # report the agent's live state to the app
nodi-agent screenshot -o out.png # capture the viewport as PNG (offscreen)
nodi-agent turntable -o spin.gif # orbit the model → looping 360° GIF
nodi-agent view-settings --material Zebra # viewport material / grid / bounding box
nodi-agent section-plane --on --origin 0,0,0 --normal 0,0,1 # clip plane
nodi-agent clean # delete captured screenshots
nodi-agent setup # (re)install the skillTurntable GIF
turntable sweeps the offscreen capture camera around the model — 36 frames
over a full 360° at 25° elevation, 12 fps by default — and packs them into a
looping GIF, so a finished model can be handed over as one artifact instead of a
handful of stills. It encodes with ffmpeg when that's on PATH and a bundled
zero-dependency encoder otherwise, so it works either way.
Every flag, framing advice, and the file-size trade-offs:
turntable.md, or nodi-agent --help.
Apply ops
{
"ops": [
{ "op": "add", "ref": "s", "variant": "ImplicitSphere", "properties": { "radius": 2.0 } },
{ "op": "add", "ref": "b", "variant": "ImplicitBox", "properties": { "size": [3, 3, 3] } },
{ "op": "add", "ref": "d", "variant": "ImplicitDifference" },
{ "op": "connect", "from": "b", "fromIndex": 0, "to": "d", "toIndex": 0 },
{ "op": "connect", "from": "s", "fromIndex": 0, "to": "d", "toIndex": 1 }
],
"evaluate": true
}Ops: add, connect, disconnect, setProperty, setVisible (show/hide a
node's geometry), isolate (show only that node), remove. Property values are
plain JSON (numbers, booleans, [x,y,z], or an enum option name); the app coerces
them to the node's types. Reference nodes you create with your own ref strings.
Launching the app
nodi-agent open (and --launch / NODI_AGENT_AUTOLAUNCH=1 on other commands)
start the desktop app if it isn't running. The launch target is resolved in
order: NODI_AGENT_LAUNCH_CMD (full shell command — best for dev builds, e.g.
cargo make run-desktop) → the exe recorded by a previous run → NODI_APP →
the platform-installed app (Nodi.app on macOS, Nodi.exe under
Programs/Program Files on Windows, nodi on PATH on Linux).
Requirements
- Nodi for desktop — download: https://nodi3d.com/desktop (the web editor is not supported; this drives the desktop app's control server).
- Node.js >= 18
License
MIT
