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 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.
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.jsonand the API - CLI:
npm install -g aicontentdropgives youacd, which reads the key
is at /v1. Same Bearer key, same quote contract, same submit-and-poll shape: POST /v1/generate/video, then GET /v1/videos/{id}.
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.
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 · the MCP reference · the skills