ZenCreator MCP Docs
/
Connect

Asset tools#

API reference for the ZenCreator MCP tools that upload media and fetch URLs for generated or uploaded assets. Every asset is identified by an asset_id (a UUID). You feed asset_ids into generation tools, and you read them back out of completed tasks.

Where asset ids come from. Generation output ids are discovered with zencreator_get_call_result after a task finishes — see generation tools. To turn user-supplied media into an asset_id, use zencreator_upload_asset below. For end-to-end recipes, see workflows.

Download vs. preview — read this first#

Two different URLs come back from this tool group, and they are not interchangeable:

download_url preview_url
What it is The full-resolution original binary A downscaled, re-encoded web preview (thumbnail)
Format The original's media_type (e.g. image/png, video/mp4) The preview's own preview_media_type (commonly image/webp) — usually differs from the original
Use it for Downloading / saving the real file Viewing / rendering in chat
Tool zencreator_get_asset_download_url / _urls zencreator_get_asset_preview_url / _urls

Never present a preview_url as "the original" or "full resolution". When the user wants to save the file, call the download tool and label it with media_type. When you just want to show the image, call the preview tool and label it with preview_media_type.

All URLs returned here are signed and expire within a few minutes. Do not cache them long-term; re-call the tool to get a fresh one.

Every tool also accepts response_format ("markdown" default, or "json") and always returns a full structuredContent object regardless of format. See concepts for the shared response contract.


zencreator_upload_asset#

Create a new ZenCreator asset from a URL or base64 bytes, returning an asset_id you can pass to generation tools that operate on user-supplied media (image-to-video, lipsync, face-swap, image editing, upscaler, photoshoot with reference, and so on). Without an upload, those generators cannot run on the user's own images.

Provide exactly one of source_url or data_base64.

  • The user pasted a public http(s):// URL → use source_url. Preferred: the server fetches the full-resolution bytes itself, with no tool-argument size limit.
  • The user gave a local file path (Claude Code, CLI clients) → read the real bytes yourself and use data_base64.
  • The user pasted a small RFC 2397 data: URL → use source_url. The base64 rides in the request body, so this works only for small images.
  • The user attached media to the chat (Claude.ai web / mobile app, ChatGPT, Cursor, Claude Desktop) → this usually cannot be uploaded via data_base64. The attachment is a vision block, not copyable bytes; data_base64 only fits tiny images, and the request body is capped (~25 MB over the HTTP transport). Never resize, downscale, crop, or re-encode the user's image to squeeze it into a tool argument — that silently destroys their photo. Instead ask the user for a public http(s):// URL, or to upload the file in the ZenCreator web app and supply the asset_id. Chat-attachment URLs are session-bound and unreachable from the server — do not try to refetch them.

Parameters

Parameter Type Required Default Description
source_url string one of source_url/data_base64 http(s):// URL or RFC 2397 data: URL. The server fetches the bytes and forwards them as a multipart upload (max 50 MB, 30 s fetch timeout). file://, blob:, javascript: and other schemes are rejected.
data_base64 string one of source_url/data_base64 Raw file bytes as a base64 string. Use for local file paths (Claude Code / CLI). Inline base64 rides in the request body (capped at ~25 MB over the HTTP transport — roughly an ≤18 MB image after base64 inflation), so it is not viable for large files or for chat attachments. Prefer source_url whenever a URL exists.
filename string No Up to 255 chars. Used to detect the media type via extension and as the multipart filename. Auto-derived from a source_url path when absent.
media_type enum No Explicit override; required only when auto-detection fails. One of the allowed media types below.
response_format string No "markdown" "markdown" or "json".

Media-type detection precedence (first match wins): explicit media_type arg → HTTP Content-Type from source_url → media type from the data: URL header → filename / URL pathname extension. If none yields an allowed value, the tool errors and asks you to pass media_type explicitly.

ReturnsstructuredContent:

{
  "asset_id": "string",   // pass to generation tools as image_asset_id / video_asset_id / etc.
  "media_type": "string", // one of the allowed list
  "size_bytes": 0          // local byte count before upload
}

