UniMate for Agents

Animate any rigged skeleton from a sentence. UniMate (SIGGRAPH Asia 2026) on a ZeroGPU slice: one synchronous call returns an animated GLB, raw motion features, joint positions and a preview. Then keep what you like and regenerate the rest: in-betweening, joint editing and multi-prompt expansion, the upstream editing modes, verified end to end.

REST + OpenAPIMCP serverGradio clientsZeroGPU, billed to the caller60 frames at 30 fpsIn-betweening · editing · expansion

Give this to your agent

A one-sentence prompt for Claude, ChatGPT, Cursor or any agent with web access. Replace the placeholder with your task; the guide holds the endpoints, parameters and workflow. Calls cost a few seconds of your ZeroGPU quota.
Read https://townbox-unimate-for-agents.hf.space/llms.txt and use UniMate to <WHAT_TO_ANIMATE_AND_WHAT_TO_DO_WITH_THE_FILES>. Use my configured Hugging Face token if available.

Connect over MCP

The same nine tools as the REST API, served over streamable HTTP. Add the server to your MCP client with the config below; the Authorization header is optional and bills GPU seconds to your own Hugging Face quota instead of the anonymous per-IP allowance.
Endpoint
https://townbox-unimate-for-agents.hf.space/gradio_api/mcp/ · schema /gradio_api/mcp/schema
Tools
animate (asset, prompt, num_samples, cfg_scale, seed, preview) · inbetween (reference_job_id, prompt, keep_frames, …) · edit_joints (reference_job_id, prompt, keep_joints, …) · expand (asset, prompts, overlap, …) · list_assets · get_result · view_animation (returns the contact-sheet PNG) · service_info · guide
Claude Code
claude mcp add --transport http unimate https://townbox-unimate-for-agents.hf.space/gradio_api/mcp/ --header "Authorization: Bearer $HF_TOKEN"
{
  "mcpServers": {
    "unimate": {
      "url": "https://townbox-unimate-for-agents.hf.space/gradio_api/mcp/",
      "headers": { "Authorization": "Bearer <HF_TOKEN>" }
    }
  }
}

First call: list_assets, then animate with a prompt that starts with “An object”; the result's file URLs download with the same header, and its job_id is the reference for inbetween and edit_joints. Signed in on the Hub, the Space's Agents menu also adds it to your Hugging Face MCP tools.

Examples generated by this Space

Nine real outputs of this API, produced on 2026-11-05 on the ZeroGPU slice with checkpoint unimate_uniml3d_f60_v3 step 150000 (ema weights): six by POST /api/animate, then one each by /api/inbetween, /api/edit and /api/expand (the three mode-verification runs). Click a picture to load the animated 3D mesh (drag to orbit); the video under it is the skeleton preview the API returns. The seeds reproduce them; the API always generates fresh results. Machine-readable list: /api/examples.

An object trots forward.
Unitree Go2, quadruped robot, 18 joints · seed 7 · cfg 3.0 · 7.6 s GPU · root travel 4.41
animation.glb · joints.json · motion.npy · contact sheet · job a_e1fa6134035e
An object rears up on its hind legs.
Unitree Go2, quadruped robot, 18 joints · seed 21 · cfg 3.0 · 8.5 s GPU · root travel 0.02
animation.glb · joints.json · motion.npy · contact sheet · job a_64afa2371744
An object flaps its wings.
Eagle, 51 joints · seed 3 · cfg 3.0 · 6.7 s GPU · root travel 0.02
animation.glb · joints.json · motion.npy · contact sheet · job a_86d036d16a9f
An object strikes forward.
Eagle, 51 joints · seed 5 · cfg 3.0 · 7.5 s GPU · root travel 0.12
animation.glb · joints.json · motion.npy · contact sheet · job a_5023ff3c864a
An object swims and turns around.
Shark, 16 joints · seed 11 · cfg 3.0 · 7.0 s GPU · root travel 1.89
animation.glb · joints.json · motion.npy · contact sheet · job a_e18619e657e1
An object bites forward.
Shark, 16 joints · seed 2 · cfg 3.0 · 6.5 s GPU · root travel 4.12
animation.glb · joints.json · motion.npy · contact sheet · job a_f08bbf21a821
In-betweening: “An object jumps in place.” between the trot's first and last frame
Unitree Go2 · POST /api/inbetween, reference = the trot above (seed 7), keep_frames 0,-1 · seed 1 · cfg 3.0 · 3.1 s GPU · kept frames identical to the reference (max difference 1.2e-7)
animation.glb · joints.json · motion.npy · contact sheet · job a_f1cdee831dc1
Joint editing: “An object flaps its wings.” with the legs of a walk kept
Eagle, 51 joints · POST /api/edit, reference = “An object walks forward.” (seed 5), keep_joints = hips, thighs, shins, fetlocks, feet, toes (27 joints) · seed 4 · cfg 3.0 · 3.1 s GPU · kept joints identical to the reference (1.2e-7), 24 joints regenerated
animation.glb · joints.json · motion.npy · contact sheet · job a_71d5cc4c0aa7
Expansion: “An object trots forward.” → “turns around.” → “sits down.” (160 frames, 5.3 s)
Unitree Go2 · POST /api/expand, 3 prompts, overlap 10 · seed 7 · cfg 3.0 · 12.1 s GPU · root travel 4.54 · segments at frames 0, 50, 100 · GLB checked against Blender's importer (6.6e-6)
animation.glb · joints.json · motion.npy · contact sheet · job a_9e36c6b38e3d

