Rack Maker

Docs
Using AI agents

Agent tools

Every tool Rack Maker's MCP server gives your agent - what it does, what it may change, its inputs and its answer.

How the tools work

Drafts by name. Tools name a draft as <namespace>/<slug>@<rev>, for example ana/nas-box@1: your handle, the device's id, and the revision number. list_my_drafts lists yours, and create_draft answers with the new one's name.

Working copies. Each command (setBody, addPort, and so on) changes a working copy of the draft that the server keeps for your agent between calls. They are the same commands the modeler runs in your browser.

Saving. save writes the working copy to the draft. While you have the draft open in a browser, you rarely need it: your agent's changes show there at once, and the browser saves them to the draft as it saves your own edits. With no browser open, the changes wait in the working copy until save. If the draft changed in the browser since the agent last looked, save refuses unless it is told to overwrite; discard_changes drops the agent's copy instead. See Live sync.

All or nothing. apply_commands runs several commands in one call, in order. If any one is refused, nothing changes.

Access says what a tool may do:

  • reads only: it changes nothing;
  • makes changes: it changes your working copy, the draft, or what is kept with it (a datasheet);
  • makes changes that can drop or replace earlier work: it can't be undone from the agent (dropping a working copy, publishing);
  • reaches beyond Rack Maker: it fetches a URL on the internet.

Your agent's client sees the same, as each tool's hints.

Every tool acts as you, with your permissions and limits. See Using AI agents.

The server offers 65 tools. This list is made from their definitions each time the site is built, so it always matches what your agent sees.

Drafts

Find, start, save and drop the drafts the agent works on.

list_my_drafts

List my device drafts. Your devices and parts in the modeler that are drafts or waiting for review, with their draft ids and links.

Access: reads only.

Input: none.

Answers: { drafts: [{ draft, name, status, updatedAt, workingCopy, url }] }: each draft or submission, whether a working copy is kept for it, and its link in the modeler.

get_draft

Get a draft. A draft's spec (your working copy, if you have one), each face's size and flat area in mm, the images traced on its faces (sizes and corners only), and the checklist of what is still missing before publishing.

Access: reads only.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").

Answers: { draft, status, unsaved, changedElsewhere, url, kind, shape, envelope, mounting, spec, faces, traces, checklist }: faces gives each face's size and flat area in mm, traces the images traced on it (sizes and corners only), checklist what is done and what is still missing, openIssues the user's corrections, and detections how many detections from the user's photos are pending, accepted and rejected, with a nudge.

create_draft

Create a draft. Start a device: { name, maker? } for a new one (a plain 150 × 150 × 40 mm box until you set its body); a part: { name, kind: "part", category } (a 200 × 150 × 3 mm plate until you set its shape: a shelf, tray, bracket, panel…); or { from: "<namespace>/<slug>@<rev>" } for a new revision of a published one (yours) or a copy of someone else's, crediting them.

Access: makes changes.

InputTypeDescription
name (optional)stringthe name, e.g. "UCG-Ultra" or "10-inch 1U shelf"
maker (optional)stringthe maker, e.g. "Ubiquiti"
kind (optional)"device" | "part"device (default) or part
category (optional)"shelf" | "tray" | "mount" | "panel" | "accessory" | "printed"a part's catalog category: shelf, tray, mount, panel, accessory, printed (default shelf)
from (optional)stringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").

Answers: { draft, url, next }: the new draft's id, its link, and what to do next.

save

Save the draft. Write your working copy to the draft, so it shows in the modeler in the browser and in the catalog as a draft. Refuses if the draft changed in the browser meanwhile, unless overwrite is true.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
overwrite (optional)boolean–

Answers: { draft, saved, url }, or saved: false with a note when there was nothing to save.

discard_changes

Discard the working copy. Drop your unsaved working copy (and the traced corners); the draft stays as last saved.

Access: makes changes that can drop or replace earlier work.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").

Answers: { draft, discarded: true }.

Modeler commands

Each is one command of the modeler, the same the browser runs, applied to the draft's working copy. Every one takes the draft it works on, and answers the same way.

apply_commands

Apply several commands. Run several modeler commands on a draft in one go, in order: [{ type: "setBody", w: 150, … }, { type: "addPort", port: { … } }]. All or nothing: if one is refused, nothing changes. Each command takes the same fields as its own tool. Detections too: { type: "acceptDetection", id: "d3" } (with label, at, size, rotate, itemId, note to correct it), { type: "rejectDetection", id, note }, { type: "updateDetection", id, label }.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
commandsobject[]the commands, each { type, ...fields }

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setIdentity

Name the device, its maker, and the link to its product or spec-sheet page.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
name (optional)stringthe device name, without the maker: "UCG-Ultra"
maker (optional)stringthe maker: "Ubiquiti"; "" clears it
datasheet (optional)stringa link to the maker's product or spec-sheet page; "" clears it

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setKind

Say what you are modelling: a device (has ports, stands on a surface or in a rack) or a part that holds or mounts things (a shelf, tray, bracket, panel, plate, spacer), with its catalog category. A part is published as that category; its mounting (setMount) and decks (addDeck) are what make it useful in a rack.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
kind"device" | "part"device (has ports; stands on a surface) or part (a shelf, bracket, tray, panel…)
category (optional)"shelf" | "tray" | "mount" | "panel" | "accessory" | "printed"a part's catalog category: shelf, tray, mount, panel, accessory, printed (mount: brackets and ears; printed: 3D-printed parts; accessory: spacers, plates, anything else)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setShape

