Skip to content
MCPBytes
DocsSimplify a 3D model

Tool reference · 3D Models

Simplify a 3D model

Reduce a model's triangle count while keeping its textures and shape.

MCP tool
simplify_3d_model
MCP endpoint
/mcp/3d
REST
POST /v1/tools/simplify_3d_model/jobs
Price
From 10 credits

Overview

Simplification collapses edges while weighing normals, texture coordinates and vertex colours, so materials and textures pass through untouched and stay aligned. Ask for a triangle count or a ratio, optionally cap the deviation, and read the achieved count and error in simplify.json. A million-triangle generated model becomes a quarter of its size in seconds, ready for web viewers, engines and AR.

Formats
.glb .gltf .obj .ply .stl .off
Outputs
model.glb, simplify.json and, on request, model.web.glb (Draco + WebP)
Textures
Materials and images unchanged; UVs, normals and vertex colours carried through
Targets
target_faces or ratio; optional max_error as a fraction of the model's extent
Aggressive mode
Continues across texture seams and topology when the target matters more than fidelity

Quickstart

Send the file as the request body with the options in the query string, or refer to it in a JSON body (upload_id or url) with an options object. The response is the new job; poll it until its status is final, then download the files in result.files.

Start a jobsimplify.sh
curl "https://api.mcpbytes.com/v1/tools/simplify_3d_model/jobs?filename=model.glb&target_faces=250000&web_copy=true" \
  -H "Authorization: Bearer $MCPBYTES_API_KEY" \
  --data-binary @model.glb
Response202 Accepted · trimmed
{
  "tool": "simplify_3d_model",
  "status": "queued",
  "options": {
    "target_faces": 250000,
    "aggressive": false,
    "lock_borders": true,
    "remove_debris": false,
    "web_copy": true
  },
  "result": null
}
Get the resultread.sh
# 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 the model from result.files[].url
curl -fsSLo model.glb "$MODEL_URL"
Response200 OK · trimmed
{
  "tool": "simplify_3d_model",
  "status": "succeeded",
  "credits_charged": 20,
  "compute_ms": 29433,
  "result": {
    "schema_version": 1,
    "input_faces": 998190,
    "output_faces": 249985,
    "ratio": 0.2504,
    "max_error_units": 0.004151,
    "mesh_count": 1,
    "notes": [],
    "files": [
      {
        "name": "model.glb",
        "bytes": 21496536,
        "content_type": "model/gltf-binary",
        "url": "https://api.mcpbytes.com/blob/dl/…"
      },
      {
        "name": "model.web.glb",
        "bytes": 9527664,
        "content_type": "model/gltf-binary",
        "url": "https://api.mcpbytes.com/blob/dl/…"
      },
      {
        "name": "simplify.json",
        "bytes": 831,
        "content_type": "application/json",
        "url": "https://api.mcpbytes.com/blob/dl/…"
      }
    ]
  }
}

A job can be canceled while it is queued: POST /v1/jobs/{id}/cancel.

More on statuses, downloads and retention in Jobs & files.

Input

One file per job, in one of these ways. The formats it accepts are listed in the overview.

Input sources
File body
REST only: the file itself as the request body, with ?filename= and the options in the query string.
upload_id
Create an upload URL (POST /v1/uploads, or create_upload over MCP), PUT the file to it, then pass the upload_id. Upload URLs expire after an hour.
url, filename
A public https URL. Add filename when the URL does not end in the file's extension.
# 1. Create an upload URL (valid for one hour)
curl https://api.mcpbytes.com/v1/uploads \
  -H "Authorization: Bearer $MCPBYTES_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filename": "model.glb"}'

# 2. PUT the file to the "url" from the response
curl -X PUT --data-binary @model.glb "$UPLOAD_URL"

# 3. Start the job with the "upload_id"
curl https://api.mcpbytes.com/v1/tools/simplify_3d_model/jobs \
  -H "Authorization: Bearer $MCPBYTES_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"upload_id\": \"$UPLOAD_ID\",
    \"options\": {
      \"target_faces\": 250000,
      \"web_copy\": true
    }
  }"

To retry safely, send an Idempotency-Key header (or idempotency_key in a JSON body): a repeated key returns the original job instead of starting a new one.

Options

Put options in the query string when the file is the request body, in the options object of a JSON body, or pass them as arguments of the MCP tool. Leave an option out to use its default.