Quick start

BASE=https://townbox-unimate-for-agents.hf.space
# 1. the skeletons (unitree_go2, eagle, shark, or upload your own)
curl -s -H "Authorization: Bearer $HF_TOKEN" $BASE/api/assets

# 2. generate (about 10 s; GPU time goes to your ZeroGPU quota)
curl -s -X POST $BASE/api/animate -H "Authorization: Bearer $HF_TOKEN" -H 'content-type: application/json' \
  -d '{"asset": "unitree_go2", "prompt": "An object trots forward.", "num_samples": 2, "seed": 7}'

# 3. download the animated mesh, the joint positions, the raw features
curl -s -H "Authorization: Bearer $HF_TOKEN" -o trot.glb "$BASE/api/jobs/<job_id>/files/sample0_animation.glb"

# 4. keep what you like, regenerate the rest (reference = that job_id), or chain prompts
curl -s -X POST $BASE/api/inbetween -H "Authorization: Bearer $HF_TOKEN" -H 'content-type: application/json' \
  -d '{"reference_job_id": "<job_id>", "keep_frames": "0,-1", "prompt": "An object jumps in place."}'
curl -s -X POST $BASE/api/edit -H "Authorization: Bearer $HF_TOKEN" -H 'content-type: application/json' \
  -d '{"reference_job_id": "<job_id>", "keep_joints": "Left Back Thigh, Right Back Thigh, Left Back Shin, Right Back Shin", "prompt": "An object rears up on its hind legs."}'
curl -s -X POST $BASE/api/expand -H "Authorization: Bearer $HF_TOKEN" -H 'content-type: application/json' \
  -d '{"asset": "unitree_go2", "prompts": ["An object trots forward.", "An object turns around.", "An object sits down."], "overlap": 10}'

Beyond one prompt

The three editing modes of the upstream inference code, exposed as they are implemented there: the kept part of a reference motion is pinned at every step of the flow ODE and the rest is denoised under the prompt (fixed-step Euler, 50 steps). Same parameters and result shape as /api/animate; cfg_scale must be above 1.0. Each was verified on this Space: the kept frames or joints come back identical to the reference, the expansion is continuous over its pinned overlaps and its 160-frame GLB matches Blender's importer.

POST /api/inbetween
MCP inbetween
Hold keep_frames of an earlier result (indices into its 60-frame window, negatives from the end; default "0,-1", first and last frame) and regenerate every other frame under prompt. Reference: reference_job_id, reference_sample, reference_start (window start, for the longer expansion results). Returns the resolved keep_frames and generated_frames. Upstream --inbetween --keep_frames.
POST /api/edit
MCP edit_joints
Hold keep_joints of an earlier result over the whole clip (joint names or anatomical labels from /api/assets, case-insensitive; a label such as “Left Wing” selects every joint carrying it) and regenerate the other joints under a new prompt: keep the legs of a walk, ask for flapping wings. Returns keep_joints and edited_joints. Upstream --motion_edit --keep_joints.
POST /api/expand
MCP expand
Chain 2 to 6 prompts into one motion: one 60-frame segment each, every further segment generated with its first overlap frames (default 10) pinned to the previous segment's last frames, in its own forward-facing frame and rotated back, so turns carry over. 60 + 50 frames per extra prompt in one GLB, .npy and JSON; returns segments with each prompt's frame range. Measured on the trot → turn → sit chain: the first regenerated frame after a seam can pop (a 33° facing change at the trot-to-turn seam with overlap 10; larger overlaps made it worse), so keep the default overlap and re-run with another seed when a seam shows. Upstream --motion_expand --expand_overlap.