Choose the body's shape (default: box). Pick the simplest that matches the silhouette: - box: a rectangular case with rounded upright corners (radius) and bevelled or rounded top and bottom edges (most switches, routers, NUCs). - rounded: a rounded rectangle seen from above whose corners are big (up to half the width: a stadium) or whose bottom edge differs from the top (bottomEdge): a Mac mini, many mini PCs. Measure the corner radius from a photo from above (the corner's arc against a ruler), or estimate from the straight part of each side. - cylinder: round seen from above (diameter): hubs, smart speakers, round workstations; a puck is a short cylinder with big round edges (edgeSize). Its round side is four faces, one quarter each (front, right, rear, left); u runs around the side from the face's left edge (measure along the surface with a tape, or from the angle: u = angle in radians × radius). Things there are drawn on the surface, not cut; photos can't be traced on the round side. - tapered: a box whose top is smaller on some sides (top: { front, rear, left, right } insets, measured horizontally): a front bezel sloping back, a NAS with a slanted front. The slanted faces are flat: their v runs up the slope. - stack: the box plus blocks (a raised section on top, rack ears, a handle). Ports go on the box's faces only; the model's size grows to take in the blocks. - extrusion: a 2D outline (with holes) on the front, right or top face, run straight through: brackets (profile angle or zee), channels, plates (plane top), panels (plane front), shelves (an angle seen from the side). Give a profile ({ kind, w, h, t }) or the outline's corners; the body's size becomes the outline's box and the length. Ports and zones go on the two outline faces only.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
shape"box" | "rounded" | "cylinder" | "tapered" | "stack" | "extrusion"box, rounded, cylinder, tapered, stack, extrusion
bottomEdge (optional)object | nullrounded, cylinder, tapered: the bottom edge when it isn't the top's (null: the same)
bottomEdge.sizenumberhow far the chamfer or round reaches in (mm)
bottomEdge.style"bevel" | "round"bevel (a chamfer) or round
top (optional)objecttapered: how much smaller the top is than the bottom on each side (mm, measured horizontally)
top.front (optional)numberfront (mm)
top.rear (optional)numberrear (mm)
top.left (optional)numberleft (mm)
top.right (optional)numberright (mm)
diameter (optional)numbercylinder: its diameter (sets w and d) (mm)
blocks (optional)object[]stack: every block added to the box (replaces the list)
plane (optional)"front" | "right" | "top"extrusion: the face the outline is drawn on, seen from outside; it runs straight through to the opposite face (front: a profile seen from the front, run to the rear; right: seen from the right side, run across the width; top: a plate seen from above, run down)
outline (optional)([number, number])[]extrusion: the outline on that face
holes (optional)(([number, number])[])[]extrusion: holes right through it (mounting holes, cut-outs)
profile (optional)objectextrusion: a standard profile instead of an outline
profile.kind"plate" | "angle" | "channel" | "zee"plate (a rectangle), angle (an L: legs along the bottom and up the left), channel (a U), zee (a Z)
profile.wnumberits width on that face (mm)
profile.hnumberits height on that face (mm)
profile.tnumberthe material thickness (mm)
length (optional)numberextrusion: how far it runs through (the thickness of a plate) (mm)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setMount

How it mounts: on rack rails (standard 10in, 19in or deskpi-tl1, its height in U, and the flange: the depth from its front to where the ears sit against the rails, usually the faceplate thickness, 2–3 mm), or null to stand on a flat surface. Anything that mounts in a rack (a shelf, a blanking panel, a 1U device with ears) needs this.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
railsobject | nullthe rails it mounts on; null: it stands on a flat surface (a shelf, a desk)
rails.standard"10in" | "19in" | "deskpi-tl1"10in and 19in: EIA-310 rack rails; deskpi-tl1: the DeskPi RackMate TL1 rails
rails.unitsnumberits height on the rails in rack units (1U = 44.45 mm); 0.5 steps
rails.flange (optional)numberfrom the front of the model to the face that sits against the rails (the back of the ears); default 3 (mm)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

addDeck

Offer a deck: a flat surface devices stand on (a shelf socket). at is its front-left corner in model coordinates (x from the left of the whole model, y from its front, z the height of the surface), size its usable [width, depth]; capacity and maxLoadG are optional limits. A shelf or tray needs one to hold anything.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
deckobject–
deck.id (optional)stringoptional; made from the label ("deck")
deck.label (optional)stringwhat the device calls it: "LAN 1", "USB-C (PD in)"
deck.at[number, number, number]its front-left corner [x, y, z] mm in model coordinates (from the left-front-bottom of the whole model); z is the height of the surface devices stand on
deck.size[number, number][width, depth] mm of the flat area devices may use
deck.capacity (optional)numberhow many devices it takes (default: any that fit)
deck.maxLoadG (optional)numberthe most it carries, grams

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

updateDeck

Change a deck's fields; null clears one.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)
patchobject–
patch.label (optional)string | nullwhat the device calls it: "LAN 1", "USB-C (PD in)"
patch.at (optional)[number, number, number] | nullits front-left corner [x, y, z] mm in model coordinates (from the left-front-bottom of the whole model); z is the height of the surface devices stand on
patch.size (optional)[number, number] | null[width, depth] mm of the flat area devices may use
patch.capacity (optional)number | nullhow many devices it takes (default: any that fit)
patch.maxLoadG (optional)number | nullthe most it carries, grams

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

removeDeck

Remove a deck.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setBody

Set the body: w (left to right), d (front to rear), h (height without feet), radius of the vertical edges, and the bevel or round along the top and bottom edges. All mm. Measure the outside of the case at its widest. On a cylinder w and d are the diameter; on an extrusion the outline stretches with the size.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
w (optional)numberwidth, left to right (mm)
d (optional)numberdepth, front to rear (mm)
h (optional)numberheight of the body, without feet (mm)
radius (optional)numberradius of the four vertical edges; 0: square (mm)
edgeSize (optional)numberthe bevel or round along the top and bottom edges; 0: sharp (mm)
edgeStyle (optional)"bevel" | "round"bevel (a chamfer) or round

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setFeet

Set the feet as pegs (setBase { kind: "pegs" } by its older name; a base made of solids goes): height (0: none), diameter, inset from the edges for the default four, or their centres [x, y] in model coordinates on the bottom, and round or square.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
h (optional)numberfoot height; 0: no feet (mm)
d (optional)numberfoot diameter (mm)
inset (optional)numberfoot centres from the side and front/rear edges (the default four feet) (mm)
at (optional)([number, number])[] | nullfoot centres [x, y] mm on the bottom in model coordinates (x from the left side, y from the front); null: four near the corners
color (optional)stringa colour like "#2a2d33"
shape (optional)"round" | "square"round (default) or square pegs (d is the side)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setBase

