---
title: "Install AI Content Drop in Meta Muse | AI Content Drop"
description: "Have Meta Muse build its own integration to the AI Content Drop MCP server: the message to paste, where the API key goes, which actions to hold for approval, and the quote-then-generate contract."
canonical: "https://aicontentdrop.com/docs/install/muse"
source: "https://aicontentdrop.com/docs/install/muse"
---

# AI Content Drop in Meta Muse

OAuth sign-in has been verified. Follow the connection steps below.

Muse does not read a config file. You describe the service in a message, and
Muse writes its own client against our MCP server, lists the tools, calls them
end to end, and saves the working integration as a skill you can reuse in later
conversations. So the setup here is one message rather than a JSON block.

## The message to paste

> Build a custom integration to AI Content Drop. Its MCP server URL is
> https://aicontentdrop.com/mcp (streamable HTTP; authenticate with an API key
> as `Authorization: Bearer` from Settings › Integrations, or sign in with
> OAuth). I want you to be able to quote the cost of a video or image, generate
> it, and check on it. Generations are submit-and-poll: never wait inside a
> tool call. For anything with more than one step, build it on a board with the
> cards connected in order and give me the board's link.

Muse will ask whether the server is reachable over HTTP or runs locally. It is
hosted and remote: `https://aicontentdrop.com/mcp`, streamable HTTP, no local process.

## The credential

Create a key at [Settings → Integrations](https://aicontentdrop.com/settings/integrations) and
give it to Muse **when Muse asks for it**, in the credential prompt. It is
stored outside the conversation and attached to the request as an
`Authorization: Bearer acd_live_…` header on the way out. Never paste a key
into the chat itself: anything typed in the thread is conversation text, not a
stored credential.

OAuth sign-in is the alternative if you would rather not hold a key. Keys are
available on a paid plan; the public read tools — models, prices and quotes,
guides, ad formats and avatars (`list_models`, `estimate_credit_cost`,
`search_articles`, `get_article`, `list_ad_formats`, `list_ugc_avatars`,
`estimate_ad_cost`) — answer with no credential at all, so Muse can browse the
catalogue and price a job before any of this.

## The policy to set

Muse lets you set a policy per connector: allow every action, require approval
for an action, or keep the whole connector read-only. Credits are only ever
charged by the tools that start a render, so:

| Action | Policy |
| --- | --- |
| `generate_video` | require approval |
| `generate_image` | require approval |
| `run_generation_card` | require approval |
| `approve_drop_spend` | require approval |
| everything else | allow: nothing else spends credits, and the board tools need to write cards |

`list_models`, `estimate_credit_cost`, `get_generation`, `list_generations`,
`get_account`, `search_articles` and `get_article` never spend anything, so a
read-only policy on them costs you no capability.

## Quote first, then generate

Every generation needs a `quote_id` from `estimate_credit_cost` for the same
model, duration and resolution. The quote is signed, valid for 15 minutes, and
is also the idempotency key: retrying `generate_video` with the same `quote_id`
returns the original job instead of starting a second one. A generation call
without a quote is refused with `QUOTE_REQUIRED`.

Credits are charged on success only. A safety refusal, a failed render or a
timeout costs nothing.

## Submit, then poll

`generate_video` and `generate_image` return a job id in about a second; the
render itself takes one to four minutes. Read the result with `get_generation`
until the job reports `completed`. Nothing in this API blocks on a render, and
a tool call that waits for one will hit Muse's own timeout long before the job
is done.

## More than one step: a board with connected cards

For anything with more than one step (an image that becomes a video, several
variations of one idea), Muse should build it on a board rather than chain
loose calls: `create_canvas`, then one `add_generation_card` per step, adding
each later step with `from_card_id` so the board connects the cards and the
earlier card's finished image becomes the next card's start frame
(`connect_cards` links any other two cards). It runs the cards in order with
`run_generation_card`, each with its own quote, polls `refresh_canvas`, and
hands you the page from `get_canvas_link`, where the work shows as connected
cards.

## Drops

The drop tools (`start_drop`, `ask_drop`, `get_drop`, `approve_drop_spend`,
`list_drops`) appear only for accounts that can use them. Where they are
listed, Muse should offer a drop for a whole campaign or several videos from
one brief: `start_drop` opens the drop, `ask_drop` sends the brief (the drop may
ask a few questions first — answer them with `ask_drop`), `get_drop` polls it,
and `approve_drop_spend` releases each priced step with the exact `quote_id`
from `pending_approval`. A planning turn can outlast a minute: `ask_drop` then
answers that the drop is still working, and `get_drop` carries the reply once
it lands. Do not resend the message.

## What a refusal looks like

Failures are typed, not prose. Each one carries a stable `code`, a `message`, a
`next_step`, and `retryable`; a rate limit adds `details.retry_after_seconds`
saying how long to wait. `QUOTE_REQUIRED`, `QUOTE_EXPIRED` and `QUOTE_MISMATCH`
mean quote again for the exact job. `AUTH_REQUIRED` and `INVALID_TOKEN` are
about the credential. `RATE_LIMITED` and `UPSTREAM_TEMPORARY` are the two worth
retrying unchanged. Repeat the code to the person rather than paraphrasing it —
every code is documented on [the errors page](https://aicontentdrop.com/docs/errors).

## If you would rather not use MCP

Muse also builds clients from an OpenAPI document or an npm CLI, and the same
account works through either.

- **REST**: the spec is at [`/openapi.json`](https://aicontentdrop.com/openapi.json) and the API
  is at [`/v1`](https://aicontentdrop.com/v1). Same Bearer key, same quote contract,
  same submit-and-poll shape: `POST /v1/generate/video`, then
  `GET /v1/videos/{id}`.
- **CLI**: `npm install -g aicontentdrop` gives you `acd`, which reads the key
  from the `ACD_API_KEY` environment variable. `acd models`, `acd cost`,
  `acd generate` and `acd status` cover the same ground.

## Troubleshooting

**Every call answers `401`.** The key is missing or wrong. Confirm Muse holds
it as a credential rather than in the message text, and that it travels as an
`Authorization: Bearer` header — a key in a query string or a request body is
never read.

**A refusal names the plan.** `ENTITLEMENT_REQUIRED` means the account cannot
create an API key or run a generation on its current plan. The public tools
still work. What each plan includes is described on
[the plans page](https://aicontentdrop.com/plans).

**Muse waits, then reports a timeout.** The integration is waiting inside the
generation call instead of polling. Tell it: submit, then call `get_generation`
on a loop.

**`QUOTE_REQUIRED`, `QUOTE_EXPIRED` or `QUOTE_MISMATCH`.** Every generation
needs a fresh `quote_id` from `estimate_credit_cost` for the same model,
duration and resolution. Quote again and retry.

See also: [the plugin overview](https://aicontentdrop.com/plugin) ·
[the MCP reference](https://aicontentdrop.com/docs/mcp) ·
[the skills](https://aicontentdrop.com/skills)
