NooksDocs Open the workbench

Developers

The workbench is also an MCP server. Connect your own agent and it builds with real parts inside one of your builds, where you can watch, edit and build the result.

TipStart from Connect an agent in the workbench. OAuth is recommended; legacy keys remain available for clients that need them.

Nothing on this page matches that.

Overview#

The Model Context Protocol lets an AI agent use tools from outside its own app. Nooks offers the workbench's construction tools this way: your agent does the thinking, and Nooks turns what it asks for into real parts, checks how they connect and whether the model holds together and stands, and saves every build as a revision.

  • Your agent, your model. Nooks makes no model calls of its own for your agent; it supplies tools.
  • Real parts only. Everything is built from parts the workbench draws, by their LDraw numbers and real colours.
  • You stay in the loop. Each revision appears in the workbench and its history. You can edit it by hand, and the agent builds on your edits.

Quick start#

  1. Sign in. Building needs a free account.
  2. Open Connect an agent in the workbench, and start a build for your agent (or pick one of yours).
  3. Add the Nooks MCP address to your client. A compatible client opens Nooks sign-in and consent. Choose the builds it may use and whether it may edit them.
  4. Verify the connection. Ask the client to call list_builds or read_project. A chat instruction alone cannot install a connection in every app.
  5. Ask your agent to build. For example: "Read the Nooks project and its runtime guide, then build a small red tower on a 4×4 base, part by part, and check it."

Endpoint and authorization#

Addresshttps://nooks.place/api/mcp
TransportStreamable HTTP. Stateless: each POST is one JSON-RPC exchange, answered as JSON.
AuthOAuth authorization code with PKCE for compatible clients. Nooks opens sign-in and consent, then issues a short-lived resource-bound token. Legacy Bearer keys remain available for clients without OAuth.
Account keysA key from Agents in your account menu (nooks_acc_…) works across your builds: your agent lists them with list_builds and picks one with open_build (or starts one with create_build). A client that keeps no MCP session names the build with ?build=<id> on the address, or a Nooks-Build header. A read-only key is offered only the tools that change nothing.

OAuth is the recommended path. The consent screen identifies the client, shows the requested read or edit access and lets you restrict it to selected builds. Inspect or revoke connected clients from your account; revoked access stops on the next call, including an active MCP session. Legacy keys coexist with OAuth: a build key opens one build, while an account key can cover selected builds and be read-only.

Connect a client#

For an OAuth-capable remote MCP client, add https://nooks.place/api/mcp. The client discovers Nooks authorization, opens sign-in and consent, and returns after approval. Do not treat setup as successful until the client calls a Nooks tool. Client support varies; some apps still require the manual key setup below.

One page for every client has the command, the config file and the sign-in step for Claude Code, Codex, Cursor, OpenClaw, Hermes and Grok Build, with the 13-tool core and the full profile side by side.

Codex OAuth#

Terminal
codex mcp add nooks --url https://nooks.place/api/mcp
codex mcp login nooks

Complete Nooks sign-in and consent in the browser, then verify the server in Codex. The login flow has been tested; a model-driven Codex tool call has not.

Legacy key fallback#

If the client cannot authorize a remote MCP server, choose My client requires a key in Connect an agent and put the resulting key where nooks_agt_… appears below. Keep it out of URLs, source files and logs.

Claude Code#

Terminal
claude mcp add --transport http --scope user nooks https://nooks.place/api/mcp \
  --header "Authorization: Bearer nooks_agt_…"

Then start Claude Code and check that /mcp lists nooks. --scope user makes it available in every folder; leave it out for this folder only.

Codex#

config.toml
# ~/.codex/config.toml
[mcp_servers.nooks]
url = "https://nooks.place/api/mcp"
bearer_token_env_var = "NOOKS_AGENT_KEY"

# then, in the shell you start Codex from:
export NOOKS_AGENT_KEY=nooks_agt_…

Codex reads the key from the environment variable, so it stays out of the config file. In PowerShell: $env:NOOKS_AGENT_KEY="…". Check with /mcp in Codex.

Claude Desktop#

claude_desktop_config.json
{
  "mcpServers": {
    "nooks": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://nooks.place/api/mcp",
        "--header",
        "Authorization:${NOOKS_AUTH}"
      ],
      "env": {
        "NOOKS_AUTH": "Bearer nooks_agt_…"
      }
    }
  }
}