Set the base: what the device stands on. Pick the kind from a photo from the side at table level and one from below: - pegs: separate feet near the corners. Measure their height, diameter (or side) and inset, or give each centre (at). layout "corners-and-middle" for six. - plinth: one base set in from the body's edges (the body seems to float over a smaller, often darker block). Measure its footprint (size, or inset from the body's edges), height and outline (rect with radius, ellipse, stadium, path), and how it meets the body: step, chamfer, cove (a concave curve flaring out into the body: measure its radius, see the server's instructions on curves) or round (convex). tuck: the body's bottom edge curving in to meet it. pad: a rubber pad or ring on its bottom. - rails: parallel runners (NAS units, some switches): count, width, height, inset from the sides, endInset from the ends, along d (front to rear) or w. - none: a flat bottom. custom: keep the height and build the base from solids (addSolid, z < 0). A plinth and rails are made as solids (role "base"), which list_solids shows and updateSolid edits; setBase again replaces them. h is always the height from the table to the body's bottom.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
kind"pegs" | "plinth" | "rails" | "none" | "custom"pegs (round or square feet), plinth (one inset base under the body), rails (parallel runners), none (flat bottom), custom (keep the height, build the base from solids yourself)
h (optional)numberthe height under the body: from the table to the bottom of the body (mm)
d (optional)numberpegs: a peg's diameter (square: its side) (mm)
inset (optional)number | [number, number]pegs: from each peg's centre to the sides and the front or rear (mm); plinth: from the body's edges to the plinth's, [side, front/rear] or one number, instead of its size; rails: from the body's sides to the outer runners' outer edges
at (optional)([number, number])[] | nullpegs: their centres [x, y] mm in model coordinates, any number; null: four near the corners
shape (optional)"round" | "square"pegs: round (default) or square
layout (optional)"corners" | "corners-and-middle"pegs: four near the corners, or six (the middles of the sides too)
color (optional)stringa colour like "#2a2d33"
outline (optional)"rect" | "ellipse" | "stadium" | "path"plinth: its outline seen from below: rect (with radius), ellipse (a circle if square), stadium, path
size (optional)[number, number]plinth: its footprint [width, depth] mm, where it stands on the table
centre (optional)[number, number]plinth: its centre [x, y] mm in body coordinates (default: the body's centre)
radius (optional)numberplinth (rect): its corners' radius (mm)
points (optional)number[][]plinth (path): its outline about its centre, [x, y] as seen from above
transition (optional)"step" | "chamfer" | "cove" | "round"plinth: how it meets the body: step (a plain right angle), chamfer (a straight bevel), cove (a concave curve: the plinth flares out into the body), round (a convex round on the plinth's top edge)
transitionSize (optional)numberplinth: the cove's or round's radius, the chamfer's leg (mm)
tuck (optional)numberplinth: the body's bottom edge rounded in to meet the plinth (a tucked underside), its radius; 0 takes it off (mm)
pad (optional)object | nullplinth: a rubber pad or ring on its bottom; null removes it
pad.insetnumberfrom the plinth's edge (mm)
pad.thicknessnumberits thickness (part of h) (mm)
pad.ring (optional)numbera ring this wide instead of a full pad (mm)
pad.color (optional)stringa colour like "#2a2d33"
finish (optional)objectdefault: the body's
finish.colorstringa colour like "#2a2d33"
finish.preset"matte-plastic" | "brushed-metal" | "perforated-grille" | "metal-foam"matte-plastic, brushed-metal, perforated-grille, metal-foam
count (optional)numberrails: how many runners (2 to 8)
width (optional)numberrails: each runner's width (mm)
endInset (optional)numberrails: from the front and rear (or the sides, across) to their ends (mm)
along (optional)"d" | "w"rails: d (front to rear, default) or w (side to side)
round (optional)numberrails: their bottom edges rounded, radius (mm)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

addSolid

Add a solid: geometry the shapes and presets don't have (a boss, a knob, a raised panel, a handle, a dome, a hood), or a cut (op "cut": a groove, a recess, a vent, taken out of the flat face it runs into). Kinds: extrude (a profile run straight; draft; rims at either end: round, cove, chamfer, flare), box, cylinder, revolve (an [r, a] profile turned round the axis), loft (from one profile to another). Profiles: rect, circle, ellipse, stadium, or a path whose [u, v, bulge] points make arcs. Place it in body coordinates (at, axis), or onFace { face, at: [u, v], depth? } like a port: the profile as seen on that face, running out of it (a cut: depth into it). A cut must be a straight extrude, box or cylinder square to one flat face, and not go through. Ports can't go where a solid covers a face or over a cut. Check it with render_faces { section: "side" } and the faces.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
solidobjecta solid: extrude, box, cylinder, revolve or loft
onFace (optional)objectplace it on a face instead of giving at and axis: its profile is drawn as seen on that face (from outside), and it runs out of the face (a cut: depth into it). The easiest way to put a groove, a recess, a vent or a boss on a face
onFace.face"front" | "rear" | "left" | "right" | "top" | "bottom"front, rear, left, right, top or bottom
onFace.at[number, number]where the profile's origin goes on that face: [u, v] mm from the face's bottom-left corner as seen from outside (u right, v up)
onFace.depth (optional)numbera cut: how deep into the face (sets its length) (mm)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

updateSolid

Change a solid's fields (any but id; null clears one): move it (at), resize it, change its profile, rims, draft, finish or op.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)
patchobject–
patch.label (optional)string | null–
patch.op (optional)"add" | "cut" | null–
patch.at (optional)[number, number, number] | null–
patch.axis (optional)"z" | "-z" | "y" | "-y" | "x" | "-x" | null–
patch.rotate (optional)number | null–
patch.finish (optional)object | null–
patch.finish.colorstringa colour like "#2a2d33"
patch.finish.preset"matte-plastic" | "brushed-metal" | "perforated-grille" | "metal-foam"–
patch.profile (optional)any | null–
patch.h (optional)number | null–
patch.draft (optional)number | null–
patch.top (optional)object | nulla rim on one end
patch.top.kind"round" | "cove" | "chamfer" | "flare"round: the edge rounded off (convex); cove: a concave curve flaring OUT by size into what it meets (the curved transition under a body); chamfer: a bevel in; flare: a bevel out
patch.top.sizenumberthe radius (round, cove) or the bevel's leg (chamfer, flare) (mm)
patch.bottom (optional)object | nulla rim on one end
patch.bottom.kind"round" | "cove" | "chamfer" | "flare"round: the edge rounded off (convex); cove: a concave curve flaring OUT by size into what it meets (the curved transition under a body); chamfer: a bevel in; flare: a bevel out
patch.bottom.sizenumberthe radius (round, cove) or the bevel's leg (chamfer, flare) (mm)
patch.size (optional)[number, number, number] | null–
patch.radius (optional)number | null–
patch.d (optional)number | null–
patch.angle (optional)number | null–
patch.from (optional)object | nulla 2D outline, centred on its origin (a path: where its points say): rect (with corner radius r), circle, ellipse, stadium, or path
patch.to (optional)object | nulla 2D outline, centred on its origin (a path: where its points say): rect (with corner radius r), circle, ellipse, stadium, or path
patch.shift (optional)[number, number] | null–

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

removeSolid

Remove a solid.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

addPort

Add a port opening (or a row of identical ones). Positions are [u, v] mm on the face (see the server instructions: seen from outside, from the bottom-left corner, centre of the item). The reply gives its id.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
portobject–
port.id (optional)stringoptional; made from the kind: "usb-c", "usb-c-2"
port.kind"usb-c" | "thunderbolt" | "usb-a" | "rj45" | "hdmi" | "displayport" | "sfp" | "qsfp" | "dc-barrel" | "audio-3.5" | "ac-c8" | "ac-c14" | "sd-card" | "power-button" | "lock-slot"one of: usb-c, thunderbolt, usb-a, rj45, hdmi, displayport, sfp, qsfp, dc-barrel, audio-3.5, ac-c8, ac-c14, sd-card, power-button, lock-slot
port.label (optional)stringwhat the device calls it: "LAN 1", "USB-C (PD in)"
port.face"front" | "rear" | "left" | "right" | "top" | "bottom"front, rear, left, right, top or bottom
port.at[number, number]the centre of the opening (the first one, for a row): [u, v] mm from the face's bottom-left corner as seen from outside (u right, v up)
port.rotate (optional)0 | 90 | 180 | 270degrees counter-clockwise seen from outside: 90 stands a port on end
port.count (optional)numbera row of this many identical ports
port.pitch (optional)numbercentre-to-centre distance in a row (mm)
port.along (optional)"u" | "v"a row runs along u (to the right, default) or v (upwards)
port.size (optional)[number, number][width, height] mm of the opening, before rotation, when it isn't the standard size

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

movePort

Move a port. Positions are [u, v] mm on the face (see the server instructions: seen from outside, from the bottom-left corner, centre of the item).

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)
at[number, number]the new centre: [u, v] mm from the face's bottom-left corner as seen from outside (u right, v up)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

updatePort

Change any of a port's fields (kind, label, face, at, rotate, count, pitch, along, size); null clears one.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)
patchobject–
patch.kind (optional)"usb-c" | "thunderbolt" | "usb-a" | "rj45" | "hdmi" | "displayport" | "sfp" | "qsfp" | "dc-barrel" | "audio-3.5" | "ac-c8" | "ac-c14" | "sd-card" | "power-button" | "lock-slot" | nullone of: usb-c, thunderbolt, usb-a, rj45, hdmi, displayport, sfp, qsfp, dc-barrel, audio-3.5, ac-c8, ac-c14, sd-card, power-button, lock-slot
patch.label (optional)string | nullwhat the device calls it: "LAN 1", "USB-C (PD in)"
patch.face (optional)"front" | "rear" | "left" | "right" | "top" | "bottom" | nullfront, rear, left, right, top or bottom
patch.at (optional)[number, number] | nullthe centre of the opening (the first one, for a row): [u, v] mm from the face's bottom-left corner as seen from outside (u right, v up)
patch.rotate (optional)0 | 90 | 180 | 270 | nulldegrees counter-clockwise seen from outside: 90 stands a port on end
patch.count (optional)number | nulla row of this many identical ports
patch.pitch (optional)number | nullcentre-to-centre distance in a row (mm)
patch.along (optional)"u" | "v" | nulla row runs along u (to the right, default) or v (upwards)
patch.size (optional)[number, number] | null[width, height] mm of the opening, before rotation, when it isn't the standard size

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

removePort

Remove a port.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

addZone

Add a zone: an area of a face with its own finish (a vent grille, a metal-foam front), flush or sunk in. Ports inside it are cut into it. Positions are [u, v] mm on the face (see the server instructions: seen from outside, from the bottom-left corner, centre of the item).

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
zoneobject–
zone.id (optional)stringoptional; made from the label
zone.label (optional)stringwhat the device calls it: "LAN 1", "USB-C (PD in)"
zone.face"front" | "rear" | "left" | "right" | "top" | "bottom"front, rear, left, right, top or bottom
zone.at[number, number]the centre of the zone: [u, v] mm from the face's bottom-left corner as seen from outside (u right, v up)
zone.size[number, number][width, height] mm
zone.radius (optional)numbercorner radius (mm)
zone.depth (optional)numberhow far it is sunk into the face; 0 or absent: flush (mm)
zone.finishobject–
zone.finish.colorstringa colour like "#2a2d33"
zone.finish.preset"matte-plastic" | "brushed-metal" | "perforated-grille" | "metal-foam"matte-plastic, brushed-metal, perforated-grille, metal-foam

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

moveZone

Move a zone. Positions are [u, v] mm on the face (see the server instructions: seen from outside, from the bottom-left corner, centre of the item).

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)
at[number, number]the new centre: [u, v] mm from the face's bottom-left corner as seen from outside (u right, v up)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

updateZone

Change a zone's fields; null clears one.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)
patchobject–
patch.label (optional)string | nullwhat the device calls it: "LAN 1", "USB-C (PD in)"
patch.face (optional)"front" | "rear" | "left" | "right" | "top" | "bottom" | nullfront, rear, left, right, top or bottom
patch.at (optional)[number, number] | nullthe centre of the zone: [u, v] mm from the face's bottom-left corner as seen from outside (u right, v up)
patch.size (optional)[number, number] | null[width, height] mm
patch.radius (optional)number | nullcorner radius (mm)
patch.depth (optional)number | nullhow far it is sunk into the face; 0 or absent: flush (mm)
patch.finish (optional)object | null–
patch.finish.colorstringa colour like "#2a2d33"
patch.finish.preset"matte-plastic" | "brushed-metal" | "perforated-grille" | "metal-foam"matte-plastic, brushed-metal, perforated-grille, metal-foam

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

removeZone

Remove a zone.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

addFeature

Add an LED or a small button. Positions are [u, v] mm on the face (see the server instructions: seen from outside, from the bottom-left corner, centre of the item).

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
featureobject–
feature.id (optional)stringoptional; made from the kind
feature.kind"led" | "button"led or button
feature.label (optional)stringwhat the device calls it: "LAN 1", "USB-C (PD in)"
feature.face"front" | "rear" | "left" | "right" | "top" | "bottom"front, rear, left, right, top or bottom
feature.at[number, number]the centre: [u, v] mm from the face's bottom-left corner as seen from outside (u right, v up)
feature.dnumberdiameter (mm)
feature.colorstringa colour like "#2a2d33"

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

moveFeature

Move an LED or button. Positions are [u, v] mm on the face (see the server instructions: seen from outside, from the bottom-left corner, centre of the item).

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)
at[number, number]the new centre: [u, v] mm from the face's bottom-left corner as seen from outside (u right, v up)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

