# rig_3d_model

Check discovery first: this tool is served only where it is enabled and priced. It adds a
skeleton and skin weights to a static model (a character, animal or creature) so it can be
posed and animated in Blender, Godot, three.js or any tool that reads glTF. The model keeps
its coordinates, scale and textures. No animation is added, and bones have generic names
(`bone_0`, `bone_1`, …), not body-part names. To make a rigged humanoid move, pass its
`model.glb` to `animate_3d_model` as `job_file`.

Input: one self-contained, uncompressed `.glb` with a single material, not already skinned or
animated and without morph targets, up to 1,000,000 triangles, as `upload_id`, a public HTTPS
`url`, or `job_file` (e.g. `model.glb` of a `create_3d_model`, `create_3d_model_from_image` or
`optimize_3d_model` job). Option: optional `seed` (0–4294967295), reproducible within the same
tested runtime; another seed can give another skeleton. `idempotency_key` is **required**:
repeating the same request with the same key returns the same job instead of paying again.

The job is accepted asynchronously with a one-hour deadline from creation, including queueing and
execution. `wait_seconds` is at most 45, so poll `get_job` with `wait_seconds: 45` until the status
is final; the job reports `workflow.stage` and `workflow.deadline`. Do not start the job again
while it runs. While the job advertises `capabilities.can_cancel`, `cancel_job` cancels and
refunds it.

Outputs:

- `model.glb`: the input with a skeleton and skin weights (up to 4 bones per vertex).
- `rig.json`: each bone's `name`, `parent`, rest-pose `head` (glTF: +Y up, +Z front, the model's
  units), `side` (`+x`, `-x` or `center`; the model's facing is not known) and the number of
  `vertices` it moves. Use it to pick bones without opening the GLB.
- `rig_report.json`: `status`, the `thresholds` used, `metrics` (bone count, influences, a 45°
  bend test per bone) and `issues`, each with `type`, `bone`, `value`, `threshold` and `severity`.
- `rig_preview.png`: the skeleton from the front and the side, each bone's area in its own
  colour, and the worst bend test.
- `generation.json`: options, version and timings.

The job's `result` carries `bone_count`, `status` and the first five `issues`.

**A succeeded job means a valid rig was produced, not that it is ready to animate.** Before
using the rig, read `rig_report.json` and look at `rig_preview.png`:

- `passed`: no measurement crossed its threshold.
- `needs_review`: at least one did; check the named bones in the preview.
- `failed_checks`: a measurement reached twice its threshold, or a bone has no length.

Issue types: `zero_length` (a joint on top of its parent), `outside` (a joint outside a closed
mesh), `asymmetry` (mirrored joints that do not match, on symmetric models), `distant_influence`
(a bone moving vertices far from it), `bind_mismatch` (the mesh moves at rest), and the bend
tests `flipped` (share of triangles that fold), `stretch` (edge stretch) and `volume` (a closed
mesh swelling or shrinking). Distances are fractions of the model's bounding-box diagonal. A
joint misplaced inside the body is not detected: the preview is the check for that. If a rig
fails, tell the user what the report says; another `seed` may give a better skeleton, and each
job is charged.

Price: read `pricing` in `GET /v1/tools` before starting the job. The charge is made once the
input passes validation; a job that fails or is canceled is refunded, and a refused input is not
charged. Free limits: 20 jobs per rolling 24 hours (3 until the account's first credit
purchase), models up to 50 MB.

Without MCP, send the file as the request body with an `Idempotency-Key` header:

```bash
curl "https://api.mcpbytes.com/v1/tools/rig_3d_model/jobs?filename=model.glb&seed=42" \
  -H "Authorization: Bearer $MCPBYTES_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  -H "Idempotency-Key: my-character-rig" \
  --data-binary @model.glb
```

Or with the bundled client: `python scripts/mcpbytes.py run rig_3d_model model.glb --out rigged/`,
or `--job-file <job_id> model.glb` for an earlier job's output.

Handle `invalid_mesh` (not a readable, self-contained GLB, or no mesh), `limit_exceeded` (more
than 1,000,000 triangles: reduce it with `simplify_3d_model` first; a file over the plan's upload
size is refused at once with HTTP 413 `too_large`), `unsupported_feature` (already skinned or
animated, morph targets, several used materials, vertex colours without a base-colour texture:
export one static mesh), `inference_failed` (no skeleton could be made: try another seed or
another input) and `timeout`. A failed job is refunded. Do not repeat a failed input unchanged.
