# Generation tools

This page is the API reference for the **generation-flow** MCP tools — the
`zencreator_*` tools your AI client uses to discover what ZenCreator can do,
price a job, submit it, and read back results.

These are MCP tools. They are distinct from **generation tools** (the
`tool_name` values like `by_prompt`, `image_editor`, `videogen`, `faceswap`,
`upscaler`, `lipsync`) and the **models** you pass into them — those are
documented in [models](../models.md). For the difference between a *task* and a
*call*, see [concepts](../concepts.md). To turn the results of a task into
viewable or downloadable files, see [assets](./assets.md).

## Typical flow

1. **Discover** — `zencreator_list_tools` to pick a `tool_name`, then
   `zencreator_get_tool_schema` to learn its input shape, model list, prompt
   guide, and the questions to ask the user.
2. **Price** — `zencreator_estimate_price` (one candidate input) or
   `zencreator_compare_prices` (all models, cheapest first). State the cost to
   the user before committing.
3. **Submit** — `zencreator_create_task` (async; returns a task id) or
   `zencreator_run_and_wait` (blocks until terminal, then auto-fetches outputs
   and asset ids — images only, not video).
4. **Poll & read** — `zencreator_get_task` to check status, then
   `zencreator_get_call_result` to read a completed call's full output and asset
   ids.
5. **Deliver** — hand the asset ids to the [asset tools](./assets.md) for
   preview or download URLs.

> **Every** tool below also accepts `response_format` (`"markdown"` default, or
> `"json"`) and always returns a full machine-readable `structuredContent`
> object regardless of format. Responses over ~25,000 characters are truncated
> with a hint to paginate or switch to `response_format: "json"`.

---

## Discovery

### zencreator_list_tools

List every available generation tool with its base credit price and current
availability.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `include_blocked` | boolean | no | `true` | If `false`, drops tools whose entire model set is blocked. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `count` — number of tools returned.
- `tools[]` — each: `name` (the `tool_name` you pass to `zencreator_create_task`),
  `description`, `price` (base credits; final cost varies by inputs), `blocked`
  (boolean), and `blocked_models` (string array, present only when blocked;
  `["*"]` means all models disabled).

The markdown view also embeds a tool-selection guide that maps common user
intents to the right `tool_name` — read it before choosing a tool.

**Errors**

- Standard transport / auth errors only. Returns the full list otherwise.

**Example** — "What tools can generate video?" Ask your agent to list tools and
filter by name/description containing "video".

### zencreator_get_tool_schema

Return the full input and output JSON Schema for a single generation tool, plus
prompt-engineering guidance, model-selection criteria, and the standard
questions to ask the user. Call this before submitting.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `tool_name` | string | yes | — | Tool identifier from `zencreator_list_tools`. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `name`, `description`, `price`.
- `input_schema` — JSON Schema of expected inputs. Where the tool exposes
  `resolution` / `output_format`, they are promoted to **required** so they
  can't be silently defaulted.
- `output_schema` — JSON Schema of the output.
- `models[]` *(optional)* — every valid `model` value: `value`, `description`,
  optional `is_default`, `trusted_only`, `input_constraints`, `output_traits`,
  `modes`, `pricing`, `notes`. The `model` field in `input_schema` shows
  `type: str` with no enum — rely on this array for valid model values.
- `prompt_guide` *(optional)* — rules for writing the `prompt` field. Treat it as
  a contract.
- `model_selection_guide` *(optional)* — decision tree for picking `model`.
- `format_questions[]` *(optional)* — questions to ask the user before
  submission (count, aspect ratio, NSFW vs SFW, model preference, etc.).

**Errors**

- `404` — `tool_name` not recognised. Call `zencreator_list_tools` for valid
  names.

**Example** — "Edit this photo to replace the dress." Ask your agent to fetch
the schema for `image_editor`; its `prompt_guide` explains the structure that
produces better edits.

