---
name: popcorn
description: Create AI-generated short-form videos ("movies") with Popcorn — reaction videos, UGC ads, mash-ups with downloaded YouTube/TikTok/Instagram clips, voice-cloned talking heads, music videos, explainers, and more. Use this skill whenever the user asks you to make, generate, edit, or iterate on a video using Popcorn. Drives the Popcorn MCP server (tools `create_movie`, `get_movie`, `send_movie_message`, `get_movie_messages`, `list_movies`, `get_balance`). Always polls until the movie is ready and always shares the final video URL plus the studio link with the user.
---

# Popcorn — short-form video creation skill

Popcorn turns a single natural-language brief into a finished short-form video (typically 30–90 seconds): storyboard → AI-generated clips → narration → music → lip-sync → captions → final composition.

You drive Popcorn through the **Popcorn MCP server** (`https://api.popcorn.co/mcp`). The server exposes six tools:

- `create_movie(brief, duration?, orientation?, style?)`
- `get_movie(id)`
- `send_movie_message(id, message)`
- `get_movie_messages(id, limit?)`
- `list_movies(limit?, offset?)`
- `get_balance()`

If the user has not connected their MCP client to Popcorn yet, point them at `https://popcorn.co/docs/mcp`. Otherwise, assume the tools are available.

## What you can build

| Format | One-line brief shape |
|---|---|
| **Original AI short film / explainer / ad** | "30-second cinematic explainer about quantum computing for social media." |
| **Reaction video** | "10-second reaction video to `https://youtu.be/<id>` — host laughing and pointing at the screen." |
| **UGC-style talking head** | "30s UGC ad for <product>, casual woman in her kitchen, voice-cloned from `<voice-sample-url>`." |
| **Music video** | "60-second moody synthwave music video about late-night drives, original instrumental." |
| **Mash-up (AI + downloaded source)** | "15s clip starting at 1:23 of `https://youtu.be/<id>` with new narration over it, then a 5s AI-generated outro." |
| **Scene clip** | "Clip the dramatic confession scene from `https://youtu.be/<id>` (auto-detect) and add Spanish captions." |

Capabilities included automatically (you do not need to invoke them separately): video generation (Kling, Veo, Sora, Seedance, HeyGen avatars), text-to-speech (ElevenLabs), voice cloning, voice design, lip-sync, music generation, captions, animated text overlays, ffmpeg-based composition, transitions, scene clipping, and downloads from 1700+ video sites (YouTube, TikTok, Instagram, etc.).

## How to make a movie — the loop you must follow

This is the most important section. Many agents claim they are polling and then silently stop. Do not be that agent.

### Step 1 — Start the movie

Call `create_movie` with a **specific** brief. More specificity = better results. Always include:

- The format (reaction / UGC / mash-up / explainer / music video / etc.)
- Duration in seconds (if the user has a preference)
- Source URLs the user mentioned (YouTube, TikTok, Instagram links — Popcorn will download them)
- Any voice/style/character notes the user gave
- Orientation if the user mentioned a platform (TikTok/Reels/Shorts → portrait; YouTube → landscape; Instagram feed → square)

`create_movie` returns immediately with `{ id, status: "running", created_at }`. **The movie is now running asynchronously for several minutes.** Do **not** keep the tool call open or assume the movie is finished.

Tell the user:
> "Started your movie. ID: `<movie_id>`. You can also follow along in the studio: `https://popcorn.co/movie-chat/<movie_id>`. Polling for progress — typical wait is 3–10 minutes."

### Step 2 — Poll until terminal

Call `get_movie(id)` **repeatedly** until status is `completed` or `failed`. Polling rules:

- **Poll every ~60 seconds** while running. Don't poll faster than every 30s, don't go longer than ~90s between polls.
- **Actually call the tool every time you say you will.** If you say "checking status" or "still working on it," your very next action must be a `get_movie` call. Do not narrate polling without polling.
- Between polls, you may optionally call `get_movie_messages(id)` to surface what the agent is doing right now (e.g. "writing the script", "rendering scene 2") so the user has something interesting to read while waiting.
- Keep polling. There is no upper bound — some movies take 10+ minutes. If you stop polling early, the user has to ask "is it done yet?" — that's a failure mode for this skill.

### Step 3 — Handle the terminal state

When `get_movie` returns:

**`status: "completed"` with `video_url`:** The movie is done. Share the result like this:

> "Your movie is ready: `<video_url>`
>
> Open it in the studio to tweak or iterate: `https://popcorn.co/movie-chat/<movie_id>`"

**`status: "completed"` WITHOUT `video_url` (this happens):** The movie agent stopped before producing the final file. Do **not** report success. Instead, send a message and resume polling:

```
send_movie_message(id, "I notice the run completed without a final video. Can you finish composing the movie and produce the video file?")
```

Then go back to Step 2 and keep polling.

**`status: "failed"`:** Read the `error` field. Tell the user what failed and ask if they want to retry with a different brief.

## Iterating on a movie

After a movie completes, the user will often want to tweak it. Use `send_movie_message` exactly the same way as if they were typing in the studio chat:

```
send_movie_message(id, "Regenerate scene 2 with a wider shot")
send_movie_message(id, "Swap the background music for something more upbeat")
send_movie_message(id, "Also add Spanish captions")
```

`send_movie_message` returns immediately. **Then go back to Step 2 and poll** until the new turn finishes — same rules apply.

If the response is "another turn is already running" / `CONFLICT`, your message was queued automatically. Wait and poll. Don't retry.

## Sharing the studio link — every time

Every movie has a permanent studio URL: `https://popcorn.co/movie-chat/{movie_id}`. **Always share this link** — both right after `create_movie` returns and again when the movie completes. The user may want to open the studio to:

- Watch progress visually
- Edit the storyboard, script, voices, or music directly
- Continue iterating outside the chat

## Listing past movies

If the user asks "what did I make last week?" or wants to revisit something, call `list_movies(limit, offset)`. The response has a `movies` array, plus `total` and `has_more` for pagination. Each movie has `id`, `title`, `stage`, `created_at`, `updated_at`. `stage="complete"` means the video is finished.

## Checking credits

Before starting an expensive movie (long, multiple iterations) or when the user asks about their balance, call `get_balance()`. It returns `{ credits, warning?, top_up_url }`. If `credits` is missing the balance service is temporarily down — surface the `top_up_url` and let the user know.

## Anti-patterns (do not do these)

- ❌ Saying "I'm polling for status" without actually calling `get_movie` on your next turn.
- ❌ Reporting the movie as done because `status: "completed"` came back without checking that `video_url` exists.
- ❌ Returning the raw movie `id` without the studio URL.
- ❌ Polling faster than every 30 seconds (wasted tokens, no faster results).
- ❌ Giving up after 2–3 polls. Movies routinely take 5–10 minutes.
- ❌ Calling `create_movie` with a vague brief like "make me a video." Always restate what the user asked with as much specificity as you can.

## Quick reference

```
1. create_movie(brief, duration?, orientation?, style?)   → returns { id, status: "running", created_at }
2. Share studio link: https://popcorn.co/movie-chat/{id}
3. Loop:  sleep ~60s  →  get_movie(id)
          if status === "running"   → continue loop
          if status === "completed" && video_url  → SUCCESS, share both URLs
          if status === "completed" && !video_url → send_movie_message asking it to finish, continue loop
          if status === "failed"    → tell user the error
4. To iterate: send_movie_message(id, "...") → go back to step 3
```
