free3d is a tiny 3D modeller built from static files and a local copy of three.js — no build step, no server code, no cloud, and it works fully offline. Orbit, pan and zoom around a lit scene; drop primitives (cubes, prisms, cylinders, spheres, cones, pyramids…); push/pull faces, sculpt, smooth and simplify surfaces; and combine shapes with real boolean operations (union, intersect, subtract). An outliner mirrors the scene graph so you can select, rename, group and reorder everything, and every edit is undoable and autosaved.
Surface colour tells you the topology at a glance: a watertight solid is blue, open geometry (anything with a naked edge) is warm orange.
.f3d: geometry + settings + recent undo history) — all under the File menu.free3d ships a small MCP server that lets a coding agent (Claude Code, Claude Desktop, or any MCP host) drive the modeller — creating shapes, transforming them, running booleans, grouping and exporting — using the exact same operations the UI uses. Paste the prompt below into your coding agent (with this repo open); it will register the server and walk you through connecting.
I'm using "free3d", a browser-based 3D modeller in this repository, and I want you to control it over MCP.
1. Register its MCP server with my agent. From the repo root, run:
claude mcp add free3d -- node "$(pwd)/mcp/server.mjs"
(Or add it to your MCP host config manually: command "node", args ["<ABSOLUTE_PATH_TO_REPO>/mcp/server.mjs"]. It needs no install — Node built-ins only.)
2. Then tell me to open the app in a browser and choose File ▸ Connect to AI (MCP). Use either the local copy (serve the repo, e.g. start_server.bat, then open http://localhost:8080/) or the hosted GitHub Pages URL. If you use the hosted (https) app, open it in Chrome or Firefox — Safari blocks its call to the local bridge. The server above still runs locally either way.
3. Verify the link by calling the "list_scene" tool — it should return the (possibly empty) scene.
Once connected, it exposes the following tools:
- list_scene: list every object in the scene as a tree (uuid, name, kind, visibility, local position, children).
- get_object: get one object's full details — transform, world-space bounding box, and whether it is a closed solid.
- add_primitive: create a primitive (cube, sphere, cylinder, cone, …) on the ground and return its uuid.
- transform_object: set an object's position, rotation (degrees), and/or scale; omitted fields are unchanged.
- rename_object: rename an object.
- delete_object: delete an object (and, if a group, its whole subtree).
- select_object: set the viewport selection to a list of uuids (empty to clear).
- boolean_op: combine 2+ objects with a CSG union, intersect, or subtract; returns the new mesh's uuid.
- group_objects: group 2+ objects into a new group at their world transforms.
- ungroup_object: dissolve a group, promoting its children to its parent.
- clear_scene: delete everything and start empty.
- undo / redo: step backward or forward through changes.
- set_snapping: configure grid/angle/screen snapping.
- export_model: export the scene as OBJ, STL, or GLB.
Always start with list_scene to see what exists and get object uuids. Positions are [x, y, z]; rotations are in degrees. To hand me a finished model, call export_model and save the result to a file.
Full details and a headless test are in mcp/README.md.
By Simon Lindstrøm, 2026