updateFeature

Change an LED's or button's fields; null clears one.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)
patchobject–
patch.kind (optional)"led" | "button" | nullled or button
patch.label (optional)string | nullwhat the device calls it: "LAN 1", "USB-C (PD in)"
patch.face (optional)"front" | "rear" | "left" | "right" | "top" | "bottom" | nullfront, rear, left, right, top or bottom
patch.at (optional)[number, number] | nullthe centre: [u, v] mm from the face's bottom-left corner as seen from outside (u right, v up)
patch.d (optional)number | nulldiameter (mm)
patch.color (optional)string | nulla colour like "#2a2d33"

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

removeFeature

Remove an LED or button.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe id of the item (as the add command or get_draft reported it)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setFinish

Set the finish of the body or a zone ("zone:<id>"): a colour, and a preset (matte-plastic, brushed-metal, perforated-grille, metal-foam). Sample the colour from a photo of the real device.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
targetstring"body" or "zone:<id>"
finishobject–
finish.color (optional)stringa colour like "#2a2d33"
finish.preset (optional)"matte-plastic" | "brushed-metal" | "perforated-grille" | "metal-foam"matte-plastic, brushed-metal, perforated-grille, metal-foam

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setSource

Say where a value comes from: measured (calipers, a ruler), datasheet, or estimated. Keys: body.w, body.d, body.h, body.radius, body.edge, body.shape, feet, mount, mass, port:<id>, zone:<id>, feature:<id>.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
keystringwhich value: "body.w", "body.d", "body.h", "body.radius", "body.edge", "body.shape", "feet", "mount", "mass", "port:<id>", "zone:<id>", "feature:<id>", "solid:<id>"
source"measured" | "datasheet" | "estimated" | nullmeasured, datasheet or estimated; null: the default

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setMass

