API

Agent kit

A prompt to paste, a skill your agent loads by itself and FFmpeg recipes to finish ads.

Agent prompt

Paste it at the start of a Claude Code, Codex or Cursor session, after you connect the MCP server.

Prompt
You make e-commerce ads with Staglight through its MCP tools (server "staglight"). Docs: https://mobyvid.com/en/docs

Money rules
- Before anything paid, tell me the price (estimate_cost is free) and ask me once. Never spend more than I approved.
- Send max_credits and a new idempotency_key (a UUID) with every paid call.
- Paid tools answer at once with a job_id or run_id. Poll get_job, get_ad or studio_get_run with wait_seconds=50 until it finishes.
- Just a product link ("make me an ad for https://..."): studio_helper(studio=link_ad, name=link_scan, payload.url, always with an idempotency_key that a retry reuses, or the retry reads and charges again) reads that page (the scan's small flat price) and returns the photos, name and a line; then studio_estimate and studio_run on link_ad with the best photo.
- After a timeout or an error, never repeat a paid call blindly: call list_jobs with the same idempotency_key first.
- If credits run out, give me the link from buy_credits_link and stop.

How to work
- When I attach a product photo or clip: upload_file, then create_product with its name and photos. Or use list_products, or upload_from_url with a direct file link.
- A finished video ad: estimate_cost for create_ad (tier "draft" unless I ask for better), tell me the price, and after my yes call create_ad with auto=true and max_credits = the price I approved. If my request is vague, use create_ad_from_brief with auto=true and the budget I approved.
- Poll get_ad until it is succeeded and give me the file. If it stops (auto_stopped), tell me why and what it costs to continue.
- Product images (store carousel, static ads, UGC photos): the Ad Studio with studio_list, studio_estimate, studio_run, then studio_get_run.
- Download finished files with curl -L -o into ./ads/ and finish them with ffmpeg: 9:16 at 1080x1920, captions, -14 LUFS.
- Keep the AI-generated label. Never present a creator-style video as a real customer review.

Ask in your own words

With the MCP server connected, attach a product photo and say what you want. The agent uploads it, saves the product, tells you the price, asks you once and hands back the finished file. For example:

  • "Make me a 15 second UGC ad for this serum, for Reels. Keep it under $3."
  • "Here are 3 photos of my ceramic mug. Save it as a product and make a vertical product video in Spanish."
  • "Turn this photo into a store carousel: white background, a lifestyle shot and a close-up of the label."
  • "Something for TikTok that sells this water bottle to gym people. Tell me the price first."

Your OK sets a credit cap for the whole ad: the run never spends more, and stops to ask if the next step would go over it.

Skill for Claude Code, Codex and Cursor

The skill tells your agent when to use Staglight, the money rules and how to finish ads. Agents load it on their own when the task fits.

  • SKILL.md to read it first.
  • staglight-ads.zip with the skill, the FFmpeg recipes and a finishing script.
  • It needs the MCP server connected, plus curl and ffmpeg on the computer.

Claude Code

Terminal
mkdir -p ~/.claude/skills && curl -sL -o /tmp/staglight-ads.zip https://mobyvid.com/agent/staglight-ads.zip \
  && unzip -o /tmp/staglight-ads.zip -d ~/.claude/skills/

Codex and Cursor

Terminal
mkdir -p ~/.agents/skills && curl -sL -o /tmp/staglight-ads.zip https://mobyvid.com/agent/staglight-ads.zip \
  && unzip -o /tmp/staglight-ads.zip -d ~/.agents/skills/

Claude Code picks up the skill in the session you have open; other agents may need a new session to see it.

Claude Code plugin files

For teams that run their own plugin marketplace: the plugin folder has .claude-plugin/plugin.json, .mcp.json and the skill. On install it asks for the key and keeps it in the system's secure storage.

Terminal
curl -sL -o staglight-plugin.zip https://mobyvid.com/agent/staglight-plugin.zip && unzip -o staglight-plugin.zip
claude plugin validate ./staglight

For one person, the claude mcp add command and the skill above do the same job.

Finish ads with FFmpeg

Download the takes, then finish them on your computer. Output: H.264 yuv420p, AAC at 48 kHz, +faststart so the video plays before it fully loads. Captions need FFmpeg built with libass.

finish_ad.sh fits a take to the aspect, sets loudness to -14 LUFS in two passes and adds faststart:

Terminal
curl -sLO https://mobyvid.com/agent/staglight-ads/scripts/finish_ad.sh
bash finish_ad.sh take.mp4 final.mp4 9:16

Probe a file

Duration, size, frame rate and sample rate as JSON.

Terminal
ffprobe -v error -show_entries format=duration:stream=codec_type,width,height,r_frame_rate,sample_rate -of json in.mp4

Fit into 9:16 with bars

Keeps the whole frame and pads to 1080x1920.

Terminal
ffmpeg -i in.mp4 -vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2:color=black,setsar=1,fps=30,format=yuv420p" \
  -c:v libx264 -preset medium -crf 18 -c:a aac -b:a 192k -ar 48000 -ac 2 -movflags +faststart out_916.mp4

Fill 9:16 with a center crop

Fills the frame and crops the sides.

Terminal
ffmpeg -i in.mp4 -vf "scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920,setsar=1,fps=30,format=yuv420p" \
  -c:v libx264 -crf 18 -c:a aac -b:a 192k -ar 48000 -movflags +faststart out_916.mp4

9:16 with a blurred background

For product shots made in 16:9 or 1:1. The 0:a? map skips audio when there is none.

Terminal
ffmpeg -i in.mp4 -filter_complex "[0:v]split=2[bg][fg];[bg]scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920,gblur=sigma=40[bg];[fg]scale=1080:1920:force_original_aspect_ratio=decrease[fg];[bg][fg]overlay=(W-w)/2:(H-h)/2,setsar=1,fps=30,format=yuv420p[v]" \
  -map "[v]" -map 0:a? -c:v libx264 -crf 18 -c:a aac -b:a 192k -movflags +faststart out_916.mp4

Join clips of different sizes

One re-encode. The third clip has no sound, so it gets a silent track as long as the clip (5.04 s here, from ffprobe).

Terminal
ffmpeg -i a.mp4 -i b.mp4 -i c.mp4 -filter_complex "
[0:v]scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v0];
[1:v]scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v1];
[2:v]scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2,setsar=1,fps=30,format=yuv420p[v2];
[0:a]aresample=48000,aformat=channel_layouts=stereo[a0];
[1:a]aresample=48000,aformat=channel_layouts=stereo[a1];
anullsrc=r=48000:cl=stereo,atrim=0:5.04[a2];
[v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[v][a]" \
  -map "[v]" -map "[a]" -c:v libx264 -crf 18 -preset medium -c:a aac -b:a 192k -movflags +faststart joined.mp4

Burn styled captions (ASS)

Set PlayResX 1080 and PlayResY 1920 in the .ass header so margins match 9:16. Use fonts with ñ, á, ¿ and ¡.

Terminal
ffmpeg -i in.mp4 -vf "ass=captions.ass:fontsdir=./fonts" -c:v libx264 -crf 18 -c:a copy -movflags +faststart captioned.mp4

Burn SRT captions with a style

MarginV lifts the captions above the platform buttons.

Terminal
ffmpeg -i in.mp4 -vf "subtitles=captions.srt:fontsdir=./fonts:force_style='FontName=Archivo,FontSize=14,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,BorderStyle=1,Outline=3,Alignment=2,MarginV=160'" \
  -c:v libx264 -crf 18 -c:a copy -movflags +faststart captioned.mp4

Loudness to -14 LUFS (two passes)

Pass 1 measures. Copy the measured values from loud.txt into pass 2.

Terminal
ffmpeg -hide_banner -i in.mp4 -af loudnorm=I=-14:TP=-1.0:LRA=11:print_format=json -f null - 2> loud.txt
ffmpeg -i in.mp4 -af "loudnorm=I=-14:TP=-1.0:LRA=11:measured_I=-20.3:measured_TP=-3.1:measured_LRA=6.2:measured_thresh=-30.6:offset=0.4:linear=true" \
  -ar 48000 -c:v copy -c:a aac -b:a 192k out_loud.mp4

Voiceover over ducked music

The music drops while the voice speaks, then the mix is set to -14 LUFS.

Terminal
ffmpeg -i video.mp4 -i vo.wav -stream_loop -1 -i music.mp3 -filter_complex "
[1:a]aresample=48000,aformat=channel_layouts=stereo,asplit=2[vo][vokey];
[2:a]aresample=48000,aformat=channel_layouts=stereo,volume=0.35[mus];
[mus][vokey]sidechaincompress=threshold=0.03:ratio=8:attack=20:release=400[ducked];
[vo][ducked]amix=inputs=2:duration=longest:dropout_transition=0:normalize=0,loudnorm=I=-14:TP=-1.0:LRA=11[a]" \
  -map 0:v -map "[a]" -c:v copy -c:a aac -b:a 192k -ar 48000 -shortest -movflags +faststart final.mp4

Logo

Bottom right, above the area where Reels and TikTok put their buttons. Adjust the margin to your placement.

Terminal
ffmpeg -i in.mp4 -i logo.png -filter_complex "[1:v]scale=220:-1,format=rgba,colorchannelmixer=aa=0.85[lg];[0:v][lg]overlay=W-w-40:H-h-260" \
  -c:v libx264 -crf 18 -c:a copy -movflags +faststart branded.mp4

Trim

The first command is fast and cuts on keyframes. The second is frame-accurate.

Terminal
ffmpeg -ss 2.0 -i in.mp4 -t 10 -c copy cut_fast.mp4
ffmpeg -ss 2.0 -i in.mp4 -t 10 -c:v libx264 -crf 18 -c:a aac cut_exact.mp4

Frames

First frame, last frame (to continue a clip from it) and a contact sheet to review a take.

Terminal
ffmpeg -i in.mp4 -frames:v 1 first.png
ffmpeg -sseof -1 -i in.mp4 -update 1 -q:v 1 last.jpg
ffmpeg -i in.mp4 -vf "fps=1/2,scale=270:-2,tile=4x3" -frames:v 1 contact.jpg

Hold the last frame

Two extra seconds for an end card or a CTA.

Terminal
ffmpeg -i in.mp4 -vf "tpad=stop_mode=clone:stop_duration=2" -af "apad=pad_dur=2" -c:v libx264 -crf 18 -c:a aac out.mp4

Other aspects

4:5 for Feed, 1:1 and 16:9 from the same take.

Terminal
ffmpeg -i in.mp4 -vf "scale=1080:1350:force_original_aspect_ratio=increase,crop=1080:1350,setsar=1" -c:v libx264 -crf 18 -c:a copy out_45.mp4
ffmpeg -i in.mp4 -vf "scale=1080:1080:force_original_aspect_ratio=increase,crop=1080:1080,setsar=1" -c:v libx264 -crf 18 -c:a copy out_11.mp4
ffmpeg -i in.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080,setsar=1" -c:v libx264 -crf 18 -c:a copy out_169.mp4

Remove technical metadata

Removes GPS, device and encoder tags only. Keep the AI-generated label on the ad.

Terminal
ffmpeg -i in.mp4 -map 0 -map_metadata -1 -map_chapters -1 -c copy -fflags +bitexact out_clean.mp4

This page as Markdown · llms.txt