### zencreator_get_model_prompt_guide

Return a focused, per-model prompt-engineering guide for a specific image model.
Each supported model has very different conventions, and using the wrong style
degrades output quality.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `model` | string | yes | — | A supported model value, case-sensitive, exactly as it appears in `models[].value`. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `model` — the echoed model value.
- `prompt_guide` — multi-section markdown: template, length, key rules,
  anti-patterns, NSFW technique, and an example.

**Errors**

- `isError` if the model name has no dedicated guide. The message lists the
  models that do; for any other model, fall back to the tool-level
  `prompt_guide` from `zencreator_get_tool_schema`.

When to call: after `zencreator_get_tool_schema` returns a model marked "has
prompt guide" and you have picked which model to use — but before writing the
prompt string you pass to `zencreator_create_task` / `zencreator_run_and_wait`.

---

## Pricing

> Both pricing tools take **two separate top-level fields**: `tool_name` and
> `params`. `params` is the **flat** shape of ONE element of
> `zencreator_create_task`'s `inputs[]` array — do **not** wrap it in
> `{ inputs: [...] }` or nest `tool_name` inside it. A malformed call returns a
> corrected, ready-to-resend payload.

Always price a job before committing the user's credits. Never print a fixed
credit number from memory — costs are backend-driven and shift with model,
resolution, duration, and batch size.

### zencreator_estimate_price

Calculate exactly how many credits one candidate input will cost, before
submitting.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `tool_name` | string | yes | — | Top-level tool identifier from `zencreator_list_tools`. |
| `params` | object | yes | — | Flat object of generation fields (prompt, model, batch_size, etc.) — same shape as one element of `create_task`'s `inputs[]`. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `tool_name`.
- `price` — best-effort total credits for ONE call with these params.
- `raw` — verbatim backend response (varies per tool; may include `per_unit`,
  `units`, `total_price`).

**Errors**

- Unknown `tool_name` — error listing valid names.
- `params` missing a required field, or carrying fields the tool's
  `input_schema` doesn't declare — error. The same payload would be rejected by
  `zencreator_create_task`; fix it via `zencreator_get_tool_schema` first.
- Requested model blocked, or trusted-only while the account has
  `is_trusted=false` — the same access error submission would give, instead of a
  misleading price.
- `422` — params do not satisfy the tool's `input_schema` (including values
  outside a field's enum); the backend message lists the exact violations.

**Example** — "How much for one Seedream image?" Ask your agent to estimate the
price for `by_prompt` with your prompt and `model: "SEEDREAM_5"`.

### zencreator_compare_prices

For a given tool and base params, return the credit price for **every**
available model, sorted cheapest-first. One call replaces N
`zencreator_estimate_price` calls. Call this whenever the user wants to spend
less — do not guess which model is cheapest, because the ranking shifts with
resolution and other params.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `tool_name` | string | yes | — | Top-level tool identifier from `zencreator_list_tools`. |
| `params` | object | yes | — | Flat object of generation fields **without** `model` — the tool injects each model automatically (a `model` in params is stripped). |
| `resolutions` | string[] | no | — | Explicit resolutions to compare across (e.g. `["720p","1080p"]`). Omit to auto-sweep every supported resolution for resolution-priced tools. A single `resolution` inside `params` pins the comparison to that resolution. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `tool_name`.
- `count` — how many model × resolution rows returned a valid price.
- `compared_resolutions[]` *(optional)* — resolutions present in the result
  (omitted when resolution is irrelevant).
- `prices[]` — sorted ascending: `model`, `description`, `price`, optional
  `resolution`, `is_default`, `trusted_only`.
- `errors[]` *(optional)* — models that failed or can't produce a requested
  resolution: `model`, optional `resolution`, `reason`.

**Errors**

