---
name: hubfluencer-create
description: Generate a finished video ad, short, or social clip with Hubfluencer. Use whenever the user wants to make a video — e.g. "use Hubfluencer to make a 15s ad for X", "create a short for my product", "make me a TikTok ad". Drives Hubfluencer end-to-end (prompt in → finished, post-ready MP4 out) through the @hubfluencer/mcp MCP server.
---

# Hubfluencer: create a video

You turn a plain-language request into a finished MP4 using the Hubfluencer MCP server. The user buys credits and creates an access token in the Hubfluencer app; you spend those credits to generate the video.

## Prerequisites

- The `hubfluencer` MCP server must be connected (tools like `make_video`, `get_credits`, `wait_for_completion` are available).
- The user must have an access token configured (via `HUBFLUENCER_API_TOKEN`, or by having run `npx -y @hubfluencer/mcp login` — a scoped token is then saved to `~/.hubfluencer/credentials.json` and the server reads it automatically).
- **Never invent a token, and never echo a token in your output.** If no token is configured, tell the user to create one in the app (Settings → Access tokens, "Generate videos" scope) or to run `npx -y @hubfluencer/mcp login`, then stop.

## The simple path (use this by default)

Call **`make_video({ prompt, save_path })`**. It creates the project, starts generation, polls to completion, and downloads the finished MP4 in one step.

- `prompt`: a vivid description of the video the user wants.
- `save_path`: an absolute path where the MP4 should be written.
- `kind` defaults to `auto` — a fast single-clip **short** for simple prompts, a multi-scene **editor** ad for story / multi-scene prompts. Override only when the user is explicit: `kind: "short"` or `kind: "editor"`.

If `make_video` returns `terminal: false`, the render is still going. Call **`wait_for_completion({ slug, kind })`** again (reuse the `slug` and `kind` it returned). Generation takes a few minutes — that is normal, not a failure.

**Don't ship a bare short.** For a short, pass `headline` (the on-screen TITLE), `subheadline` (secondary title), and a fitting `music_vibe`/`theme` right in the `make_video` call — these are SHORTS fields (`theme` applies to both kinds; `headline`/`subheadline`/`music_vibe` are ignored for editor). For the user's own product image, brand logo, or closing card, the one-shot call can't attach files — use the granular path below. If the user gave no title or assets, infer a sensible `headline`/`subheadline` from the prompt, or ask.

## The granular path (control / recovery)

Use this when you need fine control, or to recover after an interruption:

1. `get_credits` — check the balance before spending.
2. `create_short` **or** `create_editor_ad` — creates the draft (0 credits).
3. `generate_short` (for a short) **or** `autopilot` (for an editor ad) — starts the render.
4. `wait_for_completion({ slug, kind })` — poll until done.
5. `download_result` — fetch the finished MP4 to disk.

**Short creative fields** (`create_short`, also carried by `make_video`): `headline` (on-screen TITLE, ≤160), `subheadline` (secondary title, ≤200), `music_vibe` (Upbeat default / Cinematic / Minimal / Luxury / Playful / Jazz), `theme` (none / realistic default / cinematic / anime / sci_fi / fantasy / noir / superhero / horror / mockumentary / sports / gaming / retro_80s / minimalist / cyberpunk), and fine styling `text_position` (top/center/bottom), `text_animation` (reveal/typewriter/fade_in/pop/bounce), `font_family`, `music_instruments`. Populate at least the title/subtitle and a vibe.

Other useful tools: `get_status` (check progress without blocking), `list_voices`, `list_projects`.

## Granular control (direct every step, no autopilot)

When you want to author the ad yourself rather than let autopilot decide, drive the editor step by step. Autopilot (`create_editor_ad`) stays the default; this is the controlled path — all agent-driven, no human approval:

1. `create_editor_draft { product_prompt, language?, theme?, voice_id?, export_aspect_ratio?, project_intent? }` — creates an editor project **without** autopilot (0 credits).
2. `generate_scenario { slug, segments_count? }` (1 AI assist) **or** `set_scenario { slug, scenario_prompt }` (free) — `segments_count` is 3..10.
3. `get_editor { slug }` — **review** scenario, `segments[]`, narration, music, `latest_render`, `ai_assist_quota` before spending.
4. `set_scene_count { slug, count }` (1..20; only removes trailing un-generated scenes). Each AI scene is a fixed **8s**, so this sets the ad's length (`count × 8s`); uploaded clips keep their own length.
5. `set_segment_prompt { slug, segment_id, prompt }` per scene (free, 1..2000 chars).
6. `generate_segment` one at a time, or `generate_all_segments { slug }` to run pending scenes sequentially (continuity preserved). 5 credits/scene; stop on first 402.
7. `set_narration_script { slug, script }` (free, ≤12000) **or** `generate_narration { slug }` (1 assist); then a music `description` (≤1200).
8. `generate_voice { slug, voice_id }` (3 credits; `voice_id` required — from `list_voices`); `generate_music { slug, description }` (5 credits).
9. `render { slug }` (0 credits — charges only ungenerated scenes) → `wait_for_completion({ slug, kind: "editor" })` → `download_result`.