Set the weight in grams (null clears it).

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
gramsnumber | nullthe weight in grams; null clears it

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setNote

A note for whoever reopens these measurements: how they were taken, what is still a guess.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
notestringhow it was measured, what is still a guess (up to 2,000 characters)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setPhoto

Tell the modeler you traced a face on an image of this size (pixels). The image stays with you; only its size is kept, so that corners and points on it can be turned into mm. source "drawing" for a datasheet page.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
face"front" | "rear" | "left" | "right" | "top" | "bottom"front, rear, left, right, top or bottom
photoobject | nullthe size of the image you traced (the image itself stays with you); null forgets it
photo.wnumberimage width, px
photo.hnumberimage height, px
photo.source (optional)"photo" | "drawing"photo (default) or drawing (a datasheet page)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setCorners

A photo's four face corners, in pixels (y down): bottom-left, bottom-right, top-right, top-left, as seen from outside. Then image_to_face turns points on the photo into mm on the face.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
face"front" | "rear" | "left" | "right" | "top" | "bottom"front, rear, left, right, top or bottom
corners[[number, number], [number, number], [number, number], [number, number]]a photo: the face's four corners on it, as seen from outside

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setScale

A drawing: the two ends of a labelled dimension (pixels) and its length in mm.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
face"front" | "rear" | "left" | "right" | "top" | "bottom"front, rear, left, right, top or bottom
a[number, number]one end of a labelled dimension: [x, y] image pixels, y down
b[number, number]its other end: [x, y] image pixels, y down
mmnumberits length as labelled (mm)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setOrigin

A drawing: where the face's bottom-left corner is on it (pixels).

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
face"front" | "rear" | "left" | "right" | "top" | "bottom"front, rear, left, right, top or bottom
at[number, number]a drawing: where the face's bottom-left corner is: [x, y] image pixels, y down

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

setSpec

Replace the whole spec (as get_draft returns it). Prefer the other commands; this one is for bulk edits.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
specobjecta whole device spec (as get_draft returns it)