- Returns `isError` for tools with no known model catalog — use
  `zencreator_estimate_price` instead. Only works for tools with a model catalog
  (e.g. `by_prompt`, `image_editor`, `by_ref`, `faceswap`, `videogen`,
  `lipsync`, `text_to_video`).

**Example** — "Make my video cheaper." Ask your agent to compare prices for
`videogen` with your prompt and duration but no resolution; it sweeps every
resolution and ranks them cheapest-first. Dropping resolution is often the
biggest saving — surface it.

---

## Task lifecycle

### zencreator_create_task

Submit one or more generation calls as a single task. Returns immediately with a
task id; generation runs asynchronously.

> **Not idempotent.** Calling it twice creates two tasks and charges credits
> twice. Confirm with the user before resubmitting on errors. Always
> `zencreator_estimate_price` first and state the cost.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `tool_name` | string | yes | — | Tool identifier from `zencreator_list_tools`. |
| `inputs` | object[] | yes | — | 1..50 input objects, one per parallel call. Each must satisfy the tool's `input_schema`. |
| `comment` | string | no | — | Free-form note attached to the task (max 500 chars). |
| `retry_id` | string (UUID) | no | — | If retrying a previously-failed task, its id. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `id` — task UUID; pass to `zencreator_get_task`.
- `unique_name`, `tool_name`.
- `status` — `created` \| `processing` \| `partial` \| `completed` \| `failed`.
- `total` — total calls; `done` — completed so far.
- `created_at`, `comment`.

**Errors**

