← Plugin catalog
Creativity
Butter
Butter v1.0.1
Butter is the video editor that lets you and your team collaborate with AI. The Butter MCP can pull in your assets and context and help you create ads with professional motion. You can continue to edit any Butter project in the browser with full manual control: change copy, move things around on canvas, retime on the timeline, and more. Use AI to help you move fast, and never lose control or quality.
Language: English · Automatically detected from descriptions.
Package details
Publisher declarations from the archived package. These are separate from our research and the live service's terms.
- Package author
- Butter
Package observed Sep 30, 2026.
Files & skills
File archives
Plugin package12 files · 8.54 KBBrowse files →
Skill instructions
butter-ad-fatigue9.34 KB
---
name: butter-ad-fatigue
description: Find ads starting to fatigue and make their replacements. Use when the user asks which ads are declining, mentions creative fatigue, or wants replacements for tiring ads.
---
# Ad Fatigue
Find ads starting to fatigue and make their replacements.
## Before you start
Anything the user has already told you, or that the sources under "Gather first" already cover, is known — do not ask for it again; if nothing is missing, go straight to "Gather first". Otherwise ask for what is still missing with `askQuestions`, once, before gathering. It runs inside a session, so call `startSession` first, as in step 1 of "Building each video", and pass its `sessionId`; then pass only the questions below that are still unknown, and add your own for anything else you cannot build without — give an option shaped { "label": "…", "input": "url" } when the answer is a link, { "label": "…", "input": "upload" } when the user should provide a file, and leave out options for free text. Then end your turn — the answers arrive as the user's next message, starting "Answers:". Do not ask them again in chat, with three exceptions, each at most once: when an answer says the user will upload a file in chat, ask them in plain chat to attach it; when a shared ad link cannot be read, ask for a screenshot; and when something you cannot build without was skipped, ask for it. Upload any attached file with `uploadSessionAsset` into that session. For any other skipped question, use your best judgment: its recommended answer if it has one, otherwise what you can infer from the sources you have.
```json
{"questions":[{"title":"Which declining ads should I replace?","options":["Find them in a connected ads source",{"label":"Link to an ad","input":"url"},{"label":"Upload them in chat","input":"upload"}]},{"title":"Where should the assets, product details and copy come from?","options":["Use my website (recommended)",{"label":"Upload my images in chat","input":"upload"},"Use a connected source"]},{"title":"How long should the video be?","options":["Match the declining ads (recommended)","6 seconds","15 seconds","30 seconds"]}]}
```
## Gather first
Butter does not supply this data — it comes from the connectors already available to you, or from
what the user provides.
- Creatives whose CTR or ROAS is trending down over 14 days, from an ads connector (Meta, TikTok…)
- The assets those creatives use
If a source is unavailable, say so and ask the user for it rather than inventing figures. Never
invent an offer, a price, a discount, or a performance claim the user did not give you.
## Hold constant
The elements still performing — usually the offer and the product framing
## Vary
The parts that decayed — hook, opening frame and visual novelty
## How many
3
## Format
Match the fatiguing creative's placements
## Building each video
Butter turns HTML + CSS into an editable Butter project.
**Every Butter tool takes a `userPrompt`, and every call must carry one.** It is the user's latest
message word for word — what they typed, never your summary of it and never your own reasoning. On
`startSession` that is the message that asked for the video in the first place. Leave it out only
when nothing the user said prompted the call.
For every video this workflow calls for:
1. Call `startSession`, unless you already opened one for `askQuestions` that no video is built in
yet — build this video there instead. If this chat has already started a Butter session, ended or not, pass the
`sessionId` of the most recent one as `previousSessionId` so the sessions of one conversation
link up; leave it out only for the first. Pass `goal`: the outcome the user wants the video to
achieve, in one sentence, inferred from their request. It returns a `sessionId`, `userPreferences`
and the HTML contract. **The contract is authoritative** — follow it exactly, and re-read it rather
than relying on memory. `userPreferences` is what earlier sessions learned about how this user likes their videos made, one preference per entry. Treat them as already known: follow them, and do not ask about what they settle, unless the user now asks for something different. Keep track as you work: add a preference the user states or their reactions reveal, reword or remove one they contradict, and keep the rest. Record only how they like the work done (format, length, pacing, tone, style), never personal details about them. Pass only what changed as `userPreferenceChanges` on endSession, never the whole list: `added` for new preferences, `removed` for ones to drop, and `updated` as `{ old, new }` pairs for rewordings.
2. Upload **every** image and video the video will use with `uploadSessionAsset` before it
goes in the page, including any you add while iterating. The page uses the urls it returns, never
the original links: the page runs on them, and `endSession` rejects any other url. Upload
each file **once**: an asset used more than once, such as the logo in every variant, keeps the url
from its first upload in every video and session that uses it. Each upload is a public https link, or a file under 2MB; for a larger local file, ask for a link instead.
3. Write ONE self-contained HTML document that plays itself: a single timeline, elements positioned
in time with `animation-delay` measured from the start of the whole video, and
`animation-fill-mode: both` on every animation. CSS motion is unrestricted and read back
automatically. The video is silent: add no music, sound effects or voiceover. Anything visual a
script drives is invisible to the extractor, so its timing has to be declared by hand in the
manifest. Never show the user the HTML or anything rendered from it. Do not make it into an artifact, a canvas, a widget or a file, do not paste it into your reply, do not open it in a browser tab, window or side panel the user can see, and do not share a preview url. The user sees the video only as the Butter project link endSession returns.
4. Call `submitSessionVersion` with the `sessionId` and the html. It returns lint findings.
5. Fix every **blocking** finding and resubmit — a version with blocking findings cannot be built.
Warnings are safe to ship but cost editability, so prefer fixing them.
6. Do not ask the user whether they are happy with the video. As soon as the version you are shipping has no blocking findings, call
`prepareEndSession` with the session id and its version id. It returns the instructions for
measuring that version into a manifest: follow them, then call `endSession` with the session id,
the version id, that manifest, `estimatedRating`: your 1 to 10
estimate of how successful the session was, judged from how the user reacted to the projects
already built in this chat and how many rounds of changes it took, and `userPreferenceChanges`:
the preferences you `added`, `removed` or `updated`. `endSession` cannot be called
until `prepareEndSession` has been. Neither waits for the user's approval.
7. A successful `endSession` also ends the session for good: the build-session tools refuse it
from then on, and only `repairProject` and `askNextSteps` still take its ids. Whatever comes
next starts a session of its own — the asset urls already uploaded stay valid there.
8. `endSession` answers with only the ids: call `repairProject` next with the same ids, before
telling the user anything. It checks what did not survive conversion. When nothing needs
repair it routes you to `askNextSteps`; when something does it lists the repairs — make
ONLY those by driving the editor, then finish on `askNextSteps` with the same ids and
`repaired`: a line on what was put back. Do not offer the repairs or ask permission.
9. The build report lives in `askNextSteps`.
Never tell the user the project is open — the card gives them the link.
Say your one line about the build first, then call `askNextSteps` with those ids as your LAST action
and end the turn — no text after it: the card it renders carries the link, the report and
the suggested next steps (Edit this project, Make another version, or Adapt the format). They are suggestions, not
steps — the user may simply be done; wait for their answer rather than picking one. Edits to the built project go through `startEditSession`. A variant begins with
`describeProject` — the project as it is NOW, studio edits included, custom blocks named as
opaque references — then a fresh `startSession` to re-author it, or `cloneProject` +
`startEditSession` on the clone when the changes are small (a clone keeps custom blocks
verbatim; a rebuilt variant cannot). Some answers need detail the session cannot start without. Collect it with ONE askQuestions follow-up call — one question per missing detail — and only then start the session:
- "Add an end card": what the end card should include
- "Add background music": whether to upload a file, generate it, or choose from stock
- "Add sound effects": whether to upload a file, generate it, or choose from stock
- "Add a voice over": whether to upload a file, generate it, or choose from stock
- "New layout": which layout, with options tailored to this project
- "Different visual style": which style, with options tailored to this project
Any other answer naming a direction without its detail gets the same treatment, its options tailored to this project.
## Handoff
One session per replacement
butter-ad-multiplier9.38 KB
---
name: butter-ad-multiplier
description: Find what's winning and make the next 3 ads to test. Use when the user wants more ads based on what is already winning, asks for variants of a top performer, or wants the next batch of creative tests.
---
# Ad Multiplier
Find what's winning and make the next 3 ads to test.
## Before you start
Anything the user has already told you, or that the sources under "Gather first" already cover, is known — do not ask for it again; if nothing is missing, go straight to "Gather first". Otherwise ask for what is still missing with `askQuestions`, once, before gathering. It runs inside a session, so call `startSession` first, as in step 1 of "Building each video", and pass its `sessionId`; then pass only the questions below that are still unknown, and add your own for anything else you cannot build without — give an option shaped { "label": "…", "input": "url" } when the answer is a link, { "label": "…", "input": "upload" } when the user should provide a file, and leave out options for free text. Then end your turn — the answers arrive as the user's next message, starting "Answers:". Do not ask them again in chat, with three exceptions, each at most once: when an answer says the user will upload a file in chat, ask them in plain chat to attach it; when a shared ad link cannot be read, ask for a screenshot; and when something you cannot build without was skipped, ask for it. Upload any attached file with `uploadSessionAsset` into that session. For any other skipped question, use your best judgment: its recommended answer if it has one, otherwise what you can infer from the sources you have.
```json
{"questions":[{"title":"Which winning ad should I build on?","options":["Use my top ad from a connected source",{"label":"Link to the ad","input":"url"},{"label":"Upload it in chat","input":"upload"}]},{"title":"Where should the assets, product details and copy come from?","options":["Use my website (recommended)",{"label":"Upload my images in chat","input":"upload"},"Use a connected source"]},{"title":"How long should the video be?","options":["Match the source ad (recommended)","6 seconds","15 seconds","30 seconds"]}]}
```
## Gather first
Butter does not supply this data — it comes from the connectors already available to you, or from
what the user provides.
- Top creatives from the last 30 days with spend, CTR and ROAS, from an ads connector (Meta, TikTok…)
- The brand palette, logo and typeface from the brand kit or the site
If a source is unavailable, say so and ask the user for it rather than inventing figures. Never
invent an offer, a price, a discount, or a performance claim the user did not give you.
## Hold constant
The winning layout, palette and offer structure
## Vary
Hook, proof and CTA — one axis per variant, so a win is attributable
## How many
3
## Format
The source ad's placements
## Building each video
Butter turns HTML + CSS into an editable Butter project.
**Every Butter tool takes a `userPrompt`, and every call must carry one.** It is the user's latest
message word for word — what they typed, never your summary of it and never your own reasoning. On
`startSession` that is the message that asked for the video in the first place. Leave it out only
when nothing the user said prompted the call.
For every video this workflow calls for:
1. Call `startSession`, unless you already opened one for `askQuestions` that no video is built in
yet — build this video there instead. If this chat has already started a Butter session, ended or not, pass the
`sessionId` of the most recent one as `previousSessionId` so the sessions of one conversation
link up; leave it out only for the first. Pass `goal`: the outcome the user wants the video to
achieve, in one sentence, inferred from their request. It returns a `sessionId`, `userPreferences`
and the HTML contract. **The contract is authoritative** — follow it exactly, and re-read it rather
than relying on memory. `userPreferences` is what earlier sessions learned about how this user likes their videos made, one preference per entry. Treat them as already known: follow them, and do not ask about what they settle, unless the user now asks for something different. Keep track as you work: add a preference the user states or their reactions reveal, reword or remove one they contradict, and keep the rest. Record only how they like the work done (format, length, pacing, tone, style), never personal details about them. Pass only what changed as `userPreferenceChanges` on endSession, never the whole list: `added` for new preferences, `removed` for ones to drop, and `updated` as `{ old, new }` pairs for rewordings.
2. Upload **every** image and video the video will use with `uploadSessionAsset` before it
goes in the page, including any you add while iterating. The page uses the urls it returns, never
the original links: the page runs on them, and `endSession` rejects any other url. Upload
each file **once**: an asset used more than once, such as the logo in every variant, keeps the url
from its first upload in every video and session that uses it. Each upload is a public https link, or a file under 2MB; for a larger local file, ask for a link instead.
3. Write ONE self-contained HTML document that plays itself: a single timeline, elements positioned
in time with `animation-delay` measured from the start of the whole video, and
`animation-fill-mode: both` on every animation. CSS motion is unrestricted and read back
automatically. The video is silent: add no music, sound effects or voiceover. Anything visual a
script drives is invisible to the extractor, so its timing has to be declared by hand in the
manifest. Never show the user the HTML or anything rendered from it. Do not make it into an artifact, a canvas, a widget or a file, do not paste it into your reply, do not open it in a browser tab, window or side panel the user can see, and do not share a preview url. The user sees the video only as the Butter project link endSession returns.
4. Call `submitSessionVersion` with the `sessionId` and the html. It returns lint findings.
5. Fix every **blocking** finding and resubmit — a version with blocking findings cannot be built.
Warnings are safe to ship but cost editability, so prefer fixing them.
6. Do not ask the user whether they are happy with the video. As soon as the version you are shipping has no blocking findings, call
`prepareEndSession` with the session id and its version id. It returns the instructions for
measuring that version into a manifest: follow them, then call `endSession` with the session id,
the version id, that manifest, `estimatedRating`: your 1 to 10
estimate of how successful the session was, judged from how the user reacted to the projects
already built in this chat and how many rounds of changes it took, and `userPreferenceChanges`:
the preferences you `added`, `removed` or `updated`. `endSession` cannot be called
until `prepareEndSession` has been. Neither waits for the user's approval.
7. A successful `endSession` also ends the session for good: the build-session tools refuse it
from then on, and only `repairProject` and `askNextSteps` still take its ids. Whatever comes
next starts a session of its own — the asset urls already uploaded stay valid there.
8. `endSession` answers with only the ids: call `repairProject` next with the same ids, before
telling the user anything. It checks what did not survive conversion. When nothing needs
repair it routes you to `askNextSteps`; when something does it lists the repairs — make
ONLY those by driving the editor, then finish on `askNextSteps` with the same ids and
`repaired`: a line on what was put back. Do not offer the repairs or ask permission.
9. The build report lives in `askNextSteps`.
Never tell the user the project is open — the card gives them the link.
Say your one line about the build first, then call `askNextSteps` with those ids as your LAST action
and end the turn — no text after it: the card it renders carries the link, the report and
the suggested next steps (Edit this project, Make another version, or Adapt the format). They are suggestions, not
steps — the user may simply be done; wait for their answer rather than picking one. Edits to the built project go through `startEditSession`. A variant begins with
`describeProject` — the project as it is NOW, studio edits included, custom blocks named as
opaque references — then a fresh `startSession` to re-author it, or `cloneProject` +
`startEditSession` on the clone when the changes are small (a clone keeps custom blocks
verbatim; a rebuilt variant cannot). Some answers need detail the session cannot start without. Collect it with ONE askQuestions follow-up call — one question per missing detail — and only then start the session:
- "Add an end card": what the end card should include
- "Add background music": whether to upload a file, generate it, or choose from stock
- "Add sound effects": whether to upload a file, generate it, or choose from stock
- "Add a voice over": whether to upload a file, generate it, or choose from stock
- "New layout": which layout, with options tailored to this project
- "Different visual style": which style, with options tailored to this project
Any other answer naming a direction without its detail gets the same treatment, its options tailored to this project.
## Handoff
One session per variant; three Butter projects
butter-ambiguous-start3.37 KB
--- name: butter-ambiguous-start description: Start a Butter ad or video when the request is too vague to pick a workflow, such as asking for an ad without saying what to start from. Use when the user wants an ad or video from Butter and no other butter- skill clearly fits. --- # Start with Butter The user wants an ad or video from Butter, but it is not yet clear which workflow fits. ## Find the workflow 1. If the request clearly fits one of the workflows below, tell the user which one and follow that skill. 2. Otherwise ask one question — "What are you starting from?" — offering these: - **Something new** → `butter-make-something-new`, `butter-product-launch`, or `butter-reviews-to-ads` - **An ad of mine that's working** → `butter-ad-multiplier`, `butter-static-to-motion`, `butter-catalog-campaign`, `butter-globalize`, or `butter-ad-fatigue` - **A competitor or an ad I admire** → `butter-reference-to-brand` - **My own photos or clips** → `butter-make-something-new` 3. If their answer leads to more than one workflow, ask which goal they are after, offering each workflow's one-liner. If none fits, use `butter-make-something-new`. 4. Follow the chosen workflow's skill. Its "Before you start" section does not ask again for anything this conversation already answered. ## Workflows ### Make Something New — `butter-make-something-new` Make a new ad or video from scratch, or from assets you already have. Use when the user explicitly wants an ad or video built from scratch, or wants photos, clips or product shots they already have turned into an ad — not for a vague request that names no starting point, which butter-ambiguous-start handles. ### Ad Multiplier — `butter-ad-multiplier` Find what's winning and make the next 3 ads to test. Use when the user wants more ads based on what is already winning, asks for variants of a top performer, or wants the next batch of creative tests. ### Static → Motion — `butter-static-to-motion` Turn the best-performing static ads into motion ads. Use when the user wants to animate an existing static ad, turn stills into video, or add motion without changing a design. ### Product Catalog → Campaign — `butter-catalog-campaign` Turn one winning ad into ads for the 10 best-selling products. Use when the user wants ads for many products at once, or wants a winning ad adapted across a catalogue. ### Reviews → Ads — `butter-reviews-to-ads` Find the best customer reviews and turn them into 3 ads. Use when the user wants ads built from customer reviews, testimonials, or social proof. ### Product Launch — `butter-product-launch` Launch a campaign for the newest product. Use when the user is launching a new product and needs a set of launch creative across surfaces. ### Globalize a Winner — `butter-globalize` Take a winning campaign and launch it in other markets. Use when the user wants an existing campaign translated, localized, or launched in another market. ### Reference → Brand — `butter-reference-to-brand` Break down a reference ad and rebuild it as ours. Use when the user shares a reference ad or names a competitor and wants their own version of it, or wants to copy a format they admire. ### Ad Fatigue — `butter-ad-fatigue` Find ads starting to fatigue and make their replacements. Use when the user asks which ads are declining, mentions creative fatigue, or wants replacements for tiring ads.
butter-catalog-campaign9.25 KB
---
name: butter-catalog-campaign
description: Turn one winning ad into ads for the 10 best-selling products. Use when the user wants ads for many products at once, or wants a winning ad adapted across a catalogue.
---
# Product Catalog → Campaign
Turn one winning ad into ads for the 10 best-selling products.
## Before you start
Anything the user has already told you, or that the sources under "Gather first" already cover, is known — do not ask for it again; if nothing is missing, go straight to "Gather first". Otherwise ask for what is still missing with `askQuestions`, once, before gathering. It runs inside a session, so call `startSession` first, as in step 1 of "Building each video", and pass its `sessionId`; then pass only the questions below that are still unknown, and add your own for anything else you cannot build without — give an option shaped { "label": "…", "input": "url" } when the answer is a link, { "label": "…", "input": "upload" } when the user should provide a file, and leave out options for free text. Then end your turn — the answers arrive as the user's next message, starting "Answers:". Do not ask them again in chat, with three exceptions, each at most once: when an answer says the user will upload a file in chat, ask them in plain chat to attach it; when a shared ad link cannot be read, ask for a screenshot; and when something you cannot build without was skipped, ask for it. Upload any attached file with `uploadSessionAsset` into that session. For any other skipped question, use your best judgment: its recommended answer if it has one, otherwise what you can infer from the sources you have.
```json
{"questions":[{"title":"Which winning ad should I adapt?","options":["Use my top ad from a connected source",{"label":"Link to the ad","input":"url"},{"label":"Upload it in chat","input":"upload"}]},{"title":"Where should the assets, product details and copy come from?","options":["Use my website (recommended)",{"label":"Upload my images in chat","input":"upload"},"Use a connected source"]},{"title":"How long should the video be?","options":["Match the source ad (recommended)","6 seconds","15 seconds","30 seconds"]}]}
```
## Gather first
Butter does not supply this data — it comes from the connectors already available to you, or from
what the user provides.
- Best-selling products with images, titles and prices, from a store connector (Shopify…)
If a source is unavailable, say so and ask the user for it rather than inventing figures. Never
invent an offer, a price, a discount, or a performance claim the user did not give you.
## Hold constant
The winning format, layout and typography
## Vary
Product image, name, price and any product-specific claim
## How many
10
## Format
The source ad's format
## Building each video
Butter turns HTML + CSS into an editable Butter project.
**Every Butter tool takes a `userPrompt`, and every call must carry one.** It is the user's latest
message word for word — what they typed, never your summary of it and never your own reasoning. On
`startSession` that is the message that asked for the video in the first place. Leave it out only
when nothing the user said prompted the call.
For every video this workflow calls for:
1. Call `startSession`, unless you already opened one for `askQuestions` that no video is built in
yet — build this video there instead. If this chat has already started a Butter session, ended or not, pass the
`sessionId` of the most recent one as `previousSessionId` so the sessions of one conversation
link up; leave it out only for the first. Pass `goal`: the outcome the user wants the video to
achieve, in one sentence, inferred from their request. It returns a `sessionId`, `userPreferences`
and the HTML contract. **The contract is authoritative** — follow it exactly, and re-read it rather
than relying on memory. `userPreferences` is what earlier sessions learned about how this user likes their videos made, one preference per entry. Treat them as already known: follow them, and do not ask about what they settle, unless the user now asks for something different. Keep track as you work: add a preference the user states or their reactions reveal, reword or remove one they contradict, and keep the rest. Record only how they like the work done (format, length, pacing, tone, style), never personal details about them. Pass only what changed as `userPreferenceChanges` on endSession, never the whole list: `added` for new preferences, `removed` for ones to drop, and `updated` as `{ old, new }` pairs for rewordings.
2. Upload **every** image and video the video will use with `uploadSessionAsset` before it
goes in the page, including any you add while iterating. The page uses the urls it returns, never
the original links: the page runs on them, and `endSession` rejects any other url. Upload
each file **once**: an asset used more than once, such as the logo in every variant, keeps the url
from its first upload in every video and session that uses it. Each upload is a public https link, or a file under 2MB; for a larger local file, ask for a link instead.
3. Write ONE self-contained HTML document that plays itself: a single timeline, elements positioned
in time with `animation-delay` measured from the start of the whole video, and
`animation-fill-mode: both` on every animation. CSS motion is unrestricted and read back
automatically. The video is silent: add no music, sound effects or voiceover. Anything visual a
script drives is invisible to the extractor, so its timing has to be declared by hand in the
manifest. Never show the user the HTML or anything rendered from it. Do not make it into an artifact, a canvas, a widget or a file, do not paste it into your reply, do not open it in a browser tab, window or side panel the user can see, and do not share a preview url. The user sees the video only as the Butter project link endSession returns.
4. Call `submitSessionVersion` with the `sessionId` and the html. It returns lint findings.
5. Fix every **blocking** finding and resubmit — a version with blocking findings cannot be built.
Warnings are safe to ship but cost editability, so prefer fixing them.
6. Do not ask the user whether they are happy with the video. As soon as the version you are shipping has no blocking findings, call
`prepareEndSession` with the session id and its version id. It returns the instructions for
measuring that version into a manifest: follow them, then call `endSession` with the session id,
the version id, that manifest, `estimatedRating`: your 1 to 10
estimate of how successful the session was, judged from how the user reacted to the projects
already built in this chat and how many rounds of changes it took, and `userPreferenceChanges`:
the preferences you `added`, `removed` or `updated`. `endSession` cannot be called
until `prepareEndSession` has been. Neither waits for the user's approval.
7. A successful `endSession` also ends the session for good: the build-session tools refuse it
from then on, and only `repairProject` and `askNextSteps` still take its ids. Whatever comes
next starts a session of its own — the asset urls already uploaded stay valid there.
8. `endSession` answers with only the ids: call `repairProject` next with the same ids, before
telling the user anything. It checks what did not survive conversion. When nothing needs
repair it routes you to `askNextSteps`; when something does it lists the repairs — make
ONLY those by driving the editor, then finish on `askNextSteps` with the same ids and
`repaired`: a line on what was put back. Do not offer the repairs or ask permission.
9. The build report lives in `askNextSteps`.
Never tell the user the project is open — the card gives them the link.
Say your one line about the build first, then call `askNextSteps` with those ids as your LAST action
and end the turn — no text after it: the card it renders carries the link, the report and
the suggested next steps (Edit this project, Make another version, or Adapt the format). They are suggestions, not
steps — the user may simply be done; wait for their answer rather than picking one. Edits to the built project go through `startEditSession`. A variant begins with
`describeProject` — the project as it is NOW, studio edits included, custom blocks named as
opaque references — then a fresh `startSession` to re-author it, or `cloneProject` +
`startEditSession` on the clone when the changes are small (a clone keeps custom blocks
verbatim; a rebuilt variant cannot). Some answers need detail the session cannot start without. Collect it with ONE askQuestions follow-up call — one question per missing detail — and only then start the session:
- "Add an end card": what the end card should include
- "Add background music": whether to upload a file, generate it, or choose from stock
- "Add sound effects": whether to upload a file, generate it, or choose from stock
- "Add a voice over": whether to upload a file, generate it, or choose from stock
- "New layout": which layout, with options tailored to this project
- "Different visual style": which style, with options tailored to this project
Any other answer naming a direction without its detail gets the same treatment, its options tailored to this project.
## Handoff
One session per product
butter-globalize9.28 KB
---
name: butter-globalize
description: Take a winning campaign and launch it in other markets. Use when the user wants an existing campaign translated, localized, or launched in another market.
---
# Globalize a Winner
Take a winning campaign and launch it in other markets.
## Before you start
Anything the user has already told you, or that the sources under "Gather first" already cover, is known — do not ask for it again; if nothing is missing, go straight to "Gather first". Otherwise ask for what is still missing with `askQuestions`, once, before gathering. It runs inside a session, so call `startSession` first, as in step 1 of "Building each video", and pass its `sessionId`; then pass only the questions below that are still unknown, and add your own for anything else you cannot build without — give an option shaped { "label": "…", "input": "url" } when the answer is a link, { "label": "…", "input": "upload" } when the user should provide a file, and leave out options for free text. Then end your turn — the answers arrive as the user's next message, starting "Answers:". Do not ask them again in chat, with three exceptions, each at most once: when an answer says the user will upload a file in chat, ask them in plain chat to attach it; when a shared ad link cannot be read, ask for a screenshot; and when something you cannot build without was skipped, ask for it. Upload any attached file with `uploadSessionAsset` into that session. For any other skipped question, use your best judgment: its recommended answer if it has one, otherwise what you can infer from the sources you have.
```json
{"questions":[{"title":"Which winning creative should I localize?","options":[{"label":"Upload it in chat","input":"upload"},{"label":"Link to it","input":"url"},"Use my top ad from a connected source"]},{"title":"Where should the assets, product details and copy come from?","options":["Use my website (recommended)",{"label":"Upload my images in chat","input":"upload"},"Use a connected source"]},{"title":"How long should the video be?","options":["Match the source (recommended)","6 seconds","15 seconds","30 seconds"]}]}
```
## Gather first
Butter does not supply this data — it comes from the connectors already available to you, or from
what the user provides.
- Target locales, local pricing, offers and any legally required text
If a source is unavailable, say so and ask the user for it rather than inventing figures. Never
invent an offer, a price, a discount, or a performance claim the user did not give you.
## Hold constant
The creative direction, composition and motion
## Vary
Language, price, offer and legal text — and the layout only as much as the language forces
## How many
1
## Format
The source format, per locale
## Building each video
Butter turns HTML + CSS into an editable Butter project.
**Every Butter tool takes a `userPrompt`, and every call must carry one.** It is the user's latest
message word for word — what they typed, never your summary of it and never your own reasoning. On
`startSession` that is the message that asked for the video in the first place. Leave it out only
when nothing the user said prompted the call.
For every video this workflow calls for:
1. Call `startSession`, unless you already opened one for `askQuestions` that no video is built in
yet — build this video there instead. If this chat has already started a Butter session, ended or not, pass the
`sessionId` of the most recent one as `previousSessionId` so the sessions of one conversation
link up; leave it out only for the first. Pass `goal`: the outcome the user wants the video to
achieve, in one sentence, inferred from their request. It returns a `sessionId`, `userPreferences`
and the HTML contract. **The contract is authoritative** — follow it exactly, and re-read it rather
than relying on memory. `userPreferences` is what earlier sessions learned about how this user likes their videos made, one preference per entry. Treat them as already known: follow them, and do not ask about what they settle, unless the user now asks for something different. Keep track as you work: add a preference the user states or their reactions reveal, reword or remove one they contradict, and keep the rest. Record only how they like the work done (format, length, pacing, tone, style), never personal details about them. Pass only what changed as `userPreferenceChanges` on endSession, never the whole list: `added` for new preferences, `removed` for ones to drop, and `updated` as `{ old, new }` pairs for rewordings.
2. Upload **every** image and video the video will use with `uploadSessionAsset` before it
goes in the page, including any you add while iterating. The page uses the urls it returns, never
the original links: the page runs on them, and `endSession` rejects any other url. Upload
each file **once**: an asset used more than once, such as the logo in every variant, keeps the url
from its first upload in every video and session that uses it. Each upload is a public https link, or a file under 2MB; for a larger local file, ask for a link instead.
3. Write ONE self-contained HTML document that plays itself: a single timeline, elements positioned
in time with `animation-delay` measured from the start of the whole video, and
`animation-fill-mode: both` on every animation. CSS motion is unrestricted and read back
automatically. The video is silent: add no music, sound effects or voiceover. Anything visual a
script drives is invisible to the extractor, so its timing has to be declared by hand in the
manifest. Never show the user the HTML or anything rendered from it. Do not make it into an artifact, a canvas, a widget or a file, do not paste it into your reply, do not open it in a browser tab, window or side panel the user can see, and do not share a preview url. The user sees the video only as the Butter project link endSession returns.
4. Call `submitSessionVersion` with the `sessionId` and the html. It returns lint findings.
5. Fix every **blocking** finding and resubmit — a version with blocking findings cannot be built.
Warnings are safe to ship but cost editability, so prefer fixing them.
6. Do not ask the user whether they are happy with the video. As soon as the version you are shipping has no blocking findings, call
`prepareEndSession` with the session id and its version id. It returns the instructions for
measuring that version into a manifest: follow them, then call `endSession` with the session id,
the version id, that manifest, `estimatedRating`: your 1 to 10
estimate of how successful the session was, judged from how the user reacted to the projects
already built in this chat and how many rounds of changes it took, and `userPreferenceChanges`:
the preferences you `added`, `removed` or `updated`. `endSession` cannot be called
until `prepareEndSession` has been. Neither waits for the user's approval.
7. A successful `endSession` also ends the session for good: the build-session tools refuse it
from then on, and only `repairProject` and `askNextSteps` still take its ids. Whatever comes
next starts a session of its own — the asset urls already uploaded stay valid there.
8. `endSession` answers with only the ids: call `repairProject` next with the same ids, before
telling the user anything. It checks what did not survive conversion. When nothing needs
repair it routes you to `askNextSteps`; when something does it lists the repairs — make
ONLY those by driving the editor, then finish on `askNextSteps` with the same ids and
`repaired`: a line on what was put back. Do not offer the repairs or ask permission.
9. The build report lives in `askNextSteps`.
Never tell the user the project is open — the card gives them the link.
Say your one line about the build first, then call `askNextSteps` with those ids as your LAST action
and end the turn — no text after it: the card it renders carries the link, the report and
the suggested next steps (Edit this project, Make another version, or Adapt the format). They are suggestions, not
steps — the user may simply be done; wait for their answer rather than picking one. Edits to the built project go through `startEditSession`. A variant begins with
`describeProject` — the project as it is NOW, studio edits included, custom blocks named as
opaque references — then a fresh `startSession` to re-author it, or `cloneProject` +
`startEditSession` on the clone when the changes are small (a clone keeps custom blocks
verbatim; a rebuilt variant cannot). Some answers need detail the session cannot start without. Collect it with ONE askQuestions follow-up call — one question per missing detail — and only then start the session:
- "Add an end card": what the end card should include
- "Add background music": whether to upload a file, generate it, or choose from stock
- "Add sound effects": whether to upload a file, generate it, or choose from stock
- "Add a voice over": whether to upload a file, generate it, or choose from stock
- "New layout": which layout, with options tailored to this project
- "Different visual style": which style, with options tailored to this project
Any other answer naming a direction without its detail gets the same treatment, its options tailored to this project.
## Handoff
One session per locale; check that longer translations still fit
butter-make-something-new9.58 KB
---
name: butter-make-something-new
description: Make a new ad or video from scratch, or from assets you already have. Use when the user explicitly wants an ad or video built from scratch, or wants photos, clips or product shots they already have turned into an ad — not for a vague request that names no starting point, which butter-ambiguous-start handles.
---
# Make Something New
Make a new ad or video from scratch, or from assets you already have.
## Before you start
Anything the user has already told you, or that the sources under "Gather first" already cover, is known — do not ask for it again; if nothing is missing, go straight to "Gather first". Otherwise ask for what is still missing with `askQuestions`, once, before gathering. It runs inside a session, so call `startSession` first, as in step 1 of "Building each video", and pass its `sessionId`; then pass only the questions below that are still unknown, and add your own for anything else you cannot build without — give an option shaped { "label": "…", "input": "url" } when the answer is a link, { "label": "…", "input": "upload" } when the user should provide a file, and leave out options for free text. Then end your turn — the answers arrive as the user's next message, starting "Answers:". Do not ask them again in chat, with three exceptions, each at most once: when an answer says the user will upload a file in chat, ask them in plain chat to attach it; when a shared ad link cannot be read, ask for a screenshot; and when something you cannot build without was skipped, ask for it. Upload any attached file with `uploadSessionAsset` into that session. For any other skipped question, use your best judgment: its recommended answer if it has one, otherwise what you can infer from the sources you have.
```json
{"questions":[{"title":"What should I use as a visual reference?","options":[{"label":"Match my website's branding (recommended)","input":"url"},{"label":"Match an ad I'll share","input":"url"},{"label":"Upload an ad in chat","input":"upload"}]},{"title":"Where should the assets, product details and copy come from?","options":["Use my website (recommended)",{"label":"Upload my images in chat","input":"upload"},"Use a connected source"]},{"title":"What format would you like?","options":["Vertical 9:16 (recommended)","Square 1:1","Landscape 16:9"]},{"title":"How long should the video be?","options":["15 seconds (recommended)","6 seconds","30 seconds"]}]}
```
## Gather first
Butter does not supply this data — it comes from the connectors already available to you, or from
what the user provides.
- The brand palette, logo and typeface from the brand kit or the site
If a source is unavailable, say so and ask the user for it rather than inventing figures. Never
invent an offer, a price, a discount, or a performance claim the user did not give you.
## Hold constant
The brand system, and any reference the user gives
## Vary
Concept, hook, pacing and motion
## How many
1
## Format
Use the format answer; default to vertical 9:16
## Building each video
Butter turns HTML + CSS into an editable Butter project.
**Every Butter tool takes a `userPrompt`, and every call must carry one.** It is the user's latest
message word for word — what they typed, never your summary of it and never your own reasoning. On
`startSession` that is the message that asked for the video in the first place. Leave it out only
when nothing the user said prompted the call.
For every video this workflow calls for:
1. Call `startSession`, unless you already opened one for `askQuestions` that no video is built in
yet — build this video there instead. If this chat has already started a Butter session, ended or not, pass the
`sessionId` of the most recent one as `previousSessionId` so the sessions of one conversation
link up; leave it out only for the first. Pass `goal`: the outcome the user wants the video to
achieve, in one sentence, inferred from their request. It returns a `sessionId`, `userPreferences`
and the HTML contract. **The contract is authoritative** — follow it exactly, and re-read it rather
than relying on memory. `userPreferences` is what earlier sessions learned about how this user likes their videos made, one preference per entry. Treat them as already known: follow them, and do not ask about what they settle, unless the user now asks for something different. Keep track as you work: add a preference the user states or their reactions reveal, reword or remove one they contradict, and keep the rest. Record only how they like the work done (format, length, pacing, tone, style), never personal details about them. Pass only what changed as `userPreferenceChanges` on endSession, never the whole list: `added` for new preferences, `removed` for ones to drop, and `updated` as `{ old, new }` pairs for rewordings.
2. Upload **every** image and video the video will use with `uploadSessionAsset` before it
goes in the page, including any you add while iterating. The page uses the urls it returns, never
the original links: the page runs on them, and `endSession` rejects any other url. Upload
each file **once**: an asset used more than once, such as the logo in every variant, keeps the url
from its first upload in every video and session that uses it. Each upload is a public https link, or a file under 2MB; for a larger local file, ask for a link instead.
3. Write ONE self-contained HTML document that plays itself: a single timeline, elements positioned
in time with `animation-delay` measured from the start of the whole video, and
`animation-fill-mode: both` on every animation. CSS motion is unrestricted and read back
automatically. The video is silent: add no music, sound effects or voiceover. Anything visual a
script drives is invisible to the extractor, so its timing has to be declared by hand in the
manifest. Never show the user the HTML or anything rendered from it. Do not make it into an artifact, a canvas, a widget or a file, do not paste it into your reply, do not open it in a browser tab, window or side panel the user can see, and do not share a preview url. The user sees the video only as the Butter project link endSession returns.
4. Call `submitSessionVersion` with the `sessionId` and the html. It returns lint findings.
5. Fix every **blocking** finding and resubmit — a version with blocking findings cannot be built.
Warnings are safe to ship but cost editability, so prefer fixing them.
6. Do not ask the user whether they are happy with the video. As soon as the version you are shipping has no blocking findings, call
`prepareEndSession` with the session id and its version id. It returns the instructions for
measuring that version into a manifest: follow them, then call `endSession` with the session id,
the version id, that manifest, `estimatedRating`: your 1 to 10
estimate of how successful the session was, judged from how the user reacted to the projects
already built in this chat and how many rounds of changes it took, and `userPreferenceChanges`:
the preferences you `added`, `removed` or `updated`. `endSession` cannot be called
until `prepareEndSession` has been. Neither waits for the user's approval.
7. A successful `endSession` also ends the session for good: the build-session tools refuse it
from then on, and only `repairProject` and `askNextSteps` still take its ids. Whatever comes
next starts a session of its own — the asset urls already uploaded stay valid there.
8. `endSession` answers with only the ids: call `repairProject` next with the same ids, before
telling the user anything. It checks what did not survive conversion. When nothing needs
repair it routes you to `askNextSteps`; when something does it lists the repairs — make
ONLY those by driving the editor, then finish on `askNextSteps` with the same ids and
`repaired`: a line on what was put back. Do not offer the repairs or ask permission.
9. The build report lives in `askNextSteps`.
Never tell the user the project is open — the card gives them the link.
Say your one line about the build first, then call `askNextSteps` with those ids as your LAST action
and end the turn — no text after it: the card it renders carries the link, the report and
the suggested next steps (Edit this project, Make another version, or Adapt the format). They are suggestions, not
steps — the user may simply be done; wait for their answer rather than picking one. Edits to the built project go through `startEditSession`. A variant begins with
`describeProject` — the project as it is NOW, studio edits included, custom blocks named as
opaque references — then a fresh `startSession` to re-author it, or `cloneProject` +
`startEditSession` on the clone when the changes are small (a clone keeps custom blocks
verbatim; a rebuilt variant cannot). Some answers need detail the session cannot start without. Collect it with ONE askQuestions follow-up call — one question per missing detail — and only then start the session:
- "Add an end card": what the end card should include
- "Add background music": whether to upload a file, generate it, or choose from stock
- "Add sound effects": whether to upload a file, generate it, or choose from stock
- "Add a voice over": whether to upload a file, generate it, or choose from stock
- "New layout": which layout, with options tailored to this project
- "Different visual style": which style, with options tailored to this project
Any other answer naming a direction without its detail gets the same treatment, its options tailored to this project.
## Handoff
One session per video; offer variations once its project link is shared, each in a new session
butter-product-launch9.25 KB
---
name: butter-product-launch
description: Launch a campaign for the newest product. Use when the user is launching a new product and needs a set of launch creative across surfaces.
---
# Product Launch
Launch a campaign for the newest product.
## Before you start
Anything the user has already told you, or that the sources under "Gather first" already cover, is known — do not ask for it again; if nothing is missing, go straight to "Gather first". Otherwise ask for what is still missing with `askQuestions`, once, before gathering. It runs inside a session, so call `startSession` first, as in step 1 of "Building each video", and pass its `sessionId`; then pass only the questions below that are still unknown, and add your own for anything else you cannot build without — give an option shaped { "label": "…", "input": "url" } when the answer is a link, { "label": "…", "input": "upload" } when the user should provide a file, and leave out options for free text. Then end your turn — the answers arrive as the user's next message, starting "Answers:". Do not ask them again in chat, with three exceptions, each at most once: when an answer says the user will upload a file in chat, ask them in plain chat to attach it; when a shared ad link cannot be read, ask for a screenshot; and when something you cannot build without was skipped, ask for it. Upload any attached file with `uploadSessionAsset` into that session. For any other skipped question, use your best judgment: its recommended answer if it has one, otherwise what you can infer from the sources you have.
```json
{"questions":[{"title":"What should I use as a visual reference?","options":[{"label":"Match my website's branding (recommended)","input":"url"},{"label":"Match an ad I'll share","input":"url"},{"label":"Upload an ad in chat","input":"upload"}]},{"title":"Where should the assets, product details and copy come from?","options":["Use my website (recommended)",{"label":"Upload my images in chat","input":"upload"},"Use a connected source"]},{"title":"How long should the video be?","options":["15 seconds (recommended)","6 seconds","30 seconds"]}]}
```
## Gather first
Butter does not supply this data — it comes from the connectors already available to you, or from
what the user provides.
- The new product's details and images, from a store connector (Shopify…) or the product page
- Brand assets
If a source is unavailable, say so and ask the user for it rather than inventing figures. Never
invent an offer, a price, a discount, or a performance claim the user did not give you.
## Hold constant
The brand system established by existing creative
## Vary
Format and message per surface — paid, social, launch
## How many
3
## Format
One vertical, one square, one landscape
## Building each video
Butter turns HTML + CSS into an editable Butter project.
**Every Butter tool takes a `userPrompt`, and every call must carry one.** It is the user's latest
message word for word — what they typed, never your summary of it and never your own reasoning. On
`startSession` that is the message that asked for the video in the first place. Leave it out only
when nothing the user said prompted the call.
For every video this workflow calls for:
1. Call `startSession`, unless you already opened one for `askQuestions` that no video is built in
yet — build this video there instead. If this chat has already started a Butter session, ended or not, pass the
`sessionId` of the most recent one as `previousSessionId` so the sessions of one conversation
link up; leave it out only for the first. Pass `goal`: the outcome the user wants the video to
achieve, in one sentence, inferred from their request. It returns a `sessionId`, `userPreferences`
and the HTML contract. **The contract is authoritative** — follow it exactly, and re-read it rather
than relying on memory. `userPreferences` is what earlier sessions learned about how this user likes their videos made, one preference per entry. Treat them as already known: follow them, and do not ask about what they settle, unless the user now asks for something different. Keep track as you work: add a preference the user states or their reactions reveal, reword or remove one they contradict, and keep the rest. Record only how they like the work done (format, length, pacing, tone, style), never personal details about them. Pass only what changed as `userPreferenceChanges` on endSession, never the whole list: `added` for new preferences, `removed` for ones to drop, and `updated` as `{ old, new }` pairs for rewordings.
2. Upload **every** image and video the video will use with `uploadSessionAsset` before it
goes in the page, including any you add while iterating. The page uses the urls it returns, never
the original links: the page runs on them, and `endSession` rejects any other url. Upload
each file **once**: an asset used more than once, such as the logo in every variant, keeps the url
from its first upload in every video and session that uses it. Each upload is a public https link, or a file under 2MB; for a larger local file, ask for a link instead.
3. Write ONE self-contained HTML document that plays itself: a single timeline, elements positioned
in time with `animation-delay` measured from the start of the whole video, and
`animation-fill-mode: both` on every animation. CSS motion is unrestricted and read back
automatically. The video is silent: add no music, sound effects or voiceover. Anything visual a
script drives is invisible to the extractor, so its timing has to be declared by hand in the
manifest. Never show the user the HTML or anything rendered from it. Do not make it into an artifact, a canvas, a widget or a file, do not paste it into your reply, do not open it in a browser tab, window or side panel the user can see, and do not share a preview url. The user sees the video only as the Butter project link endSession returns.
4. Call `submitSessionVersion` with the `sessionId` and the html. It returns lint findings.
5. Fix every **blocking** finding and resubmit — a version with blocking findings cannot be built.
Warnings are safe to ship but cost editability, so prefer fixing them.
6. Do not ask the user whether they are happy with the video. As soon as the version you are shipping has no blocking findings, call
`prepareEndSession` with the session id and its version id. It returns the instructions for
measuring that version into a manifest: follow them, then call `endSession` with the session id,
the version id, that manifest, `estimatedRating`: your 1 to 10
estimate of how successful the session was, judged from how the user reacted to the projects
already built in this chat and how many rounds of changes it took, and `userPreferenceChanges`:
the preferences you `added`, `removed` or `updated`. `endSession` cannot be called
until `prepareEndSession` has been. Neither waits for the user's approval.
7. A successful `endSession` also ends the session for good: the build-session tools refuse it
from then on, and only `repairProject` and `askNextSteps` still take its ids. Whatever comes
next starts a session of its own — the asset urls already uploaded stay valid there.
8. `endSession` answers with only the ids: call `repairProject` next with the same ids, before
telling the user anything. It checks what did not survive conversion. When nothing needs
repair it routes you to `askNextSteps`; when something does it lists the repairs — make
ONLY those by driving the editor, then finish on `askNextSteps` with the same ids and
`repaired`: a line on what was put back. Do not offer the repairs or ask permission.
9. The build report lives in `askNextSteps`.
Never tell the user the project is open — the card gives them the link.
Say your one line about the build first, then call `askNextSteps` with those ids as your LAST action
and end the turn — no text after it: the card it renders carries the link, the report and
the suggested next steps (Edit this project, Make another version, or Adapt the format). They are suggestions, not
steps — the user may simply be done; wait for their answer rather than picking one. Edits to the built project go through `startEditSession`. A variant begins with
`describeProject` — the project as it is NOW, studio edits included, custom blocks named as
opaque references — then a fresh `startSession` to re-author it, or `cloneProject` +
`startEditSession` on the clone when the changes are small (a clone keeps custom blocks
verbatim; a rebuilt variant cannot). Some answers need detail the session cannot start without. Collect it with ONE askQuestions follow-up call — one question per missing detail — and only then start the session:
- "Add an end card": what the end card should include
- "Add background music": whether to upload a file, generate it, or choose from stock
- "Add sound effects": whether to upload a file, generate it, or choose from stock
- "Add a voice over": whether to upload a file, generate it, or choose from stock
- "New layout": which layout, with options tailored to this project
- "Different visual style": which style, with options tailored to this project
Any other answer naming a direction without its detail gets the same treatment, its options tailored to this project.
## Handoff
One session per surface
butter-reference-to-brand9.41 KB
---
name: butter-reference-to-brand
description: Break down a reference ad and rebuild it as ours. Use when the user shares a reference ad or names a competitor and wants their own version of it, or wants to copy a format they admire.
---
# Reference → Brand
Break down a reference ad and rebuild it as ours.
## Before you start
Anything the user has already told you, or that the sources under "Gather first" already cover, is known — do not ask for it again; if nothing is missing, go straight to "Gather first". Otherwise ask for what is still missing with `askQuestions`, once, before gathering. It runs inside a session, so call `startSession` first, as in step 1 of "Building each video", and pass its `sessionId`; then pass only the questions below that are still unknown, and add your own for anything else you cannot build without — give an option shaped { "label": "…", "input": "url" } when the answer is a link, { "label": "…", "input": "upload" } when the user should provide a file, and leave out options for free text. Then end your turn — the answers arrive as the user's next message, starting "Answers:". Do not ask them again in chat, with three exceptions, each at most once: when an answer says the user will upload a file in chat, ask them in plain chat to attach it; when a shared ad link cannot be read, ask for a screenshot; and when something you cannot build without was skipped, ask for it. Upload any attached file with `uploadSessionAsset` into that session. For any other skipped question, use your best judgment: its recommended answer if it has one, otherwise what you can infer from the sources you have.
```json
{"questions":[{"title":"Which ad should I rebuild? Link it, upload it, or type a competitor to find one of theirs.","options":[{"label":"Link to the ad","input":"url"},{"label":"Upload it in chat","input":"upload"}]},{"title":"Where should the assets, product details and copy come from?","options":["Use my website (recommended)",{"label":"Upload my images in chat","input":"upload"},"Use a connected source"]},{"title":"How long should the video be?","options":["Match the reference (recommended)","6 seconds","15 seconds","30 seconds"]}]}
```
## Gather first
Butter does not supply this data — it comes from the connectors already available to you, or from
what the user provides.
- Our brand assets, products and palette
- If the user names a competitor rather than an ad, one of that brand's ads — confirm it with the user before building
If a source is unavailable, say so and ask the user for it rather than inventing figures. Never
invent an offer, a price, a discount, or a performance claim the user did not give you.
## Hold constant
The reference's concept, pacing, composition and motion
## Vary
Every asset, colour and word — nothing of the reference's content survives
## How many
1
## Format
Match the reference
## Building each video
Butter turns HTML + CSS into an editable Butter project.
**Every Butter tool takes a `userPrompt`, and every call must carry one.** It is the user's latest
message word for word — what they typed, never your summary of it and never your own reasoning. On
`startSession` that is the message that asked for the video in the first place. Leave it out only
when nothing the user said prompted the call.
For every video this workflow calls for:
1. Call `startSession`, unless you already opened one for `askQuestions` that no video is built in
yet — build this video there instead. If this chat has already started a Butter session, ended or not, pass the
`sessionId` of the most recent one as `previousSessionId` so the sessions of one conversation
link up; leave it out only for the first. Pass `goal`: the outcome the user wants the video to
achieve, in one sentence, inferred from their request. It returns a `sessionId`, `userPreferences`
and the HTML contract. **The contract is authoritative** — follow it exactly, and re-read it rather
than relying on memory. `userPreferences` is what earlier sessions learned about how this user likes their videos made, one preference per entry. Treat them as already known: follow them, and do not ask about what they settle, unless the user now asks for something different. Keep track as you work: add a preference the user states or their reactions reveal, reword or remove one they contradict, and keep the rest. Record only how they like the work done (format, length, pacing, tone, style), never personal details about them. Pass only what changed as `userPreferenceChanges` on endSession, never the whole list: `added` for new preferences, `removed` for ones to drop, and `updated` as `{ old, new }` pairs for rewordings.
2. Upload **every** image and video the video will use with `uploadSessionAsset` before it
goes in the page, including any you add while iterating. The page uses the urls it returns, never
the original links: the page runs on them, and `endSession` rejects any other url. Upload
each file **once**: an asset used more than once, such as the logo in every variant, keeps the url
from its first upload in every video and session that uses it. Each upload is a public https link, or a file under 2MB; for a larger local file, ask for a link instead.
3. Write ONE self-contained HTML document that plays itself: a single timeline, elements positioned
in time with `animation-delay` measured from the start of the whole video, and
`animation-fill-mode: both` on every animation. CSS motion is unrestricted and read back
automatically. The video is silent: add no music, sound effects or voiceover. Anything visual a
script drives is invisible to the extractor, so its timing has to be declared by hand in the
manifest. Never show the user the HTML or anything rendered from it. Do not make it into an artifact, a canvas, a widget or a file, do not paste it into your reply, do not open it in a browser tab, window or side panel the user can see, and do not share a preview url. The user sees the video only as the Butter project link endSession returns.
4. Call `submitSessionVersion` with the `sessionId` and the html. It returns lint findings.
5. Fix every **blocking** finding and resubmit — a version with blocking findings cannot be built.
Warnings are safe to ship but cost editability, so prefer fixing them.
6. Do not ask the user whether they are happy with the video. As soon as the version you are shipping has no blocking findings, call
`prepareEndSession` with the session id and its version id. It returns the instructions for
measuring that version into a manifest: follow them, then call `endSession` with the session id,
the version id, that manifest, `estimatedRating`: your 1 to 10
estimate of how successful the session was, judged from how the user reacted to the projects
already built in this chat and how many rounds of changes it took, and `userPreferenceChanges`:
the preferences you `added`, `removed` or `updated`. `endSession` cannot be called
until `prepareEndSession` has been. Neither waits for the user's approval.
7. A successful `endSession` also ends the session for good: the build-session tools refuse it
from then on, and only `repairProject` and `askNextSteps` still take its ids. Whatever comes
next starts a session of its own — the asset urls already uploaded stay valid there.
8. `endSession` answers with only the ids: call `repairProject` next with the same ids, before
telling the user anything. It checks what did not survive conversion. When nothing needs
repair it routes you to `askNextSteps`; when something does it lists the repairs — make
ONLY those by driving the editor, then finish on `askNextSteps` with the same ids and
`repaired`: a line on what was put back. Do not offer the repairs or ask permission.
9. The build report lives in `askNextSteps`.
Never tell the user the project is open — the card gives them the link.
Say your one line about the build first, then call `askNextSteps` with those ids as your LAST action
and end the turn — no text after it: the card it renders carries the link, the report and
the suggested next steps (Edit this project, Make another version, or Adapt the format). They are suggestions, not
steps — the user may simply be done; wait for their answer rather than picking one. Edits to the built project go through `startEditSession`. A variant begins with
`describeProject` — the project as it is NOW, studio edits included, custom blocks named as
opaque references — then a fresh `startSession` to re-author it, or `cloneProject` +
`startEditSession` on the clone when the changes are small (a clone keeps custom blocks
verbatim; a rebuilt variant cannot). Some answers need detail the session cannot start without. Collect it with ONE askQuestions follow-up call — one question per missing detail — and only then start the session:
- "Add an end card": what the end card should include
- "Add background music": whether to upload a file, generate it, or choose from stock
- "Add sound effects": whether to upload a file, generate it, or choose from stock
- "Add a voice over": whether to upload a file, generate it, or choose from stock
- "New layout": which layout, with options tailored to this project
- "Different visual style": which style, with options tailored to this project
Any other answer naming a direction without its detail gets the same treatment, its options tailored to this project.
## Handoff
One session; state which structural choices came from the reference
butter-reviews-to-ads9.33 KB
---
name: butter-reviews-to-ads
description: Find the best customer reviews and turn them into 3 ads. Use when the user wants ads built from customer reviews, testimonials, or social proof.
---
# Reviews → Ads
Find the best customer reviews and turn them into 3 ads.
## Before you start
Anything the user has already told you, or that the sources under "Gather first" already cover, is known — do not ask for it again; if nothing is missing, go straight to "Gather first". Otherwise ask for what is still missing with `askQuestions`, once, before gathering. It runs inside a session, so call `startSession` first, as in step 1 of "Building each video", and pass its `sessionId`; then pass only the questions below that are still unknown, and add your own for anything else you cannot build without — give an option shaped { "label": "…", "input": "url" } when the answer is a link, { "label": "…", "input": "upload" } when the user should provide a file, and leave out options for free text. Then end your turn — the answers arrive as the user's next message, starting "Answers:". Do not ask them again in chat, with three exceptions, each at most once: when an answer says the user will upload a file in chat, ask them in plain chat to attach it; when a shared ad link cannot be read, ask for a screenshot; and when something you cannot build without was skipped, ask for it. Upload any attached file with `uploadSessionAsset` into that session. For any other skipped question, use your best judgment: its recommended answer if it has one, otherwise what you can infer from the sources you have.
```json
{"questions":[{"title":"What should I use as a visual reference?","options":[{"label":"Match my website's branding (recommended)","input":"url"},{"label":"Match an ad I'll share","input":"url"},{"label":"Upload an ad in chat","input":"upload"}]},{"title":"Where should the assets, product details and copy come from?","options":["Use my website (recommended)",{"label":"Upload my images in chat","input":"upload"},"Use a connected source"]},{"title":"How long should the video be?","options":["15 seconds (recommended)","6 seconds","30 seconds"]}]}
```
## Gather first
Butter does not supply this data — it comes from the connectors already available to you, or from
what the user provides.
- Highest-rated recent reviews with product and reviewer name, from a reviews connector
- Images of the products those reviews name
If a source is unavailable, say so and ask the user for it rather than inventing figures. Never
invent an offer, a price, a discount, or a performance claim the user did not give you.
## Hold constant
The brand voice and visual system
## Vary
Which proof point leads, and which product it is matched to
## How many
3
## Format
Vertical for social, square for feed
## Building each video
Butter turns HTML + CSS into an editable Butter project.
**Every Butter tool takes a `userPrompt`, and every call must carry one.** It is the user's latest
message word for word — what they typed, never your summary of it and never your own reasoning. On
`startSession` that is the message that asked for the video in the first place. Leave it out only
when nothing the user said prompted the call.
For every video this workflow calls for:
1. Call `startSession`, unless you already opened one for `askQuestions` that no video is built in
yet — build this video there instead. If this chat has already started a Butter session, ended or not, pass the
`sessionId` of the most recent one as `previousSessionId` so the sessions of one conversation
link up; leave it out only for the first. Pass `goal`: the outcome the user wants the video to
achieve, in one sentence, inferred from their request. It returns a `sessionId`, `userPreferences`
and the HTML contract. **The contract is authoritative** — follow it exactly, and re-read it rather
than relying on memory. `userPreferences` is what earlier sessions learned about how this user likes their videos made, one preference per entry. Treat them as already known: follow them, and do not ask about what they settle, unless the user now asks for something different. Keep track as you work: add a preference the user states or their reactions reveal, reword or remove one they contradict, and keep the rest. Record only how they like the work done (format, length, pacing, tone, style), never personal details about them. Pass only what changed as `userPreferenceChanges` on endSession, never the whole list: `added` for new preferences, `removed` for ones to drop, and `updated` as `{ old, new }` pairs for rewordings.
2. Upload **every** image and video the video will use with `uploadSessionAsset` before it
goes in the page, including any you add while iterating. The page uses the urls it returns, never
the original links: the page runs on them, and `endSession` rejects any other url. Upload
each file **once**: an asset used more than once, such as the logo in every variant, keeps the url
from its first upload in every video and session that uses it. Each upload is a public https link, or a file under 2MB; for a larger local file, ask for a link instead.
3. Write ONE self-contained HTML document that plays itself: a single timeline, elements positioned
in time with `animation-delay` measured from the start of the whole video, and
`animation-fill-mode: both` on every animation. CSS motion is unrestricted and read back
automatically. The video is silent: add no music, sound effects or voiceover. Anything visual a
script drives is invisible to the extractor, so its timing has to be declared by hand in the
manifest. Never show the user the HTML or anything rendered from it. Do not make it into an artifact, a canvas, a widget or a file, do not paste it into your reply, do not open it in a browser tab, window or side panel the user can see, and do not share a preview url. The user sees the video only as the Butter project link endSession returns.
4. Call `submitSessionVersion` with the `sessionId` and the html. It returns lint findings.
5. Fix every **blocking** finding and resubmit — a version with blocking findings cannot be built.
Warnings are safe to ship but cost editability, so prefer fixing them.
6. Do not ask the user whether they are happy with the video. As soon as the version you are shipping has no blocking findings, call
`prepareEndSession` with the session id and its version id. It returns the instructions for
measuring that version into a manifest: follow them, then call `endSession` with the session id,
the version id, that manifest, `estimatedRating`: your 1 to 10
estimate of how successful the session was, judged from how the user reacted to the projects
already built in this chat and how many rounds of changes it took, and `userPreferenceChanges`:
the preferences you `added`, `removed` or `updated`. `endSession` cannot be called
until `prepareEndSession` has been. Neither waits for the user's approval.
7. A successful `endSession` also ends the session for good: the build-session tools refuse it
from then on, and only `repairProject` and `askNextSteps` still take its ids. Whatever comes
next starts a session of its own — the asset urls already uploaded stay valid there.
8. `endSession` answers with only the ids: call `repairProject` next with the same ids, before
telling the user anything. It checks what did not survive conversion. When nothing needs
repair it routes you to `askNextSteps`; when something does it lists the repairs — make
ONLY those by driving the editor, then finish on `askNextSteps` with the same ids and
`repaired`: a line on what was put back. Do not offer the repairs or ask permission.
9. The build report lives in `askNextSteps`.
Never tell the user the project is open — the card gives them the link.
Say your one line about the build first, then call `askNextSteps` with those ids as your LAST action
and end the turn — no text after it: the card it renders carries the link, the report and
the suggested next steps (Edit this project, Make another version, or Adapt the format). They are suggestions, not
steps — the user may simply be done; wait for their answer rather than picking one. Edits to the built project go through `startEditSession`. A variant begins with
`describeProject` — the project as it is NOW, studio edits included, custom blocks named as
opaque references — then a fresh `startSession` to re-author it, or `cloneProject` +
`startEditSession` on the clone when the changes are small (a clone keeps custom blocks
verbatim; a rebuilt variant cannot). Some answers need detail the session cannot start without. Collect it with ONE askQuestions follow-up call — one question per missing detail — and only then start the session:
- "Add an end card": what the end card should include
- "Add background music": whether to upload a file, generate it, or choose from stock
- "Add sound effects": whether to upload a file, generate it, or choose from stock
- "Add a voice over": whether to upload a file, generate it, or choose from stock
- "New layout": which layout, with options tailored to this project
- "Different visual style": which style, with options tailored to this project
Any other answer naming a direction without its detail gets the same treatment, its options tailored to this project.
## Handoff
One session per creative; quote reviews verbatim and never invent one
butter-static-to-motion9.24 KB
---
name: butter-static-to-motion
description: Turn the best-performing static ads into motion ads. Use when the user wants to animate an existing static ad, turn stills into video, or add motion without changing a design.
---
# Static → Motion
Turn the best-performing static ads into motion ads.
## Before you start
Anything the user has already told you, or that the sources under "Gather first" already cover, is known — do not ask for it again; if nothing is missing, go straight to "Gather first". Otherwise ask for what is still missing with `askQuestions`, once, before gathering. It runs inside a session, so call `startSession` first, as in step 1 of "Building each video", and pass its `sessionId`; then pass only the questions below that are still unknown, and add your own for anything else you cannot build without — give an option shaped { "label": "…", "input": "url" } when the answer is a link, { "label": "…", "input": "upload" } when the user should provide a file, and leave out options for free text. Then end your turn — the answers arrive as the user's next message, starting "Answers:". Do not ask them again in chat, with three exceptions, each at most once: when an answer says the user will upload a file in chat, ask them in plain chat to attach it; when a shared ad link cannot be read, ask for a screenshot; and when something you cannot build without was skipped, ask for it. Upload any attached file with `uploadSessionAsset` into that session. For any other skipped question, use your best judgment: its recommended answer if it has one, otherwise what you can infer from the sources you have.
```json
{"questions":[{"title":"Which static ad should I animate?","options":[{"label":"Upload it in chat","input":"upload"},{"label":"Link to the ad","input":"url"},"Use my top static ad from a connected source"]},{"title":"Where should the assets, product details and copy come from?","options":["Use my website (recommended)",{"label":"Upload my images in chat","input":"upload"},"Use a connected source"]},{"title":"How long should the video be?","options":["6–8 second loop (recommended)","6 seconds","15 seconds","30 seconds"]}]}
```
## Gather first
Butter does not supply this data — it comes from the connectors already available to you, or from
what the user provides.
- The product shots and logo used in the static ad
If a source is unavailable, say so and ask the user for it rather than inventing figures. Never
invent an offer, a price, a discount, or a performance claim the user did not give you.
## Hold constant
The composition, palette and copy exactly as they are
## Vary
Only motion: entrance order, pacing and emphasis
## How many
1
## Format
One project per placement the source ran in
## Building each video
Butter turns HTML + CSS into an editable Butter project.
**Every Butter tool takes a `userPrompt`, and every call must carry one.** It is the user's latest
message word for word — what they typed, never your summary of it and never your own reasoning. On
`startSession` that is the message that asked for the video in the first place. Leave it out only
when nothing the user said prompted the call.
For every video this workflow calls for:
1. Call `startSession`, unless you already opened one for `askQuestions` that no video is built in
yet — build this video there instead. If this chat has already started a Butter session, ended or not, pass the
`sessionId` of the most recent one as `previousSessionId` so the sessions of one conversation
link up; leave it out only for the first. Pass `goal`: the outcome the user wants the video to
achieve, in one sentence, inferred from their request. It returns a `sessionId`, `userPreferences`
and the HTML contract. **The contract is authoritative** — follow it exactly, and re-read it rather
than relying on memory. `userPreferences` is what earlier sessions learned about how this user likes their videos made, one preference per entry. Treat them as already known: follow them, and do not ask about what they settle, unless the user now asks for something different. Keep track as you work: add a preference the user states or their reactions reveal, reword or remove one they contradict, and keep the rest. Record only how they like the work done (format, length, pacing, tone, style), never personal details about them. Pass only what changed as `userPreferenceChanges` on endSession, never the whole list: `added` for new preferences, `removed` for ones to drop, and `updated` as `{ old, new }` pairs for rewordings.
2. Upload **every** image and video the video will use with `uploadSessionAsset` before it
goes in the page, including any you add while iterating. The page uses the urls it returns, never
the original links: the page runs on them, and `endSession` rejects any other url. Upload
each file **once**: an asset used more than once, such as the logo in every variant, keeps the url
from its first upload in every video and session that uses it. Each upload is a public https link, or a file under 2MB; for a larger local file, ask for a link instead.
3. Write ONE self-contained HTML document that plays itself: a single timeline, elements positioned
in time with `animation-delay` measured from the start of the whole video, and
`animation-fill-mode: both` on every animation. CSS motion is unrestricted and read back
automatically. The video is silent: add no music, sound effects or voiceover. Anything visual a
script drives is invisible to the extractor, so its timing has to be declared by hand in the
manifest. Never show the user the HTML or anything rendered from it. Do not make it into an artifact, a canvas, a widget or a file, do not paste it into your reply, do not open it in a browser tab, window or side panel the user can see, and do not share a preview url. The user sees the video only as the Butter project link endSession returns.
4. Call `submitSessionVersion` with the `sessionId` and the html. It returns lint findings.
5. Fix every **blocking** finding and resubmit — a version with blocking findings cannot be built.
Warnings are safe to ship but cost editability, so prefer fixing them.
6. Do not ask the user whether they are happy with the video. As soon as the version you are shipping has no blocking findings, call
`prepareEndSession` with the session id and its version id. It returns the instructions for
measuring that version into a manifest: follow them, then call `endSession` with the session id,
the version id, that manifest, `estimatedRating`: your 1 to 10
estimate of how successful the session was, judged from how the user reacted to the projects
already built in this chat and how many rounds of changes it took, and `userPreferenceChanges`:
the preferences you `added`, `removed` or `updated`. `endSession` cannot be called
until `prepareEndSession` has been. Neither waits for the user's approval.
7. A successful `endSession` also ends the session for good: the build-session tools refuse it
from then on, and only `repairProject` and `askNextSteps` still take its ids. Whatever comes
next starts a session of its own — the asset urls already uploaded stay valid there.
8. `endSession` answers with only the ids: call `repairProject` next with the same ids, before
telling the user anything. It checks what did not survive conversion. When nothing needs
repair it routes you to `askNextSteps`; when something does it lists the repairs — make
ONLY those by driving the editor, then finish on `askNextSteps` with the same ids and
`repaired`: a line on what was put back. Do not offer the repairs or ask permission.
9. The build report lives in `askNextSteps`.
Never tell the user the project is open — the card gives them the link.
Say your one line about the build first, then call `askNextSteps` with those ids as your LAST action
and end the turn — no text after it: the card it renders carries the link, the report and
the suggested next steps (Edit this project, Make another version, or Adapt the format). They are suggestions, not
steps — the user may simply be done; wait for their answer rather than picking one. Edits to the built project go through `startEditSession`. A variant begins with
`describeProject` — the project as it is NOW, studio edits included, custom blocks named as
opaque references — then a fresh `startSession` to re-author it, or `cloneProject` +
`startEditSession` on the clone when the changes are small (a clone keeps custom blocks
verbatim; a rebuilt variant cannot). Some answers need detail the session cannot start without. Collect it with ONE askQuestions follow-up call — one question per missing detail — and only then start the session:
- "Add an end card": what the end card should include
- "Add background music": whether to upload a file, generate it, or choose from stock
- "Add sound effects": whether to upload a file, generate it, or choose from stock
- "Add a voice over": whether to upload a file, generate it, or choose from stock
- "New layout": which layout, with options tailored to this project
- "Different visual style": which style, with options tailored to this project
Any other answer naming a direction without its detail gets the same treatment, its options tailored to this project.
## Handoff
One session per source creative
Technical details
- First seen
- Sep 30, 2026 · 22:02 UTC
- Last seen
- Oct 1, 2026 · 12:00 UTC
- Collection status
- Collected
plugin_asdk_app_6aa99efe80b48191a87d2cc21193994e
Download listing JSON