Options
target_faces
100 … 10,000,000Triangles to keep. The result may land below it, or above it when max_error or topology stop the collapse.
ratio
0.01 … 0.95Share of triangles to keep when target_faces is not given. Default 0.25.
max_error
0.0005 … 0.5Optional quality guard: the largest deviation allowed as a fraction of the model's extent. Without it, seams and topology can still stop the collapse; read the achieved count and error.
aggressive
true · falseForce the target when seams or topology stop the collapse. Expect visible texture distortion on atlas-textured models. Default false.
lock_borders
true · falseKeep open boundaries in place. Default true.
remove_debris
true · falseDrop disconnected pieces below 1 % of the surface before simplifying. Default false: small parts are often real.
web_copy
true · falseAlso write model.web.glb. Default false.

Outputs

A succeeded job lists its files in result.files, each with a download url.

Output files
model.glb
The simplified model with the same materials and images.
simplify.json
Per mesh: faces and vertices before and after, the target, the error (relative and in model units), attributes used, passes run.
model.web.glb
With web_copy: Draco geometry and WebP textures for browsers (single textured meshes).

Download from result.files or read simplify.json with read_job_file. The error combines geometric and attribute deviation; it is not a pure surface distance.

Result summary

Next to files, the job's result has a summary you can check without downloading anything:

result
input_faces, output_faces
Triangles before and after, over every mesh.
ratio
output_faces divided by input_faces.
max_error_units
The largest simplification error, in model units. It combines shape and texture-coordinate deviation, so it is not a pure surface distance.
mesh_count
Meshes simplified.
schema_version
Version of the simplify.json format.
notes
Says when the target was not reached, and why.

Tips

  • Give target_faces or ratio, not both. Without either, a quarter of the triangles is kept.
  • Textured generated models keep their look down to roughly 15 to 25 % of their triangles; below that, texture seams stop the collapse. For lower counts with the look intact, use optimize_3d_model, which bakes new textures.
  • The result can land above the target when max_error, seams or topology stop the collapse: result.notes says so and why. Read simplify.json for per-mesh counts and the error.
  • This tool takes no job_file: download an earlier job's output and upload it.

MCP

Your agent calls simplify_3d_model. 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, Split a 3D model into parts, Inspect a 3D model), or to https://api.mcpbytes.com/mcp for every tool.

Claude Code

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/3d
Codex (CLI, IDE extension, ChatGPT desktop)

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_KEY
Cursor

~/.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

~/.cursor/mcp.json
{
  "mcpServers": {
    "mcpbytes": {
      "url": "https://api.mcpbytes.com/mcp/3d",
      "headers": {
        "Authorization": "Bearer ${env:MCPBYTES_API_KEY}"
      }
    }
  }
}
11 more clients in the docs →

Arguments

The tool's options are flat arguments. Besides them:

simplify_3d_model arguments
upload_id
From create_upload, after the agent has PUT the file.
url, filename
A public https URL, and the file name when the URL does not end in the extension.
wait_seconds
0–45, default 20How long the call waits for the result. If the job is still running, the agent calls get_job.
idempotency_key
OptionalReuse it with the same arguments when retrying after a network error.

What the agent sees

MCP tools
simplify_3d_model
Reduces the triangle count of a 3D model by attribute-aware edge collapse: materials and textures pass through unchanged, and UVs, normals and vertex colours are carried along so the original textures stay aligned. Choose target_faces or ratio; an optional max_error caps the deviation as a fraction of the model's extent. Returns model.glb, simplify.json (per-mesh counts and the achieved error) and, with web_copy, model.web.glb (Draco geometry, WebP textures). Geometry is never smoothed or re-textured. Costs 10 credits up to 200,000 faces, 20 credits up to 1,000,000 faces, 40 credits up to 2,000,000 faces.
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/simplify_3d_model.md. Agents without MCP run it through the REST API with the skill's script, which reads your key from MCPBYTES_API_KEY:

mcpbytes.py
python scripts/mcpbytes.py run simplify_3d_model model.glb \
  -o target_faces=250000 -o web_copy=true --out simplified/
python scripts/mcpbytes.py read j_... simplify.json

Pricing

From 10 credits. The price follows the input's size and is charged once the input has been measured; starting a job needs at least the smallest price. A job that fails costs nothing: its charge is refunded.

Up to 200,000 faces
10 credits
Up to 1,000,000 faces
20 credits
Up to 2,000,000 faces
40 credits

One credit balance pays for every tool, and a new account starts with free credits. See Credits & prices or buy credits.

Limits

Limits
Geometry
Up to 1,000,000 faces per model
At a time
1 job
Uploads
Up to 50 MB
Results
24 hours by default

GET /v1/me returns 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.

Job errors
invalid_mesh
Unreadable file or no triangle meshes.
unsupported_feature
Skinned, animated or morph-target meshes, or compressed/quantized geometry; export a plain mesh.
invalid_options
target_faces and ratio given together.
limit_exceeded
More faces than the plan allows.
timeout
The run exceeded max_seconds; send a smaller model or split it first.
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.