## Bring your own media (local uploads)

An **editor** project can use the user's **own local files** — video clips on the timeline, or a product / closing / logo image — all **0 credits**:

1. `upload_video { slug, file_path, add_to_timeline? }` — uploads a local clip and waits until it's processed (`status: ready`). With `add_to_timeline` (the default) it also appends the clip as a finished scene; otherwise place it later with `add_segment_from_upload { slug, upload_id }`, or set a specific scene with `use_asset_for_segment { slug, segment_id, upload_id }` (also takes `source_segment_id` to reuse a finished scene).
2. Images: `set_product { slug, file_path, description? }` (then `set_product_placement { slug, mode: "throughout"|"end" }` to control where it shows), `set_closing_image { slug, file_path }`, `set_logo { slug, file_path }`.

A **short** can also take a product image — `set_short_product { slug, file_path, description? }` (used as the Veo image-to-video input) — and an end-card poster — `set_short_poster { slug, file_path }` (a closing still that extends the render to 14s). Same 0 credits, jpeg/png ≤ 20 MB. Shorts have **no logo overlay** (that's editor-only).

Video: mp4 / mov / webm / mkv, **≤ 500 MB, ≤ 5 min**. Image: jpeg / png, **≤ 20 MB** (no WebP). A freshly uploaded clip must finish processing before it can be placed — `upload_video` waits for you, so don't place an upload it reports as still processing. **Only upload files the user explicitly gave you** — never read arbitrary local paths.

## AI assists

Helper calls that have the model write content draw from a **free daily quota of 20** per account (separate from credits). Check with `get_ai_assists`; buy more with `unlock_ai_assists` (**1 credit → +10**).

- **Consume 1 assist:** `generate_scenario`, `enhance_prompt`, `suggest_next_scene`, `suggest_music_prompt`, `generate_narration`/`regenerate_segment_narration`.
- **Free writes:** `set_scenario`, `set_segment_prompt`, `set_narration_script`, add/reorder, `apply_scenario`, `render`.
- **Cost credits (not assists):** segment 5, regenerate 4, voice 3, music 5.

`generate_narration` **consumes a quota assist** even though its summary says "free" — that means free of credits, not quota. **429 `ai_assist_quota_exceeded`** = out of assists (unlock once or write it yourself; never loop); **402 `credits_insufficient`** = out of credits (stop).

## Field limits

| Field | Min | Max |
|-------|-----|-----|
| editor `product_prompt` (create) | 0 or 10 | 5000 |
| `scenario_prompt` | 1 | 50000 |
| `generate_scenario` `segments_count` | 3 | 10 |
| scene count (`set_scene_count`) | 1 | 20 |
| segment `prompt` | 1 | 2000 |
| `narration_script` | — | 12000 |
| music `description` (silently truncated) | — | 1200 |
| `voice_id` (`^[A-Za-z0-9_-]+$`, required) | 1 | 64 |
| `language` | 2 | 10 |
| short `headline` (title) / `subheadline` | — | 160 / 200 |
| short `music_vibe` | — | 80 |
| AI assist daily quota | 0 | 20 |

## Credits

- Creating a draft = **0 credits**.
- Rendering a short = **15 credits**.
- Granular editor steps: generate segment 5, regenerate 4, batch per-segment (≥3) 4, voice 3, music 5, render 0 (charges only ungenerated scenes). Unlock AI assists = 1 credit → +10.
- Multi-scene editor ads (autopilot) cost more — preflight the cost before rendering (the MCP surfaces this via the editor autopilot cost check).
- Check the balance any time with `get_credits`.

## Result URLs

Downloaded result URLs are **presigned and expire in about 24 hours** — they are not permalinks. Download promptly via `make_video`'s `save_path` or `download_result`, and give the user the local file path.

## Failure handling

- **402 credits_insufficient** → tell the user the required vs. available credits, then **stop**. Do not loop or retry.
- **429 ai_assist_quota_exceeded** → daily AI-assist quota used up (NOT a credit problem). `unlock_ai_assists` once or write the content yourself; never loop.
- **409 already running** → a render is already in progress. **Keep polling** with `wait_for_completion` / `get_status`; do **not** start a new generation.
- **403 insufficient_scope** → the token is missing the `video:generate` scope. Ask the user to create a token with the "Generate videos" scope.
- **Long waits are normal.** A few minutes per render is expected; don't treat a slow poll as an error.

## Out of scope: publishing

Publishing to TikTok / Instagram / etc. requires a human-linked social account. **Do not auto-publish.** When the video is ready, return the finished MP4 path plus a ready-to-paste caption so the user can post it themselves.