- `402` — insufficient credits. The error result carries a structured
  `out_of_credits` signal (`error_code: "insufficient_credits"`, `purchase_url`,
  `message`); relay it verbatim and have the user top up at
  [app.zencreator.pro/billing](https://app.zencreator.pro/billing).
- `422` — an input element does not satisfy the tool's `input_schema`. This tool
  also rejects a submission that omits `resolution` on a resolution-priced tool
  (e.g. `videogen`) rather than letting the backend pick a silent default.
- `429` — rate-limited. Back off.

**Example** — "Generate 4 variations of this scene." Ask your agent to submit
one task with 4 entries in `inputs` (one task, N calls — never N tasks).

### zencreator_run_and_wait

Submit a task and **block** until it reaches a terminal status (`completed`,
`failed`, `partial`), then auto-fetch each completed call's lazy output and
extract asset ids. Collapses create → poll → get-result into one call. Best for
images you want in the same turn.

> **Not idempotent** — every successful submission charges credits.
> **Not for video.** `videogen`, `video2video`, `lipsync`, and
> `video_upscaler` routinely take 60-180 s, longer than most MCP client
> transport timeouts. The transport hangs up before this tool returns, leaving
> no task id to resume. Submit videos with `zencreator_create_task` and poll
> with `zencreator_get_task` on the next turn.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `tool_name` | string | yes | — | Tool identifier from `zencreator_list_tools`. |
| `inputs` | object[] | yes | — | 1..50 input objects (same shape as `create_task`). |
| `comment` | string | no | — | Free-form note (max 500 chars). |
| `retry_id` | string (UUID) | no | — | If retrying a failed task, its id. |
| `timeout_s` | number (int) | no | `30` | 5..50. Internal wall-clock cap on the wait, kept short to stay under the Cloudflare/Traefik edge timeout (long-held requests get a 504). On `timed_out=true`, call `zencreator_wait_for_task` again, or poll `zencreator_get_task`. Under heavy load the server may refuse a blocking wait and ask you to poll instead. |
| `poll_interval_s` | number (int) | no | `2` | 1..30. Initial polling interval; backs off 1.5x per poll, capped at 15s. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `task_id` — resume polling with `zencreator_get_task` if it timed out.
- `tool_name`, `status`, `total`, `done`.
- `timed_out` — `true` if the wall-clock cap hit before terminal status; the
  task is still running on the backend.
- `duration_ms`, `polls`.
- `calls[]` — each: `call_id`, `status`, `output` (already fetched for completed
  calls), `error` (null unless failed), `asset_ids`.
- `asset_ids` — flat union across all completed calls.
- `created_at`, `finished_at`, `comment`.

**Errors**

- `402` (create phase) — insufficient credits; same structured `out_of_credits`
  signal as `create_task`.
- `422` (create phase) — an input does not satisfy the tool's `input_schema`.
- `429` — rate-limited. Back off.
- On timeout it returns cleanly with `timed_out: true` and the live `task_id`.
  Do **not** call this tool again with the same inputs — resume via
  `zencreator_get_task` (re-calling creates a new task and charges again).

### zencreator_get_task

Fetch the full state of a single task — status, progress, inputs, and per-call
entries.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `task_id` | string (UUID) | yes | — | Task UUID. |
| `include_error` | boolean | no | `false` | Deprecated and ignored — error details are always included on failed calls. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `id`, `unique_name`, `tool_name`, `status`, `total`, `done`, `inputs`.
- `calls[]` — each: `id`, `status`, `output` (lazy — usually `null` here; fetch
  with `zencreator_get_call_result` once `status="completed"`), `error` (null
  unless the call failed).
- `created_at`, `finished_at`, `comment`, `owner_id`.

**Errors**

- `403` — the task belongs to a different user.
- `404` — `task_id` not recognised or the task was deleted.

Polling guidance: tasks typically complete in 5-60 seconds; wait at least 2s
between polls. `status="partial"` means some calls finished — you can already
fetch those assets. `status="failed"` is terminal; read `calls[].error` and do
not retry without user confirmation.

### zencreator_get_call_result

Return the structured output of one call. This is the **only** way to discover
the asset ids produced by a completed generation — the task's own
`calls[].output` is intentionally lazy and comes back null.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `call_id` | string (UUID) | yes | — | From a task's `calls[].id`. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `call_id`.
- `output` — tool-specific, verbatim from the backend.
- `asset_ids` — best-effort extraction of asset UUIDs from common output keys
  (e.g. `image_assets` for image tools; `video_asset` / `asset_id` for video).
  If extraction returns empty, inspect `output` directly.

**Errors**

- `404` — `call_id` not found or not owned by the user. List the parent task
  first.

Hand the returned `asset_ids` to the [asset tools](./assets.md) for preview or
download URLs.

### zencreator_list_tasks

Return a paginated list of the user's tasks, optionally filtered by tool,
status, or free-text search over the comment field.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `tool_name` | string | no | — | Filter by tool name (exact match). |
| `status` | string | no | — | `created` \| `processing` \| `partial` \| `completed` \| `failed`. |
| `query` | string | no | — | Substring search on the comment field. |
| `order_by` | string | no | `"created_at"` | `created_at` \| `done` \| `total`. |
| `direction` | string | no | `"desc"` | `asc` \| `desc`. |
| `limit` | number | no | `20` | 1..100. |
| `offset` | number | no | `0` | `>= 0`. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent` (the canonical paginated envelope):

- `total`, `count`, `offset`.
- `items[]` — each: `id`, `unique_name`, `tool_name`, `status`, `total`, `done`,
  `created_at`, `finished_at`, `comment`.
- `has_more`, `next_offset` (present when there are more items).

To page, pass `next_offset` back as `offset`. Use offsets that are multiples of
`limit` for predictable boundaries.

**Errors**

- Standard transport / auth errors only.

### zencreator_get_processing_tasks

Return, per tool, whether the user has at least one task currently in flight — a
cheap "are any of my generations still running?" check.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `tools[]` — each: `tool_name`, `processing` (boolean).
- `any_processing` — boolean.

**Errors**

- Standard transport / auth errors only.

### zencreator_delete_task

Soft-delete a task and its associated generations. The user will no longer see
it in their task list.

> **Destructive.** Deleted tasks cannot be retrieved through normal endpoints.
> Always confirm with the user before calling.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `task_id` | string (UUID) | yes | — | UUID of the task to delete. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `deleted_task_id`.

**Errors**

- `404` — `task_id` not found or not owned by the current user.

---

## Prompt helpers (optional)

> These two tools are present **only when the prompt-agent sidecar is
> configured**. They may not be available on every deployment. Neither spends
> ZenCreator credits — they call an external LLM; credits are spent only when
> you submit the resulting prompt via `zencreator_create_task` /
> `zencreator_run_and_wait`.

### zencreator_craft_prompt

Delegate prompt-writing to a dedicated uncensored LLM that knows the
model-specific conventions for ZenCreator's image / video models. Returns a
fully-formed prompt ready to drop into the generation's `positive_prompt` (or
equivalent) field. The orchestrator pipes the user's brief through; it does not
author the explicit text itself. This project does not use negative prompts.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `brief` | string | yes | — | The user's literal request, in English (translate first if needed; do not censor). Max 4000 chars. |
| `tool_name` | string | yes | — | e.g. `by_prompt`, `image_editor`, `videogen`. |
| `model` | string | yes | — | Exact model value from `zencreator_get_tool_schema` `models[]`. |
| `nsfw` | boolean | no | `false` | Set `true` only if the user explicitly opted into adult content and the account allows it. |
| `count` | number (int) | no | `1` | 1..4. Number of distinct prompt variations to draft. |
| `references` | object[] | no | — | Already-uploaded asset ids the generation will use: each `{ asset_id (UUID), role?, description? }`. Include a factual `description` per reference (max 800 chars) — the agent has no visual access to the bytes; without it identity / wardrobe / pose are lost. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `prompts[]` — each: `prompt` (drop verbatim into the generation field),
  optional `rationale`.
- `model_used` — echoes the model you asked for.
- `agent_model` — which uncensored LLM answered.

Generation settings (aspect ratio, image size, batch size, output format) are
**not** in this output — you set them yourself when calling
`zencreator_create_task` / `zencreator_run_and_wait`.

**Errors**

- `PROMPT_AGENT_API_KEY` not configured — the sidecar is disabled.
- Upstream HTTP error (rate limit, model down) — retry once.
- Agent returned non-JSON — rare transient glitch; retry.

For any NSFW workflow, check `zencreator_get_me` first: the user needs both
`nsfw_allowed: true` and `is_trusted: true`, or the downstream generation will
refuse and waste credits.

### zencreator_describe_asset

Generate a factual visual description of an `asset_id` via an uncensored
multimodal LLM. Engineered for downstream prompt engineering — identity
attributes, state of dress, pose, setting, lighting, camera framing. Descriptions
are cached per `asset_id` in-process (assets are immutable).

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `asset_id` | string (UUID) | yes | — | The ZenCreator asset to describe. |
| `force_refresh` | boolean | no | `false` | If `true`, ignore the cache and re-describe. |
| `response_format` | string | no | `"markdown"` | `"markdown"` or `"json"`. |

**Returns** — `structuredContent`:

- `asset_id`.
- `description` — factual paragraph (~80-200 words).
- `media_type` — e.g. `image/png`, `image/jpeg`.
- `cached` — `true` if served from the in-process cache.
- `vision_model` — which uncensored vision LLM answered.

**Errors**

- `PROMPT_AGENT_API_KEY` not configured — the vision agent is disabled.
- Asset is video or audio — the vision model may produce a weak or generic
  description.
- Vision model upstream error — retry once.

You usually don't need to call this explicitly — `zencreator_craft_prompt`
auto-calls it for any reference passed without a `description`.

---

## See also

- [Models](../models.md) — the `tool_name` and `model` values you pass in.
- [Concepts](../concepts.md) — tasks, calls, assets, credits.
- [Asset tools](./assets.md) — turn asset ids into preview / download URLs.
- [Account tools](./account.md) — credit balance and `out_of_credits` checks.