Endpoints

GET /api/assets
Skeletons that can be animated: joints, anatomical labels, hierarchy, rest-pose GLB.
POST /api/assets
Upload a zipped rig_preprocess output (cond.npy + canonical GLB) of your own rig; returns a u_… id.
POST /api/animate
Body {asset, prompt, num_samples?, cfg_scale?, seed?, preview?}. Returns the result with a URL per output file and ready-made next bodies for the modes below.
POST /api/inbetween
Body {reference_job_id, reference_sample?, reference_start?, keep_frames?, prompt, …}. Kept frames stay, the others are regenerated.
POST /api/edit
Body {reference_job_id, reference_sample?, reference_start?, keep_joints, prompt, …}. Kept joints stay, the others are regenerated.
POST /api/expand
Body {asset, prompts[], overlap?, …}. One long motion from several prompts; num_samples × prompts ≤ 8 per call.
GET /api/jobs/{job_id}
A result again (kept 24 h). Files: /api/jobs/{job_id}/files/{name}.
GET /api/examples
The examples above with URLs and the request that reproduces each.
GET /api/identity
Who pays the GPU time for the headers you send.
GET /api, /api/health
Parameters, limits, provenance; liveness.

MCP tools: animate, inbetween, edit_joints, expand, list_assets, get_result, view_animation (returns the contact-sheet PNG), service_info, guide.

Parameters

asset
An id from /api/assets.
prompt
Training-style caption: start with “An object” and describe one motion (“An object flaps its wings.”). Up to 300 characters.
num_samples
1 to 4 independent samples (default 1).
cfg_scale
Guidance 1.0 to 15.0 (default 3.0): 5 to 7 if the prompt is ignored, lower for calmer motion.
seed
Integer for reproducibility (default random).
preview
Also render the skeleton MP4 and the 6-frame contact sheet (default true).
reference_job_id, reference_sample, reference_start
In-betweening and editing: an earlier result of the same asset (kept 24 h), which sample (default 0) and the first frame of its 60-frame window (default 0; a window that starts later is re-aligned to face forward, as upstream does).
keep_frames
In-betweening: frame indices held at the reference, a list or a comma-separated string; negatives count from the end (default "0,-1").
keep_joints
Editing: joint names or labels held at the reference (list or comma-separated, case-insensitive). Every name must match a joint; the error lists the asset's names and labels.
prompts
Expansion: 2 to 6 captions, one 60-frame segment each, in order.
overlap
Expansion: frames pinned between consecutive segments, 1 to 59 (default 10).

Outputs per sample

animation.glb
Canonical mesh + skeleton + the generated animation (glTF 2.0, 60 LINEAR keys at 30 fps; expansion: 60 + 50 keys per extra prompt). Opens in Blender, three.js, Unity, Godot.
motion.npy
(frames, J, 12) float32 UniMate features, exactly what unimate.inference.sample writes.
joints.json
World joint positions per frame (forward kinematics), joint names, labels, parents.
skeleton.mp4, contact_sheet.png
Rendered skeleton preview; the PNG shows 6 frames spanning the clip.

Model and provenance

UniMate: One Unified Model to Animate Diverse Skeletons. Linzhan Mou, Jiahui Lei, Zhiyang Dou, Chenyue Cai, Chaoyue Song, Adam Finkelstein, Szymon Rusinkiewicz. SIGGRAPH Asia 2026. arXiv 2609.05415 · project page · code (MIT) · checkpoints (CC BY-NC 4.0)

This service runs the released checkpoint unimate_uniml3d_f60_v3/checkpoints/checkpoint_step_150000.pt (EMA weights, 74M-parameter topology-aware flow-matching transformer, 50 ODE steps with classifier-free guidance) with the frozen google/flan-t5-base text encoder, through the repository's own inference code at commit b78c7807: unimate.inference.generate for text-to-motion and its motion_inbetweening, motion_editing and motion_expansion modules for the three editing modes. The animated GLB comes from a Blender-free glTF baker that applies the generated joint transforms to the asset's canonical rest-pose GLB; it was checked against Blender's glTF importer (joint positions agree to 1e-5 over every frame).

Weights are for non-commercial research use (CC BY-NC 4.0); the training data (Truebones ZOO, Mixamo, Objaverse-XL) keep their own terms, see the model card. The project page's 3D showcase is access-controlled and is not used by this service; every output is generated live.