Settings › Developer › Edit config, add this and restart. It bridges through mcp-remote, which needs Node.js.

Other clients#

JSON
{
  "mcpServers": {
    "nooks": {
      "url": "https://nooks.place/api/mcp",
      "headers": {
        "Authorization": "Bearer nooks_agt_…"
      }
    }
  }
}

Any client that speaks MCP over Streamable HTTP and can send a header needs only the address and the Authorization header.

Build programs#

An agent builds the way a person does: part by part, each placed by its connectors (this stud into that hole, this pin into that beam), so hinges, clips, Technic and minifigures join exactly. It writes the steps as a build program: plain JSON, never code, kept with the revision so it can be read, replayed and edited.

A build program
{
 "name": "bridge",
 "ops": [
  {
   "op": "add",
   "name": "left",
   "part": "brick 1x1",
   "color": "tan"
  },
  {
   "op": "add",
   "name": "right",
   "part": "brick 1x1",
   "pose": [
    {
     "at": [
      2,
      0,
      0
     ]
    }
   ],
   "color": "tan"
  },
  {
   "op": "attach",
   "name": "span",
   "part": "plate 1x3",
   "to": "left.stud[0]",
   "by": [
    "hole",
    0
   ],
   "color": "red"
  },
  {
   "op": "contact",
   "a": "span.hole[2]",
   "b": "right.stud[0]"
  }
 ]
}

The ops: add and attach (with yaw, flip, slide, align and orient), define…end for a sub-build placed many times, mirror, contact for a join the check must also find, and base to start from a saved revision. runtime_guide has them all, with worked examples.

Every part your agent can find, describe and place is sold loose, in the colours it is sold in, so whatever it builds can be ordered as a kit. A part or colour that is not is refused, with the closest one that is. Hoses and strings are switched off for now. export_python gives any build as a standalone Python script for the open-source construction library the runtime follows, which builds the same parts at the same poses.

A typical loop:

  1. Find parts with find_parts, and what joins a connector with parts_that_fit.
  2. See where to build next with program_connectors: each connector of a placement, free or joined.
  3. Check with check_program: every join, collision and stability problem, and an inventory if you give one, each naming its parts.
  4. Look with view from several sides.
  5. Save with build_program, then change it with edit_program.

An agent can also save a model it placed part by part (save_parts) or an LDraw file (import_ldraw).

Code. Instead of a list of ops, your agent can write Python with run_code: loops, variables, arithmetic and parts it can ask where their connectors are. The code runs in a sandbox of its own, a small virtual machine with no network and none of our data, for at most 30 seconds. What it builds is checked like any program and saved with the code, so you can read how a build was made and your agent can run it again.

Live sessions. Each connection also has a live model. Your agent builds it up a step at a time (session_ops, or code cells that remember their variables), asks it anything (session_query: its size, parts, joins, free connectors, a full check, a picture), takes steps back, and saves it as a revision only when it is right. It is kept if the connection drops. If you edit the build in the workbench meanwhile, your agent is told and puts its work on top of yours.

Checks. Joins, collisions and the two-second gravity test for agents run on the physics engine the open-source library uses, in a sandbox; the workbench's own Test gravity runs another engine in your browser on the same part shapes and the same rule. They agree on the builds we test, though a build right at the edge can pass one and not the other; every result says which engine gave it. The report names the rule, the elements it is about and the op, code line or step that placed them.

How to read a report#

A check returns a report, not just a pass or a fail. Every finding names its level and its rule, then the fact it found; the lines under it say where and which parts or discs:

A check report
error[overlap]: the bodies of 2 parts share positive volume
  --> x 2..4  y 0..2  z 3..4  (1.2 .. 1.6 mm)
   = #3 3001 Brick 2 x 4, Red         op 14 "roof-3"
   = #7 3020 Plate 2 x 4, White       op 9 "base-2"

warn[unstable-component]: 1 group of 3 parts tips toward -y
  --> x 0..6  y 2..8  z 12..18  (4.8 .. 7.2 mm)
   = #11 3005 Brick 1 x 1, Tan        op 21 "finial"

