# How an agent measures

The conventions an agent follows in the device modeler - units, faces, [u, v] positions, flat areas, photos and drawings to mm, ports, shapes, parts and sources.

Source: https://rack-maker.cbnsndwch.dev/docs/agents/measuring

## Where these come from

The MCP server sends these conventions to your agent when it connects (as its instructions), and each tool describes its own inputs. They are the same rules the modeler uses in the browser, so what an agent builds opens there unchanged. Knowing them helps you check its work and ask for the right corrections.

## The workflow

1. Find a draft (`list_my_drafts`), or start one (`create_draft`): a device by its name, a part by its name and category, or a new revision of a published one.
2. Set the shape if it isn't a plain box, the body's size, the feet and the identity. For anything that mounts in a rack or holds devices, set the mounting and the decks.
3. For each face with ports, find the face on a photo or drawing, work out where each opening is in mm on that face, and add the ports, zones, LEDs and buttons.
4. Draw the faces (`render_faces`), compare each drawing with your photos, correct what differs, and draw again. `get_draft` shows what is still missing.
5. Keep the datasheet with the device, if there is one.
6. Save, and publish when you say so.

## Units and the body

- **Millimetres everywhere.** Weight is in grams.
- The device stands upright. **w** (width) is left to right, **d** (depth) front to rear, and **h** (height) is the body without its feet.
- Measure the outside of the case at its widest.
- **Model coordinates**, used for decks, blocks and feet: the origin is the left-front-bottom corner, x to the right, y towards the rear, z up.

## Faces and positions

The six faces are front, rear, left, right, top and bottom. A position on a face is `[u, v]`: mm from that face's bottom-left corner **as seen from outside, looking straight at it**, with u to the right and v up. Every position is the **centre** of what it places.

| Face   | Seen from                                          | u     | v                              | Size  |
| ------ | -------------------------------------------------- | ----- | ------------------------------ | ----- |
| front  | the front                                          | x     | height above the body's bottom | w × h |
| rear   | behind: the device's right side is on your left    | w − x | height                         | w × h |
| left   | the device's left side: the front is on your right | d − y | height                         | d × h |
| right  | its right side: the front is on your left          | y     | height                         | d × h |
| top    | above, front edge at the bottom of the view        | x     | y                              | w × d |
| bottom | below, front edge at the bottom of the view        | w − x | y                              | w × d |

On the sides, v starts at the body's bottom edge; the feet are below it.

## The flat area

Openings must sit inside a face's **flat area**, clear of the rounded corners and edge bevels, with 0.4 mm to spare. `get_draft` lists each face's size and flat area as `[u0, v0, u1, v1]`, and `render_faces` draws the flat area dashed. In the modeler it is the dashed line on each face.

## Photos to mm

1. Use a view of one face, as straight on as possible.
2. Find the pixel positions `[x, y]` of the face's four corners, with y counting down as images do, in this order: bottom-left, bottom-right, top-right, top-left, as seen from outside.
3. Send the photo's size in pixels (`setPhoto`), then the corners (`setCorners`).
4. `image_to_face` then turns any pixel on that photo into `[u, v]` mm on the face, correcting the perspective. The agent uses it on the centre of each opening, then adds a port there.

The photo itself stays on your computer: only its size and the corners are sent.

### Without the tool

For a straight-on photo, the sums are simple:

```text
u = (x − x_left) / (x_right − x_left) × face width
v = (y_bottom − y) / (y_bottom − y_top) × face height
```

### Drawings

A datasheet drawing is already straight on, so it is placed by a scale and an origin instead of corners:

- `setPhoto` with the page's size and `source: "drawing"`;
- `setScale`: the two ends of a labelled dimension, in pixels, and its length in mm;
- `setOrigin`: where the face's bottom-left corner is on the page.

### Checking the numbers

Check against something known: a port's standard size (below), the pitch of a row of RJ45 ports (about 14 to 16 mm), the labelled overall size.

## Ports

A port has a **kind**, a **face** and a centre (`at`). The kind brings its standard opening, in mm, lying flat:

