Skill instructions
vsb-ad-variations3.2 KB
View saved version →
---
name: vsb-ad-variations
description: >
Make several versions of one image ad to test against each other with the
Visual Sandbox MCP tools: the same product and offer, with a different
hook, scene, person or layout in each version. Trigger when the person
asks for "ad variations", "versions to A/B test", "more creatives",
"different hooks", "5 ads for Meta", "new angles for this ad" or sends one
ad and asks for more like it. Changes one thing per version, so a test
says which thing worked. Uses the MCP tools only.
license: Proprietary. See LICENSE for the terms.
---
# Ad variations to test
An ad test only teaches something when each version changes one thing. This
skill takes one ad, or one product, and makes 3 to 6 versions that differ in
one named way.
Use the MCP tools only.
## 1. Get the base
- **An ad they already have.** Use it as the reference image. Pass a public
`https` URL. Give an ad attached in the chat, or a local file, to
`upload_media` first.
- **Only a product.** Make the base ad first with
[`vsb-product-photoshoot`](../vsb-product-photoshoot/SKILL.md), then come
back here.
Ask where the ads run. Use 4:5 for a Meta feed, 9:16 for Stories, Reels and
TikTok, and 1:1 when they do not know.
## 2. Pick the one thing that changes
Propose one axis and let the person pick:
| Axis | The versions differ in |
|------|------------------------|
| Hook | The headline on the ad. The picture stays the same |
| Scene | The place: a kitchen, an office, outdoors, a studio |
| Person | Who holds or uses the product |
| Angle | The reason to buy: price, speed, quality, a feeling |
| Layout | Where the product, the headline and the space sit |
Write the versions as a short table first: the version number and the one
thing that changes. Show it before you spend.
## 3. Make the versions
1. Read [`vsb-image-prompting`](../vsb-image-prompting/SKILL.md) with
`get_skill`. When the ad has text, read
[`vsb-nano-banana`](../vsb-nano-banana/SKILL.md) too: it has the rules
for words that render cleanly.
2. Call `list_models` with `modality: "image"` and `get_model` for the model
you pick. Use the same model for every version.
3. Write one base prompt. For each version, change only the part for the
axis. Keep every other word the same.
4. Call `generate` once for each version, with the same reference and the
same `sandbox_name`, such as "Serum ad test".
5. Call `get_job` for each one after `eta_seconds`. Check every word on each
ad. A misspelled headline is a failed version.
## 4. Hand them over
List the versions in the order of the table, each with its `share_url` and
the one thing it changes. Give the `sandbox_url` of the canvas, where they
sit side by side. Offer one next step: a short video of the version the
person likes, with [`vsb-video`](../vsb-video/SKILL.md).
## Rules
- One axis for each set. Two changes in one version make the test useless.
- Never invent a claim, a price, a discount or a review for the ad. Use only
the words the person gave you.
- Call `estimate_cost` before a set of more than six versions, and say the
total.
- When a run is refused for want of credit, say the balance is too low, and
follow what the server instructions say about credit.
Referenced files: 1 — file references are metadata, not package contents.
vsb-animate-photo2.82 KB
View saved version →
---
name: vsb-animate-photo
description: >
Turn one photo into a short video clip with the Visual Sandbox MCP tools:
a product shot that moves, a portrait that comes alive, a still that gets
a slow camera move. Trigger when the person asks to "animate this photo",
"make this picture move", "turn my product photo into a video", "add
motion", "image to video", or attaches a picture and asks for a clip.
Keeps the subject unchanged, asks for the price first, and shows the clip
in a card. Uses the MCP tools only.
license: Proprietary. See LICENSE for the terms.
---
# Animate a photo
One photo becomes one clip of about 5 seconds. The subject stays the same.
Only the motion is new. Use the MCP tools only.
## 1. Get the photo and the motion
- A photo attached in the chat goes to `upload_media` as `file`. Use the
`url` it returns. A public `https` link can go in directly.
- Ask what moves, in one question, only if the person did not say. Offer
two choices: a slow camera move, or one small action of the subject.
- Keep the shape of the photo. A tall photo makes a 9:16 clip, a wide photo
makes a 16:9 clip.
## 2. Pick the model
Read [`vsb-video`](../vsb-video/SKILL.md) with `get_skill`, at "Picking a
model". Then use this short rule:
- **A first try, or a product shot:** `video/p-video` or `video/p-video-2`
with the photo as `image`. Fast and low in cost.
- **People, hands, or a hard motion:** `video/seedance-2.0-mini` with the
photo as `image`. It holds faces and hands better.
- **Speech:** this is not the right skill. Read `vsb-talking-avatar`.
## 3. Write the prompt
Describe only the motion and the camera. The photo already holds the look.
- Name one motion: "steam rises from the cup", "she turns her head and
smiles", "the camera pushes in slowly".
- Add what must not change: "The product keeps its exact shape, colour and
label."
- Leave out new objects, new text and scene changes. They make the model
redraw the photo.
## 4. Price, run, show
1. Call `estimate_cost` with the model and the inputs. Tell the person the
price and wait for their yes.
2. Run the model with the photo `url`, the prompt, the aspect ratio and a
duration of 5. Name the work with `sandbox_name`. In Review mode, a run
of 10 cents or more waits for the person's press of Generate: show the
card with `show_media`, or give the review link. Never press it for them.
3. Call `show_media` with the job id at once. The card shows the percent and
then plays the clip.
4. When the person wants to judge it yourself, call `get_job` after
`eta_seconds`. It returns four frames of the clip.
## Rules
- One clip per request unless the person asks for more.
- When the label or the face changes, say so. Offer a second run with a
smaller motion, not a longer clip.
- To make it vertical later, or to add music, read `vsb-edit-video`.
Referenced files: 1 — file references are metadata, not package contents.
vsb-audio16.6 KB
View saved version →
---
name: vsb-audio
renamed_from: audio
description: >
Generate sound effects, full music tracks, spoken voiceovers and new
voices designed from a description via Visual Sandbox. Trigger when the
user wants short SFX, ambient audio, background music, a soundtrack, a
voiceover, narration, text to speech or a custom voice via the vsb CLI. SFX and speech runs are quick; music scales
with track length. Submit with `--async` then poll with `vsb status`
for anything long.
license: Proprietary. See LICENSE for the terms.
---
# Audio generation with vsb
> **On the MCP surface?** If the `visual-sandbox` MCP tools are in your
> tool list, use `generate` and `get_job` instead of the shell commands
> below. The model choice and the prompt craft on this page still apply.
> See `vsb` → Two ways to run.
Four jobs: sound effects, music, speech and voice design. Short SFX finishes in
5–30 seconds and a few hundred characters of speech in a few seconds
(sync is fine); music can take longer, so prefer `--async` + `vsb status`
for tracks over ~60s.
Start every run in a **background shell** (Claude Code: `run_in_background:
true`) so the turn stays free, and put the wait loop there too — the shell's
exit is the "done" signal. `vsb status` never waits on its own. Rules in
`vsb` → Background generations.
## What's live
| Task | Slug | Notes |
|------|------|-------|
| Sound effects (0.5–30s clips) | `audio/elevenlabs-sound-fx` | ElevenLabs. Foley, ambient, transitions, UI sounds. Loop mode for tiling beds. |
| Voiceover or narration from a script (text to speech) | `audio/elevenlabs-tts` | ElevenLabs. 21 stock voices (`--voice`, default `george`), or a voice you designed (`--my_voice <name>` or `--designed_voice <sample url>`, see below). No voice cloning: a recording of a real person is refused. `--mode v4` (default) is the newest and most natural and follows audio tags like `[whispers]`, 10,000 characters per run; `v3` also follows tags, 5,000; `multilingual-v2` reads long narration more evenly, 10,000; `flash-v2.5` costs half as much, 40,000. Billed per character. |
| Voiceover or narration at a much lower rate, or in a language ElevenLabs does not cover | `audio/gemini-3.8-flash-tts` | Google's flagship voice. 30 voices (`--voice`, default `Kore`), over 130 languages detected from the text, 10,000 characters per run, WAV out. Pauses and sounds come from inline tags in English: `<laugh>`, `<sigh>`, `<short pause>`. One voice per run. No designed voice, no cloning, no `[square bracket]` tags. Billed per character. |
| Many short reads, read-aloud lines or a cheap first draft | `audio/gemini-3.8-flash-lite-tts` | The faster, cheaper Gemini 3.8 voice: about a third less than Flash. The same voices, tags and limit, over 100 languages. Switch to `audio/gemini-3.8-flash-tts` for the final take of a long or emotional read. Billed per character. |
| A new voice from a written description | `audio/elevenlabs-voice-design` | ElevenLabs Voice Design v3. Returns one MP3 sample of a new voice reading one line. A sample is an audition, not the voiceover: pass it to `audio/elevenlabs-tts` as `--designed_voice`. Run again for another take. Billed per character of the sample line. The web Composer runs one design per click. Safety-filtered: a description that reads as a child, like "girl", is refused; "woman" passes. Not voice cloning. |
| Speak a recording again in another voice (voice changer, speech to speech) | `audio/elevenlabs-voice-changer` | ElevenLabs. Takes an audio or a video file of up to 5 minutes and one of the voices TTS takes: `--voice`, `--designed_voice` or `--my_voice`. Keeps the words, the timing and the emotion; only the voice changes. Use it to put one voice back on clips that a video model voiced itself. Billed per minute of the recording: the quote holds 5 minutes, then drops to the real length. |
| Music (10s–5min tracks) | `audio/eleven-music` | ElevenLabs music_v2. Full structured tracks, vocals (model-written or your
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-characters2.63 KB
View saved version →
---
name: vsb-characters
description: >
Keep one person, mascot or product the same in every picture and video
with Visual Sandbox characters. Make a character sheet, save it with
create_character, give it a voice, and pass its pictures to every later
shot. Trigger when the person asks for "the same character", "a recurring
host", "an AI influencer", "a mascot", "consistent faces", "a cast for my
film", or names a character they made before. Uses the MCP tools, or
`vsb characters` in the CLI.
license: Proprietary. See LICENSE for the terms.
---
# Characters
A model forgets a face between two runs. A character is what you give it
each time: the same reference pictures, the same description and the same
voice. Saving it is free.
## Make a character
1. **Ask what must not change.** Face, age, hair, build, skin, clothes, and
the style (photo, 3D, cartoon). Write it down in two or three lines.
2. **Make the sheet.** Generate pictures of the character on a plain light
background, in even light: a front view, a three-quarter view and a full
body. Use one image model for all of them and read `vsb-image-prompting`
first. For a real product, start from its photo.
3. **Show the sheet and get a yes.** Remake a view that drifted before you
save.
4. **Save it.** `create_character` with the name, the description and the
URLs of the pictures (up to 8). Links that are not on Visual Sandbox are
copied, so they last.
5. **Give it a voice, if it speaks.** Pick a stock voice with `list_voices`,
or design one with `audio/elevenlabs-voice-design`. Save its id with
`update_character`.
## Use a character
1. `get_character` with its name.
2. Pass its `reference_urls` to the model's reference input, as `get_model`
names it.
3. Put the description in the prompt, then say what is new in this shot:
the place, the action, the camera.
4. For speech, pass the `voice_id` to `audio/elevenlabs-tts`: as `voice` for
a stock voice, as `my_voice` for a voice the person designed or cloned.
A `voice_id` can be the link of one take of a voice, which is what the
Voice Studio card saves; `my_voice` takes that link as it is.
For two characters in one shot, pass the pictures of both and name each one
in the prompt: "the woman from the first pictures, the dog from the last".
## Look after the cast
- `list_characters` shows every character on the account. Check it when the
person names someone, before you make a new one.
- Replace a weak reference with `update_character`. The new set replaces
the old one.
- `delete_character` removes the character, not its pictures.
- Never make a character of a real person without their consent.
Referenced files: 1 — file references are metadata, not package contents.
vsb-clone-voice2.68 KB
View saved version →
---
name: vsb-clone-voice
description: >
Clone a voice from a recording with the Visual Sandbox MCP tools, then
read any script in it: a voiceover, an ad, a narration or a talking
avatar in the person's own voice. Trigger when the person asks to "clone
my voice", "use my voice", "make it sound like me", "voice cloning",
"narrate this in my voice", or attaches a voice recording and asks to
reuse it. Checks consent, makes the clone once, and reads scripts in it
after that. Uses the MCP tools only.
license: Proprietary. See LICENSE for the terms.
---
# Clone a voice
Make the clone once. After that, every script reads in that voice. Use the
MCP tools only.
## 1. Check consent first
Clone only the voice of the person who asks, or a voice whose speaker gave
permission. Ask in one line when it is not clear. Set `confirm_rights: true`
only after the person confirms it. Never clone a public figure.
## 2. Get the recording
- One speaker, clear speech, no music. One to two minutes gives the best
clone. A phone recording is good enough.
- A file attached in the chat goes to `upload_media` as `file`. Use the
`url` it returns.
- Set `remove_background_noise: true` only for a noisy recording. It can
lower the quality of a clean one.
## 3. Make the clone
1. Call `estimate_cost` for `audio/elevenlabs-voice-clone`. Tell the person
the price and wait for their yes.
2. Run it with `audio` (the recording URL), `confirm_rights: true`, and a
short `prompt` that the clone reads back as a sample. The voice stays
usable later: Visual Sandbox keeps the recording, and a later run clones
the voice again when it needs to. An account can clone 3 times a day.
3. Call `show_media` with the job id, so the person hears the sample.
## 4. Read a script in the voice
1. Call `list_voices`. The new voice is in the list of voices the person
made. Use its name or id.
2. Run `audio/elevenlabs-tts` with `prompt` (the script) and `my_voice`.
`mode: "v4"` is the most natural.
3. Write the script without dashes, and write numbers as words.
To put the voice on a face, read `vsb-talking-avatar`. To put it on a video,
read `vsb-edit-video` and use `add_audio`.
## In ChatGPT: the Voice Studio card
On an account that may clone a voice, `voice_studio` with no job id opens
a card that records the person, or takes a saved recording. They tick the
consent box, and the card sends you the recording's URL. Run the clone
with that URL and `confirm_rights: true`, then call `voice_studio` with
the clone's job id so they hear it and save it to a character.
## Rules
- One clone per voice. Reuse it with `my_voice`; do not clone again.
- When the sample sounds wrong, ask for a cleaner or a longer recording.
Referenced files: 1 — file references are metadata, not package contents.
vsb-design14.3 KB
View saved version →
---
name: vsb-design
description: >
Make designs on the Visual Sandbox canvas with `vsb design` (or the
`create_design` MCP tool): web pages, app screens, cards, posters and vector
drawings, organized in named layers like a Figma file, and exported as HTML,
React, SVG or PNG. Trigger when the user wants to "design a page", "mock up
a screen", "make a landing page / hero / card", "make this UI" or
"rebuild this page" from a screenshot, "draw a picture or an
illustration in code", "make an SVG by drawing it", "put a design on the
canvas", "export it to React", or points at a layer they picked on the
canvas ("change this button"). Free: nothing is generated and nothing is
billed.
license: Proprietary. See LICENSE for the terms.
---
# Design on the canvas
A design is **one HTML document on the canvas**, drawn at 1:1 like a frame in
Figma. A page, a screen and a card are HTML and CSS. A drawing is one `<svg>`.
**A layer is an element with a `data-name` attribute**, and the layer tree is
how those elements nest. The person sees the tree beside the canvas, hovers a
layer to outline it, and picks one to point at it.
The canvas, the HTML export and the React export are drawn by the same
browser engine from the same document, so they match pixel for pixel.
```bash
vsb design new hero.html --name "Landing hero" --width 1440 --height 900
vsb design export "Landing hero" -f png -o hero.png # look at it, then fix it
vsb design update "Landing hero" hero.html --version 1
vsb design export "Landing hero" -f react # landing-hero.jsx
```
## The loop
1. Write the file: `page.html`, or `drawing.js` for a drawing. Build a page
with more than one section in sections (see below).
2. `vsb design new <file> --name "<what it is>" --width <px> --height <px>`.
3. `vsb design export <design> -f png -o check.png`, and **look at the PNG**.
Read it with your image tool. Never report a design you have not looked at.
Read the `warnings` the write printed too.
4. Fix what is wrong, then `vsb design update <design> <file> --version <n>`.
5. Give the person the canvas link the command printed.
`<design>` is the node uuid or the design's name. `--version` is the version
you last read. When the person changed the design since, the write is refused
with a 409: read it again (`vsb design get`) and apply your change to that.
**The person edits by hand too.** On the canvas they reorder layers inside
auto layout and by dragging rows in the layer tree, move and resize layers
(with snapping), type into text, rename and delete layers, set auto layout
and Fixed / Hug / Fill in a panel, align layers in their frame, resize the
artboard, and undo with Cmd+Z. A hand move is a `translate`, and a resize is
`width` and `height`, in the layer's `style`. Keep what they did: read the
design before you change it, and always pass `--version`.
## Build a page in sections
The canvas shows each write in less than two seconds. Put a page on it one
section at a time, so the person sees it grow and can stop you early.
1. Write the outline: the whole `<style>` block, the root, and one empty
frame for each section, each with its `data-name`.
2. `vsb design new outline.html`, then give the person the canvas link.
3. Write the sections from top to bottom, one file each. The root element
of the file carries the `data-name` of its section.
4. `vsb design update Home hero.html --layer Hero --version <n>` for each
section. Each write adds one to the version.
5. Export the PNG after the last section, and look at it.
```html
<style>
/* Every class of every section. A layer write replaces only its element,
so this block stays as the outline wrote it. */
</style>
<div class="page" data-name="Home">
<nav class="nav" data-name="Nav"></nav>
<section class="hero" data-name="Hero"></section>
<section class="features" data-name="Features"></section>
<footer class="footer" data-name="Footer"></footer>
</div>
```
A card, a screen orPreview of the first 4,000 characters. Read full instructions →
Referenced files: 2 — file references are metadata, not package contents.
vsb-edit-video3.61 KB
View saved version →
---
name: vsb-edit-video
description: >
Edit video with the Visual Sandbox MCP tools, on the server, with nothing
to install: join clips into one video, add a voiceover or music, burn
word-timed captions, trim and reframe to 9:16, take a frame, place a logo.
Trigger when the person asks to "put these clips together", "make a reel",
"add music", "add a voiceover", "add captions or subtitles", "cut it to 15
seconds", "make it vertical", "add my logo", or to finish a video made of
several generated shots. Uses the MCP tools only.
license: Proprietary. See LICENSE for the terms.
---
# Edit a video
Every edit is its own tool. It returns a job id, like `generate`; show the
result with `show_media`. Each edit is also a tool model that `generate` and
`vsb run` can run.
Use the MCP tools only.
| To | Tool | Model | Price |
|----|------|-------|-------|
| Join clips and pictures, with a cut or a fade | `join_clips` | `tool/video-join` | Free |
| Add a voiceover, music or effects | `add_audio` | `tool/video-add-audio` | Free |
| Burn captions from the speech | `add_captions` | `tool/video-captions` | 5 cents |
| Trim, reframe to another shape, change speed | `trim_video` | `tool/video-trim` | Free |
| Take the first, the last or one frame as a picture | `extract_frame` | `tool/video-frame` | Free |
| Place a logo or a picture on the video | `add_logo` | `tool/video-overlay` | Free |
The free tools allow 200 runs a day. Each input can be up to 15 minutes.
Captions take a video of up to 10 minutes.
## Inputs
- Pass every video, picture and sound as a URL: a `result.urls` entry of an
earlier job, a URL from `upload_media`, or any public `https` URL.
- A file attached in the chat goes to `upload_media` as `file` first.
- Pass the same `sandbox_name` as the rest of the task, so the edit lands on
the same canvas.
## Make a reel from generated shots
1. Generate the shots. Give all of them the same shape, for example 9:16.
2. Join them: `join_clips` with `clips` in order. Use
`transition: "fade"` for a calm piece, `"cut"` for an ad.
3. Make the voiceover with `audio/elevenlabs-tts`, then add it:
`add_audio` with `video_volume: 0.2`, so the clip sound sits
under the voice.
4. Add music the same way: `loop_audio: true`, `audio_volume: 0.3`,
`fade_out_seconds: 1.5`.
5. Add captions last, on the finished mix: `add_captions` with a
`style`: `highlight` (the default: large capitals, the spoken word in
yellow), `hormozi` (the spoken word in green, yellow or red), `beast`
(two or three comic-book words that pop in), `classic` (words appear one
by one), `box` (sentences on a dark box) or `plain`. In ChatGPT the card
offers the other looks under the captioned video; a press runs the
captions again for 5 cents.
6. Call `show_media` with the job id of each step, or of the last step.
Captions read the speech of the video, so run them after the voiceover is
in. Run each step after the job before it is completed.
## Keep shots flowing
The last frame of one shot is the start frame of the next:
`extract_frame` with `position: "last"`, then pass its URL to the next
video model as the start image. Do this for shots that must continue one
movement.
## Fit one video to another platform
`trim_video` with `aspect_ratio: "9:16"` crops a 16:9 video from the
centre. Use `fit: "pad"` to keep the whole frame with bars. Add
`start_seconds` and `end_seconds` to keep only the best part, and `speed` to
fit a length.
## Before you run
- Say what each step does and which job it uses, in one line each.
- Captions cost 5 cents. Say so before the run.
- A failed step costs nothing. Read the error, fix the input, run again.
Referenced files: 1 — file references are metadata, not package contents.
vsb-feedback2.57 KB
View saved version →
---
name: vsb-feedback
description: >
Send feedback to the Visual Sandbox team with the MCP tool submit_feedback
or `vsb feedback`: a bug, a result that missed what was asked, a missing
feature or model, something confusing, or praise. Trigger when the person
says "tell them", "report this", "send feedback", "this is broken", "this
should exist", "I love this", or when a tool fails in a way that is not
the person's input or your own mistake. One report for each issue, never
when the person asks you not to send one.
license: Proprietary. See LICENSE for the terms.
---
# Send feedback
Feedback goes to the team that builds Visual Sandbox. It is free, and it is
how a defect gets fixed.
## When to send
- **The person asks.** Send what they say, as `source: "user"`.
- **You see a defect yourself.** A tool fails with a server error, a result
breaks the model's own rules, an error message is wrong, or a documented
field does not work. Send it as `source: "agent"`, then tell the person in
one line that you sent it.
Do not send:
- Your own mistakes: a wrong field, a wrong slug, a file that was not there.
- An expected refusal, such as too little credit or a field out of range.
- Anything when the person asks you not to.
- A refund request. Feedback starts no refund and no new run. Send the person
to hello@visualsandbox.com for a refund.
## How to send
Over MCP:
```json
{
"category": "generation_quality",
"source": "agent",
"message": "Asked for a 9:16 clip of a red mug; got 16:9 with a blue mug. The prompt named the color twice.",
"attempted_task": "A product video for a mug",
"tool_name": "video_p_video",
"job_id": "8f3…"
}
```
With the CLI: `vsb feedback "<message>" --kind generation_quality --json`.
| `category` | Use it for |
|------------|------------|
| `bug` | An error, a crash, a tool that does not do what its description says |
| `generation_quality` | A result that missed the prompt, the reference or the model's own promise |
| `missing_feature` | A model, a field or a tool that the person needed and is not there |
| `confusing` | A message, a price or a step that the person or you could not understand |
| `praise` | Something that worked well |
| `other` | Anything else |
## Write the message
- What was asked, what came back, and what was expected. Two or three
sentences.
- The exact error text and the job id, when there is one.
- No passwords, payment details, private files or the person's own words that
they did not want shared.
Send one report for each issue. A second failure of the same kind in the same
task is not a new report.
Referenced files: 1 — file references are metadata, not package contents.
vsb-html-video4.95 KB
View saved version →
---
name: vsb-html-video
description: >
Write HTML and render it into a video or a picture with the Visual Sandbox
MCP tools render_html_video and render_html_image: motion graphics, kinetic
type, an animated explainer, a title card, lower thirds, a logo sting, a
social card, a quote card or a thumbnail with exact text. Trigger when the
person asks for "motion graphics", "kinetic typography", "an animated
explainer", "a title card", "an intro", "a lower third", "a logo
animation", "a social card with this text" or a design that must move.
Covers the composition contract, the render clock, GSAP timelines, sound,
the limits, and how to check a render. Free. Uses the MCP tools only.
license: Proprietary. See LICENSE for the terms.
---
# HTML to video
You write one HTML document. The renderer plays it in headless Chromium on a
clock that it moves frame by frame, so every frame is drawn at an exact time
and the same HTML always gives the same video. Both tools are free.
Use this pack only when the person asks for designed motion or exact text.
For filmed footage, a person or a real place, use a video model instead
([`vsb-video`](../vsb-video/SKILL.md)).
## The two tools
| Tool | Gives | Inputs |
|------|-------|--------|
| `render_html_video` | An MP4 | `html`, `width`, `height` (even, 16 to 1920), `duration` (up to 60 s), `fps` (24, 30 or 60) |
| `render_html_image` | A PNG | `html`, `width`, `height`, `time` (the moment to draw), `transparent` |
Each returns a job id. Call `show_media` with it, or `get_job` when it is
done. The result's `metrics.warnings` lists blocked requests and script
errors. Read them before you report the result.
## The composition contract
1. Set a fixed pixel size on `html` and `body`, the same as `width` and
`height`. Use `overflow: hidden`.
2. Make every frame a function of the time alone. The renderer replaces
`Date`, `performance.now`, `requestAnimationFrame`, `setTimeout` and
`setInterval` with its own clock, and seeds `Math.random`. Do not read
the real time in any other way.
3. Animate with one of these. All of them follow the render clock:
- CSS animations and transitions.
- The Web Animations API (`element.animate`).
- A GSAP timeline, created paused and registered after the setup:
`window.__timelines = { main: tl }`. The renderer seeks it to each
frame's time.
- `requestAnimationFrame`, with the time from its argument.
4. Never use an infinite loop that does not depend on the time, such as a
`while` loop that waits for a load.
5. Load fonts, pictures, footage and libraries from public `https` URLs.
A private, local or link-local address is blocked, and the block shows in
the warnings.
6. Put footage in `<video muted playsinline src="…" data-start="2">`. The
renderer seeks it to the frame's time minus `data-start`.
7. Add sound with `<audio src="…" data-start="0" data-duration="8"
data-volume="0.8">`. Up to 8 tracks of up to 50 MB each. The renderer mixes
them after the frames. A narration from `audio_elevenlabs_tts` works here.
## A skeleton
```html
<!doctype html>
<html><head><meta charset="utf-8">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@800&display=swap" rel="stylesheet">
<style>
html, body { margin: 0; width: 1080px; height: 1920px; overflow: hidden; background: #0B0B0F; }
h1 { font: 800 140px/1 Inter, sans-serif; color: #fff; position: absolute; top: 760px; left: 80px; }
</style>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
</head><body>
<h1 id="title">Launch day</h1>
<audio src="https://cdn.visualsandbox.com/…/voice.mp3" data-start="0.5"></audio>
<script>
const tl = gsap.timeline({ paused: true });
tl.from("#title", { y: 120, opacity: 0, duration: 0.8, ease: "power3.out" })
.to("#title", { scale: 1.06, duration: 3 }, 0.8);
window.__timelines = { main: tl };
</script>
</body></html>
```
## How to work
1. Agree the size, the length and thPreview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-image24.5 KB
View saved version →
---
name: vsb-image
renamed_from: image
description: >
Pick the right Visual Sandbox model for any image task and prompt it well.
Trigger when the user wants to generate, edit, restyle, upscale, or remove
the background from images via the vsb CLI. All execution goes through
`vsb run image/<slug>` — sync, ~5–10s for the standard models. Always
verify slugs with `vsb models --modality image --json` first.
license: Proprietary. See LICENSE for the terms.
---
## Default model in ChatGPT
For a new image from a prompt, call `image_recraft_v4_1_flash` ($0.01 an image).
It takes no reference image, so for an edit of a photo call `image_nano_banana_2_lite`.
Use another model only when the person names one or asks for what these cannot do.
This rule comes before the defaults in the table below.
# Image generation with vsb
> **On the MCP surface?** If the `visual-sandbox` MCP tools are in your
> tool list, use `generate` and `get_job` instead of the shell commands
> below. The model choice and the prompt craft on this page still apply.
> See `vsb` → Two ways to run.
Image runs are sync — `vsb run image/<slug>` blocks until done (typically
5–10s). No `--async` needed, but **still start the run in a background shell**
(Claude Code: `run_in_background: true`) so the turn stays free and parallel
variations fan out (vsb critical rule 6).
Pipe `--json` and `--download "<template>"` to capture results, then
**open every finished image in Preview** — `open -a Preview <file>` — so the
user sees the picture instead of a link
(vsb critical rule 12). Download
to a scratch folder (`mktemp -d`) for that; a **project** save still needs the
opt-in from vsb critical rule 5.
Hand back the share page `https://visualsandbox.com/share/<job_id>/`, never a
raw CDN URL.
> **Before writing any image prompt, read
> [`vsb-image-prompting`](../vsb-image-prompting/SKILL.md).** It covers the universal
> rules, the prompt-anatomy slot list, the reference-image keep/ignore
> pattern (what to take from an attached image and what to ignore — without
> this, watermarks and text overlays leak into outputs), and the camera /
> lens / lighting / grade vocabulary banks. This skill only covers
> *picking* a model — the prompt-craft itself lives in `image-prompting`,
> with model-specific quirks in [`vsb-nano-banana`](../vsb-nano-banana/SKILL.md) and
> [`vsb-ugc-people`](../vsb-ugc-people/SKILL.md).
## Rules for every paid image run
- **Keep a simple request simple.** "Make an image of X" is one image: no
questionnaire, no extra drafts, no variations nobody asked for.
- **One request is one paid attempt.** A complaint or "fix it" is not a yes
for a new run. Say what you would change, and ask first.
- **Review mode (MCP).** A run of 10 cents or more can answer
`awaiting_approval`. In ChatGPT, call `show_media`; elsewhere, give the
`share_url`. Never press Generate for the person.
- **Branded work** reads the brand first with `get_theme`
([`vsb-library-themes`](../vsb-library-themes/SKILL.md)).
## Picking a model
Verify the live catalog with `vsb models --modality image --json | jq '.models[] | {slug, category, owner}'`.
| Task | Default slug | Why |
|------|--------------|-----|
| Fast text-to-image / edit | `image/nano-banana-2-lite` | Google. Default. Cheapest (~$0.05/image), fastest, ~5s, on the newer NB2 architecture. Handles both text-to-image AND image edits — the same endpoint switches modes when a reference image array is non-empty. |
| Same cost, original model | `image/nano-banana` | The original Gemini 3 model at the same ~$0.05/image. Fall back here if a lite result looks off. |
| Higher quality / 4K / web-grounded | `image/nano-banana-2.1` | Google. The update to NB2: sharper output, cleaner text, steadier subjects across edits. **Pick it over `nano-banana-2`:** it costs about half as much at 1K and 2K (~$0.05 at 1K, ~$0.07 at 2K, ~$0.15 at 4K), and each of `google_search` / `image_search` adds a small charge, as on NB2. `resolution`Preview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-image-iteration16.9 KB
View saved version →
---
name: vsb-image-iteration
description: >
Change an image more than once without it falling apart. Read this before the
SECOND `vsb run` on the same picture — before chaining a sandbox node's
`output_url` into the next run's `image_input`, before "now make the shirt
blue too", and before any loop that feeds an output back in as an input.
Covers generation loss (why every image model degrades on repeated edits), the
four workflows that prevent it (prompt stacking, contact sheet, crop and
composite, noise repair), and the `output_format` / `resolution` settings that
decide the outcome. For writing the prompt itself, read
[`vsb-image-prompting`](../vsb-image-prompting/SKILL.md) first.
license: Proprietary. See LICENSE for the terms.
---
# Iterating on an image without degrading it
## The one thing to know
**No image model edits an image. It reads the image and draws a new one that
copies it.** Every "edit" is a full redraw from scratch.
So each pass adds error on top of the last pass. After two edits you see it.
After ten, the parts you never touched are unusable. Users call it
*generation loss*, or "a photocopy of a photocopy".
This is not a Nano Banana bug. It happens on `image/nano-banana*`,
`image/gpt-image-2`, `image/seedream-5-pro`, and `image/flux-2-*`. It happens
through the API, not only in a chat interface. It cannot be prompted away.
**What it looks like:** grain and noise creep in, edges go soft, colors drift,
JPEG blocks and banding appear, faces slowly stop being the same face.
> **The trap in this CLI.** `vsb` critical rule 10
> tells you to pass a selected node's `output_url` into the next run's
> `image_input`. That is correct for the FIRST edit. Do it twice in a row and
> you have built the photocopy loop. Read the decision table below before the
> second one.
## Pick a workflow
| You want | Use | Quality cost |
|----------|-----|--------------|
| Several changes to one picture | **A — prompt stacking** | None. Always one pass. |
| Many frames of the same subject / scene | **B — contact sheet** | None. One pass for all frames. |
| One small change, rest must stay untouched | **C — crop and composite** | None outside the crop. |
| An image that is already damaged | **D — noise repair** | Recovers some. Not all. |
Workflows A and C are the only two that actually solve the problem. B avoids it
by never chaining. D is a rescue for work you cannot redo.
---
## Workflow A — prompt stacking (the default)
**Never edit the edit. Grow the prompt and re-run from the original.**
Keep two things in a scratch file: the original image (or the original
text-to-image prompt) and a master prompt. For each new change, append one
sentence to the master prompt, then run again from the original source.
```bash
# Turn 1 — establish the original. Note the job_id it returns.
vsb run image/nano-banana-2 --json --no-sandbox \
--output_format png --resolution 2K \
--prompt "A man in a grey suit stands in a bright office."
# Turn 2 — the user wants a green tie. Re-run the SAME inputs with one
# sentence added. No reference image, so the picture is drawn fresh.
vsb run image/nano-banana-2 --json \
--from-job <job_id_from_turn_1> \
--prompt-add "He wears a dark green tie."
# Turn 3 — and a red door behind him. Stack again, from turn 2's job.
vsb run image/nano-banana-2 --json \
--from-job <job_id_from_turn_2> \
--prompt-add "A red door stands behind him."
```
`--from-job` copies the past run's inputs and `--prompt-add` appends to its
prompt. Explicit flags override anything inherited. Nothing is ever fed back in
as `image_input`, so there is no chain and no decay.
Doing it by hand works the same way: keep the master prompt in a file, append a
line per change, and pass the whole file each time.
When the original is a photo the user supplied, the same rule applies — the
`image_input` always points at **their** file, never at your last output.
**Cost:** a full generation per change, same as a
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-image-prompting8.26 KB
View saved version →
---
name: vsb-image-prompting
renamed_from: image-prompting
description: >
Canonical prompt-craft skill for every image model in Visual Sandbox
(`image/nano-banana*`, `image/gpt-image-2.5-flare`, `image/gpt-image-2`,
`image/flux-2-klein-9b`, future
slugs). Read before writing any `vsb run image/<slug>` prompt — text-to-image
or edit-with-reference. Covers the universal rules, the prompt-anatomy slot
list, the reference-image keep / ignore formula (what to take from the
reference, what to ignore — watermarks, text overlays, original lighting,
original background), and the "enumerate models before picking cheapest"
rule. Model-specific quirks live in sibling skills (`vsb-nano-banana`,
`vsb-ugc-people`).
license: Proprietary. See LICENSE for the terms.
---
# Image prompting (model-agnostic)
## Universal rules
1. **Be specific.** Concrete subject, scene, light. Not "dog in park".
2. **Positive framing.** Describe what's there, not what isn't. ("Empty street" ✓, "street with no cars" ✗.)
3. **Use photography language.** `f/1.8 shallow DoF`, `golden hour`, `Rembrandt lighting` map to real transforms.
4. **Iterate on the prompt, not on the pixels.** One change per turn — but
grow the prompt and re-run from the original. Feeding your own last output
back in as `image_input` compounds loss on every pass. See
[`vsb-image-iteration`](../vsb-image-iteration/SKILL.md).
## Prompt anatomy
Pick 5–9 slots. Concreteness > coverage.
| Slot | Example |
|------|---------|
| Subject | 28yo brunette, shoulder-length wavy hair, faint freckles, pale skin |
| Wardrobe | oversized cream cable-knit sweater, gold hoop earrings, no makeup |
| Action | holding latte mug close to chest with both hands |
| Location | sunlit Brooklyn apartment corner, exposed brick, fairy lights on window frame |
| Composition | medium close-up selfie, 9:16, eyes upper third, shoulders cropped |
| Camera | Shot on iPhone 17 Pro Max main lens (~26mm equiv) |
| Lens / DoF | f/1.8 shallow DoF, slight motion blur on hand |
| Lighting | warm late-morning window backlight, soft ambient room fill |
| Color grade | neutral white balance, slightly muted, no Instagram filter |
| Materiality | ribbed ceramic mug, cable-knit cotton, raw oak windowsill |
| Mood | cozy, candid, unposed |
| Anti-AI cues | sensor grain, lens flare, asymmetric framing, hair flyaway, faint pores |
## Bad → good
**Bad** (model fills every gap with AI-glossy defaults):
> "candid iPhone selfie of brunette in cozy apartment holding latte, UGC TikTok aesthetic"
**Good** (directed):
> "Candid iPhone selfie of 28yo brunette, shoulder-length wavy hair, faint freckles. Oversized cream cable-knit sweater, ribbed ceramic mug of latte at chest. Sunlit Brooklyn apartment corner, exposed brick, fairy lights on the window frame behind. Medium close-up, 9:16, eyes upper third. Shot on iPhone 17 Pro Max (~26mm), f/1.8, slight hand motion blur. Warm window backlight, soft ambient fill. Neutral white balance, sensor grain, asymmetric framing, single hair flyaway, no makeup. Cozy, candid, unposed."
## Reference-image prompting (CRITICAL — fixes watermark/caption bleed)
When `image_input` is set, the model uses the reference as *every* signal —
subject, watermarks, captions, UI bars, original lighting, original framing
all bleed forward unless you tell it not to.
**Formula** — paste at the top of every reference-anchored prompt:
```
Use the reference image as the IDENTITY source only.
Keep: [face, hair color and length, skin tone, body proportions, age, distinctive features].
Ignore everything else from the reference — including any watermarks, text overlays, captions, logos, UI bars, original lighting, original background, and original framing.
Now place the same subject in: [fresh scene — full anatomy from above].
```
End with: `"No logos, no captions, no watermarks, clean frame."`
(Negative framing — "don't add a watermark" — doesn't work. Stating the desired clean state does.)
**MulPreview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-library-themes3.77 KB
View saved version →
---
name: vsb-library-themes
description: >
Keep a brand and its media in Visual Sandbox with the MCP tools: read a
brand's colors, fonts, logo and tone from its website into a saved theme,
apply the theme to every later prompt, and find, name and tag results in
the person's library so they can be used again. Trigger when the person
says "use my brand", "set up my brand", "match our website", "our colors",
"our logo", "find the picture we made last week", "use the approved
keyframe", "name this", "tag these" or gives a website for branded work.
Saves only values the person confirmed. Uses the MCP tools only.
license: Proprietary. See LICENSE for the terms.
---
# Brand themes and the library
A **theme** keeps a brand once: its colors, fonts, logos, notes and
reference pictures. The **library** is every result and upload on the
account, the same rows the person sees on visualsandbox.com. Both are free.
## Set up a brand
1. Ask for the website, or for the colors, fonts and logo.
2. Call `extract_theme` with the website. It reads the site on the server
and proposes colors with roles, fonts, logos and the site's own
description. It saves nothing.
3. Show the proposal to the person before you save it:
- **In ChatGPT,** call `edit_theme` with the name and the proposal as
`draft`. The card shows the swatches, fonts and logos. The person fixes
what is wrong and presses Save. Do not call `update_theme` for it.
- **Elsewhere,** list the colors (hex and role), the fonts and the logo,
and ask what to change. Then call `update_theme` with the agreed values.
4. Never invent a brand value. A value that you guess is a proposal until the
person agrees to it.
### The theme's shape
- Colors: `hex`, `name`, and a `role`: `primary`, `secondary`, `accent`,
`bg`, `fg` or `muted`.
- Fonts: `name`, `source` (`google` or `custom`) and a `role`: `heading`,
`body`, `mono` or `accent`.
- Logos: `url`, `name`, `variant` (`light`, `dark`, `mono` or `color`) and
`has_background`.
- `notes`: the audience, the tone, the look, and what to do and never do.
- `images`: reference pictures. The first one is the thumbnail.
`update_theme` replaces each field it is given and keeps the rest. A new
`colors`, `fonts` or `logos` list replaces the whole list. The first theme on
an account is its default; `set_default` changes that.
## Apply a theme
Before any branded image, video, design or HTML render:
1. Call `get_theme` (no name gives the default theme).
2. Put the look into the prompt in words: the main colors by name and hex,
the mood from `notes`, and every "never" rule.
3. Pass a logo or a reference picture as a reference image when the model
takes one. Say in the prompt what to keep from it and what to ignore.
4. In HTML ([`vsb-html-video`](../vsb-html-video/SKILL.md)) and designs
([`vsb-design`](../vsb-design/SKILL.md)), use the hex values and the
font names exactly.
## Find and name media
- `search_assets` finds results and uploads by words (`query`), `tags`,
exact `name`, `type` (`image`, `video`, `audio`, `3d`, `vector`, `text`)
and `source` (`generated` or `uploaded`). Each asset carries a `url` to
pass to the next run.
- `update_asset` gives an asset a `name`, `tags` and a `description`. It
takes the asset's id, its name or its file URL.
How to name:
- A name is a unique slug: `acme-launch-hero`, `acme-launch-hero-v2`.
- A derivative keeps the name and adds a suffix: `-cutout`, `-vertical`,
`-upscaled`. The original stays.
- Keep tags few and stable: the brand (`acme`), the campaign
(`launch-2026`), the kind (`logo`, `keyframe`) and the state (`approved`).
- `tags` replaces the whole list, so send the tags to keep as well.
Name a result when the person approves it, so a later chat finds it with
`search_assets` instead of a new paid run.
Referenced files: 1 — file references are metadata, not package contents.
vsb-nano-banana9.49 KB
View saved version →
---
name: vsb-nano-banana
renamed_from: nano-banana
description: >
Prompt the Nano Banana family (Google's Gemini Image — `image/nano-banana-2-lite`,
`image/nano-banana`, `image/nano-banana-2`, `image/nano-banana-pro`) well. Trigger whenever the
user is about to call `vsb run image/nano-banana*` or asks how to phrase a
prompt for these models — covers the variant picker, edit-mode rules, text
rendering, multi-reference blending, and the things this family gets
wrong. For the universal prompt-anatomy rules and reference-image
subject-anchor pattern, read [`vsb-image-prompting`](../vsb-image-prompting/SKILL.md)
first — this skill only adds nano-banana-specific quirks on top.
license: Proprietary. See LICENSE for the terms.
---
# Prompting Nano Banana
**Read [`vsb-image-prompting`](../vsb-image-prompting/SKILL.md) first.** It covers the
four universal rules, the full prompt-anatomy slot list, the
reference-image keep/ignore pattern, and the vocabulary banks — those apply
to every image model. This skill only adds Nano Banana–specific behavior
that diverges from the trunk.
Nano Banana is built on Gemini 3 — it reasons over the prompt before
drawing, so the natural-language scene-description approach in
[`vsb-image-prompting`](../vsb-image-prompting/SKILL.md) works especially well here.
The same endpoint handles text-to-image AND edits: pass `image_input` (an
array) to switch into edit mode.
Verify the live schema first: `vsb schema image/nano-banana --json`.
## Picking a variant
| Slug | When to use |
|------|-------------|
| `image/nano-banana-2-lite` | **Default.** Lightweight Nano Banana 2 — same low cost as the original (~$0.05/image, ~5s) but on the newer NB2 architecture. Great for iterating and everyday text-to-image + image edits. No `resolution` or web-search knobs. |
| `image/nano-banana` | The original Gemini 3 model. Same ~$0.05/image. Fall back here if a `nano-banana-2-lite` result looks off. Best with 1–3 reference images. |
| `image/nano-banana-2` | Full NB2 — adds `resolution` (up to 4K) and web-search grounding. Use when stills aren't crisp enough or you need higher fidelity. |
| `image/nano-banana-pro` | 4K-capable, sharpest text + typography, best for posters, infographics, packaging mockups, editorial work, and multi-reference character blending (up to 14 refs). Slowest + priciest of the three. |
All three share the same `image_input` array, `aspect_ratio` enum, and
`output_format` enum. Confirm with `vsb schema` before assuming.
## Image edits (`image_input` set)
> ⚠️ **Editing the same picture a second time degrades it.** The model never
> edits — it redraws the whole image from scratch on every pass, so error
> compounds. Before a second edit on one image, read
> [`vsb-image-iteration`](../vsb-image-iteration/SKILL.md). Also pass
> `--output_format png` on any output you may feed back in; the default is
> `jpg` and its compression stacks on every pass.
When `image_input` is non-empty, the model is editing — the prompt should
lead with the change and be explicit about what stays the same. The
universal subject-anchor pattern (in
[`vsb-image-prompting`](../vsb-image-prompting/SKILL.md)) is the floor; Nano Banana
takes especially well to plain-English edit instructions on top.
**Good:** `"Change the man's tie to dark green. Keep the rest of the photo,
lighting, and composition exactly as they are."`
**Bad:** `"man with green tie"` (loses every other detail).
Edit patterns Nano Banana handles cleanly:
- **Add / remove / swap:** `"Remove the car in the background."`
`"Replace the coffee mug with a vintage typewriter."`
- **Restyle:** `"Restyle as a 1990s film photograph — kodak gold, slight
grain, warm cast."` `"Convert to ink-on-paper line art."`
- **Reframe / re-angle:** `"Re-render this scene from a low angle, keeping
the same subject and lighting."`
- **Weather / time-of-day:** `"Same scene but at golden hour with backlit
rim light."`
- **Product extraction:** `"Extract t
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-product-photoshoot3.33 KB
View saved version →
---
name: vsb-product-photoshoot
description: >
Make a set of product photos from one photo of the product with the Visual
Sandbox MCP tools: hero shots, lifestyle scenes, flat lays and ad images
that keep the product the same in every picture. Trigger when the person
asks for "product photos", "a product shoot", "photos for my store",
"Amazon or Shopify images", "lifestyle shots of my product", "a hero
image", or sends a product photo and asks to make it look professional.
Uses the MCP tools only.
license: Proprietary. See LICENSE for the terms.
---
# A product photo shoot
One photo of the product goes in. A set of pictures comes out, and the
product looks the same in all of them: the same shape, the same colour and
the same label.
Use the MCP tools only.
## 1. Get the product
- Ask for one clear photo of the product, if the person sent none. A phone
photo on a plain table is enough.
- Pass a public `https` URL straight to `generate`. For a photo attached in
the chat, call `upload_media` with it as `file`. For a local file, call
`upload_media` with a base64 `data_uri`. Use the URL it returns.
- Ask where the pictures go: a store page, an ad, or social media. That sets
the shape: 1:1 for a store, 4:5 or 9:16 for social media, 16:9 for a
banner.
## 2. Plan the set
Propose four shots and let the person change the list before you run:
| Shot | What it shows |
|------|---------------|
| Hero | The product alone on a clean background, with soft studio light |
| Lifestyle | The product in use, in the place a buyer uses it |
| Detail | A close view of the texture, the material or the label |
| Flat lay | The product from above, with two or three props that fit it |
## 3. Run the first shot
1. Read [`vsb-image-prompting`](../vsb-image-prompting/SKILL.md) with
`get_skill`. Its reference section says what to keep from the photo and
what to drop, such as the old background and the old light.
2. Call `list_models` with `modality: "image"`. Pick an edit model that takes
a reference image. Read [`vsb-nano-banana`](../vsb-nano-banana/SKILL.md)
when you pick a Nano Banana model.
3. Call `get_model`, then `generate` with the photo as the reference. Name
the work with `sandbox_name`, such as "Candle product shoot".
4. Call `get_job` after `eta_seconds`. Compare the product with the photo:
the shape, the colour and every word on the label.
Run the hero shot first and show it. Run the other shots only after the
person approves the look.
## 4. Run the rest of the set
- Use the same model and the same reference on every shot.
- Start every prompt with the same sentence that describes the product, so
the product stays the same.
- Send the same `sandbox_name` on every call, so the set lands on one canvas.
## 5. Hand it over
Give one `share_url` for each picture and the `sandbox_url` for the set.
Offer one next step: ad variations of the hero shot with
[`vsb-ad-variations`](../vsb-ad-variations/SKILL.md), or a short video of it
with [`vsb-video`](../vsb-video/SKILL.md).
## Rules
- Never change the product. A changed label or shape is a failed shot, even
when the picture looks good. Say so and run the shot again.
- Never add a logo, a price or a claim that the person did not give you.
- When a run is refused for want of credit, say the balance is too low, and
follow what the server instructions say about credit.
Referenced files: 1 — file references are metadata, not package contents.
vsb-p-video7.98 KB
View saved version →
---
name: vsb-p-video
renamed_from: p-video
description: >
Prompt and run Pruna AI's P-Video family well. `video/p-video` is the
cheapest video model in Visual Sandbox, with a built-in `draft` toggle that
drops cost ~4×, and two newer tiers sit above it. Trigger whenever the user
is about to call `vsb run video/p-video*` or asks "cheapest video model",
"draft video", "iterate fast", or "lots of video variations". Always ask the
user **draft or standard** before running.
Pairs with the parent [`vsb-video`](../vsb-video/SKILL.md) skill for the async +
poll pattern.
license: Proprietary. See LICENSE for the terms.
---
# P-Video (Pruna AI)
Cheapest video model in the catalog. Fast iteration. Two-mode runtime via the
`draft` boolean — flip it on for previews, off when you're locking the shot.
## Which P-Video tier
Three generation tiers now share this family. Price alone no longer picks one.
| Pick | When |
|---|---|
| `video/p-video` | Bulk prompt exploration. Its draft rate is still the lowest in the whole catalog. No audio of any kind. |
| `video/p-video-2` | The clip has to talk, or needs 1080p, 48 fps, a last frame, or a run past 15s. It writes native speech with lip-sync from dialogue in the prompt, and also takes an audio track to drive motion. |
| `video/p-video-2-pro` | The best Pruna picture. Silent: no audio in, no audio out, and 768p is the ceiling. |
People who talk, with one voice across shots: `video/p-video-2 --image <still>
--audio <ElevenLabs line>` is the cheapest path. The clip runs as long as the
audio, so `--duration` has no effect; pad the line with silence to the shot
length. Say in the prompt that the person speaks. Compare it with the other
paths in [`vsb-video` → People who talk](../vsb-video/SKILL.md#people-who-talk-pick-the-sound-path-before-you-spend) before you
spend.
Three more slugs in the family transform a clip you already have rather than
generate one, and they are covered in [`vsb-video`](../vsb-video/SKILL.md):
`video/p-video-edit`, `video/p-video-replace`, `video/p-video-animate`, plus
`video/p-video-avatar` for a photo that speaks a typed script.
Read the parent [`vsb-video`](../vsb-video/SKILL.md) skill first for the universal
async + poll + cancel pattern. This skill only adds p-video–specific behavior.
Prompt craft — slot formula, narration pattern, DO/DON'T — lives in the
sibling [`vsb-p-video-prompting`](../vsb-p-video-prompting/SKILL.md) skill. Load it
before writing any prompt.
Verify the live schema before assuming fields:
```bash
vsb schema video/p-video --json
vsb pricing video/p-video --json
```
## Always ask first: draft or standard?
Before running, ask the user which mode they want. Don't guess.
```
Draft (cheap, fast — for iteration) or standard (final-quality render)?
```
| Mode | `--draft` | 720p | 1080p | When to pick |
|------|-----------|------|-------|--------------|
| **Draft** | `true` | $0.00625/s | $0.0125/s | Trying out a prompt. Exploring 5–10 variations. Storyboards. Anything you'd re-run. |
| **Standard** | `false` | $0.025/s | $0.05/s | Locking the final shot. Delivering to client. The shot you'll post. |
A 5s 720p draft ≈ $0.03. The same shot at standard = $0.125 (4×). Use draft
to land the prompt + composition, then run **the exact same args with
`--draft false`** once to lock the final.
## Pricing reference
What you pay (verify live with `vsb pricing video/p-video --json`):
| Resolution | Mode | $/s |
|------------|------|-----|
| 720p | draft on | $0.00625 |
| 720p | draft off | $0.025 |
| 1080p | draft on | $0.0125 |
| 1080p | draft off | $0.05 |
Per-second billing. `--duration` is integer 1–10 (default 5).
## Input modes
P-Video accepts three independent conditioning signals — combine freely.
| Field | Meaning |
|-------|---------|
| `prompt` | Required. Scene + motion description. |
| `image` | Optional first-frame for image-to-video. |
| `audio` | Optional audio track — motion syncs to the sound. Use
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-p-video-prompting9.43 KB
View saved version →
---
name: vsb-p-video-prompting
renamed_from: p-video-prompting
description: >
Canonical prompt-craft skill for Pruna AI's P-Video family in Visual
Sandbox: `video/p-video`, `video/p-video-2` and `video/p-video-2-pro`. Read
before writing any `vsb run video/p-video*` prompt — text-to-video,
image-to-video, or audio-conditioned. Covers the official
Pruna slot formula (Subject / Action / Scene / Camera / Lighting / Style /
Audio), the image-to-video narration pattern for talking avatars, the
DO/DON'T list straight from Pruna's docs, and the `prompt_upsampling`
override rule. Pairs with [`vsb-p-video`](../vsb-p-video/SKILL.md) for runtime
(draft toggle, pricing, schema, async + poll).
license: Proprietary. See LICENSE for the terms.
---
# P-Video prompting
Prompt craft only. For runtime, pricing, draft toggle, async + poll, read
[`vsb-p-video`](../vsb-p-video/SKILL.md) first. For universal video knobs (aspect,
duration, fps), read [`vsb-video`](../vsb-video/SKILL.md).
The slot formula below carries across all three generation tiers. Three
differences matter when you write for the newer two:
- **`video/p-video-2` speaks.** Write the dialogue into the prompt, in quotation
marks, keep `save_audio` on, and attach no audio file. It generates the speech
with matched lip movement. `video/p-video` has no native audio at all.
- **Both newer tiers take a `last_frame_image`.** Describe the motion that has to
land on it, not just the opening.
- **`video/p-video-2-pro` renames the knob.** Its control is `prompt_upsampler`
with `off`, `turbo` or `max`, not the boolean `prompt_upsampling` the other two
carry. `video/p-video-2-pro` is silent, so leave the Audio slot out of its
prompts entirely.
## Universal rules
1. **Describe motion, not stills.** "Waves crashing against rocky shore" ✓. "A rocky shore with waves" ✗.
2. **Dynamic verbs.** running, soaring, dancing, transforming, colliding. Skip "is moving", "was walking" — passive voice flattens motion.
3. **Direct language, not commands.** "Camera slowly pans across serene lake at sunset" ✓. "Please create a video of a lake" ✗.
4. **Specify timing.** slow-mo / gradually / building to crescendo / quick burst — pacing is half the shot.
5. **Atmosphere matters.** "Misty morning with soft diffused light" reads better than "morning scene".
6. **Iterate with `draft: true`.** Don't one-shot in standard mode. Land phrasing cheap, lock with `draft: false` + same seed.
## Pruna's official prompt formula
```
[Subject] [Action] [Scene] [Camera] [Lighting] [Style] [Audio]
```
First three required. Last four optional but lift quality fast. Pruna's own basic example:
> Knitted purple prune character, reading a book, cozy room, static camera, warm natural light, documentary style, character reading aloud: "P-Video generates state-of-the-art AI video in seconds."
Same shot, advanced (richer per-slot):
> Cinematic shot of a knitted purple prune character, dancing joyfully through a large pink and purple room, camera starting in front then circling and ending behind the character showing a race car, warm golden hour lighting creating soft illumination, cinematic animation style.
## Slot cheat sheet
| Slot | What to include | Strong values |
|------|-----------------|---------------|
| **Subject** | age, gender, clothing, features, posture (human) / breed, size, color, behavior (animal) / material, dimensions, condition (object) | "28yo brunette with shoulder-length wavy hair", "knitted purple prune character with white eyes" |
| **Action** | motion verb + tempo + direction + intensity + continuity | "running gradually building to a sprint, from left to right", "wakes up, then puts on glasses, then drinks coffee" |
| **Scene** | location + spatial elements + weather/time + depth | "intimate cozy room with wooden floor and window, warm afternoon", "vast neon-lit Tokyo crosswalk at midnight, light rain" |
| **Camera** | tracking / orbital / zoom / pan / tilt / aerial / han
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-seedance16.4 KB
View saved version →
---
name: vsb-seedance
description: >
Run the ByteDance Seedance family in Visual Sandbox well: `video/seedance-2.5`
(up to 30 reference images, reference video and audio lists), `video/seedance-2`
(1080p and 4K), `video/seedance-2-fast`, and `video/seedance-2.0-mini`.
Trigger whenever the user is about to call `vsb run video/seedance-*`, names
Seedance, or asks for reference-driven video: a cast held across shots, a
motion copied from a clip, a voice from an audio file, a first and last frame,
a video edit, or a video extension. Covers the flags, the reference numbering,
the locked aspect and duration rules per task, the price jump for a reference
video, and the safety filter. Prompt craft lives in
[`vsb-seedance-prompting`](../vsb-seedance-prompting/SKILL.md). Pairs with
[`vsb-video`](../vsb-video/SKILL.md) for the async + poll pattern.
license: Proprietary. See LICENSE for the terms.
---
# Seedance (ByteDance)
Four slugs share one input shape. Read the parent
[`vsb-video`](../vsb-video/SKILL.md) first for async + poll + cancel. Read
[`vsb-seedance-prompting`](../vsb-seedance-prompting/SKILL.md) before you write
the prompt. This page only adds what is specific to Seedance.
Verify the live schema and price before you assume anything:
```bash
vsb schema video/seedance-2.5 --json
vsb pricing video/seedance-2.5 --json
```
## Pick a tier
| Slug | Pick it for | Resolution | Duration | Aspect |
|------|-------------|------------|----------|--------|
| `video/seedance-2.5` | Hero shots, many references, native audio, clips up to 30 s. The slowest model in the catalog: about 4 minutes for a short clip, longer for a long one. Draft, then finish at 1080p. | 480p, 720p, 1080p | -1, 4 to 30 | 16:9, 4:3, 1:1, 3:4, 9:16, 21:9, adaptive |
| `video/seedance-2` | 4K output, or 1080p with up to 15 s | 480p to 4K | -1, 4 to 15 | adds 9:21 |
| `video/seedance-2-fast` | Same inputs as `seedance-2`, faster and cheaper, 720p cap | 480p, 720p | -1, 4 to 15 | adds 9:21 |
| `video/seedance-2.0-mini` | Drafts and batches at the lowest rate. One reference video and one reference audio only. No adaptive. | 480p, 720p | 4 to 12 | no adaptive |
Iterate on Mini or Fast. Finish the chosen shot on 2.5, or on 2 when the
delivery needs 1080p or 4K.
## Inputs
Every tier takes the same fields:
| Field | What it is |
|-------|------------|
| `prompt` | Required. Put spoken lines in double quotes. |
| `image` | First frame. Pins the opening picture. |
| `last_frame_image` | Last frame. Needs `image`. Same aspect as `image`. |
| `reference_images` | JSON list of URLs. 2.5 takes up to 30, the 2.0 family fewer. Cast, wardrobe, product, set, style. |
| `reference_videos` | JSON list of URLs. Motion, camera, pacing, the clip to edit or extend. Raises the price. |
| `reference_audios` | JSON list of URLs. Voice timbre, dialogue, music, ambience. |
| `generate_audio` | Default `true`. Turn off for a silent shot. |
| `aspect_ratio`, `resolution`, `duration`, `seed` | Per tier, see the table above. |
Lists go in as JSON strings. Upload local files first; `vsb upload` accepts
image, video and audio.
```bash
CAST=$(vsb upload ./cast.jpg --json | jq -r '.url')
SET=$(vsb upload ./set.jpg --json | jq -r '.url')
MOVE=$(vsb upload ./move.mp4 --json | jq -r '.url')
JOB=$(vsb run video/seedance-2.5 \
--prompt "$(cat prompt.txt)" \
--reference_images "[\"$CAST\",\"$SET\"]" \
--reference_videos "[\"$MOVE\"]" \
--aspect_ratio 16:9 \
--resolution 720p \
--duration 8 \
--async --json | jq -r '.job_id')
```
## Reference numbering
The prompt binds each asset by its position in its list. The first URL in
`reference_images` is `[Image1]`, the second is `[Image2]`. The first URL in
`reference_videos` is `[Video1]`. The first URL in `reference_audios` is
`[Audio1]`. Each list counts on its own.
`image` and `last_frame_image` are not in those lists. Do not number them.
The model pins them as the first and last frame from the field alone.
Writ
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-seedance-prompting11.5 KB
View saved version →
---
name: vsb-seedance-prompting
description: >
Canonical prompt-craft skill for the ByteDance Seedance family in Visual
Sandbox (`video/seedance-2.5`, `video/seedance-2`, `video/seedance-2-fast`,
`video/seedance-2.0-mini`). Read before writing any `vsb run video/seedance-*`
prompt: text-to-video, reference-to-video, first and last frame, keyframes,
storyboard, blockout, video edit, audio edit, or video extension. Built from
the official Seedance 2.5 and 2.0 prompt guides. Covers the prompt shape
(summary, shot list, notes), the asset binding rule, timestamps versus shot
numbers, camera language, action and emotion writing, sound notation,
negative control, and the 2.0 versus 2.5 differences. Templates and worked
examples live in [references/templates.md](references/templates.md).
Runtime, flags and locked parameters live in
[`vsb-seedance`](../vsb-seedance/SKILL.md).
license: Proprietary. See LICENSE for the terms.
---
# Seedance prompting
Prompt craft only. For the flags, the reference numbering, the locked aspect
and duration rules, and the price, read [`vsb-seedance`](../vsb-seedance/SKILL.md)
first. For the async + poll pattern read [`vsb-video`](../vsb-video/SKILL.md).
Treat Seedance as a visual content producer. Write the prompt as a shot list,
not as ad copy. The model splits the prompt into a spatial layer (who is in
the frame, where) and a temporal layer (what changes, in what order). Give it
both.
## The prompt shape
Four parts, in this order. Drop a part when the shot does not need it. Never
drop the summary.
1. **Asset bindings.** One line per attached asset: which asset, which
subject, which attributes to take, which to ignore.
2. **One-sentence summary.** Subject + location + event + genre or style +
camera.
3. **Shot list or timeline.** `Shot 1 / Shot 2` or `0-3s / 3-8s`. Each
segment: camera, subject action and expression, position in the scene,
sound.
4. **Notes that hold for the whole clip.** Camera angle, lighting, style,
audio mode, constraints such as "No subtitles."
Example, text only:
> Realistic nature documentary style, natural light. Warm afternoon, a
> grassy slope in a forest, a chubby panda cub rolls down the hill.
>
> 0-3s: The cub lies on the slope and starts to roll sideways, bending the
> grass. Sunlight comes through the trees from the upper left.
> 3-8s: The cub rolls to the lower right of the frame and stops on its
> belly. It turns its round face to the camera and makes a soft hum.
>
> Low camera, slight handheld feel, follows the cub to the lower right.
> Shallow natural depth of field. Environmental audio only: wind, grass,
> the soft plop of the roll. No BGM. No subtitles.
## Asset bindings
Number assets by their position in each list: `[Image1]`, `[Video1]`,
`[Audio1]`. Bind every one in the prompt. Never rely on a name written on the
image itself; the model confuses or duplicates the character.
- **One line per subject.** "The knight is [Image1]." "The archivist is
[Image2]." Never "Characters A and B are [Image1] and [Image2]."
- **Say what to take and what to ignore.** "Use [Image1] for the face, hair
and apron; do not use the background." "Use [Video1] for the spell-casting
action and the orbit camera move; do not use its character or scene."
- **Several images for one subject.** "Images 1 to 3 are one character: face
from [Image1], wardrobe from [Image2], back view from [Image3]. One person,
not three."
- **Pair voice with face.** "[Image1] is the host and speaks with the voice
in [Audio1]."
- **When the asset already says it, stop describing.** "Strictly follow the
actions and camera in [Video1], same order." Do not then narrate the raise
of a hand and the turn; the restatement fights the clip.
- **Reference video with no role stated** lends motion, camera and pacing.
It does not lend identity, wardrobe or the scene unless you say so.
- **Unused assets.** If an attached asset has no role, say so: "[Image4] is
n
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 2 — file references are metadata, not package contents.
vsb-setup4.83 KB
View saved version →
---
name: vsb-setup
description: >
Get a new person started with Visual Sandbox over the MCP tools, in ChatGPT,
Claude or any other chat client, one step per message. Trigger right after
the plugin is installed, when the person says "set up Visual Sandbox",
"what can you make", "get started", "how does this work", or when the first
tool call says the account is not connected. Checks the connection, turns
the person's photos, product, logo or website into saved anchors, makes one
preview keyframe, a first 5-second video and three voice takes, then opens
the canvas. Every step is optional. Uses the MCP tools only, never a shell.
license: Proprietary. See LICENSE for the terms.
---
# Get started with Visual Sandbox
Visual Sandbox runs image, video, audio, 3D and vector models on the person's
account. Each run is charged to that account. This skill takes a new person
from "installed" to a first video they like.
**One step for each message.** Do one step, show the result, and ask one
question. Every step is optional: when the person wants to skip one, skip it.
Use the MCP tools only. There is no shell and no CLI on this surface.
## 1. Check the connection
Call `get_balance`.
- **It answers.** The account is connected. Go on.
- **It refuses with "Authorization is required".** Tell the person to open
the plugin settings, press Connect and sign in to Visual Sandbox. Stop until
they come back.
- **It refuses with `email_unverified`.** Tell the person to confirm the
address from the Visual Sandbox email. Generation waits until they do.
When `balance_usd` is zero, say that runs are charged to the account and that
credit is added on visualsandbox.com. Do not quote a price for credit, and do
not offer to buy it.
## 2. Ask what to make first
Say in one sentence what the plugin makes: videos, ads, voiceovers, product
photos, music, logos and pages. Then ask what they want to make first, and
ask for what they have:
- a photo of themselves or of a person in the work,
- a product photo,
- a logo or a website,
- a script or an idea.
## 3. Turn their files into anchors
An anchor is saved once and used in every later run. Make only the ones that
the work needs.
- **A file in the chat** goes to `upload_media` as `file`. In ChatGPT, when
nothing is attached, `import_media` opens a card where they pick a file.
- **A person or a mascot:** a character sheet, then `create_character`. See
[`vsb-characters`](../vsb-characters/SKILL.md).
- **A website or a logo:** a brand theme with `extract_theme`, checked by the
person before it is saved. See
[`vsb-library-themes`](../vsb-library-themes/SKILL.md).
- **A product photo:** name it with `update_asset`, such as `acme-mug`, so
later runs find it.
## 4. One preview keyframe
Make one image at the shape of the video they want (9:16 for Reels and
TikTok, 16:9 for YouTube). It is the first frame of the video. Read
[`vsb-image-prompting`](../vsb-image-prompting/SKILL.md) before the prompt.
Use the anchors as references.
Show it and ask: "Is this the look?" Change it until they agree. Make no
video before they agree.
## 5. A first 5-second video
1. Pick the cheapest video model that takes a first frame. Call
`estimate_cost` and say the price.
2. Run it with the approved keyframe as the first frame, 5 seconds, at the
keyframe's shape. Read [`vsb-video`](../vsb-video/SKILL.md) for the model.
3. In Review mode a run of 10 cents or more waits for the person's press of
Generate: show the card, or give the review link. Never press for them.
## 6. Three voices, while the video renders
Ask whether the work needs a voice. When it does:
1. Run `audio_elevenlabs_voice_design` with a description of the voice,
`auditions: 3`, and a sample line of 100 to 400 characters in the
person's own words. That costs a few cents.
2. In ChatGPT, call `voice_studio` with the job id. The person hears the
three takes and saves one to a character. Elsewhere, give the share lin
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-short-film4.48 KB
View saved version →
---
name: vsb-short-film
description: >
Make a short film of several shots inside a chat with the Visual Sandbox
MCP tools: a story of 15 to 60 seconds with the same character in every
shot, kept as a film project between chats, joined into one cut with a
narration and a music bed. Trigger when the person asks to "make a short
film", "turn this script into a video", "a story with several scenes", "a
trailer", "a music video", "a multi-scene ad", "an episode with my
character", or "continue my film". Plans the shots, gives the total price
once, approves the keyframes before any video, then assembles the cut.
Uses the MCP tools only; for the CLI, read vsb-film.
license: Proprietary. See LICENSE for the terms.
---
# A short film
A short film is 3 to 8 shots of about 5 seconds, one character, one shape. A
**film project** keeps the brief, the script, the shot list and where each
shot stands, so the work goes on in a later chat. Video costs many times more
than an image, so every shot is approved as a keyframe before it moves.
## 0. Find or start the film
Call `list_film_projects`. When the person continues a film, `get_film_project`
returns everything, and you go on from its `stage`. Otherwise ask for the
brief (step 1), then call `create_film_project` with the `name`, the `brief`,
the `aspect_ratio`, `target_seconds` and the `characters`. It opens the
film's canvas and writes the plan there as `FILM.md`. **Send its
`sandbox_uuid` with every run of the film.**
## 1. Get the brief
Ask only for what is missing, in three questions or less.
- **The story** in one or two sentences, or the person's script.
- **The length:** 15, 30 or 60 seconds. Default: 30.
- **The shape:** 9:16 for a phone, 16:9 for a screen. Default: 16:9.
## 2. Write the script and the shot list
One row for each shot, one action for each shot. Write spoken lines without
dashes, and write numbers as words.
Save them with `update_film_project`: `script`, and `shots` with an `id`
(`shot-1`), a `title`, the `script` line and the `prompt`. When the person
approves them, set `stage: "script_ok"`.
## 3. Give the total price once
Call `estimate_cost` for one keyframe, one clip of each length you plan, and
the narration. Multiply by the number of shots and give one total. Wait for
the person's yes. Spend nothing before it.
## 4. Make the character
Read [`vsb-characters`](../vsb-characters/SKILL.md). Make one character sheet,
save it with `create_character`, and pass its pictures as references to every
keyframe. A product or a place can be a character too.
## 5. One keyframe for each shot
1. Read [`vsb-image-prompting`](../vsb-image-prompting/SKILL.md).
2. Make one keyframe for each shot, at the film's shape, with the character
pictures as references. Say first how many images that is.
3. Call `show_media` with the keyframe job ids. Change a keyframe until the
person approves the set.
4. Record each approved keyframe with `update_film_project`, `patch_shots`:
`storyboard_url` and `approved: true`. Then `stage: "storyboard_ok"`.
## 6. Move each shot
1. Read [`vsb-video`](../vsb-video/SKILL.md) at "Picking a model" and, for
spoken lines, "People who talk".
2. Run one image-to-video job for each shot, with its keyframe as the first
frame. In Review mode each run waits for the person's press: show the card
or give the review link.
3. Record each job at once with `patch_shots`: `job_id`. The shot's
`clip_url` fills in by itself when the job is done.
## 7. Narration, music and the cut
1. A narration: speak the film's script with `audio_elevenlabs_tts`, in the
character's voice when it has one. Save it with `narration_url`.
2. A music bed (optional): make one with [`vsb-audio`](../vsb-audio/SKILL.md)
and save it with `music_url`.
3. Call `assemble_film`. It joins every shot in order and lays the sound:
`audio_mode: "narration"` replaces the shots' sound with the narration,
`"mix"` lays it over, `"shots"` keeps th
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-swap-motion3.34 KB
View saved version →
---
name: vsb-swap-motion
description: >
Put a different person or character into an existing video, or make a
photo move the way a person moves in another video, with the Visual
Sandbox MCP tools: P-Video Replace swaps the subject, Kling 3.0 Motion
Control and P-Video Animate copy a motion onto a photo, and Kling 3.0 Omni
restyles or edits a reference video. Trigger when the person asks to
"swap the person in this video", "put me in this clip", "replace the
actor", "make my character do this dance", "copy this motion", "motion
transfer", "restyle this video" or "change what is in this video".
Consent first, a still check before the paid run. Uses the MCP tools only.
license: Proprietary. See LICENSE for the terms.
---
# Swap a character, copy a motion
Three jobs, three model families. Read each model's form in its tool before
the first run; the field names below are the ones to look for.
| The person wants | Tool | Inputs |
|------------------|------|--------|
| A new person in their video, with its motion and sound | `video_p_video_replace` | `video` (the source), `images` (1 to 3 photos of the new person), `instruction_prompt`, `resolution` |
| A photo that moves like a person in another video | `video_kling_v3_motion_control` | `image` (the character), `video` (the driving motion, 3 to 30 s), `prompt` |
| The same, at a lower price | `video_p_video_animate` | `image`, `video`, `instruction_prompt`, `resolution` |
| A video restyled, or edited in place | `video_kling_v3_omni_video` | `reference_video`, `video_reference_type` (`base` edits it, `feature` takes only its camera and style), `reference_images`, `prompt` |
## Before any run
1. **Consent.** Put a real person into a video only when that person agreed
to it. Ask when you are not sure. Never put a real person into a scene
that harms or mocks them.
2. **The rights to the source.** The source video must be the person's own,
or one they have the right to use.
3. **Get the files.** A file attached in the chat goes to `upload_media` as
`file`. A public video page goes to `download_video`. Use the URLs they
return.
4. **Check the price.** P-Video Replace and Animate reserve 30 seconds of
output and refund the rest; Motion Control reserves its longest length.
Call `estimate_cost`, and say the price.
## Check the look first
A swap fails when the new person's photos do not match the source's light
and angle.
1. Take a frame of the source with `extract_frame`.
2. Make one still of the new person in that frame with an image model and the
frame as a reference ([`vsb-image`](../vsb-image/SKILL.md)). It costs a few
cents.
3. Show the still. When the person agrees, use it as one of the `images`, or
as the `image` for a motion copy.
## Write the instruction
Name each person by what the camera sees, in one line each:
- "The woman on the left in the black top becomes the person in the photos."
- "The dancer keeps every step; the character's outfit stays as in the photo."
Keep the scene, the camera and the sound unless the person asks to change
them.
## Run, then hand over
1. Run the tool once. In Review mode the run waits for the person's press:
show the card or give the review link, and wait.
2. Call `show_media` with the job id in ChatGPT, or `get_job` when the
job is done.
3. Look at the frames. Say what is wrong before you offer another take.
Referenced files: 1 — file references are metadata, not package contents.
vsb-talking-avatar2.79 KB
View saved version →
---
name: vsb-talking-avatar
description: >
Make a talking video from one photo and a script with the Visual Sandbox
MCP tools: a presenter, a spokesperson, an AI avatar or a person who reads
a line, with the lips in time with the words. Trigger when the person asks
to "make this photo talk", "create my avatar", "a talking head", "an AI
spokesperson", "a presenter video", "lip sync this picture", or "make me
say this". Picks a stock voice, an ElevenLabs voice or the person's cloned
voice, asks for the price first, and shows the video in a card. Uses the
MCP tools only.
license: Proprietary. See LICENSE for the terms.
---
# A talking avatar
One photo and one script make one talking video. The length of the video is
the length of the speech. Use the MCP tools only.
## 1. Get the photo and the words
- **The photo:** one face, looking at the camera, in good light. A photo
attached in the chat goes to `upload_media` as `file`.
- **Consent:** use a photo of the person who asks, of a made-up character,
or of somebody who gave permission. Do not make a real person say words
they did not agree to.
- **The script:** about 2.5 words fit in one second. Write it without
dashes, and write numbers as words. Show the script before you spend.
## 2. Pick the voice
| The person wants | Do this |
|------------------|---------|
| Any good voice | `video/p-video-avatar` with `voice_script` and a `voice` from its list |
| A natural ElevenLabs voice | `list_voices`, then `audio/elevenlabs-tts` with `voice` |
| Their own voice | Read `vsb-clone-voice`, then `audio/elevenlabs-tts` with `my_voice` |
For the second and the third row, make the speech first. Its result URL is
the `audio` of the video run.
## 3. Pick the video model
- **`video/p-video-avatar`:** the default. It takes `voice_script` and a
stock `voice`, or an `audio` track. Use `video_prompt` for how the person
moves, such as "nods and smiles while talking".
- **`video/kling-avatar-v2`:** for a sharper, more expressive face. It needs
an `audio` track of 5 MB or less. `mode: "std"` first, `"pro"` for a final
cut.
Read [`vsb-video`](../vsb-video/SKILL.md) with `get_skill`, at "People who
talk", when the person wants a full scene and not only a face.
## 4. Price, run, show
1. Call `estimate_cost`. Tell the person the price and wait for their yes.
2. Run the speech first, if the voice needs it. Then run the video model
with the photo and the speech. In Review mode, a run of 10 cents or
more waits for the person's press of Generate: show the card with
`show_media`, or give the review link. Never press it for them.
3. Call `show_media` with the job ids. Give the `sandbox_url`.
## Rules
- One video per script. Change the script, not the model, when a word
sounds wrong.
- For captions or a vertical cut, read `vsb-edit-video`.
Referenced files: 1 — file references are metadata, not package contents.
vsb-ugc-ad3.9 KB
View saved version →
---
name: vsb-ugc-ad
description: >
Make a creator-style UGC video ad for a product with the Visual Sandbox MCP
tools: a vertical 9:16 clip of one person who shows, uses or talks about
the product, for TikTok, Instagram Reels or YouTube Shorts. Trigger when
the person asks for a "UGC ad", "creator ad", "testimonial video",
"unboxing video", "talking head ad", "TikTok ad for my product" or "a
person holding my product". Plans a script, approves the first frame as an
image, then animates it with speech. Uses the MCP tools only.
license: Proprietary. See LICENSE for the terms.
---
# A UGC video ad
A UGC ad looks like a real person filmed it on a phone. One person, one
product, one message, 9:16, 5 to 15 seconds. The person talks to the camera,
or shows the product while a voice talks.
Use the MCP tools only. Video is the expensive part, so this skill makes the
look right as a still image first, and spends on video once.
## 1. Get the brief
Ask only for what is missing. Never ask more than three questions.
- **The product.** A photo is best. Pass a public `https` URL. Give a photo
attached in the chat, or a local file, to `upload_media` first.
- **The hook.** The one thing the ad must say, such as "it fixed my skin in
a week".
- **The format.** Pick one: a talking head, a selfie walk-and-talk, an
unboxing, or a before-and-after. When the person does not say, use a
talking head.
## 2. Write the script
Write 2 to 4 short lines that one person can say in the clip length. About
2.5 words fit in one second.
- Line 1 is the hook. It names the problem or the result.
- The middle line shows the product in use.
- The last line tells the viewer what to do.
Do not use dashes in the spoken lines. A speech model reads a dash badly.
Write numbers as words. Show the script to the person before you spend.
## 3. Make the first frame as an image
1. Read [`vsb-ugc-people`](../vsb-ugc-people/SKILL.md) with `get_skill`. It
has the two UGC formats, the slot order and the words that stop a face
from looking plastic.
2. Call `list_models` with `modality: "image"` and pick the model that pack
recommends. Call `get_model` for its fields.
3. Call `generate` at 9:16 with the product photo as a reference. Name the
work with `sandbox_name`, such as "Serum UGC ad", and send that same name
on every later call.
4. Call `get_job` after `eta_seconds` and look at the frame. Check the hands,
the label on the product and the face.
5. Show the frame. Change it until the person approves it.
## 4. Animate it with speech
1. Read [`vsb-video`](../vsb-video/SKILL.md) with `get_skill`, at the section
"People who talk". It says which model speaks in one pass and which needs
a voice track first.
2. Call `list_models` with `modality: "video"`. Pick an image-to-video model
that speaks, from that section.
3. Call `get_model`, then `estimate_cost`. Tell the person the price and wait
for a yes.
4. Call `generate` with the approved frame's URL as the start image and the
script as the spoken line.
5. Call `get_job` after `eta_seconds`. A video takes one to three minutes.
`get_job` returns four frames, so check them before you report.
When the person wants one voice across several clips, make the voiceover
first with [`vsb-audio`](../vsb-audio/SKILL.md) and follow the lip-sync path
in `vsb-video`.
## 5. Hand it over
Give the person the `share_url` of the video and the `sandbox_url` of the
canvas. Offer one next step: a second hook on the same frame, which costs one
video run and no new image.
## Rules
- One approved frame before any video run. A video costs many times more
than an image.
- Never run a video twice to check it. Read the four frames `get_job` sends.
- Keep the product label sharp. If the model changes the label, say so and
offer a new frame, not a new video.
- When a run is refused for want of credit, say the balance is too low, and
follow what the server instructions say about credit.
Referenced files: 1 — file references are metadata, not package contents.
vsb-ugc-people9.61 KB
View saved version →
---
name: vsb-ugc-people
renamed_from: ugc-people
description: >
Prompt AI image models to produce UGC-style photos of a single person for
9:16 paid ad creative (TikTok, Reels, Shorts). Covers two distinct formats —
selfie / phone-camera POV (handheld, hook shot) and locked-off talking-head
testimonial (single frame meant to look like a real creator on a tripod).
Trigger when the user asks for "UGC ad", "AI influencer photo", "creator
selfie", "talking head ad frame", "ugc style", "fake iPhone photo of a
person", or is about to run `vsb run image/<slug>` for a person shot
intended to look like real UGC. Pairs with the `vsb-nano-banana` skill for
prompt craft and the `vsb-image` skill for picking a model.
license: Proprietary. See LICENSE for the terms.
---
# UGC people for 9:16 ad creative
UGC ads succeed when the image **does not look AI**. Modern image models are
biased toward "professional photography" — clean studio light, smooth skin,
symmetric framing. UGC is the opposite: phone camera, imperfect, candid. Every
rule below pushes the model away from its default and toward something a real
creator would post.
Two formats, two rule sets. Pick one before you start writing the prompt.
## The two formats
| | **Selfie / phone POV** | **Talking-head testimonial** |
|---|---|---|
| Use case | Hook shot, scroll-stopper, "real moment" frame | Testimonial frame, problem/solution, single-take ad |
| Camera | Handheld, micro-jitter | Locked-off, no pan, no zoom |
| Eye line | Slightly **above** subject's eye, angled down | Subject's eye level, dead-on |
| Framing | Medium close-up to mid-shot, off-center OK | Medium close-up (chest to head), centered |
| Distinctive cues | Hand holding phone in frame, mirror, reflection | Static room, single light source, gesture script |
| Full rules | `references/selfie-pov.md` | `references/talking-head.md` |
Open the matching reference file before writing the prompt — it has the filled
template, the verbatim worked examples, and the failure modes specific to that
format.
## The slot order
Every working UGC people prompt fills these slots, in this order. Skipping a
slot lets the model default to its training median (stocky, smooth, posed).
1. **Device token** — `"shot on iPhone 15 Pro, front camera feel, not DSLR,
not studio quality"`. See § "The iPhone token rule" below.
2. **Subject** — age range, ethnicity, build, mood. Specific: `"early-to-mid
20s, mixed-heritage, freckles across nose, messy low bun"`. Not: `"a young
woman"`.
3. **Wardrobe** — named items, fit, fabric: `"short-sleeve beige ribbed
scoop-neck top"`, `"white fitted long-sleeve crop top, light blue
leggings"`.
4. **Action** — micro-gesture, mid-action. `"tucking hair behind ear"`, `"hand
loosely near chin"`, `"mid-laugh, phone held naturally"`. Static A-pose
kills UGC realism.
5. **Location** — specific room, time of day, named light source: `"open
luxury kitchen interior, polished concrete flooring, morning light from
window camera-left"`.
6. **Lighting** — soft, natural, named. Two light sources (window + lamp) is
a high-fidelity trick. Never `"studio lighting"`.
7. **Camera artifacts** — `"slight motion softness, mild grain, natural
exposure, slight lens distortion from front camera, no HDR or cinematic
color grading"`.
8. **Vibe line** — one sentence at the end: `"candid, unposed, natural
lifestyle selfie — looks like a quick real moment, not staged or
professionally shot."`
Then end with a negative block (see § "What to avoid").
## The iPhone token rule
The single most load-bearing line in any UGC prompt:
```
shot on iPhone 15 Pro, front camera feel, not DSLR, not studio quality
```
Why it works: every image model has been trained on millions of photos
tagged `iPhone`. The token activates the right cluster of training data
(short focal length, front-camera color science, soft auto-HDR look) and
the `not DSLR, not studio quality` half explicitly suppresse
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 4 — file references are metadata, not package contents.
vsb-vector12.4 KB
View saved version →
---
name: vsb-vector
description: >
Make, edit and animate SVG files with Visual Sandbox. Trigger when the
user asks for an SVG, a vector, a logo, an icon, an animated logo or
loading state, a cut file (Cricut, laser, CNC, embroidery), or wants to
"vectorize" a raster image via the vsb CLI. `vector/quiver-arrow-2` is
the default: it writes an SVG from a prompt, vectorizes a raster, edits
an SVG you already have, and animates one into a loop. For a detailed
illustration, generate a flat raster with an image model first and
trace it with `vector/recraft-vectorize`. Always ask the user how many
colours the SVG must have before you run anything.
license: Proprietary. See LICENSE for the terms.
---
# Vector generation with vsb
> **On the MCP surface?** If the `visual-sandbox` MCP tools are in your
> tool list, use `generate` and `get_job` instead of the shell commands
> below. The route choice and the prompt craft on this page still apply.
> See `vsb` → Two ways to run.
Five live models. Verify with `vsb models --modality vector --json` before
you trust this table.
| Slug | Input | Cost | Good for |
|------|-------|------|----------|
| `vector/quiver-arrow-2` | prompt, or prompt + images, or image only, or `svg` (+ prompt) | ~$0.07 an icon, ~$0.60 a dense illustration, ~$0.03 an edit or an animation | **The default.** Icons, glyphs, monoline marks, simple logos. The only family that edits and animates an SVG you already have. |
| `vector/quiver-arrow-2-telos` | same as Arrow 2 | ~$0.10 an icon, ~$0.90 a dense illustration, ~$0.04 an edit or an animation | Arrow 2 plus a frontier reasoning model. A diagram whose logic must hold, an infographic from real figures, a mark that must obey a page of brand rules. Reads about eight times as much brief. |
| `vector/quiver-arrow-1.1` | prompt, or prompt + reference images, or image only | $0.25 a generate, $0.19 a vectorize, flat | Only when a dense illustration must land on a known flat price. Cannot edit and cannot animate. |
| `vector/recraft-v4.1-svg` | prompt only, plus `aspect_ratio` | ~$0.05 per SVG, flat | Recraft. A new SVG from a prompt at one low price, even for a dense illustration, with Recraft's composition and colour. **No reference images, and it cannot edit or animate.** About 20 seconds. Commercial use allowed. |
| `vector/recraft-vectorize` | one raster image | ~$0.02 per SVG | Tracing any raster into editable paths. The second half of the illustration route. |
**The Arrow 2 family is token-billed**, so the price moves with how much
drawing the model does. `vsb pricing` shows a ceiling, and the user is
charged for what the model actually produced, never more than the quote.
Arrow 1.1 and Recraft V4.1 SVG are the flat-price generators.
**Do not pick Telos for an icon.** It draws the same shapes as Arrow 2 and
costs half again as much. Pick it when the thinking is the hard part.
Start every run in a **background shell** (Claude Code: `run_in_background:
true`). All five models are sync. Recraft Vectorize finishes in seconds and
Recraft V4.1 SVG in about 20; the Arrow 2 family takes about a minute, and
Telos longer. Rules in
`vsb` → Background generations.
## Ask first, then route
Ask these two questions in one message before any run:
1. **How many colours?** One, two to three, four to six, or full colour.
2. **Background?** Transparent, or a solid colour.
If the user says "whatever", use four to six colours on a white
background and say so.
Then pick the route:
| The request is | Route |
|----------------|-------|
| An icon, a glyph, a monoline mark, a simple logo, one to three colours | **A. Quiver direct** |
| A scene, a character, a mascot, a poster, shading, four or more colours, or "detailed" | **B. Raster first, then vectorize** |
| The user already has a raster (PNG, JPG, a sandbox node) | **C. Vectorize only** |
| The user has an SVG and wants it changed ("recolour it", "thicken the strokes", "add a badge") | **D. Edit an SVG** |
| The uPreview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-video29.8 KB
View saved version →
---
name: vsb-video
renamed_from: video
description: >
Generate or edit video with Visual Sandbox. Trigger when the user wants
text-to-video, image-to-video, or motion-control video via the vsb CLI.
Always uses async + status polling — video runs take 30s–3min. Verify slugs
with `vsb models --modality video --json`. Read it before any video in which
people speak: it picks the speech and lip-sync path, and the price of each.
license: Proprietary. See LICENSE for the terms.
---
## Default model in ChatGPT
For a video, call `video_p_video_2`. It makes a clip from a prompt, a first frame or an audio file, with sound.
Use another model only when the person names one or asks for what P-Video 2 cannot do.
This rule comes before the defaults in the table below.
# Video generation with vsb
> **On the MCP surface?** If the `visual-sandbox` MCP tools are in your
> tool list, use `generate` and `get_job` instead of the shell commands
> below. The model choice and the prompt craft on this page still apply.
> See `vsb` → Two ways to run.
Video runs are slow (30s–3min). **Always use `--async`**, then poll with `vsb status`. Don't block a sync `vsb run` on a 2-minute job — the CLI will sit there and re-poll, blowing your terminal session.
Agents: don't block the conversation on a running job either — start it, keep talking, check later. Put the wait loop in a **background shell** (Claude Code: `run_in_background: true`), so the harness notifies you when the job lands. `vsb status` never waits on its own. Rules in `vsb` → Background generations.
## Rules for every paid video run
- **One request is one paid attempt.** A complaint, "fix it", a failed job or
`retryable: true` is not a yes for another run. Ask before the next take.
- **One keyframe image for each shot first.** Make it from the anchors (the
character, the theme, the product photo), at the video's shape, and get a
yes on it before any video. Say how many images that is. Skip it when the
person gives the first frame or asks for text to video.
- **A timeout is not a failure.** A `queued` or `processing` job still runs.
Check the job you know before any new run, and claim no result before the
job is `completed`.
- **Review mode (MCP).** A run of 10 cents or more can answer
`awaiting_approval`. In ChatGPT, call `show_media`: the card shows the
price and the Generate button. Elsewhere, give the `share_url`. Never press
Generate for the person, and never request the run again while it waits.
- **A person in the video** must have agreed to it. A cloned voice needs the
speaker's consent.
## The async + poll pattern
```bash
# 1. Submit
JOB=$(vsb run video/veo-3.1-fast \
--prompt "a tiger walking through tall grass at golden hour, camera tracks alongside" \
--aspect_ratio 16:9 \
--duration 8 \
--async --json | jq -r '.job_id')
echo "Job: $JOB"
# 2. Wait in a BACKGROUND shell. vsb status never waits, so loop until the
# job is terminal. The shell's exit is the "done" signal.
until vsb status "$JOB" --json 2>&1 | jq -e '.status | IN("completed","failed","cancelled","error")' > /dev/null; do sleep 10; done
vsb status "$JOB" --result --download "./out/{request_id}.{ext}" --json > "/tmp/vsb-$JOB.json" 2>&1
# 3. On the notification, read /tmp/vsb-$JOB.json. Non-blocking peek any time:
vsb status "$JOB" --json | jq -r '.status'
# 4. Look at it before you report it: nine frames, first to last, in one image.
# Pass the downloaded file, or the output URL from the JSON.
vsb video frame ./out/"$JOB".mp4 --json # → out/<job>-frames.jpg — read it
```
Read the contact sheet before you tell the user the clip is done. A completed
job can still hold a frozen subject, a warped face or the wrong action.
`--at end` gives the last frame at full size, which is also the start frame for
the next shot (vsb critical rule 15).
Status can be `queued | in_progress | completed | failed | cancelled`. Open the
finished clip for the user with `open <file>` (the defPreview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
vsb-video-to-reels4.31 KB
View saved version →
---
name: vsb-video-to-reels
description: >
Cut a long video into short vertical clips with the Visual Sandbox MCP
tools: find the best passages in a podcast, an interview, a webinar or a
talk, cut and reframe them to 9:16 in one render, and burn word-timed
captions from the source's own transcript. Trigger when the person asks to
"turn this video into reels", "make shorts from my podcast", "find the best
clips", "clip this interview", "repurpose this video for TikTok", sends a
YouTube, TikTok, Instagram or X link, or attaches a long video and asks for
short ones. Transcribes, proposes the passages, and cuts only the ones the
person picks. Uses the MCP tools only.
license: Proprietary. See LICENSE for the terms.
---
# Long video to reels
The transcript finds the passages, the person picks them, and one render cuts
them. You pick the moments; `cut_and_reframe_video` only cuts what it is
given. Use the MCP tools only.
## 1. Get the video
- **A public page** (YouTube, TikTok, Instagram, X): keep the link for step 2,
and call `download_video` with it for step 4. A site can refuse the server;
then ask the person to attach the file. Use only video the person has the
right to use.
- **A file in the chat** goes to `upload_media` as `file`. Use the `url` it
returns.
The source can be up to 2 hours long.
## 2. Transcribe it
- **A public page:** call `transcribe_link` with the link. A page with
captions, such as most YouTube videos, costs nothing. A page without
captions ends the run with no charge. Then say that Scribe charges for the
real length, and on a yes call `transcribe_link` again with
`use_captions: false`.
- **A file:** run `audio/scribe` with the file URL. Call `estimate_cost` with
the length first, and say the price.
`get_job` returns the transcript as timed lines, `[12.3-18.0] The sentence.`
Keep the job id: the captions in step 4 read the words from it.
## 3. Propose the passages
A passage with a hook, the context and a payoff beats a quotable line with no
end. Default to one passage of 30 to 60 seconds; offer up to five.
- It opens with a strong line in its first 3 seconds: a claim, a question or
a surprise.
- It ends at the end of a thought, not in the middle of a sentence.
- It stands alone. A viewer who did not see the rest understands it.
- A passage can join two or three parts of the source, in order or not, when
the joined parts still say what the speaker meant.
Cut at a pause. A pause of 400 ms or more is a clean cut; take care between
150 and 400 ms; below 150 ms, keep more context. **Never join parts so that a
speaker seems to say something they did not say.**
Show a list: the start and end seconds of each part, the length, and the
first line. Wait for the person to pick.
## 4. Cut, reframe and caption in one run
Call `cut_and_reframe_video` once for each reel:
- `video`: the source URL from step 1.
- `segments`: the parts in the order the reel plays them, each with `start`
and `end` in source seconds. Up to 40 parts and 5 minutes in all, each at
least 0.15 s.
- `framing` for each part: `center_crop` for one person in the middle,
`pad` when two people sit far apart, or `crop` with `crop_x`, `crop_y`,
`crop_width` and `crop_height` in source pixels to follow one speaker.
- `aspect_ratio`: `9:16` by default.
- `captions`: one of the six looks of `add_captions`, with `transcript` set
to the job id of step 2: `highlight` (large capitals, the spoken word lit
up), `hormozi`, `beast`, `classic`, `box` or `plain`. Each look has its own
place and number of words. Use `none` when the source already has captions
burned in.
The cut is free. Captions from the source transcript need no second
transcription. Send the same `sandbox_name` on every run, such as
"Podcast ep 12 reels".
To change the caption look, run `cut_and_reframe_video` again with the same
parts and another look. The cut is free, and the old captions do not stay on
the new reel. The looks
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.