checked 42 parts against 12 rules (piece-budget, size-bounds, palette ignored): 1 error, 1 warning
  • The heading is level[rule]. error fails the build, warn is reported without failing it, and ignore is off until a request turns it on. ok is true only when no error remains.
  • The region after --> is an axis-aligned box in model units: LDU for bricks (with its height in millimetres), millimetres for Brain Flakes.
  • Each = line is one element the caller already knows: a part key or connector address, or a disc and slot. Its source follows where there is one: op 14 "roof-3", line 12, step 4 or a revision id.
  • The closing line counts what was checked, names the ignored rules, and reports errors and warnings. It counts omitted findings too, and names any deferred rule and why, so a truncated or partial report never reads as a pass.

Rules are configured, never passes: a request can raise or lower a rule's level, or enable one whose default is ignore. The rule reference lists every rule, its default level and the pass that checks it.

Revisions and conflicts#

Every build is saved as a new revision on top of the one before. Pass the build's currentRevision from read_project as baseRevision when you build.

A 409 means someone saved in between, often you, editing by hand in the workbench: read again and build on the latest. An agent replaces a hand edit only if it passes replaceHumanEdit: true, which it should do only when you have said so.

Tools#

Start here#

ToolWhat it does
read_projectThe build, its revision history (who made each and why), and one revision: its build program, size, colours and whether it holds together.
runtime_guideHow build programs work: units and axes, connectors and how they pair, and every op with worked examples. Read it first.
explain_ruleWhat a rule named in a check report means, for bricks and Brain Flakes: its name, default level, the check that runs it and the condition in plain words.

Your builds (account keys)#

ToolWhat it does
list_buildsThe builds of yours this key may open, newest change first.
open_buildWork on one of them: every later call on the connection reads, checks and saves it. Switch any time.
create_buildStart a new, empty build in your account (only a key that can edit all your builds).
remix_kitStart a build from a shared kit (its nooks.place/kit link or id), credited to its maker (only a key that can edit all your builds).
delete_buildDelete the build this connection works on, with its revisions, sources, keys and shared kits; the build name must be typed back. Permanent.
delete_kitTake a kit this build shared down from its public page and player, with the kit title typed back; the build stays.
kit_partsOpen a parts page for a public kit, including a wanted list and links to individual parts.
list_kitsList the public Nooks demo kits and BrickBench builds, with their title, parts, maker and system.
read_kitRead an existing kit’s build as LDraw text, with its title, parts count and maker.

What a build starts from#

ToolWhat it does
record_sourceKeep the person’s own words and photo privately with the build; the photo appears with the kit only when the person shares it.

Estimated inventories#

ToolWhat it does
start_inventory_scanStart a loose-brick photo scan; for a set box, search the catalog by name or number.
submit_inventory_photoSubmit one photo for an inventory estimate. The external service may retain and reuse it. The result is an AI inference, not verified physical inventory.
inventory_scan_statusRead scan status and inferred candidates; they are not verified physical inventory.
lookup_inventory_setsFind set matches by name or number in the local catalog.
choose_inventory_setChoose a set catalog candidate for the build. Its inventory assumes the set is complete.
inspect_set_inventoryInspect a candidate’s catalog list, assuming the set is complete.
list_inventoriesList estimates and catalog inventories for this build.
select_inventoryUse an inventory for checks and builds, or clear the selection. Physical availability is not verified.

3D models#

ToolWhat it does
import_3dA 3D model (.glb, .obj, .stl) by link or as data: its size and pictures from three sides to build against, or filled with bricks as a starting revision.
export_3dA saved revision as an STL (for printing), OBJ or GLB (with colours): a download link that works for half an hour.

A real place#

ToolWhat it does
read_placeA square of the real world from OpenStreetMap at the scale you ask: the ground stud by stud, and each building's footprint, height in plates, colours and roof, for the agent to build.

Parts and connectors#

ToolWhat it does
find_partsSearch every part the workbench draws by words ("brick 2x4", "hinge plate") for LDraw numbers and names.
describe_partA part's connectors by address (stud[0], hole[3], pin[1]…) with position, axis and bounds.
parts_that_fitThe parts with a connector that joins a given one (a stud, a pin hole, a clip), with which of their connectors fit, the most used parts first.
program_connectorsWhere a placement's connectors are in the model, and which are free or joined (and to what), so the agent knows where it can build next. Reaches parts inside sub-builds as copy/inner.
minifigureA whole minifigure from real figure parts, dressed and posed, as program ops or LDraw lines.
brainflakes_techniqueTested Brain Flakes construction techniques (beam, post, panel, arc, block, sculpt, ring) returned as ready definitions to place with instance.
brainflakes_catalogBrain Flakes disc specifications, slot frames, legal mating poses, confirmed manufacturer colours, standard set inventories, and benchmark tasks.
inspect_brainflakesInspect Brain Flakes disc poses, connector locations and optional symmetry of centers, normals and colours.

