Tool reference · 3D Models
Create a game asset
Create a rigged, animated game character from a description in one job: a textured model at your triangle budget, a skeleton and a standard set of clips, with checks and previews.
- MCP tool
- create_game_asset
- MCP endpoint
- /mcp/3d
- REST
- POST /v1/tools/create_game_asset/jobs
- Price
- 250 credits per job
Overview
Describe one character or four-legged animal. The job makes a picture of it in a neutral pose, builds a textured model, rebuilds it at target_faces triangles with new textures, adds a skeleton and skin weights, finds whether the body is a humanoid (two legs, two arms and a head) or four-legged, and animates it with that body's clip set: humanoids idle, walk, run, jump, attack, hit, wave and death; four-legged animals idle, walk, run, jump, attack and death. idle, walk and run loop; clips play in place unless in_place is false. model.glb carries every clip as a named animation at 30 frames per second. rig_report.json and rig_preview.png judge the skeleton and skin; motion_report.json and motion_preview.png judge each clip. The job's status is the worst of the two: passed, needs_review or failed_checks. A succeeded job means the character was made, not that it looks right. Other bodies (props, vehicles, birds, winged creatures) fail and are refunded. It takes several minutes: start the job, keep its id and poll.
- Input
- A description of one character or four-legged animal; no file
- Outputs
- model.glb with every clip, reference.png, rig and motion reports, their previews and generation.json
- Clips
- Humanoids: idle, walk, run, jump, attack, hit, wave, death · four-legged animals: idle, walk, run, jump, attack, death
- Model
- 1,000 to 100,000 triangles (default 20,000) with 1024 or 2048 textures
- Duration
- Asynchronous; two-hour deadline including queueing and execution
Quickstart
Send the options as JSON. The response is the new job; poll it until its status is final, then download the files in result.files.
# idempotency_key is required: repeating it returns the same job
curl https://api.mcpbytes.com/v1/tools/create_game_asset/jobs \
-H "Authorization: Bearer $MCPBYTES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"options": {
"description": "a stylized knight with a round shield on his back",
"seed": 42
},
"idempotency_key": "game-asset-example-001"
}'{
"tool": "create_game_asset",
"status": "queued",
"input_kind": "parameters",
"workflow": {
"stage": "Generating visuals",
"deadline": "2026-09-29T04:53:33.061Z",
"cancel_pending": false,
"refund_pending": false
},
"capabilities": {
"can_cancel": true
},
"options": {
"description": "a stylized knight with a round shield on his back",
"target_faces": 20000,
"texture_resolution": 2048,
"body": "auto",
"in_place": true,
"seed": 42
},
"result": null
}# JOB_ID is the id from the create response; poll until status is final
curl "https://api.mcpbytes.com/v1/jobs/$JOB_ID" \
-H "Authorization: Bearer $MCPBYTES_API_KEY"
# Once status is succeeded, download each file from result.files[].url
curl -fsSLo model.glb "$MODEL_URL"{
"tool": "create_game_asset",
"status": "succeeded",
"result": {
"notes": [],
"body": "humanoid",
"faces": 20000,
"bone_count": 34,
"clips": [
{
"name": "idle",
"status": "passed"
},
{
"name": "walk",
"status": "passed"
},
{
"name": "run",
"status": "passed"
},
{
"name": "jump",
"status": "passed"
},
{
"name": "attack",
"status": "passed"
},
{
"name": "hit",
"status": "passed"
},
{
"name": "wave",
"status": "passed"
},
{
"name": "death",
"status": "passed"
}
],
"status": "failed_checks",
"issues": [
{
"type": "stretch",
"bone": "mixamorig:LeftShoulder",
"value": 7.8137,
"threshold": 2,
"severity": 0.977,
"axis": "b",
"degrees": -45
}
],
"files": [
{
"name": "rig_report.json",
"bytes": 6443,
"content_type": "application/json",
"url": "https://api.mcpbytes.com/blob/dl/…"
},
{
"name": "model.glb",
"bytes": 3755956,
"content_type": "model/gltf-binary",
"url": "https://api.mcpbytes.com/blob/dl/…"
},
{
"name": "motion_report.json",
"bytes": 5969,
"content_type": "application/json",
"url": "https://api.mcpbytes.com/blob/dl/…"
},
{
"name": "motion_preview.png",
"bytes": 330696,
"content_type": "image/png",
"url": "https://api.mcpbytes.com/blob/dl/…"
}
]
},
"compute_ms": 492225,
"credits_charged": 250
}Jobs of this tool take minutes. While one runs, workflow.stage says what is happening and workflow.deadline when it must finish. Cancel it with POST /v1/jobs/{id}/cancel while capabilities.can_cancel is true.
More on statuses, downloads and retention in Jobs & files.
Input
No file. Send the options in a JSON body, {"options": {…}}, or as arguments of the MCP tool. Keep private text such as prompts out of URLs.
idempotency_key is required. Repeating a request with the same key returns the original job instead of starting and charging a new one; reusing a key for a different request returns 409 idempotency_conflict.Options
Put options in the options object of the JSON body, or pass them as arguments of the MCP tool. Leave an option out to use its default.
- description
text, up to 4000 charactersThe character or animal. Kept out of generation.json. Required.- target_faces
1000 – 100000Triangles in the finished model. Default 20000.- texture_resolution
1024 · 2048Texture size in pixels. Default 2048.- body
auto · humanoid · four_leggedFound from the model (auto), or set when auto picks wrong. Default auto.- in_place
true · falseClips stay on the spot; false keeps the forward travel of walk and run. Default true.- seed
integer 0 – 4294967295Reproducible within the same tested runtime; another seed gives another character. Random when omitted.
Outputs
A succeeded job lists its files in result.files, each with a download url.
- model.glb
- The finished character: one textured mesh at target_faces triangles, its skeleton and skin, and every clip as a named animation at 30 frames per second (humanoids: idle, walk, run, jump, attack, hit, wave, death; four-legged animals the same without hit and wave). Uncompressed, textures embedded.
- reference.png
- The picture the model was built from: the character in a neutral pose on a transparent background.
- rig.json
- The skeleton: each bone's name, parent, rest position, side and how many vertices it moves.
- rig_report.json
- The rig's checks and bend tests: status, measurements and issues per bone.
- rig_preview.png
- The skeleton over the model from the front and side, the skin weights, and the worst bend test.
- motion.json
- The clip set: the body, and for each clip its name, frames, duration, the model's facing, the hips' travel, the bone roles and the feet's contacts.
- motion_report.json
- Each clip's checks (planted feet sliding or floating, the floor, sudden turns, the loop's seam) and the overall status.
- motion_preview.png
- Five moments of every clip, one row per clip, with the skeleton drawn over the model.
- generation.json
- Provenance: your options except the description, and for each step its image digest, model revision, files, summary and timings.
Download links last up to 24 hours, capped by output retention; read the job again for fresh links. A succeeded job means the character was made; whether it looks right is in the reports and previews.
Result summary
Next to files, the job's result has a summary you can check without downloading anything:
- body
- humanoid or four_legged: the body found, or the one you set.
- faces, bone_count
- Triangles in the finished model, and bones in its skeleton.
- clips
- Each clip's name and status.
- status
- The worst of the rig's checks and the clips': passed, needs_review or failed_checks.
- issues
- The first five issues of the rig and the clips.
Tips
- Describe one character or animal with its look: "a small green goblin in a leather tunic", "a friendly cartoon fox". Leave the pose out: the job asks for a full body in a neutral pose.
- Send the description in the JSON body or as MCP arguments, never in a URL.
- Set body to humanoid or four_legged when auto finds the wrong one; auto refuses props, vehicles and winged creatures (refunded).
- target_faces is the finished model's triangle budget: 20,000 by default, up to 100,000.
- Read the result's status and clips, then look at motion_preview.png and rig_preview.png. A rig flagged failed_checks can tear the skin in wide motions even when every clip passes.
- For another motion, pass model.glb to animate_3d_model as job_file with keep_animations: true and a clip_name.
MCP
Your agent calls create_game_asset. Connect it to https://api.mcpbytes.com/mcp/3d for this tool and the rest of its family (Create a 3D model, Create a 3D model from an image, Optimize a 3D model, Simplify a 3D model, Rig a 3D model, Animate a 3D model, Split a 3D model into parts, Inspect a 3D model), or to https://api.mcpbytes.com/mcp for every tool.
Claude CodeOAuth or API key
The first form signs in through the browser when you run /mcp. In .mcp.json (project root), ${MCPBYTES_API_KEY} is read from the environment when Claude Code connects. Claude Code docs
claude mcp add --transport http mcpbytes \
https://api.mcpbytes.com/mcp/3dCodex (CLI, IDE extension, ChatGPT desktop)OAuth or API key
Codex reads the key from the environment variable each time it connects. The same table can go in ~/.codex/config.toml by hand; codex mcp add has no --header flag. Codex docs
codex mcp add mcpbytes --url https://api.mcpbytes.com/mcp/3d \
--bearer-token-env-var MCPBYTES_API_KEYCursorOAuth or API key
~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project). Remote servers take no "type". Without the header, the client signs you in with GitHub or an email link (OAuth). Cursor docs
{
"mcpServers": {
"mcpbytes": {
"url": "https://api.mcpbytes.com/mcp/3d",
"headers": {
"Authorization": "Bearer ${env:MCPBYTES_API_KEY}"
}
}
}
}Arguments
The tool's options are flat arguments. Besides them:
- wait_seconds
0–45, default 0How long the call waits for the result. If the job is still running, the agent calls get_job.- idempotency_key
RequiredReuse it with the same arguments when retrying after a network error.
What the agent sees
- create_game_asset
- Creates a game-ready animated character from a description: a textured 3D model, rebuilt at your triangle budget (1,000 to 100,000) with new textures, rigged, and animated with a standard set of clips in one GLB. Humanoids (people and humanoid characters) get idle, walk, run, jump, attack, hit, wave and death; four-legged animals get idle, walk, run, jump, attack and death. idle, walk and run loop; clips play in place unless in_place is false. Humanoid bones carry Mixamo names (mixamorig:Hips…). Returns model.glb (rigged and animated, uncompressed, textures embedded), reference.png, rig.json, rig_report.json, rig_preview.png, motion.json, motion_report.json (checks per clip), motion_preview.png and generation.json. Other bodies (props, vehicles, birds, winged creatures) are not supported: such a job fails and is refunded. For another motion, pass model.glb to animate_3d_model with keep_animations. This is an asynchronous job of several minutes, longer when workers start cold; use get_job to follow progress. A failed job is refunded. Costs 250 credits per job. Requires idempotency_key; retain it when retrying the same request.
- create_upload
- Returns a one-hour URL to PUT a local file to; then call the tool with the upload_id.
- get_job
- Status and results of a job; waits up to wait_seconds for it to finish.
- cancel_job
- Cancel a queued job or a workflow whose can_cancel is true; repeated calls never delete results.
- list_jobs
- Your most recent jobs, newest first.
- read_job_file
- Reads a text output (.txt .json .md .csv) of a succeeded job in chunks.
Setup for every client, and how agents upload files and read results: Connect over MCP.
Agent skill
The MCPBytes skill teaches agents this tool, in references/create_game_asset.md. Agents without MCP run it through the REST API with the skill's script, which reads your key from MCPBYTES_API_KEY:
printf '{"description": "a small green goblin in a leather tunic",
"target_faces": 20000}' > options.json
python scripts/mcpbytes.py run create_game_asset \
--options-json options.json --out goblin/
python scripts/mcpbytes.py job j_...Pricing
250 credits per job. The price is charged before paid processing starts, and a canceled job is refunded. A job that fails costs nothing: its charge is refunded.
- Per job
- 250 credits
One credit balance pays for every tool, and a new account starts with free credits. See Credits & prices or buy credits.
Limits
By account
- Jobs per 24 hours
- Free3
- Pay as you go20
- Monthly bundle100
- Jobs at once
- Free3 jobs
- Pay as you go5 jobs
- Monthly bundle8 jobs
- Results kept
- Free1 day
- Pay as you go7 days
- Monthly bundle30 days
- Model
- 1,000 to 100,000 triangles
- Bodies
- Humanoids and four-legged animals; props, vehicles, birds and winged creatures are refunded
Free until the first purchase, Pay as you go after any credit pack, Monthly bundle while one is active. GPU tools, this one included, run up to 5 of an account's jobs at a time; the rest wait their turn. GET /v1/me returns your tier (plan), your limits and current usage; Limits & errors explains what happens when one is reached.
Errors
A failed job comes back with error.code, error.message and often error.hint. Codes are stable. Inputs that fail with a validation error will fail again unchanged.
- inference_failed
- No humanoid or four-legged skeleton in three tries: props, vehicles, birds and winged creatures are not supported, and a character drawn holding things can fail too. Any charge is refunded.
- unsupported_rig
- The skeleton does not fit the body's clip set. Any charge is refunded.
- invalid_image
- The picture had no usable foreground to build the model from. Any charge is refunded.
- invalid_output
- An output failed validation. Any charge is refunded.
- timeout
- The job did not finish within its deadline. Any charge is refunded.
- capacity_exhausted
- Budget exhausted: HTTP 503 at creation, or a failed job if the budget ran out before charging. Try again later.
- unsupported_format
- The tool does not take this file type.
- insufficient_credits
- The job costs more than the balance, which is known once the input has been measured. Nothing was charged.
- out_of_memory
- The file needs more memory than a job has.
Requests can also fail before a job starts, with an HTTP status: see HTTP errors.