Make UGC video
Quick answer
- 01What is it?
- End-to-end UGC video in one call. Provide EITHER a text description of the person, OR a portrait URL (R2-hosted), OR an uploaded image. It stands out by giving content production a defined shape, so the agent asks for better context and returns a more usable result.
- 02Inputs
- Context for content production: your goals, audience, constraints, and any source material the skill asks for.
- 03Output
- A ready-to-use result for content production: the analysis, copy, or recommendations the agent produces.
Add this skill
Install as a package
Installs this one skill package for your coding agent, including any supporting files that skill ships with — not every skill in the repository. Read the tutorial.
$ npx skills add gitroomhq/agent-media --skill "Agent-Media UGC Video"Skill instructions
The instruction file for this skill. The skill also includes other files you need to install to use it.
Agent-Media UGC Video
One tool. One call. A finished, captioned, vertical UGC video.
You give a script and (optionally) who says it — agent-media picks the pipeline, the take count, and the duration for you. You NEVER pick a sub-tool:
- Short line → one clean talking-head clip.
- Full monologue (any length) → a seamless multi-take video, never trimmed to fit a clip.
broll_url→ the person narrates over your b-roll / gameplay / product footage.
Inputs
What they say — exactly one of:
script— the spoken line, any length. A sentence becomes one clip; a paragraph becomes the full multi-take video. Never trimmed.scene_action— a silent clip instead (dancing, b-roll, vibes). Requires acharacter.
Who says it — optional, pass at most one (omit → a default person is generated):
person— describe them in words, e.g."a 25-year-old woman with curly red hair".image— a photo of the person: a publichttpsURL or base64. The face is locked to it.character— reuse a saved character: itschar_…id (fromlist_characters) or itscharacter_sheet_url.name— optional name/age/vibe hint, e.g."Sophia, 28".
A long monologue or a
broll_urlreview needs a real face — passimageorcharacter, not justperson.
Captions are OPT-IN — do NOT add them on your own. First ASK the user whether they want captions and which caption_style (hormozi | tiktok | minimal); set captions:true only if they say yes, otherwise leave it off.
Look & format — all optional:
captions— off unless set true (ask first, above);caption_style(hormozi|tiktok|minimal)look(natural|commercial|raw_iphone),aspect_ratio(9:16|1:1)broll_url— anhttpsvideo overlaid on the lower half while they narrate.duration— leave blank; length is inferred from the script. Set only to force a short clip.
Examples
A quick clip from a text description:
{ "script": "Honestly? This app saved my whole morning routine.", "person": "a friendly young woman, soft daylight" }
A full monologue from a saved character — multi-take, never trimmed:
{ "script": "Okay I have to be honest with you for a second. Three months ago I was completely overwhelmed … (the entire monologue, as long as you like) … and that is your sign.", "character": "char_8f3ac210" }
From a photo of a real person:
{ "script": "Wait — you have to see what this actually does.", "image": "https://example.com/face.jpg", "name": "Maya, 27" }
A narrated b-roll / gameplay review:
{ "script": "Watch this play — this is where the whole match turns around.", "broll_url": "https://example.com/clip.mp4", "character": "char_8f3ac210" }
Reuse the same person across a session
After a video finishes, the character is saved — GET /v1/characters lists it with a character_id (char_…) and a character_sheet_url. For the NEXT video in the same task, pass that as character instead of a new person: it keeps the exact same face, and it's faster + cheaper because it reuses the existing portrait + character sheet rather than re-making them (the character sheet is never skipped — it's reused). Only generate a NEW person when the user asks for a different one. If you're not sure whether they want the same person or a new one, ASK the user before generating.
How to call it
Preferred path: MCP tool mcp__agent-media__make_ugc. The full schema is auto-published via tools/list; the fields above are the manual.
Fallback path: REST.
POST https://api.agent-media.ai/v1/skills/make_ugc/run
Authorization: Bearer $AGENT_MEDIA_API_KEY
Content-Type: application/json
Idempotency-Key: <any unique string per intent>
{ "script": "Okay this completely changed how I work — I plan my whole week in ten minutes now.", "character": "char_8f3ac210" }
Cost & timing
- Credits:
route-dependent: ~190–505 for a short clip; priced per-take for a long monologue or b-roll review - Wall time (typical):
360–1400s - Deducted as each take runs.
Polling the result
GET https://api.agent-media.ai/v1/skills/runs/<skill_run_id>
Authorization: Bearer $AGENT_MEDIA_API_KEY
Returns per-step status + current_step; final_output.video_url is your finished MP4 when status is succeeded.
Keep the user posted — don't go silent. A video takes a few minutes: a new person runs portrait → character sheet → the video (→ captions if asked); reusing a saved person skips straight to the video. When you submit, tell the user the plan + a rough ETA, then poll and report each current_step as it changes (e.g. "building the character sheet…", "rendering the video…", "adding captions…") so they always know what's happening.
House rules
- See reference/realism-rubric.md (../../reference/realism-rubric.md) for the realism doctrine baked into every prompt.
- See reference/pacing.md (../../reference/pacing.md) — you don't manage pacing; make_ugc sizes every take to the words.
- See reference/auth.md (../../reference/auth.md) for first-time install and
agent-media login.
Source of truth
Auto-generated by scripts/generate-public-skill.ts from services/api-v2/src/skills/registry.ts. Do not hand-edit; CI rejects drift.
Supporting file: reference/auth.md
Auth — first-time setup
agent-media uses a ma_* Bearer API key. Get one via the CLI:
npm install -g agent-media-cli
agent-media login
This stores the key at ~/.agent-media/credentials.json. The bundled MCP server reads it via the AGENT_MEDIA_API_KEY environment variable; the plugin's .mcp.json does ${AGENT_MEDIA_API_KEY} interpolation.
Without the CLI
You can paste the ma_* token directly:
export AGENT_MEDIA_API_KEY="ma_..."
How the key is used
- MCP server forwards it as
Authorization: Bearer ma_...toapi.agent-media.ai. - Server resolves it to a
user_idand runs every primitive against that account. - Credits debit from the same account.
Rotation
agent-media logout && agent-media login rotates the key. The old key keeps working for ~30 days unless explicitly revoked.
Supporting file: reference/pacing.md
Script pacing — how word count picks the duration
make_ugc does not ask you for a duration. It counts the words in your script and picks the take length for you:
| Words in your script | Duration you get | Credits |
|---|---|---|
| 1 – 11 | 5s | 140 |
| 12 – 22 | 10s | 280 |
| 23 + | 15s | 420 |
That mapping is the server's fitDuration() — the same function the quote and the run both use, so the number /quote returns is the number you are charged.
The boundaries are what matter. A 12-word script is a 10-second video, not a 5-second one — and costs 280 credits, not 140. For a 5s take, stay at 11 words or fewer.
Roughly 2.5 words per second is the natural TikTok talking-head cadence: too few words leaves dead air the model fills with filler "um"s, too many and it races and the lip-sync breaks.
Longer scripts
There is no rejection for a long script. 23–33 words becomes a single 15s take. Past 33 the script is split into several takes stitched together, each priced by the same table — 33 words is the most a 15s take can hold (round(15 × 2.2)), so a 34-word script is two takes, not one long one. Call /quote first if you want the cost before spending.
Examples
- 5s clip: "This app completely changed my morning routine — try it." (9 words)
- 10s clip: "I've used this for two weeks and it saves me thirty minutes every morning. My coffee is still hot." (20 words)
- 15s clip: "Okay so I've been using this for two weeks now and it genuinely saves me thirty minutes every single morning, no joke — my coffee is still hot by the time I'm finished." (33 words)
Supporting file: reference/realism-rubric.md
Realism
Every image and video is automatically enhanced so people look real, not AI-perfect — natural skin and lighting, candid UGC framing, believable imperfection. This happens server-side on every render; there is nothing to configure and no way (or need) to hand-write it.
Choosing the look
Use realism_target to pick the overall look:
natural— soft, natural daylight look.commercial— clean, brand-ready look.raw_iphone— unpolished, shot-on-phone look.
Just describe the person and scene in plain language in description; the realism enhancement is applied for you.
Common questions
How do I install Make UGC video in Cursor, Claude Code, or Codex?
Run npx skills add gitroomhq/agent-media --skill "Agent-Media UGC Video" in the project where you want it, then ask your agent for the skill by name. The --skill flag installs only Make UGC video, not every skill in the repository.
Where does Make UGC video come from and what license is it under?
Make UGC video comes from the gitroomhq/agent-media repository on GitHub. That repository has 61 GitHub stars. The skill is published under the Apache-2.0 license.
Prefer plain text? Read the Make UGC video guide as markdown.