# OneBilly — agent skill

A **1000×1000×1000** pixel world. One billion pixels. **$1 per pixel.** Humans and agents buy the same way: pick a stamp, find empty space, pay with Stripe.

Discovery: `GET /api/agent` · MCP: `POST /api/mcp` · this file: `GET /skill.md`

## Connect MCP

```json
{ "mcpServers": { "onebilly": { "url": "https://HOST/api/mcp" } } }
```

Local: `http://localhost:3001/api/mcp`. Preview URLs are Vercel-SSO gated; use localhost or a public custom domain.

Tools: `world_status`, `list_landmarks`, `list_stamps`, `build_stamp`, `compose_stamp`, `pixlify_image`, `suggest_placement`, `preview_placement`, `quote_stamp`, `create_checkout`, `hold_space`, `signup_instructions`.

**`hold_space`** reserves an empty cuboid *volume* (max 200/axis, 1M cells) at **25%** of its painted price. A light-blue frame renders at the boundary, blocks other buyers, and converts to credit when a purchase paints inside it. Use it when the human wants to lock a location before finalizing a design.

If the host cannot speak MCP, call the REST API below. Same facts.

## Grid

- Coordinates are integers `x y z` in `0…999`. Pack id = `z*1e6 + y*1000 + x`.
- Jump names: Origin, Core, Redwood, Cthulhu, Dragon, Panda, Matrix, Starry Night, Sunflowers, Almond Blossom, Café Terrace, Wheatfield, Irises, Bedroom, Self-Portrait, Scale, or `412 88 900`.
- Empty space is buyable. Occupied cells are owned collections. The top face (`y=999`, 1,000,000 pixels) is **reserved** (The Matrix) and not for sale.

## Stamps (POST body `stamp`)

| kind | body | notes |
|---|---|---|
| `picture` | `{ "kind":"picture","name":"<id>","depth":3 }` | Van Gogh pixel paintings. `name`: `starry_night`, `sunflowers`, `almond_blossom`, `cafe_terrace`, `wheatfield`, `irises`, `bedroom`, `self_portrait`. Palette is baked in. |
| `dragon` | `{ "kind":"dragon" }` | ~100,000 pixels, ~$100,000. Invoice rail. One already sits at Origin Market. |
| `panda` | `{ "kind":"panda" }` | ~100,000 pixels, ~$100,000. Jump: `Panda`. |
| `cthulhu` | `{ "kind":"cthulhu" }` | 1,000,000 pixels, $1,000,000. Invoice rail. Jump: `Cthulhu`. One already sits in the cube. |
| `redwood` | `{ "kind":"redwood" }` | 10,000,000 pixels, $10,000,000. Invoice rail. Jump: `Redwood`. Almost the height of the cube. |
| `sculpt` | `{ "kind":"sculpt","name":"unicorn" }` | ~10,000 pixels, ~$10,000. 30 procedural sculptures (`unicorn`, `kraken`, `godzilla`, `eiffel_tower`, `mona_lisa`, …). See `/api/stamps`. Palette is baked in. |
| `box` | `{ "kind":"box","w":8,"h":8,"d":8 }` | Solid block. |
| `wall_text` | `{ "kind":"wall_text","text":"HELLO","scale":2,"depth":2 }` | A–Z 0–9 $ , : =, max 24 chars. |
| `heart` / `sphere` / `model` | see `/api/stamps` | Still valid. |
| `build` | `{ "kind":"build","parts":[…] }` | Custom. Union of `box`, `sphere`, `capsule`, `heart` with xyz offsets. Max 32 parts. |
| `voxels` | `{ "kind":"voxels","cells":[[x,y,z,color?],…] }` | Explicit pixel list, max 40,000. Prefer `build` parts. |
| `draft` | `{ "kind":"draft","id":"<uuid>" }` | Result of `build_stamp` or `pixlify_image`. Use this for checkout. |

### Pixlify a brand image (no model)

`pixlify_image` `{ "imageUrl": "https://…/logo.png", "width": 48, "depth": 3 }`