Limits

  • 50 MB per upload (applied locally to all media types). This full cap is reachable via source_url (fetched server-side); for inline data_base64 over the HTTP transport the effective ceiling is the ~25 MB request-body cap (roughly an ≤18 MB image after base64 inflation).
  • For image/* the backend additionally validates that the bytes are a real, decodable image and may reject with a 400 even if the mime passes.

Not idempotent — every call creates a new asset row. Calling twice with the same bytes produces two distinct asset_ids.

Errors

  • pass exactly one of 'source_url' or 'data_base64' — provide one input mode, not zero or both.
  • unsupported scheme / scheme blocked — use http(s):// or data: only.
  • malformed data: URL — the data: URL could not be parsed.
  • data_base64 is not valid base64 / decoded to zero bytes — fix the encoding.
  • payload > 50 MB cap — resize or compress before uploading.
  • could not determine an allowed media_type — pass an explicit media_type.
  • 400 from backend — corrupt image, oversized image, or a mime that doesn't match the bytes.
  • 401 — the caller must re-authorize.

Example

"Here's a photo at this URL — upload it and use it as the reference for the next generation." (The client calls zencreator_upload_asset with source_url; the server fetches the full-resolution bytes.) For a raw chat attachment with no URL, ask the user for a public link or to upload it in the ZenCreator web app — never downscale it to fit a tool argument.

Allowed media types#

zencreator_upload_asset's media_type enum and the upload validator accept exactly:

image/png   image/jpeg  image/jpg   image/webp  image/heic  image/heif
video/mp4   video/mov   video/quicktime
audio/mpeg  audio/mp3   audio/wav   audio/x-wav  audio/x-m4a

Anything else is rejected.


zencreator_get_asset#

Return an asset's media type so you know how to handle it before fetching the binary.

Parameters

Parameter Type Required Default Description
asset_id string (UUID) Yes The asset UUID.
response_format string No "markdown" "markdown" or "json".

ReturnsstructuredContent:

{
  "id": "string",
  "media_type": "string"  // RFC 6838 media type, e.g. 'image/png'
}

Errors

  • 404 — asset_id not recognised or not owned by the user.

zencreator_get_asset_download_url#

Return a short-lived presigned URL for the full-resolution original binary, plus the asset's media type so you can state the file format to the user.

Always tell the user the format — never hand over a bare URL. For 2+ assets, prefer the batch variant zencreator_get_asset_download_urls.

Parameters

Parameter Type Required Default Description
asset_id string (UUID) Yes The asset UUID.
response_format string No "markdown" "markdown" or "json".

ReturnsstructuredContent:

{
  "asset_id": "string",
  "download_url": "string", // signed; expires within minutes
  "media_type": "string"    // RFC 6838 type of the original, e.g. 'image/png', 'video/mp4'
}

Errors

  • 404 — asset_id not recognised or not owned by the user.
  • The URL expires shortly — if it's stale, re-call to get a fresh one.

Example

"Give me the download link for that image." → returns download_url + media_type to surface as "Here's your image (PNG): <url>".


zencreator_get_asset_download_urls#

Batch version of zencreator_get_asset_download_url: fetch full-resolution download URLs and media types for 1..50 assets in one round-trip. Use whenever a task produced 2+ assets. Per-asset failures do not abort the batch.

Parameters

Parameter Type Required Default Description
asset_ids array<string UUID> Yes 1 to 50 asset UUIDs.
response_format string No "markdown" "markdown" or "json".

ReturnsstructuredContent:

{
  "count": 0,
  "succeeded": 0,
  "failed": 0,
  "items": [
    {
      "asset_id": "string",
      "download_url": "string", // present iff succeeded; signed and expires shortly
      "media_type": "string",   // RFC 6838; present iff succeeded
      "error": "string"          // present iff failed (e.g. backend 404)
    }
  ]
}

Errors

  • Per-asset: each failed item carries an error string; the rest still succeed.
  • URLs are signed and expire within a few minutes — surface them promptly or re-call.

zencreator_get_asset_preview_url#

Return a short-lived URL to a reduced-size, re-encoded web preview (a downscaled thumbnail — commonly WebP, not the original), the original asset's media type, and — by default — the preview bytes inline as an MCP image content block so sandboxed clients (e.g. Claude.ai web) can render the image without reaching storage directly.

preview_url is for viewing, not downloading. Label it with preview_media_type and state the original's media_type separately. For the full-resolution original, use zencreator_get_asset_download_url. For 2+ assets, prefer zencreator_get_asset_preview_urls.

Parameters

Parameter Type Required Default Description
asset_id string (UUID) Yes The asset UUID.
inline boolean No true When true, fetch the preview bytes and attach them as an image content block. Per-image inline cap is 2 MB; over that it falls back to URL-only with an inline_skipped note. Set false for a smaller response or when the client renders URLs natively.
response_format string No "markdown" "markdown" or "json".

ReturnsstructuredContent:

{
  "asset_id": "string",
  "preview_url": "string",        // reduced-size web preview — NOT the original
  "preview_media_type": "string", // RFC 6838 type of preview_url itself, e.g. 'image/webp' (omitted if undeterminable)
  "media_type": "string",         // RFC 6838 type of the ORIGINAL asset, e.g. 'image/png'
  "inline_skipped": "string"      // present only when inline was requested but skipped
}

When inlining succeeds, the response also carries an extra { type: "image", mimeType, data } content block, which most clients render as an inline thumbnail.

Errors

  • 404 — asset_id not recognised or not owned by the user.
  • inline_skipped is informational (e.g. image > 2 MB, or a network error fetching the preview) — the URL is still returned.

Example

"Show me that result in the chat." → returns preview_url + inlined thumbnail; tell the user "Preview (WebP), shown inline; original is PNG — say the word for the full-res link."


zencreator_get_asset_preview_urls#

Batch version of zencreator_get_asset_preview_url: fetch reduced-size web preview URLs plus each original's media type for 1..50 assets in one round-trip, and — by default — inline the preview bytes as image content blocks. Use whenever a task produced 2+ assets. Per-asset failures do not abort the batch.

These URLs are for viewing, not downloading. For full-resolution originals use zencreator_get_asset_download_urls.

Parameters

Parameter Type Required Default Description
asset_ids array<string UUID> Yes 1 to 50 asset UUIDs.
inline boolean No true Attach preview bytes as image content blocks. Per-image cap 2 MB; per-call total cap 8 MB. Assets exceeding either cap fall back to URL-only with an inline_skipped note. Set false to keep the response small.
response_format string No "markdown" "markdown" or "json".

ReturnsstructuredContent:

{
  "count": 0,     // input count
  "succeeded": 0, // URL fetched
  "failed": 0,    // URL fetch failed (no preview_url, has error)
  "inlined": 0,   // bytes also attached as image content blocks
  "items": [
    {
      "asset_id": "string",
      "preview_url": "string",        // web preview — NOT the original; present iff URL fetch succeeded
      "preview_media_type": "string", // RFC 6838 type of preview_url itself (omitted if undeterminable)
      "media_type": "string",         // RFC 6838 type of the ORIGINAL asset; present iff succeeded
      "inline_skipped": "string",     // present iff URL ok but inlining was skipped
      "error": "string"               // present iff URL fetch failed
    }
  ]
}

The response carries one { type: "image", mimeType, data } content block per successfully inlined asset, in the same order as items.

Errors

  • Per-asset: failed items carry an error; inlining failures carry inline_skipped. The rest still succeed.
  • The per-call 8 MB inline budget: once reached, remaining assets fall back to URL-only with inline_skipped: "batch ... cap reached".

See also#

  • Generation tools — submit generations and discover output asset_ids with zencreator_get_call_result.
  • Workflows — end-to-end upload → generate → fetch recipes.
  • Concepts — the shared response, pagination, and credits contracts.