Media
ClipUGC
Make AI influencer UGC videos for a mobile app from the terminal or any MCP client. Create an AI character from one sentence, generate more looks of the same face, turn a look into a talking clip, merge in a screen recording of your app with a hook line, and download a ready-to-post vertical video. Free credits on signup.
---
name: clipugc
description: Make AI influencer UGC videos for a mobile app from the terminal or any MCP client. Use when the user wants to create an AI character or AI influencer, generate looks or reference images, turn a look or photo into a short video clip, animate a photo with a driver video, merge an app screen recording into a finished UGC video with a hook line, get hook ideas, check ClipUGC credits, or manage ClipUGC characters, images and videos.
metadata:
version: "2.2.2"
author: ClipUGC
homepage: https://clipugc.com/mcp
repository: https://github.com/clipugc/ClipUGC-CLI
category: marketing
tags: [ugc, ai-video, ai-influencer, app-marketing, mcp, video-generation, mobile-apps]
requires:
- Node.js 18+ and the clipugc CLI (npm i -g clipugc, or npx -y clipugc@latest)
- a ClipUGC personal access token from clipugc.com Dashboard > API Keys
mcp:
command: npx
args: ["-y", "clipugc@latest", "mcp"]
---
# ClipUGC CLI Skill
You are helping the user run ClipUGC CLI commands. [ClipUGC](https://clipugc.com) makes AI-generated, influencer-style UGC (user-generated-content) marketing videos for mobile apps. The pipeline: create an AI character (structured appearance "DNA") β generate photorealistic looks (reference images) β turn a look into short video clips β merge a clip with the user's app screen recording + a hook text (+ optional music) into a final UGC ad.
Credits are consumed server-side (duration-aware; refunds return the exact amount charged): image = 2, clip (5s) = 7, clip (10s) = 13, motion control = 3 per second of driver video (rounded up, capped at 30s), scene-staged clip (a video created with `--scene`) = 9, merge = free (0). Prefer the live values from `clipugc credits`.
> **MCP alternative.** The same binary is an MCP server (`clipugc mcp`). If this session has the
> `clipugc` MCP server connected (tools named `list_characters`, `create_character`, `generate_image`,
> `list_images`, `create_clip`, `create_motion_clip`, `merge_ad`, `get_video`, `download_video`,
> `get_credits`, `list_hooks`), prefer those tools over shelling out: they call the same API with the
> same API key, take the same arguments as the CLI flags (underscores instead of dashes, e.g.
> `per_page`), and return JSON. Generation tools return the job id immediately; poll `get_video`
> (clips, and ads with `kind: "ad"`) or `list_images` (looks) until `status` is `completed`, the way
> `--wait` would. Everything else in this skill (workspace layout, credit gates, id spaces, prompt
> rules) applies unchanged. To connect it: `claude mcp add clipugc -- npx -y clipugc@latest mcp`. When the
> MCP server is not connected, use the CLI commands below.
> **Creative direction lives in the `ugc-director` skill.** If the user asks "make an ad for my app", wants hook ideas, reaction styles, casting advice, or a full concept-to-ad plan, use `ugc-director` (it decides WHAT to generate: archetype, hook text, look scene, clip prompt) and come back here for command syntax. This skill is the command manual.
## Routing
Match the user's intent (from `$ARGUMENTS` or conversation context) to the right command:
| Intent | Command |
|--------|---------|
| Log in / authenticate | `clipugc auth login [--api-key <key>]` |
| Check login state | `clipugc auth status` |
| Log out | `clipugc auth logout` |
| Who am I | `clipugc whoami` |
| Check credits / balance / costs | `clipugc credits` |
| Show credit transaction history | `clipugc credits history [--per-page <n>] [--page <n>]` β paginated ledger of spends (negative), top-ups, and refunds |
| List / read / set config | `clipugc config list` / `config get <key>` / `config set <key> <value>` / `config path` |
| Delete the account | `clipugc account delete` (double confirmation; `--yes` skips) |
| Browse public characters | `clipugc characters list --discover [--search <q>]` |
| List my characters | `clipugc characters list --mine` |
| Combined character feed | `clipugc characters list --feed` β own characters newest-first, then public ones in unlock order; a Locked column marks locked rows |
| Create an AI character / influencer | `clipugc characters create --description "plain-text description of the person" [--scene "optional scene/pose"] [--inspiration img1.jpg img2.jpg] [--private] [--make-video [--motion-prompt "β¦"]] [--wait]` β the server extracts appearance DNA from the description and generates the first look automatically (2 credits). Public/discoverable by default; `--private` opts out. `--make-video` also stages the character's first video clip (id + status are printed; follow with `videos status <id>`), `--motion-prompt` steers its motion. Advanced structured path: `--name` + DNA flags/`--dna-json`. |
| Show / rename / publish / unpublish / delete a character | `clipugc characters show <id>` / `rename <id> --name "New"` / `publish <id>` / `unpublish <id>` / `delete <id> [--yes]` |
| Generate looks / reference images | `clipugc images generate --character <id> [--shots frontal,three_quarter,profile,back] [--template model_digitals\|scene_recreation\|specific_angle] [--scene "..."] [--resolution 0.5K\|1K\|2K\|4K] --wait` β a new look OF that character; `--scene` puts the same person in a new setting/outfit |
| List / inspect a character's images | `clipugc images list --character <id>` / `images show <id>` / `images status <id>` |
| Download a look image | `clipugc images download <id> [-o out.png]` |
| Scene variation of a look | `clipugc images variation <id> --scene "..." [--count 1-4] [--before-after] --wait` β remixes THAT specific look; `--count` returns up to 4 alternatives in one call |
| Retry / delete an image | `clipugc images retry <id> --wait` / `images delete <id> [--yes]` |
| List clips | `clipugc videos list [--character <id>] [--mergeable]` β `--character` filters to one AI character, `--mergeable` = completed clips not yet merged (ready for merge) |
| Create a video clip from a look or photo | `clipugc videos create (--image <lookId> \| --photo <file>) [--prompt "..."] [--scene "..."] [--duration 5\|10] [--keep-sound] --wait` β with `--scene` the server first stages that look into the new setting (same face), then animates it (scene-staged cost) |
| Animate a look/photo with a driver video | `clipugc videos motion (--image <lookId> \| --photo <file>) --driver <video.mp4> [--keep-sound] --wait` |
| Merge clip + app recording into a UGC ad | `clipugc videos merge <videoId> --app-video <screenrec.mp4> --hook "..." [--music <file.mp3>] --wait` β creates an AD with its OWN id (printed; `merged_video_id` under `--json`). `--wait` blocks until the render finishes (or fails); then `ads download <adId>` gets the final ad |
| Inspect / download a clip | `clipugc videos show <id>` / `videos status <id>` / `videos download <id> [-o out.mp4]` |
| Retry / delete a clip | `clipugc videos retry <id> --wait` / `videos delete <id> [--yes]` |
| List finished ads | `clipugc ads list [--status pending\|processing\|completed\|failed]` (same as `videos list --finals`) |
| Inspect / download an ad | `clipugc ads show <adId>` / `ads download <adId> [-o out.mp4]` |
| Retry / delete an ad | `clipugc ads retry <adId> --wait` (free; only when `can_retry`) / `ads delete <adId> [--yes]` β deleting an ad leaves its source clip on the profile |
| Suggest hook texts | `clipugc hooks suggest [--context "my app is a habit tracker"]` |
**Clip ids and ad ids are different id spaces.** A clip lives at `clipugc videos β¦`, the ad merged
from it lives at `clipugc ads β¦`, and `ads download 121` is not `videos download 121`. Always take
the ad id from the merge output (`merged_video_id`) β never assume it equals the clip id.
**Every picture keeps the character's face.** A character's first completed picture is its BASE
IMAGE β the identity anchor, which never moves. Every later picture, from either picture command,
is generated as an edit of that base image, so the same person carries across settings, outfits and
moods. Only a brand-new character's first picture comes from the description/DNA alone (there is
nothing to anchor to yet), and uploaded `--inspiration` images take precedence over the base image.
So choose by intent, not by identity risk:
- `images generate --character <id> --scene "β¦"` β a new look OF this character. The default for
building out a character (new setting, outfit, mood) and for extra angles via `--shots`.
- `images variation <lookId> --scene "β¦"` β remix THAT specific look, or when you want `--count 1-4`
alternatives in a single call, or a `--before-after` pair.
If the intent is unclear, ask the user what they want to do and show the available commands.
Constraints to enforce before running: `--scene` max 600 chars; `--prompt` max 1500 chars; `--hook` max 150 chars; driver video mp4/mov max 50MB and max 30s; `--per-page` max 50. File formats β photo: png/jpg/jpeg/webp; app video + driver video: mp4/mov; music: mp3/wav/m4a. Uploads are auto-presigned; just pass local file paths.
## Prerequisites Check
Before running ANY command, always check:
0. **MCP connected?** If the `clipugc` MCP tools are available in this session, call `get_credits` instead of steps 1-3: a successful reply proves the server is installed and authenticated and gives the balance in one call. If it returns an auth error, the message tells the user to run `clipugc auth login` (or set `CLIPUGC_API_KEY` for the server).
1. **CLI installed**: Run `which clipugc`. If missing, run `npm install -g clipugc` (requires Node >= 20).
2. **Authenticated**: Run `clipugc auth status`. If not logged in, tell the user to create an API key in the ClipUGC dashboard (https://clipugc.com/dashboard β API keys) and run `clipugc auth login`. Do NOT ask the user to paste the key into chat β `auth login` prompts for it securely in the terminal.
**Credits packs**: `clipugc credits packs` lists purchasable packs (buy on the web dashboard / mobile IAP).
3. **Credits**: Before any generation command (`images generate`, `images variation`, `videos create`, `videos motion`, `videos merge`), run `clipugc credits` to check the balance against the action's cost (image 2, clip 5s 7, clip 10s 13, motion control 3 per second of driver video, scene-staged clip 9, merge free). Costs are duration-aware, so prefer the live values from `clipugc credits` over hard-coded numbers.
## Project workspace β organized output & resuming
Keep every artifact and id in a predictable workspace so a later session (or another agent) can resume without archaeology. Root: `./clipugc/` in the user's project cwd, unless the user names another location.
```
clipugc/
βββ assets/ # user inputs kept for reuse: app screen recordings, music, inspiration photos
βββ influencers/
βββ <id>-<kebab-name>/ # e.g. 12-isabella-romero
βββ influencer.json # manifest β source of truth for resuming
βββ pictures/ # looks: <imageId>-<short-desc>.<ext>
βββ clips/ # raw clips: <videoId>-<mode>-<duration>s.mp4 (mode: i2v | motion)
βββ ads/ # finished ads: <adId>-<hook-slug>.mp4 (adId = merged_video_id)
```
Rules:
1. **Record ids immediately.** Append each new id + the exact prompt to `influencer.json` right after the API call returns β BEFORE any `--wait` β so an interrupted session loses nothing.
2. **Update the manifest after EVERY step** (create / generate / variation / videos create / motion / merge / download): statuses, file paths, merge state.
3. **Copy user inputs into `clipugc/assets/`** before uploading them, so hook A/B re-merges reuse the same recording/music.
4. **Download with explicit output paths** into the folders (`-o` creates missing parent directories):
```bash
clipugc images download 87 -o clipugc/influencers/12-isabella-romero/pictures/87-cafe-selfie.png
clipugc videos download 91 -o clipugc/influencers/12-isabella-romero/clips/91-i2v-5s.mp4
# `videos merge 91 β¦` returns an AD with its own id (merged_video_id, e.g. 121) β download it
# from the ads endpoint, named by the AD id, into ads/:
clipugc ads download 121 -o clipugc/influencers/12-isabella-romero/ads/121-fixed-my-morning-routine.mp4
```
Compact `influencer.json` shape (extend as needed, keep these fields):
```json
{
"id": 12,
"name": "Isabella Romero",
"description": "casual gen-z woman in her early 20s, brown hair, friendly smile",
"created_at": "2026-07-23",
"visibility": "public",
"pictures": [
{ "id": 87, "prompt": "golden-hour cafe selfie", "file": "pictures/87-cafe-selfie.png", "status": "completed" }
],
"clips": [
{ "id": 91, "mode": "i2v", "duration": 5, "prompt": "β¦a smirk slowly spreads, lips closedβ¦", "source_image_id": 87, "file": "clips/91-i2v-5s.mp4", "status": "completed", "merged": true }
],
"ads": [
{ "merged_video_id": 121, "video_id": 91, "hook_text": "this app fixed my morning routine", "app_video": "../../../assets/screenrec.mp4", "file": "ads/121-fixed-my-morning-routine.mp4", "status": "completed" }
]
}
```
**Resuming**: when asked to continue work on an influencer or ad, FIRST read `clipugc/influencers/*/influencer.json`. Then reconcile with the server before doing new work: `clipugc characters show <id> --json`, `clipugc videos list --character <id> --json`, `clipugc ads list --json`, and `images status <id>` / `videos status <id>` / `ads show <adId>` on anything the manifest still marks pending/processing β update the manifest with what you learn. If no manifest exists but the user references an existing influencer, find it (`characters list --mine`), then create the folder + manifest from server state (`characters show`, `images list --character <id>`, `videos list --character <id>`).
## Typical Workflows
Use `--json` on any command when you need to parse output β capture ids (character id, image id, video id) from command output and reuse them in the next step. Use `--wait` on generation commands so they block until the job is `completed` or `failed`. Route every id, prompt, and download through the project workspace above.
**Picture before clip.** Generate the look first, show it to the user, and wait for an explicit yes before running `videos create` β a rejected look costs 2 credits, a rejected clip costs 9.
### Workflow A β Create a character with looks
1. Create the character from the user's description (map traits to DNA flags):
```bash
clipugc characters create --description "casual gen-z woman in her early 20s, brown hair, friendly smile" --json
```
Capture the character id from the output, create `clipugc/influencers/<id>-<kebab-name>/`, and start its `influencer.json`.
2. Generate reference looks (2 credits per image; check credits first):
```bash
clipugc images generate --character <characterId> --shots frontal,three_quarter --wait --json
```
3. Add looks in other settings whenever the plan needs them β same face, new scene (2 credits each):
```bash
clipugc images generate --character <characterId> --scene "front-camera phone selfie in a parked car, daylight through the windshield, natural skin texture" --wait --json
```
Reach for `images variation <lookId> --scene "β¦"` instead when the user points at ONE existing
look to remix, or when `--count 1-4` / `--before-after` is wanted.
4. Show the results and let the user pick:
```bash
clipugc images list --character <characterId>
```
There is no separate "select" step β pass the chosen look's ID straight to `videos create --image <ID>`. Record each look's id + prompt in `influencer.json` and download keepers into `pictures/`.
### Workflow B β Make a UGC ad video end-to-end
1. Pick a look: `clipugc images list --character <characterId>` and note its ID (or use `--photo <file>` if the user supplies their own photo). No separate select step β the chosen ID is passed straight to `videos create --image <ID>`.
2. Create the clip (7 credits for 5s, 13 for 10s; a `--scene` staged clip is 9). Prefer a SILENT reaction β mouth closed, no talking β because lip-sync is the biggest AI giveaway; the hook text overlay does the talking:
```bash
clipugc videos create --image <imageId> --prompt "Handheld selfie framing, tiny wobble. Her eyebrows lift, eyes widen, a delighted grin slowly spreads, she nods twice holding eye contact. Lips closed, no talking. Hair moves subtly." --duration 5 --wait --json
```
Capture the video id (record it + the prompt in `influencer.json` before waiting). For archetype-specific reaction prompts (smirk, jaw-drop, crying, side-eye, deadpanβ¦), hook formulas, and casting guidance, use the `ugc-director` skill β it turns an app idea into a full ad plan.
3. Get hook suggestions if the user doesn't have one:
```bash
clipugc hooks suggest --context "my app is a habit tracker"
```
Let the user pick a hook (max 150 chars).
4. Merge with the app screen recording (free) β copy the recording into `clipugc/assets/` first so re-merges reuse it:
```bash
clipugc videos merge <videoId> --app-video clipugc/assets/screenrec.mp4 --hook "This app fixed my morning routine" --wait --json
```
Capture `merged_video_id` from the output β that is the AD id, and it is what every later ad
command takes. Record it in the manifest's `ads` array immediately.
5. Download the final ad into the workspace, named by the AD id:
```bash
clipugc ads download <adId> -o clipugc/influencers/<id>-<name>/ads/<adId>-<hook-slug>.mp4
```
## Troubleshooting
Exit codes: 0 ok, 1 generic, 2 validation, 3 auth, 4 not found, 5 premium required, 6 insufficient credits, 7 network/server unreachable.
| Symptom | Fix |
|---------|-----|
| Exit 6 / "Insufficient credits" | Run `clipugc credits` to show the balance and per-action costs. Tell the user to top up credits in the ClipUGC dashboard (https://clipugc.com/dashboard). |
| Exit 3 / auth error | The stored key is missing, invalid, or revoked. Tell the user to create a fresh API key in the dashboard and re-run `clipugc auth login`. |
| Exit 7 / network error | Check `clipugc config get apiBaseUrl` (and the `CLIPUGC_API_BASE_URL` env var) β the API base URL may be wrong or the server unreachable. Retry after verifying connectivity. |
| Exit 5 / premium required | The action needs a paid plan. Tell the user to upgrade their plan in the ClipUGC dashboard. |
| "plan" error on `characters create` or `stories` | Plan limits: character creation is capped per month by plan (Professional 3, Business 10), and Stories need the Business plan. Relay the server's message and suggest upgrading β do not retry. |
| Exit 2 / validation error | An input broke a constraint (scene > 600 chars, prompt > 1500, hook > 150, driver video > 50MB or > 30s, wrong file format, per-page > 50). Fix the input and re-run. |
| A generation ended `failed` | Retry it: `clipugc images retry <id> --wait` or `clipugc videos retry <id> --wait`. Check details first with `images show <id>` / `videos show <id>`. |
| Not sure what state a job is in | `clipugc images status <id>` / `clipugc videos status <id>` (no credits consumed). |
ugc
ai video
ai influencer
app marketing
mcp
video generation
mobile apps
Comments
Sign in to leave a comment