Skip to main content
Glama
hermoso-ai

Hermoso

Official

Render ad video

render_ad

Turn a plan_ad concept into a studio-quality finished video ad: timed shots, clean speech, composited text, licensed music, optional end card, saved creator, and stitched acts for longer storyboards.

Instructions

RECOMMENDED for finished video ADS: render a plan_ad concept through the SAME quality pipeline as the Hermoso web Studio — timed shot list, exact/clean speech (no garbled words), text composited in post (never model-painted), an optional brand end card (only when the user asks), licensed music bed, real product references. Pass plan_ad’s full structured output as creative. Honors the plan’s render_plan structure/duration: a storyboard that FITS ONE CLIP OF THE RENDER MODEL renders as a single continuous pass; anything longer automatically renders as STITCHED ACTS (the fewest balanced clips, each at most one model clip) — never time-compressed into one clip. That threshold is the render model’s own maximum, not a fixed number: most models cap a clip at 15s and the longest-clip one goes to 30s, so use dryRun:true to see the act split this plan will actually get, for free, before spending. CAST A SAVED CREATOR with creator so the SAME person stars in this ad as in the last one (list_creators is the roster) — otherwise every render invents a new face. Renders take 1–3 min; keep polling get_job if it returns still-rendering. Spends credits.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
modelNovideo model id from hermoso_capabilities (default: the plan’s pick). Naming one is a DELIBERATE pick — the server asks before ever swapping it (no silent fallback)
musicNolicensed music bed on/off (default on)
dryRunNoreturn the routing decision (single pass vs stitched acts, resolved model + act lengths) WITHOUT submitting a render — free, nothing charged
lockupNobrand wordmark + tagline composited over the closing seconds. DEFAULT FALSE — set true ONLY when the user asks for branding on the close
creatorNoCAST A SAVED CREATOR in this ad — their id from list_creators, or the name you know them by (“Sarah”). Their saved portrait becomes the on-camera identity for the whole spot, so the same face carries across every act and across every ad you render for this brand — and because we already have their picture, the character portrait this pipeline would otherwise generate is skipped, so casting somebody costs LESS than not casting them. Omit to let the ad cast a fresh person — EXCEPT for a CREATOR account (onboarded from their own @handle): their own saved likeness is cast by default on any plan with a person on camera, and the read-back says `default:true`; pass "none" to render without them. Refused for free, with nothing rendered, if the name matches nobody or more than one creator, if an explicitly named creator is cast on a plan with nobody on camera, or if they are a REAL person with no likeness consent on file.
endCardNoappend the branded end card. DEFAULT FALSE on every recipe — set true ONLY when the user asks for an end card (a clone of a video that had none should not grow one)
captionsNoburn the plan's per-scene on-screen words as caption pills. DEFAULT FALSE on every recipe — set true ONLY when the user asks for on-screen text or captions; no recipe turns them on by itself
creativeYesthe FULL structured output of plan_ad (must contain video_storyboard)
ttsVoiceNovoiceover voice name (e.g. Rachel / George) when the plan voices over
textStyleNoTHE LOOK of captions and the end card — only meaningful with captions:true or endCard:true, and only when the user described a look. Presets: editorial (a large elegant serif title mid-frame with a small italic line under it, no box), bold (tall condensed caps with a black outline), minimal (small lowercase near the bottom), handwritten (tilted marker), boxed (dark words on a white box), pill (the plain default). Pass a preset name, or an object with a preset plus overrides. A caption written "TITLE · small line" puts the part after the middle dot on a second line. An invalid field is refused by name before anything renders.
resolutionNo'1080p' default (what we ship and bill for); '480p'/'720p' = cheaper draft passes, '4k' = premium final delivery (more credits). NOT EVERY MODEL OFFERS EVERY TIER — this enum is what the tool accepts, and each model's OWN `resolutions` list in hermoso_capabilities is what it can actually render (the longest-clip 30s model, for one, tops out at 720p). Ask for a tier the chosen model does not list and it is rendered at that model's best available tier instead, with nothing in the reply saying so — so check `resolutions` before promising anyone 1080p or 4k.
aspectRatioNooutput aspect ratio, e.g. 9:16 (default) / 1:1 / 16:9
durationSecondsNototal ad length in seconds (supported range 4–180; outside that it is clamped). Omit to honor the plan’s own duration — that is almost always right. This only RE-TIMES an already-authored board (its scenes are scaled to fit), it does NOT re-write it, so to change the length of the ad the user asked for, re-run plan_ad with durationSeconds instead. A length that fits ONE clip of the render model renders as one continuous pass; longer is stitched from acts filled to that model’s clip maximum with the remainder last — the maximum is 15s on most models and 30s on the longest-clip one, so use dryRun:true to see the exact act split for free before spending.
allowGenericProductNoproceed even though this brand has NO product photo on file and the ad features a product — the packaging will be INVENTED. Only pass true after telling the user that and hearing they are fine with a generic stand-in

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.1.272
    • changedInput schema / properties / creator / description
      Previous value: -"CAST A SAVED CREATOR in this ad — their id from list_creators, or the name you know them by (“Sarah”). Their saved portrait becomes the on-camera identity for the whole spot, so the same face carries across every act and across every ad you render for this brand — and because we already have their picture, the character portrait this pipeline would otherwise generate is skipped, so casting somebody costs LESS than not casting them. Omit to let the ad cast a fresh person. Refused for free, with nothing rendered, if the name matches nobody or more than one creator, if the plan has nobody on camera, or if they are a REAL person with no likeness consent on file."New value: +"CAST A SAVED CREATOR in this ad — their id from list_creators, or the name you know them by (“Sarah”). Their saved portrait becomes the on-camera identity for the whole spot, so the same face carries across every act and across every ad you render for this brand — and because we already have their picture, the character portrait this pipeline would otherwise generate is skipped, so casting somebody costs LESS than not casting them. Omit to let the ad cast a fresh person — EXCEPT for a CREATOR account (onboarded from their own @handle): their own saved likeness is cast by default on any plan with a person on camera, and the read-back says `default:true`; pass \"none\" to render without them. Refused for free, with nothing rendered, if the name matches nobody or more than one creator, if an explicitly named creator is cast on a plan with nobody on camera, or if they are a REAL person with no likeness consent on file."
  2. Changed4 schema fields changedv0.1.225
    • changedInput schema / properties / captions / description
      Previous value: -"burn the plan's per-scene on-screen words as caption pills. DEFAULT FALSE — leave it off unless the user asks for on-screen text (no captions, or true subtitles of what is said; never scene or emphasis labels); a recipe whose format IS on-screen text keeps its text either way"New value: +"burn the plan's per-scene on-screen words as caption pills. DEFAULT FALSE on every recipe — set true ONLY when the user asks for on-screen text or captions; no recipe turns them on by itself"
    • changedInput schema / properties / endCard / description
      Previous value: -"branded end card on/off (default: on, except organic recipes)"New value: +"append the branded end card. DEFAULT FALSE on every recipe — set true ONLY when the user asks for an end card (a clone of a video that had none should not grow one)"
    • changedInput schema / properties / lockup / description
      Previous value: -"persistent brand-logo lockup overlay on/off"New value: +"brand wordmark + tagline composited over the closing seconds. DEFAULT FALSE — set true ONLY when the user asks for branding on the close"
    • addedInput schema / properties / textStyle
      Added value: +{
      +  "anyOf": [
      +    {
      +      "enum": [
      +        "pill",
      +        "editorial",
      +        "bold",
      +        "minimal",
      +        "handwritten",
      +        "boxed"
      +      ],
      +      "type": "string"
      +    },
      +    {
      +      "properties": {
      +        "background": {
      +          "description": "\"none\", \"pill\", or a #hex box",
      +          "type": "string"
      +        },
      +        "cardColor": {
      +          "description": "#hex end card background",
      +          "type": "string"
      +        },
      +        "color": {
      +          "description": "#hex",
      +          "type": "string"
      +        },
      +        "font": {
      +          "enum": [
      +            "sans",
      +            "serif",
      +            "elegant",
      +            "condensed",
      +            "hand"
      +          ],
      +          "type": "string"
      +        },
      +        "italic": {
      +          "type": "boolean"
      +        },
      +        "outline": {
      +          "type": "boolean"
      +        },
      +        "position": {
      +          "enum": [
      +            "top",
      +            "center",
      +            "lower",
      +            "bottom"
      +          ],
      +          "type": "string"
      +        },
      +        "preset": {
      +          "enum": [
      +            "pill",
      +            "editorial",
      +            "bold",
      +            "minimal",
      +            "handwritten",
      +            "boxed"
      +          ],
      +          "type": "string"
      +        },
      +        "shadow": {
      +          "type": "boolean"
      +        },
      +        "size": {
      +          "anyOf": [
      +            {
      +              "enum": [
      +                "s",
      +                "m",
      +                "l",
      +                "xl"
      +              ],
      +              "type": "string"
      +            },
      +            {
      +              "type": "number"
      +            }
      +          ]
      +        },
      +        "subFont": {
      +          "enum": [
      +            "sans",
      +            "serif",
      +            "elegant",
      +            "condensed",
      +            "hand"
      +          ],
      +          "type": "string"
      +        },
      +        "subItalic": {
      +          "type": "boolean"
      +        },
      +        "textCase": {
      +          "enum": [
      +            "as-is",
      +            "upper",
      +            "lower",
      +            "title"
      +          ],
      +          "type": "string"
      +        },
      +        "tilt": {
      +          "description": "degrees, ±12",
      +          "type": "number"
      +        },
      +        "weight": {
      +          "type": "number"
      +        }
      +      },
      +      "type": "object"
      +    }
      +  ],
      +  "description": "THE LOOK of captions and the end card — only meaningful with captions:true or endCard:true, and only when the user described a look. Presets: editorial (a large elegant serif title mid-frame with a small italic line under it, no box), bold (tall condensed caps with a black outline), minimal (small lowercase near the bottom), handwritten (tilted marker), boxed (dark words on a white box), pill (the plain default). Pass a preset name, or an object with a preset plus overrides. A caption written \"TITLE · small line\" puts the part after the middle dot on a second line. An invalid field is refused by name before anything renders."
      +}
  3. Changed1 schema field changedv0.1.189
    • changedInput schema / properties / captions / description
      Previous value: -"composited caption pills on/off (default: the recipe decides)"New value: +"burn the plan's per-scene on-screen words as caption pills. DEFAULT FALSE — leave it off unless the user asks for on-screen text (no captions, or true subtitles of what is said; never scene or emphasis labels); a recipe whose format IS on-screen text keeps its text either way"
  4. Changed5 schema fields changedv0.1.161
    • addedInput schema / properties / allowGenericProduct
      Added value: +{
      +  "description": "proceed even though this brand has NO product photo on file and the ad features a product — the packaging will be INVENTED. Only pass true after telling the user that and hearing they are fine with a generic stand-in",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / creator
      Added value: +{
      +  "description": "CAST A SAVED CREATOR in this ad — their id from list_creators, or the name you know them by (“Sarah”). Their saved portrait becomes the on-camera identity for the whole spot, so the same face carries across every act and across every ad you render for this brand — and because we already have their picture, the character portrait this pipeline would otherwise generate is skipped, so casting somebody costs LESS than not casting them. Omit to let the ad cast a fresh person. Refused for free, with nothing rendered, if the name matches nobody or more than one creator, if the plan has nobody on camera, or if they are a REAL person with no likeness consent on file.",
      +  "type": "string"
      +}
    • changedInput schema / properties / durationSeconds / description
      Previous value: -"total ad length in seconds — omit to honor the plan’s own duration"New value: +"total ad length in seconds (supported range 4–180; outside that it is clamped). Omit to honor the plan’s own duration — that is almost always right. This only RE-TIMES an already-authored board (its scenes are scaled to fit), it does NOT re-write it, so to change the length of the ad the user asked for, re-run plan_ad with durationSeconds instead. A length that fits ONE clip of the render model renders as one continuous pass; longer is stitched from acts filled to that model’s clip maximum with the remainder last — the maximum is 15s on most models and 30s on the longest-clip one, so use dryRun:true to see the exact act split for free before spending."
    • changedInput schema / properties / resolution / description
      Previous value: -"'720p' default; '480p' = cheap fast draft pass, '1080p'/'4k' = premium final delivery (more credits)"New value: +"'1080p' default (what we ship and bill for); '480p'/'720p' = cheaper draft passes, '4k' = premium final delivery (more credits). NOT EVERY MODEL OFFERS EVERY TIER — this enum is what the tool accepts, and each model's OWN `resolutions` list in hermoso_capabilities is what it can actually render (the longest-clip 30s model, for one, tops out at 720p). Ask for a tier the chosen model does not list and it is rendered at that model's best available tier instead, with nothing in the reply saying so — so check `resolutions` before promising anyone 1080p or 4k."
    • changedOutput schema / (root)
      Previous value: -{
      -  "$schema": "http://json-schema.org/draft-07/schema#",
      -  "additionalProperties": false,
      -  "properties": {
      -    "dryRun": {
      -      "description": "true when this was a dry run (no job submitted, nothing charged)",
      -      "type": "boolean"
      -    },
      -    "input": {
      -      "description": "the assembled render input (dry run only — resolved model, duration, scenes)"
      -    },
      -    "jobId": {
      -      "description": "the render job id — poll get_job with this id to resume or inspect",
      -      "type": "string"
      -    },
      -    "jobType": {
      -      "description": "the routing decision — 'video' (single pass) or 'stitch' (acts)",
      -      "type": "string"
      -    },
      -    "model": {
      -      "anyOf": [
      -        {
      -          "type": "string"
      -        },
      -        {
      -          "type": "null"
      -        }
      -      ],
      -      "description": "the product-facing label of the model that rendered it"
      -    },
      -    "raw": {
      -      "description": "the raw job result payload (e.g. images[] for carousel template ads)"
      -    },
      -    "stillRendering": {
      -      "description": "true when the render is still in progress — keep polling get_job with jobId",
      -      "type": "boolean"
      -    },
      -    "url": {
      -      "anyOf": [
      -        {
      -          "type": "string"
      -        },
      -        {
      -          "type": "null"
      -        }
      -      ],
      -      "description": "the served URL of the finished media (absent/null while still rendering)"
      -    }
      -  },
      -  "type": "object"
      -}New value: +null
  5. First observedv0.1.0

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no safety annotations to rely on, the description carries the full behavioral burden and does it thoroughly. It discloses that renders spend credits, take 1–3 minutes, never time-compress long boards, silently fall back on unavailable resolutions, default end-card/captions/lockup to false, refuse certain creator casts for free, and only allow generic product only after user consent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long and dense, covering many parameters and edge cases, but every section earns its place: production constraints, stitching behavior, drying-run guidance, creator casting, cost, and polling. It is front-loaded with the most important use case. It could be better structured with headings, but for a 14-parameter, high-complexity tool it is appropriately sized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description takes on responsibility for explaining effects and next steps; it handles this well by pointing to get_job polling, mentioning spend, and covering defaults and refusal cases. The main gap is that it never describes the exact return shape or final video retrieval contract beyond polling get_job.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3, but the description adds meaningful cross-tool references: `creative` must come from plan_ad, `creator` maps to list_creators entries, dryRun is a free routing check, and casting from existing portraits costs less. This meaningfully supplements the schema despite its high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action and resource: it renders a plan_ad concept into a finished ad video through the Hermoso web Studio pipeline. It is clearly distinct from generic generation tools by requiring plan_ad's full structured output as `creative`, and it situates itself as the recommended step after planning.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly frames this as RECOMMENDED for finished video ads and tells the agent when to use dryRun:true, when to cast a saved creator via list_creators, and when to poll get_job. It does not explicitly say which sibling tools to use instead for raw clips or pre-render planning, but the primary routing guidance is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools