---
name: popcorn
description: Make and change videos with Popcorn, the AI video production team for brands — explainers, product films, recurring branded series, thought leadership, UGC-style ads, voice-cloned presenters, music videos, edits of YouTube clips and videos from the user's own footage — by working with the user's Popcorn Showrunner (Pop), the AI producer that runs their project. Use this skill whenever the user asks to make, generate, edit, or iterate on a video with Popcorn; to use their saved characters, sets, or props (often written as `@Name`); to talk to, check on, or start a Popcorn project or its Showrunner; or to check their Popcorn credits or plan. Drives the Popcorn MCP server, keeps polling the project chat until the Showrunner answers, and always shares the final video URL plus the studio link.
---

# Popcorn — short-form video through the user's Showrunner

Popcorn is the AI video production team for brands. It turns a request, or the products, expertise and content the user already has, into a finished, edited video (typically 30–90 seconds): script → script review → shots (generated or the user's real footage) → voice → music → graphics and captions → final cut.

Every Popcorn user works with a **Showrunner**: an AI producer that runs a **project** (a brand, a show, a channel) and keeps its creative direction, characters, and history. **You make and change videos by talking to the Showrunner**, exactly as the user would in the project chat. The Showrunner plans the video, asks questions when it needs to, commissions production, and reports back with the finished video. No tool drives the video studio directly.

You reach Popcorn through the **Popcorn MCP server** (`https://api.popcorn.co/mcp`). Every connection has all of these tools:

Showrunner projects — how videos get made and changed:

- `list_projects(limit?, offset?)`
- `create_project(title?)` — creates a real project; confirm with the user first
- `get_project(project_id)`
- `get_project_chat_threads(project_id)`
- `send_message_to_project_showrunner(project_id, message, thread_id?)`
- `get_project_chat_messages(project_id, thread_id?, limit?, before_index?)`

Movies and account — read-only:

- `get_movie(id)`, `get_movie_messages(id, limit?)`, `list_movies(limit?, offset?)`
- `get_balance()`, `get_user_plan()`

**Retired — never call:** `create_movie`, `send_movie_message`, `search_elements`. They are still listed, marked DEPRECATED, only so older agents get redirected. They do nothing. If you call one by mistake, follow the steps in its error message.

Files are not a tool — there is no upload *tool*, because MCP tool arguments are JSON. Attaching a file is a plain HTTP call plus an ordinary message; see "Attaching files" below. Do not conclude from your tool list that you cannot send one.

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.

A **project** is not a **movie**. A project is the ongoing body of work its Showrunner runs, with a project id; a movie is one video the Showrunner made, with a movie id. The ids are never interchangeable.

## What you can ask for

| Format | One-line request 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." |

The Showrunner handles everything else — video models, voices and voice cloning, music, motion graphics, captions, text overlays, composition, clips from YouTube and other video links. You don't invoke any of it separately.

## The loop you must follow

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

### Step 1 — Find the project

Call `list_projects()`.

- **One project:** use it.
- **Several:** pick the one whose title matches what the user is talking about, or ask which one.
- **None:** tell the user they need a project and offer to start one. Call `create_project(title?)` only after they agree, and only once — every call creates another project. See "Starting a new project" below.

Then call `get_project(project_id)`. If `showrunner.onboardingStatus` is not `"complete"`, the Showrunner is still setting up. It can usually take a message anyway; tell the user it may be slower to respond.

### Step 2 — Send the full request

Call `send_message_to_project_showrunner(project_id, message)` with the user's request in full. Restate it with as much specificity as you have:

- The format (reaction / UGC / mash-up / explainer / music video / …)
- Length in seconds, if the user has a preference
- Platform or orientation (TikTok/Reels/Shorts → vertical; YouTube → landscape; Instagram feed → square)
- Every source URL the user mentioned (YouTube, TikTok, Instagram — Popcorn downloads them)
- Saved characters, sets, and props **by name**, e.g. "use @Wizard Cat as the host". The Showrunner finds them in the user's library itself.
- Tone, voice, and style notes
- URLs of any files the user gave you (see "Attaching files")

The call returns as soon as the message is accepted. **Never hold it open waiting for a reply**, and don't resend it: messages queue in order, so a turn already running needs no retry.

Tell the user: "Sent your request to your Showrunner — I'll keep checking for its reply."

### Step 3 — Poll the project chat

Call `get_project_chat_messages(project_id)` **every 20–30 seconds** until a new `assistant` message appears after yours.

- **Actually call the tool every time you say you will.** If you say "checking" or "still working on it", your very next action must be a `get_project_chat_messages` call. Do not narrate polling without polling.
- **Relay what the Showrunner says.** If it asks a question or proposes a plan, put it to the user, then send their answer with `send_message_to_project_showrunner` and resume polling. Don't answer for the user unless the answer is already clear from what they told you.
- **A reply is not the end.** Producing a video takes several minutes. If the Showrunner says it has started production, keep polling: it posts progress and, when it's done, the finished video. There is no upper bound — some videos take 10+ minutes. Stopping early means the user has to ask "is it done yet?", which is a failure for this skill.

### Step 4 — Hand back the result

When the Showrunner reports a finished movie, call `get_movie(id)` with the movie id it names (if it doesn't name one, `list_movies(limit: 5)` lists the newest first).

**`status: "completed"` with `video_url`:** done. Share both links:

> "Your video is ready: `<video_url>`
>
> Open it in the studio to tweak it: `<studio_url>`"

**`status: "completed"` WITHOUT `video_url` (this happens):** production stopped before the final file. Do **not** report success. Ask the Showrunner to finish ("The latest video completed without a final file — can you finish composing it?") and go back to Step 3.

**`status: "failed"`:** tell the user what the `error` says and ask whether they want the Showrunner to try again or change the request.

## Changing a video

Send the change to the Showrunner, the same way the user would type it in the project chat, then go back to Step 3:

```
send_message_to_project_showrunner(project_id, "In the latest video, regenerate scene 2 with a wider shot")
send_message_to_project_showrunner(project_id, "Swap the background music for something more upbeat")
send_message_to_project_showrunner(project_id, "Move the scene to @CoffeeBar and keep @Luna as the host")
```

Messages you send appear in the project chat labelled **Sent via MCP**. When one asks for a change to an existing video, the Showrunner goes ahead without the review card the user would see in the web chat — so agree on the change with the user before you send it, especially anything that re-renders a lot (and costs credits).

## Starting a new project

Only when the user has no project, or explicitly asks for a new one — and only after they confirm:

1. `create_project(title?)` — the title is the brand, show, or channel name (optional, up to 120 characters). It returns the project and its Showrunner, like `get_project`; `onboardingStatus` is usually `"pending"`.
2. The new Showrunner first **interviews the user** in the project chat to learn the brand or show. Poll `get_project_chat_messages`, relay its questions, and send the answers back.
3. Once the interview is done, make videos with the loop above.

If `create_project` fails, tell the user to try again shortly or to create the project at `https://www.popcorn.co/projects/new`.

## Threads

`send_message_to_project_showrunner` and `get_project_chat_messages` both default to the project's most recently active thread, which is almost always what the user means. Keep passing the same `thread_id` the send returned while you poll. Use `get_project_chat_threads(project_id)` only when the user wants a specific past conversation. Page into older history with `before_index` = the previous response's `next_before_index`.

## Past movies, credits, and plan

- **Past movies:** `list_movies(limit, offset)` returns a `movies` array (`id`, `title`, `stage`, `created_at`, `updated_at`) plus `total` and `has_more`. `stage="complete"` means finished. `get_movie_messages(id)` reads a movie's production log, if the user wants to know what happened during production.
- **Credits:** before asking for something long or expensive, or when the user asks, call `get_balance()` → `{ credits, warning?, top_up_url }`. If `credits` is missing, the balance service is temporarily down — share `top_up_url` and say so.
- **Plan:** `get_user_plan()` → `{ subscription, manage_url, message? }`.

## Attaching files

MCP tool arguments are JSON, so you cannot hand a file to a tool. Upload it over plain HTTP first, then put the URL in your message to the Showrunner.

```bash
curl -sS -F "file=@/path/to/reference.png" https://api.popcorn.co/api/v1/uploads
# → { "url": "...", "filename": "...", "mime_type": "...", "size_bytes": 51244 }
```

No credentials needed. Then send the `url`, saying what the file is and how it should be used:

```
send_message_to_project_showrunner(project_id, "Reference photo for Mara — use it as her look: <url>")
```

The Showrunner fetches the URL itself. Accepted: images, video, audio, PDF, plain text, Markdown — up to 25 MB, one file per request. For several files, repeat the upload and reference all the URLs in a single message.

Do this whenever the user hands you a file they want Popcorn to use: a reference photo for a character, a product shot, a brand style guide, a voice sample to clone, a script, a rough cut. Those are examples, not the allowed set.

If you have the file, upload it — a written description of an image is not a substitute, because the Showrunner cannot see what you saw.

## Anti-patterns (do not do these)

- ❌ Calling `create_movie`, `send_movie_message`, or `search_elements`. They are retired and do nothing.
- ❌ Calling `create_project` without the user's OK, or calling it again because the first call was slow. Every call creates another project.
- ❌ Saying "I'm checking" without actually calling `get_project_chat_messages` on your next turn.
- ❌ Stopping after the Showrunner's first reply when it has only started production.
- ❌ Holding `send_message_to_project_showrunner` open, or resending a message because no reply came yet.
- ❌ Sending a vague request like "make me a video." Restate what the user asked with as much specificity as you can.
- ❌ Answering the Showrunner's questions yourself when the user hasn't told you the answer.
- ❌ Reporting success because `status: "completed"` came back without checking that `video_url` exists.
- ❌ Returning a movie without its `studio_url`.
- ❌ Polling faster than every 20 seconds (wasted tokens, no faster results).
- ❌ Passing a movie id as `project_id`, or a project id to `get_movie`. They are different entities.
- ❌ Describing a file's contents in words when you could have uploaded it. Upload and send the URL.

## Quick reference

```
0. If the user gave you a FILE: POST it to https://api.popcorn.co/api/v1/uploads
   (multipart, one `file` field, no auth) → read `url` → include it in the message below.
1. list_projects()                    → one: use it · several: pick or ask · none: offer create_project (confirm first)
2. get_project(project_id)            → onboardingStatus !== "complete" → warn it may be slow
3. send_message_to_project_showrunner(project_id, "<full request: format, length, platform,
   source URLs, @names, tone, file URLs>")   → returns at once { thread_id, … }
4. Loop:  wait 20–30s → get_project_chat_messages(project_id, thread_id)
          new assistant message → relay it; question? → ask user → send answer → keep looping
          production started    → keep looping
          finished movie        → get_movie(id)
5. get_movie: completed + video_url  → share video_url AND studio_url
              completed, no video_url → ask the Showrunner to finish → back to 4
              failed                  → tell the user the error
6. Changes: confirm with the user → send to the Showrunner → back to 4
```