Build programs#

ToolWhat it does
check_programRun a program and check it without saving: joins, collisions and the gravity test (in a sandbox, on the open-source library’s physics engine), and an inventory if you give one.
simulate_programTwo seconds of gravity with each connected group rigid, reporting how far anything moves.
build_programRun, check and save a program as a new revision, kept so it can be edited.
edit_programReplace, insert, remove or append ops in the latest program and build it.
run_codeBuild with Python instead of a list of ops: loops, variables and live parts, run in a sandbox of its own with no network. What it builds is checked like any program, and saved with the code so it can be read and run again.

Live sessions#

ToolWhat it does
session_opsAdd steps to a live model the agent builds up call by call, kept between calls and across reconnects, saved only when it says so.
session_queryAsk the live model anything without changing it: its size, its parts, every join, a placement's free connectors, a full check, or a render.
session_statusWhere the live model stands: what it builds on, and whether the person has saved a newer version since.
session_undoTake back the last change to the live model, or several.
session_saveSave the live model as a new version, checked like any build.
session_rebasePut the live model on top of the person's newer version, their parts kept where they left them.
session_resetStart the live model again, empty. Nothing saved is touched.

Looking and checking#

ToolWhat it does
viewA real render of a program or a saved revision, from any angle.
render_previewA quick blockout PNG of each part's bounding box, for shape and colour layout.
check_modelThe build checker: one connected assembly, no part inside another, stands up, stock parts only, plus any limits you set (pieces, size, colours, inventory).

Saving and history#

ToolWhat it does
save_partsSave a model placed part by part (part number, colour, position in studs and plates).
import_ldrawSave an LDraw .ldr or .mpd file as a new revision; sub-models and steps carry over.
finalize_modelCheck, simulate, render and export one explicit saved revision. Returns its revision and model hash; missing evidence never passes.
check_instructionsCheck a revision’s manual and report its issues.
edit_instructionsSave manual edits as a revision while preserving the construction parts.
plan_instructionsPlan or repair the building instructions.
read_instructionsRead manual steps, views, callouts and page settings.
render_instructionsPreview up to four manual pages.
try_instructionsTry manual edits without saving.
export_kitExport a saved revision: manual steps, parts CSV, BrickLink wanted list and the link to buy parts directly from sellers. Preview and print the illustrated manual in the workbench.
export_ldrawAny revision as an LDraw .mpd file, with its manual's steps.
export_pythonAny revision as a standalone Python script for the open-source construction library the runtime follows: run it to build the same parts at the same poses.
restore_revisionMake an earlier revision the latest again. Nothing in the history is removed.
share_kitWhen the person asks for a share or a link, publish the kit free in the community gallery and return its public link and a Post on X link.

Box art#

ToolWhat it does
prepare_box_artFor a saved brick revision, the exact product render and the front-art prompt to give an image provider, with print guidance. It does not generate the art itself.
save_box_artAttach provider-generated 3:2 front artwork to a saved brick revision; a shared kit’s player then offers a Box view.

Briefs#

ToolWhat it does
list_briefsBriefs to build against: a prompt (some with a picture), the setting (Model, Set or Alt-Build), the questions a person reviews a build with, and constraints the checker tests. People build the same briefs, so builds can be compared.
start_briefLink this build to a brief, so it counts as an agent build of it, next to the builds people made. Returns the brief and its rubric: the setting and question graph.
evaluate_brainflakes_benchmarkScore a Brain Flakes build program against one of the standard Brain Flakes benchmark tasks (flower, ball, tower, animal, or jar-500 starburst).

Community#

ToolWhat it does
list_contributionsPublished community models and tasks, newest first.
read_contributionOne published contribution: its description, a task's constraints, or a model's program and checks.
evaluate_taskRun a published task's software checks on your build and answer valid (no error-level rule failed), with the task's setting and question graph. _meta.usage sums the run's reported tokens and prices them from a published table, or says unknown; it submits nothing.

Rule reference#

Every rule a check can report, generated from the rule tables the checks use (lib/rules/bricks.mjs, lib/rules/instructions.mjs and lib/rules/brainflakes.mjs). A rule is one kind of fact: a kebab-case name, a default level, the pass that checks it and the condition in plain words. People and agents configure rules, never passes.

