Skip to content
MCPBytes
DocsCreate a 3D model from an image

Tool reference · 3D Models

Create a 3D model from an image

Turn one PNG or JPEG into a textured 3D model, with economy and high quality options.

MCP tool
create_3d_model_from_image
MCP endpoint
/mcp/3d
REST
POST /v1/tools/create_3d_model_from_image/jobs
Price
From 30 credits

Overview

Send one image of an object and get back a self-contained glTF binary with PBR textures, plus a generation.json that records the exact image digest, model revision, seeds, settings and validation counts. Economy uses a roughly 40,000-face paint budget and 1K textures; high offers a configurable face target and 2K textures. Start the job, keep its id and poll. Geometry is unitless: no physical size, rigging, watertightness or print readiness is inferred from a picture.

Formats
.png .jpg .jpeg, up to 20 MB and 25 megapixels
Outputs
model.glb, model.web.glb and generation.json
Quality
economy: about 40,000 faces, 1024 × 1024 PBR textures · high: 2048 × 2048 textures, about one million faces after decimation
Background
Transparent PNGs are used as-is; opaque images are segmented first
Duration
Asynchronous; one-hour deadline including queueing and execution

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 jobreconstruct.sh
# idempotency_key is required: repeating the same request returns the same job
curl https://api.mcpbytes.com/v1/tools/create_3d_model_from_image/jobs \
  -H "Authorization: Bearer $MCPBYTES_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://mcpbytes.com/showcase/photo-t.png",
    "options": {"quality": "high", "seed": 42},
    "idempotency_key": "image-example-001"
  }'
Response202 Accepted · trimmed
{
  "tool": "create_3d_model_from_image",
  "status": "queued",
  "input_kind": "file",
  "options": {
    "quality": "high",
    "texture_resolution": 2048,
    "seed": 42
  },
  "workflow": {
    "stage": "Modeling",
    "deadline": "2026-09-22T00:58:46.412Z",
    "cancel_pending": false,
    "refund_pending": false
  },
  "capabilities": {
    "can_cancel": 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": "create_3d_model_from_image",
  "status": "succeeded",
  "credits_charged": 100,
  "compute_ms": 196488,
  "result": {
    "files": [
      {
        "name": "model.glb",
        "bytes": 48154080,
        "content_type": "model/gltf-binary",
        "url": "https://api.mcpbytes.com/blob/dl/…"
      },
      {
        "name": "generation.json",
        "bytes": 1694,
        "content_type": "application/json",
        "url": "https://api.mcpbytes.com/blob/dl/…"
      }
    ]
  }
}

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

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.
job_file
{job_id, name}: an output of one of your own completed jobs that has not expired. It is copied into the new job, with no download in between.
# 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": "T.png"}'

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

# 3. Start the job with the "upload_id"
curl https://api.mcpbytes.com/v1/tools/create_3d_model_from_image/jobs \
  -H "Authorization: Bearer $MCPBYTES_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"upload_id\": \"$UPLOAD_ID\",
    \"options\": {
      \"quality\": \"economy\"
    },
    \"idempotency_key\": \"create_3d_model_from_image-upload-001\"
  }"
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. With a file body, send the key as an Idempotency-Key header.

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
quality
economy · highEconomy uses a roughly 40,000-face paint budget and 1024² PBR textures. High uses 2048² textures and a configurable face target. Default economy.
texture_resolution
1024 · 2048Texture size in pixels, fixed by the quality profile (1024 for economy, 2048 for high).
target_faces
100000 · 300000 · 1000000High quality only: how many faces to keep before textures are baked. Default 1000000; lower values give lighter models with matching textures.
seed
integer 0 – 4294967295Reproducible sampling seed within the same profile version. Random when omitted.

Outputs

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

Output files
model.glb
Self-contained glTF binary: one mesh, PBR material with base colour and metal/roughness textures, opaque rendering.
model.web.glb
The same model for browsers and engines: Draco-compressed geometry and WebP textures; size depends on the asset. Every face and the full texture resolution are kept.
generation.json
Provenance: your options, the image digest and model revision, seeds, effective settings, validation counts (vertices, faces, texture sizes) and timings.

Download links last up to 24 hours, capped by output retention; read the job again for fresh links. The mesh is a best-effort reconstruction of what the image shows: hidden sides are invented, dimensions are not physical, and materials use opaque rendering even where the texture has alpha.

Tips

  • One object on a transparent background gives the cleanest silhouette. Opaque images are cut out first.
  • Hidden sides are invented, and geometry is unitless: no physical size, rigging, watertightness or print readiness is inferred from a picture.
  • Pass image.png of a create_image job as job_file. Its reference_3d preset frames one isolated object from a three-quarter view.
  • A job takes minutes: keep its id and poll get_job. Repeating the request with the same idempotency key returns the same job instead of a new charge.

MCP

Your agent calls create_3d_model_from_image. Connect it to https://api.mcpbytes.com/mcp/3d for this tool and the rest of its family (Create a 3D model, Optimize a 3D model, Simplify 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:

create_3d_model_from_image 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.
job_file
{job_id, name}: an owned output of an earlier job.
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

MCP tools
create_3d_model_from_image
Reconstruct a textured model from a PNG or JPEG. Select an approved economy or high quality profile. Returns model.glb, model.web.glb (Draco + WebP, for browsers and engines) and generation.json; geometry has no inferred physical scale. quality: economy, texture_resolution: 1024: 30 credits. quality: high, texture_resolution: 2048: 100 credits. 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_3d_model_from_image.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 create_3d_model_from_image \
  photo.png -o quality=economy --out model/
# Or an earlier job's output, without downloading it
python scripts/mcpbytes.py run create_3d_model_from_image \
  --job-file j_... image.png --no-wait
python scripts/mcpbytes.py job j_...

Pricing

From 30 credits. The selected option's price is charged before paid processing starts, and a canceled job is refunded. A job that fails costs nothing: its charge is refunded.

Economy · 1024 px textures
30 credits
High · 2048 px textures
100 credits

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

Limits

Limits
Jobs
20 per rolling 24 hours; 3 until your first credit purchase
Image
Up to 20 MB and 25 megapixels
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_image
Not a decodable PNG or JPEG, animated, larger than the limits, or without a visible foreground.
invalid_output
The generated model failed validation (empty geometry, missing texture or oversized file). Any charge is refunded.
out_of_memory
The image needed more memory than the profile allows; try a smaller or simpler image.
timeout
The generation 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.

Requests can also fail before a job starts, with an HTTP status: see HTTP errors.