Answers: { ok, draft, id?, ids?, unsaved: true, problemsWithThis?, problems }: the id of what an add command created, and how many problems the spec has now (with the ones about what this command touched). A refusal says why, and nothing changes.

Checking the work

See what the agent built, and turn pixels on a photo into millimetres.

image_to_face

Image pixels to face mm. Turn points on the image traced on a face (pixels, y down) into positions on the face ([u, v] mm), correcting the photo's perspective. Needs setPhoto and setCorners (a photo) or setScale and setOrigin (a drawing) for that face first.

Access: reads only.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
face"front" | "rear" | "left" | "right" | "top" | "bottom"–
points([number, number])[][x, y] pixels on the image, e.g. the centre of each opening

Answers: { face, points: [{ px, at, note? }] }: each pixel's [u, v] mm on the face, noted if it falls off the face.

build_summary

Summarise the model. What the modeler's builder makes of the spec, counted from it without building: the triangle count, the port anchors, the materials, about how big the GLB will be, every error and warning, and the checklist of what is still missing. Use render_faces to see it.

Access: reads only.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").

Answers: { draft, unsaved, changedElsewhere, shape, envelope, mounting, triangles, triangleTarget, anchors, materials, glbBytesEstimate, glbTarget, errors, warnings, checklist }.

render_faces