Levels are error (the build fails), warn (reported, does not fail) and ignore (off unless a constraint or an explicit level turns it on). The default is what applies when a request says nothing; a constraint such as maxPieces runs its rule at error.

Bricks#

12 rules. Parts, connections, collisions, stability, inventory and the catalogue. Regions are in LDU, with the height also in millimetres.

RuleDefault levelPassWhat it means
overlaperrorcollisionTwo parts' bodies share positive volume; touching faces do not count.
missing-connectionerrorconnectivityA join the build requires has connectors that do not meet, so the parts are not held together there.
floating-parterrorconnectivityNo chain of stud connections reaches the desk, or reaches a part that reaches it.
unstable-componentwarnstabilityA group's centre of mass leaves the hull of what holds it up, or the group moves under gravity.
inventory-exceedederrorinventoryA part or colour count is greater than the count in the inventory given.
unsold-parterrorcatalogueA part or colour is not sold loose; minifigure pieces are excepted.
stock-parterrorcatalogueA designed part that is not a stock element is present while stockPartsOnly applies.
piece-budgetignoresizeThe part count lies outside minPieces..maxPieces.
size-boundsignoresizeThe model's bounding box exceeds maxDimensionsMm.
paletteignorepaletteA part colour is outside allowedColours.
part-unplaceableerrorcatalogueGeometry or connector data is missing, so no verdict is possible.
physics-incompleteerrorstabilityThe engine could not run, or it ran past its bound.

Instructions#

8 rules. Findings about a saved revision's printed manual; the source is the step.

RuleDefault levelPassWhat it means
instructions-sizewarninstructionsSteps are neither too big nor too small, and there are about as many as a real manual of that size has.
instructions-hiddenwarninstructionsA part added in a step is hidden in that step's picture, by the step's other parts or by what is already built.
instructions-repeatswarninstructionsA sub-assembly built more than once is not shown once, marked ×N.
instructions-camerawarninstructionsThe camera does not stay put, or the turn icon is missing wherever the view turns.
instructions-bomwarninstructionsA part is not in exactly one step and in the parts list, or the parts list page is missing.
instructions-buildablewarninstructionsA step does not build on the steps before it: a part comes before what holds it, or is left in the air.
instructions-insertion-blockedwarninstructionsA part's straight-line insertion path is blocked by a part built before it, or the insertion check could not complete.
instructions-approach-closedwarninstructionsA part has no open way in at all, because what is built closes every approach. A part that can come in along another open, held way than its natural one is not reported: the natural way is a preference, not a rule. The current checker reports this placement as the instructions-insertion-blocked rule (rule "blocked"); this rule is retained for older reports.

Brain Flakes#

14 rules. Discs, slots, colours and the tasks’ limits. Regions are in millimetres, and elements are disc and slot ids.

RuleDefault levelPassWhat it means
unintended-overlaperrorcollisionTwo discs intersect and the pair is not a designed press-fit.
inexact-connectionerrorconnectivityA connection's slots do not line up.
floating-discwarnconnectivityA disc is not joined to anything and does not rest on the floor or on another disc.
invalid-operrorprogramAn op cannot be applied; source.op names it.
palette-unknownerrorpaletteA colour is outside the confirmed catalogue.
palette-disallowedignorepaletteA colour is outside the task's allowed list.
symmetry-unmatchedignoresymmetryA requested reflection has no counterpart.
disc-budgetignoresizeThe disc count lies outside minDiscs..maxDiscs.
loop-minimumignoretopologyThere are fewer closed loops than required.
size-boundsignoresizeThe bounding box exceeds the task's.
reach-minimumignoresizeThe largest span is under the task's minimum.
set-mix-exceededignoreinventoryA colour needs more discs than the chosen set has.
support-unsupportedwarnsupportThe static support estimate cannot hold a component.
mesh-incompleteerrormeshThe mesh check could not complete; it is never a pass.

Limits and safety#

  • Sharing is yours. When you ask, an agent can publish your kit in the public gallery and give you a link. Agents cannot order parts.
  • Other people's text is data. Community titles and descriptions are written by contributors; the server tells agents never to follow instructions in them.
  • Wrong keys are refused. A key is checked before any tool runs, and an address that keeps sending wrong keys is turned away for a while (429, with Retry-After).