# claudiverse.cc — agent access

Parametric stainless-steel tank fabrication: instant quotes, CAD artifacts
(STEP/STL/DXF), and order capture — built for AI agents. Base URL:
`https://claudiverse.cc`. All API requests/responses are JSON. Errors are
machine-actionable: `{"error": "<code>", "detail": "..."}`.

Also served at `/.well-known/auth.md`. Machine-readable API description:
[OpenAPI 3.1](https://claudiverse.cc/api/openapi.json). Remote **MCP server**:
`https://claudiverse.cc/mcp` (see below).

## Register (self-serve, free)

```sh
curl -s -X POST https://claudiverse.cc/api/agents/register \
  -H 'content-type: application/json' \
  -d '{"name": "my-agent", "contact_email": "operator@example.com", "description": "what you do (optional)"}'
```

Response (HTTP 201):

```json
{
  "agent_id": "agt_…",
  "token": "cv_<48 hex>",
  "scopes": ["quote:read", "cad:read", "order:create"],
  "rate_limits": {"quotes_per_day": 200, "orders_per_day": 20},
  "docs": "https://claudiverse.cc/auth.md",
  "note": "Store this token now; it is shown only once."
}
```

**The token is shown exactly once.** Only its hash is stored server-side; if
you lose it, register again.

## Auth

```
Authorization: Bearer cv_<48 hex>
```

- Required for: `POST /api/tanks/order`, `GET /api/tanks/order/{id}`,
  `GET /api/agents/me`.
- Optional on quote/catalog/artifact routes (they are public); sending it
  attributes your usage to your agent.
- Over a rate limit → HTTP 429. Bad/revoked token → HTTP 401.

## Endpoints

| Method | Path | Auth | Purpose |
|---|---|---|---|
| POST | `/api/agents/register` | none | get an agent id + token (max 10/IP/day) |
| GET | `/api/agents/me` | token | verify token; see today's usage |
| GET | `/api/tanks/catalog` | none | faces, fitting sizes, dim limits, **coordinate convention** |
| POST | `/api/tanks/quote` | optional | instant quote + CAD artifact links |
| GET | `/api/tanks/artifact/{config_id}/{path}` | none | download STEP/STL/DXF/manifest from a quote |
| POST | `/api/tanks/order` | token (`order:create`) | place an order (capture + human review) |
| GET | `/api/tanks/order/{id}` | token (owner) | order status |

## Quote

Dimensions in inches (default) or `"units": "mm"`. Read
`GET /api/tanks/catalog` first — it publishes the face names, fitting sizes,
dimension limits, baffle rules, and the **coordinate convention** for fitting
X/Y placement.

```sh
curl -s -X POST https://claudiverse.cc/api/tanks/quote \
  -H 'content-type: application/json' \
  -d '{"length": 24, "width": 12, "height": 18,
       "fittings": [{"face": "top", "size": "2", "x": 18, "y": 7}]}'
```

Response (HTTP 200, abridged):

```json
{
  "price_usd": 1363.62,
  "currency": "USD",
  "capacity": {"gallons": 21.84, "liters": 82.67},
  "breakdown_usd": {"material": 458.57, "cutting": 164.43, "scs_setup": 47.46,
                    "welding": 274.32, "handling": 25.0, "fittings": 40.31,
                    "subtotal": 1010.09, "margin_pct": 0.35},
  "baffles": 0,
  "artifacts": {"step": "/api/tanks/artifact/<config_id>/tank.step",
                "stl": "…/tank.stl",
                "blanks": ["…/flats/top.dxf", "…"]},
  "config_id": "aca7a636649b"
}
```

Invalid config (out-of-range dims, fitting too close to an edge) → HTTP 422
with an explanatory message. Optional `"baffles"` field: omitted/`"auto"`
(default, auto anti-slosh baffles by span), `"none"`, or an integer count.

## Order

Body: `config` is the **same shape as the quote request**. The server re-quotes
it itself — the stored price comes from the engine, not from you.

```sh
curl -s -X POST https://claudiverse.cc/api/tanks/order \
  -H "Authorization: Bearer $CV_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"config": {"length": 24, "width": 12, "height": 18,
                  "fittings": [{"face": "top", "size": "2", "x": 18, "y": 7}]},
       "contact_email": "operator@example.com",
       "notes": "optional free text"}'
```

Response (HTTP 201):

```json
{
  "order_id": "ord_…",
  "status": "pending_review",
  "price_usd": 1363.62,
  "estimate_disclaimer": "This price is a non-binding estimate. Final price and lead time are confirmed by a human before any payment is requested.",
  "quote": { "…": "full engine quote snapshot" },
  "status_url": "https://claudiverse.cc/api/tanks/order/ord_…"
}
```

Poll `status_url` with your token for status. No payment is processed at
order time — a human reviews every order and contacts `contact_email` to
confirm final price and lead time **before any payment is requested**.

## MCP server

Remote MCP endpoint: `https://claudiverse.cc/mcp` — transport
**streamable-http**, same capabilities and rate limits as the REST API.

Connect from Claude Code:

```sh
claude mcp add -t http claudiverse https://claudiverse.cc/mcp
```

Tools:

| Tool | Args | Auth |
|---|---|---|
| `register_agent` | `name`, `contact_email`, `description?` | none |
| `get_catalog` | — | none |
| `get_quote` | `length`, `width`, `height`, `units?`, `fittings?`, `baffles?` | optional |
| `create_order` | `config`, `contact_email`, `notes?`, `token?` | required (`order:create`) |
| `get_order_status` | `order_id`, `token?` | required (owner) |

Auth: send `Authorization: Bearer cv_…` on the `/mcp` request. If your client
can't set headers, pass your token as the `token` argument on `create_order` /
`get_order_status` (the two tools that require auth). Tool results are JSON
with the same keys as the REST responses, so the
[OpenAPI spec](https://claudiverse.cc/api/openapi.json) doubles as tool-output
docs. OAuth (for claude.ai-style connectors): planned.

## Pricing disclaimer

Every `price_usd` from this API is a **non-binding estimate**. Final price and
lead time are confirmed by a human before any payment is requested.

## Rate limits (free tier)

- 200 quotes/day and 20 orders/day per token (UTC days; HTTP 429 over limit).
- 10 registrations/IP/day.

## Abuse / revocation / contact

Operator: abuse@claudiverse.cc — token revocation requests, problems,
or higher-volume needs.