- PNG URL only on MCP. JPEG/WebP: human uploads in the app (Image stamp).
- Nearest-neighbor downsample. Long edge 12–80. Depth 2–6. Price = painted pixels × depth (plus a 1px frame), **not** the probe box.
- Returns `previewUrl`, `checkoutStamp: { kind:"draft", id }`, `voxels`, `priceUsd`.

Then: human opens `previewUrl` and places it. Agent calls `create_checkout` with that **same** `checkoutStamp` and the chosen `anchor`. **`create_checkout` returns a Stripe URL for that exact billboard.** Give the human `payUrl`. Do not send a collection name or link — checkout stores a catalog label only.

Custom shapes the catalog does not have: call **`build_stamp`** with `parts` (or `cells`). It voxelizes, runs the solid-fill check, and returns `previewUrl` + `checkoutStamp`. Human opens the preview, then you `create_checkout` with `{ kind:"draft", id }`. Payment saves it as a normal collection. Inspection is free; placement is paid. Drafts expire in 2 hours.

**Prefer `compose_stamp`** for structured or organic shapes: layered primitives (box/sphere/cylinder/cone/torus/lathe) with per-layer `at`, `color`, `mirror`, `radial` (n-fold repeat), and `grid` repeats. Lathe profiles (`[radius,y]` pairs) make vases, rockets, chess pieces. Max 32 layers / 250k cells; billed at $1/cell after solid-fill, same draft→`create_checkout` flow.

`GET /api/stamps` returns live pixel counts and USD prices. Ghost previews for every catalog stamp resolve server-side via `POST /api/stamps/ghost`; generator geometry is never shipped to the browser. Catalog ghosts are preview-resolution (sparse cells, quantized colors) — the billed count stays exact.

## Place something (preview first)

1. `GET /api/version` — `salesFreeze` must be false.
2. `GET /api/stamps` or `list_stamps` — pick a stamp.
3. Pick an `anchor` (the cube is mostly empty). Optional `suggest_placement` is occupancy math, not a model — skip it unless you need a free-space probe.
4. **`preview_placement`** — returns `previewUrl` like `/?stamp=panda&x=&y=&z=&rot=0`. **Give that to the human. Do not checkout yet.**
5. Human opens the URL (Place mode is on). They **drag the ghost** in the cube:
   - Left-drag: move on X/Z
   - Q / E (or PageDown / PageUp): Y
   - G: drop to the floor
   - R: rotate
   - Right-drag: look around
   - Arrow keys still work (Shift = ×10)
   - Floor / in view / axis buttons in the Place panel
6. Optional `quote_stamp` after they settle.
7. Only then `create_checkout` / `POST /api/checkout`. **Agents always get a Stripe-hosted `payUrl`.** The website A/B tests that page vs an on-site checkout form; both are priced on the server (never trust a client amount).
8. After payment, `/api/version` bumps; `GET /api/world?v=N` is the mesh.

Collision, out-of-bounds, reserved listing, or a hollow shell → 409/422.

## Solids only (no hollow spam)

Stamps must fill volume. The backend:

- Bills **painted pixels plus enclosed interiors**, not the axis-aligned probe box. A dragon that occupies 6% of its helper cube is 6% of that cube, not 100%.
- Rejects wireframes / sparse shells that span empty space.
- Fills enclosed interiors and bills that volume (a 40³ hollow cube becomes 64,000 pixels). Empty corners of a concave sculpture (wings, tentacles) that open to the outside are not interiors.
- Rejects fills over 10,500,000 pixels.

A giant empty box around the world is not a cheap trick. `wall_text` is exempt (separate glyphs).

## Sign up / claim

Checkout is anonymous. Fulfillment keys off the **Stripe receipt email**.

- Browser: `/claim`
- Agent: `POST /api/auth/magic` `{ "email": "buyer@host" }`. In development the JSON includes `devLink`.
- There is no agent API key and no free placement. Inspection is free.

## Tongue in cheek

The seeded world is a Van Gogh room, a $100k dragon, a $100k panda, and a $1M Cthulhu. Hanging another Starry Night is the point. The original was oil. These are cubes.