| Kind           | What                       | Opening (w × h) |
| -------------- | -------------------------- | --------------- |
| `usb-c`        | USB-C                      | 8.9 × 3.2       |
| `thunderbolt`  | Thunderbolt / USB4 (USB-C) | 8.9 × 3.2       |
| `usb-a`        | USB-A                      | 13.2 × 5.7      |
| `rj45`         | RJ45 (Ethernet)            | 11.8 × 9.4      |
| `hdmi`         | HDMI                       | 15 × 5.6        |
| `displayport`  | DisplayPort                | 16.1 × 5.5      |
| `sfp`          | SFP / SFP+ cage            | 14.2 × 9.4      |
| `qsfp`         | QSFP cage                  | 19 × 9.2        |
| `dc-barrel`    | DC barrel jack             | 8 × 8           |
| `audio-3.5`    | 3.5 mm audio jack          | 3.8 × 3.8       |
| `ac-c8`        | Mains inlet, figure-8 (C8) | 10.6 × 5.6      |
| `ac-c14`       | Mains inlet (C14)          | 24.5 × 16.5     |
| `sd-card`      | SD card slot               | 24.5 × 2.6      |
| `power-button` | Power button               | 9 × 9           |
| `lock-slot`    | Security lock slot         | 7 × 3           |

- **Rows:** a row of identical ports is one port with `count`, `pitch` (centre to centre) and `along` (`"u"`, the default, or `"v"`). Its `at` is the first one's centre: the leftmost, or the lowest.
- **Turned:** `rotate: 90` for a port standing on end.
- **Other sizes:** `size` overrides the opening when the device's differs from the standard.

Zones (areas with their own finish, such as a vent grille), LEDs and buttons are placed the same way.

## Shapes

The default is a box. `setShape` picks another; the simplest that matches the silhouette is best.

- **box**: rectangular, with rounded upright corners (`radius`) and bevelled or rounded top and bottom edges.
- **rounded**: a rounded rectangle seen from above, with big corners (up to half the width) or a bottom edge unlike the top, as on a Mac mini.
- **cylinder**: round seen from above (hubs, speakers, round workstations). Its round side is the front, right, rear and left faces, a quarter each, unwrapped: u runs around the side, so measure along the surface. Things there are drawn on, not cut, and can't be traced from a photo.
- **tapered**: a box with a smaller top (an inset per side). The slanted faces are flat, and v runs up the slope.
- **stack**: the box plus blocks (a raised section, rack ears, a handle). Only the box's faces carry things. With blocks reaching left or forward, model coordinates count from the blocks.
- **extrusion**: an outline, or a standard profile (plate, angle, channel, zee), on the front, right or top face, run straight through: brackets, panels, plates, shelves. Only its two outline faces carry things, inside the outline and clear of its holes.

A face that carries nothing on its shape (an extrusion's walls, a side rounded all the way) refuses what is put on it and says why, in `get_draft`, `render_faces` and the problems. See [Shapes and parts](https://rack-maker.cbnsndwch.dev/docs/modeler/shapes-and-parts).

## Parts and mounting

- **A part:** `create_draft` with `kind: "part"` and a `category` (or `setKind` later) for a shelf, tray, mount (brackets, ears), panel, printed part or accessory (spacers, plates). Devices are the default.
- **Rails:** `setMount` with `rails: { standard, units, flange }` puts it on `10in`, `19in` or `deskpi-tl1` rails: anything that mounts in a rack, including a 1U device with ears. `flange` is the depth from its front to where the ears sit against the rails, usually 2 to 3 mm. Without it, the model stands on a flat surface.
- **Decks:** `addDeck` offers a flat surface devices stand on. Its `at` is its front-left corner in model coordinates, with z the surface's height, and `size` its usable `[width, depth]`. A capacity and a load limit are optional.

For example, a 10-inch 1U shelf: an angle profile on the right face, 254 mm long, on 10-inch rails, 1U, flange 3, with a deck about 222 mm wide between the rails.

The published entry fits the catalog's racks like any other part, so a modelled shelf holds devices in a project.

## Sources

Each value is marked with where it comes from, with `setSource`: **measured** (calipers, a ruler), **datasheet**, or **estimated**. Unmarked values count as estimated. The review counts them, and a device with no real measurements helps nobody, so a good agent marks what it measured.