Render the faces. See what you built: each face drawn straight on as seen from outside (the same view as a straight-on photo of it), with its outline, the flat area (dashed), a 10 mm grid and ruler, zones in their colours, every opening with its port's name (rows once, with their count), LEDs and buttons, what can't be cut in red, the base and solids seen from that side (the base's height beside it), where solids cover the face (nothing can be cut there) and the cuts; overview: true adds an isometric wireframe of the whole device; section: "side" (or "front") adds a cut through the middle (sectionAt: elsewhere, mm) to check a profile, a plinth's curve or a groove's depth against a side photo. Returns PNG images (format: svg for SVG) and the same as a text listing. Compare each picture with the user's photos or drawings of that face: the position, size, spacing and name of every opening, the zones, the LEDs. Where they differ, correct the spec (movePort, updatePort, moveZone, …) and render again until they match.

Access: reads only.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
faces (optional)("front" | "rear" | "left" | "right" | "top" | "bottom")[]which faces; default: every face with something on it
format (optional)"png" | "svg"png (default: what most clients can show a model) or svg
overview (optional)booleanalso an isometric wireframe of the whole device
section (optional)"side" | "front"also a section through the model: side (at the middle of the width, seen from the right, the front on the left) or front (at the middle of the depth, seen from the front): the base's profile, rims, grooves
sectionAt (optional)numberwhere the section is instead: x (side) or y (front), model mm

Answers: A text listing of each face (its size, flat area and everything on it), then one image per face drawn (PNG, or SVG with format: "svg"), and the overview when asked for. Faces that did not fit this call's pixel budget are listed as not drawn.

Datasheets

Keep a device's datasheet PDF with it, privately.

attach_datasheet

Attach a datasheet. Keep a copy of the device's datasheet (a PDF at a public http(s) URL, up to 15 MB) with the draft, as the modeler's Datasheets panel does: the server fetches it and stores it privately (only the user and admins can open it; the public page shows only its link). The device links to the URL if it had no datasheet link yet. Read the PDF yourself for the numbers. For a PDF on the user's computer, use create_datasheet_upload instead.

Access: makes changes; reaches beyond Rack Maker (fetches a URL).

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
urlstringthe PDF's public URL, e.g. "https://example.com/specs/router.pdf"
name (optional)stringa file name to show (default: from the URL)

Answers: { draft, datasheet: { id, name, bytes, source }, note?, private, deviceLink, url }: the kept copy, who can open it, and whether the device now links to the URL.

create_datasheet_upload

Upload a datasheet from this computer. Get a link to upload the device's datasheet, a PDF on the user's computer (up to 15 MB), and keep a private copy with the draft, as the modeler's Datasheets panel does (only the user and admins can open it). Then upload the file yourself with a shell command: curl -sS -T '/path/to/datasheet.pdf' '<url>' (a PUT; curl --data-binary @file.pdf <url> also works). The link works once, for 10 minutes, for this draft only, and needs no sign-in header. This is the only way a file reaches Rack Maker from you, and only a datasheet PDF: never upload photos (read them yourself and send numbers). Read the PDF yourself for the numbers. For a PDF at a public URL, use attach_datasheet.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
filenamestringthe PDF's file name, e.g. "router-datasheet.pdf" (it is kept under this name)

Answers: { draft, upload: { url, method, expiresAt, once, maxBytes }, curl, how, private, url }: the one-time link, the command to upload the PDF with, and what the link answers.

Detections

What the detector found on the user's photos, in their browser: candidates to accept, reject or relabel. Numbers and labels only; the photos never reach the server.

list_detections

List detections. What the detector found on the user's photos of the device, run in their browser: candidate ports (by kind), vents, LEDs and buttons, each with a label, a confidence (0–1), its box on the face ([u, v] centre and [w, h] mm), the next best labels, and the user's notes. Default: the pending ones. Read them with the user's words and annotations; confirm uncertain ones with the user; then accept, reject or relabel each.

Access: reads only.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
face (optional)"front" | "rear" | "left" | "right" | "top" | "bottom"only those on this face
status (optional)"pending" | "accepted" | "rejected" | "all"pending (default), accepted, rejected or all
min (optional)numberonly those at least this confident

Answers: { draft, detections: [{ id, face, label, what, confidence, at, size, rotate?, holes?, alternatives?, status, became?, foundAs?, note?, by? }], counts, how }: each detection with its box in face mm, and how many are pending, accepted and rejected.

accept_detection

Accept a detection. Make what a detection shows, with the ordinary commands, in your working copy: a port of its kind (turned on end, and with its own opening size when it differs from the standard one by more than 0.8 mm), a zone with a grille finish for a vent, or an LED or button. Correct it on the way: label, at, size, rotate. Say why in note when it helps the user. An "opening" of no known kind needs a label.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe detection, as list_detections names it: "d3"
label (optional)"usb-c" | "thunderbolt" | "usb-a" | "rj45" | "hdmi" | "displayport" | "sfp" | "qsfp" | "dc-barrel" | "audio-3.5" | "ac-c8" | "ac-c14" | "sd-card" | "power-button" | "lock-slot" | "vent" | "led" | "button" | "opening"a port kind, or vent (a zone), led, button: usb-c, thunderbolt, usb-a, rj45, hdmi, displayport, sfp, qsfp, dc-barrel, audio-3.5, ac-c8, ac-c14, sd-card, power-button, lock-slot, vent, led, button, opening
at (optional)[number, number][u, v] mm on the face: the centre
size (optional)[number, number][w, h] mm as it lies on the face
rotate (optional)0 | 9090: a port standing on end
itemId (optional)stringan id for the new port, zone or LED
note (optional)stringwhy, for the user

Answers: { ok, draft, id, unsaved, problems, accepted, became }, as a command answers: the id of the port, zone or LED it became.

reject_detection

Reject a detection. Drop a detection that is nothing (a screw, a label, a shadow) or that you won't model, with a note saying why. The user sees it rejected, live.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe detection, as list_detections names it: "d3"
note (optional)stringwhy, for the user

Answers: { draft, rejected, pending }: how many are still pending.

update_detection

Relabel or adjust a detection. Relabel a detection (the kind you or the user think it is), move or resize its box, or note something on it, without accepting it yet: e.g. when you want the user to confirm first. The label as found is kept (foundAs).

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe detection, as list_detections names it: "d3"
label (optional)"usb-c" | "thunderbolt" | "usb-a" | "rj45" | "hdmi" | "displayport" | "sfp" | "qsfp" | "dc-barrel" | "audio-3.5" | "ac-c8" | "ac-c14" | "sd-card" | "power-button" | "lock-slot" | "vent" | "led" | "button" | "opening"a port kind, or vent (a zone), led, button: usb-c, thunderbolt, usb-a, rj45, hdmi, displayport, sfp, qsfp, dc-barrel, audio-3.5, ac-c8, ac-c14, sd-card, power-button, lock-slot, vent, led, button, opening
at (optional)[number, number][u, v] mm on the face: the centre
size (optional)[number, number][w, h] mm as it lies on the face
rotate (optional)0 | 9090: a port standing on end
note (optional)stringa note for the user ("" removes it)

Answers: { draft, updated }: the detection as it is now.

Publishing

Submit to the catalog.

publish

Publish. Save, then submit the device or part to the catalog under CC BY-SA 4.0. With contributor access it is published in your namespace with its model file (GLB), built here from its spec and credited to the user (if that build fails, it is published with its spec and the user's browser attaches the model file later; the answer says which). Without contributor access, the measurements go to an admin for review and it is drawn from its spec meanwhile. Ask the user before publishing.

Access: makes changes that can drop or replace earlier work.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
overwrite (optional)boolean–

Answers: { draft, status, note?, model, asset?, url }: published or review, and what became of the model file (built here, with its asset id, or attached by a browser later).

More tools

Newer tools, not grouped yet.

list_annotations

List annotations. The user's annotations on the draft's device: pins and boxes on its faces or model, and notes on its ports, zones and measurements. Kinds: issue and wrong ("this is wrong": corrections for you to make), measure (a number someone should measure), note. Each has its number (#3), where it is (face and [u, v] mm), its text, replies, and how it was resolved. Default: the open ones. Read them before changing a device, fix every issue, and resolve each with a note on what you changed.

Access: reads only.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
status (optional)"open" | "resolved" | "all"which ones (default: open)
face (optional)"front" | "rear" | "left" | "right" | "top" | "bottom"only those on this face

Answers: JSON text; see the description.

add_annotation

Add an annotation. Pin a note on the device for the user, shown at once in their modeler: most often kind "measure" to ask them to measure something you can't see well ("measure the distance from the left edge to the first USB port"), with an anchor where it is. Also "note" (something they should know) or "issue" (a problem you found but can't fix). Their answer comes back as a reply (list_annotations).

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
kind (optional)"note" | "issue" | "measure" | "wrong"measure (default: ask the user to measure it), note, issue or wrong
textstringwhat you ask or say, in one or two sentences
anchorobjectWhere it is. On a face ([u, v] mm, as every position): { kind: "point", face, at: [u, v] } a pin; { kind: "rect", face, at: [u, v] (centre), size: [w, h] } a box; { kind: "polygon", face, points: [[u, v], …] }. On the model: { kind: "surface", at: [x, y, z] } (model mm). A thing: { kind: "item", ref: "port:<id>" | "zone:<id>" | "feature:<id>" | "measure:body.h" }. The whole model: { kind: "part" }.
anchor.kind"point" | "rect" | "polygon" | "surface" | "item" | "part"–

Answers: JSON text; see the description.

resolve_annotation

Resolve an annotation. Mark an annotation resolved, with a note saying what you changed ("moved usb-c-1 3 mm left, to [42, 12]") or why nothing needed to change. Do this after fixing each issue the user raised; the user sees it resolved, live.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe annotation: its number ("#3") or its id, as list_annotations shows it
notestringwhat you changed, with the numbers

Answers: JSON text; see the description.

reply_to_annotation

Reply to an annotation. Answer an annotation without resolving it: ask the user what they meant, or for a measurement you need, when a correction doesn't make sense to you. The user sees the reply under it, live.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe annotation: its number ("#3") or its id, as list_annotations shows it
textstringyour reply

Answers: JSON text; see the description.

list_solids

List the solids. The draft's base in words and its solids (added and cut), each in words and as data (what updateSolid changes), where it reaches in the model, which faces it covers (nothing can be cut there) or which face it is cut into, and its problems.

Access: reads only.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").

Answers: JSON text; see the description.

report_modeling_gap

Report a modelling gap. Tell Rack Maker's admins about a shape of the device that the modeler can't represent, instead of hitting a dead end. Use it only after trying to compose the shape from the modeler's solids (extrude, revolve, loft, box, cylinder, with rim fillets/chamfers, added or cut) and presets. Describe the shape in words and mm, what you tried, and optionally the primitive that would do it. Text only: never include photos, links to them, or personal data. It is filed for the admins with the draft; tell the user it was filed.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
descriptionstringthe shape, in words and mm, e.g. "a 30 mm dome, 120 mm across, on the top"
what_was_triedstringthe solids, presets and commands you tried, and why they fell short
suggested_primitive (optional)stringthe primitive or option that would do it, e.g. "sphere cap"

Answers: JSON text; see the description.

define_form

Define the measurement form. Build a measurement form for this device from what you know of it (its datasheet, photos, similar devices): the few numbers the user can measure with calipers or a ruler, grouped in sections in the order to measure them, each with how to measure it, a sensible range, your best value and its source (estimated until the user confirms). Then formulas turn them into the spec: body.w = case_w, the u of a row of ports = margin + i*pitch, a zone = case_w - 2*bezel. Values worked out from others are measurements with expr. Everything is optional but the sections. Clients that render MCP Apps show the form inline in the chat: the user sees every value with its unit, source and the formulas it feeds, a drawing of the face, and can edit values or flag one as wrong right there; everyone else gets the same as text. It is live in the user's open modeler too (the Measurements panel), where editing a value re-renders the 3D model at once. After defining it, show it to the user and ask them to check each value; apply what they correct with set_measurements, and fix formulas they say are wrong with set_formula.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
titlestringthe form's title: "DGX Spark: case and rear ports"
intro (optional)stringa line for the user: what they need (calipers, a ruler)
sectionsobject[]–
formulas (optional)object[]the spec fields worked out from the measurements

Answers: JSON text; see the description.

get_form

Get the measurement form. The draft's measurement form: every measurement with its value, unit, source, how to measure it, the formulas it feeds and their results, errors, the user's open flags, and checks (a part bigger than its face, an opening over an edge, a value that looks 25.4× off). Clients that render MCP Apps show the form inline in the chat: the user sees every value with its unit, source and the formulas it feeds, a drawing of the face, and can edit values or flag one as wrong right there; everyone else gets the same as text. It is live in the user's open modeler too (the Measurements panel), where editing a value re-renders the 3D model at once.

Access: reads only.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").

Answers: JSON text; see the description.

show_form

Show the measurement form. Show the user the draft's measurement form to check and correct: inline in the chat where the client renders MCP Apps, as text otherwise (with the link to the modeler). Clients that render MCP Apps show the form inline in the chat: the user sees every value with its unit, source and the formulas it feeds, a drawing of the face, and can edit values or flag one as wrong right there; everyone else gets the same as text. It is live in the user's open modeler too (the Measurements panel), where editing a value re-renders the 3D model at once. Afterwards, read what they changed or flagged (get_form, list_flags).

Access: reads only.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").

Answers: JSON text; see the description.

set_measurements

Set measurements. Set several measurements at once, as the user gives them ("the case is 151.2, the bumper 1.5"): each { id, value, source }. Mark what the user measured as measured, what came from the datasheet as datasheet. Every formula is worked out again and the spec follows; the answer lists what changed, errors (a negative size, a value out of range) and checks. The inline form calls this too when the user edits a value.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
valuesobject[]–

Answers: JSON text; see the description.

set_formula

Set a formula. Drive a spec field by a formula over the measurements (expr), or drop its formula (expr: null; the field keeps its number). Several fields with one formula (paths) each get their index as i: the u of lan-1…lan-4 = margin + i*pitch. Units are checked: a formula that gives mm² or a count where mm are due is refused, as are unknown names and cycles. Use it to fix a formula the user says is wrong.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
path (optional)stringthe spec field: body.w, body.d, body.h, body.radius, body.edge, body.bottom, body.top.front|rear|left|right, feet.h|d|inset, massG, mount.units|flange, port:<id>.at.u|v, port:<id>.pitch|count, port:<id>.size.w|h, zone:<id>.at.u|v, zone:<id>.size.w|h, zone:<id>.radius|depth, feature:<id>.at.u|v, feature:<id>.d, block:<id>.at.x|y|z, block:<id>.size.w|d|h, deck:<id>.at.x|y|z, deck:<id>.size.w|d
paths (optional)string[]several fields, one formula: each gets its index as i (0, 1, 2…), e.g. the u of lan-1…lan-4 = margin + i*pitch
exprstring | nullthe formula; null drops it

Answers: JSON text; see the description.

explain

Explain the formulas. Every measurement and formula with its worked-out value, as text: what each spec field is computed from, which fields each measurement feeds, errors, open flags and checks. Use it to tell the user how their measurements are used, or to check your formulas.

Access: reads only.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").

Answers: JSON text; see the description.

list_flags

List the user's flags. The values and formulas the user marked as wrong (in the modeler's Measurements panel or the inline form), each with their note: open ones first. Fix each (set_measurements, set_formula, or ask the user), then resolve_flag it with what you did.

Access: reads only.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
status (optional)"open" | "resolved" | "all"default open

Answers: JSON text; see the description.

resolve_flag

Resolve a flag. Close a flag the user raised, once you have fixed what it points at (or explained why it is right): resolution says what you did, and the user sees it next to the value.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
idstringthe flag, "f1"
resolution (optional)stringwhat you changed, for the user

Answers: JSON text; see the description.

flag_value

Flag a value as wrong. The user marks a measurement ("measurement:<id>") or a formula ("formula:<path>") as wrong, with a note. The inline form calls this; list_flags reads them.

Access: makes changes.

InputTypeDescription
draftstringThe draft: "<namespace>/<slug>@<rev>", as list_my_drafts or create_draft gave it (e.g. "ana/nas-box@1").
targetstring"measurement:<id>" or "formula:<path>"
notestringwhat looks wrong

Answers: JSON text; see the description.

On this page