MCP server
ReelMoney runs a Model Context Protocol server at https://reel.money/mcp. Point Claude, Cursor, or any MCP client at it and the model gets 18 tools that do the same work as the REST API, calling the same code underneath, so the two surfaces can never drift.
| Endpoint | https://reel.money/mcp |
| Transport | Streamable HTTP, stateless. One self contained exchange per POST. |
| Auth | Authorization: Bearer rm_your_key, the same key the REST API takes. |
| Protocol | JSON-RPC 2.0: initialize, tools/list, tools/call. |
There is no OAuth flow yet. The key goes in the header, which every client below supports.
Connect a client
Claude Code, one line in a terminal:
claude mcp add reelmoney --transport http https://reel.money/mcp --header "Authorization: Bearer rm_your_key"
Claude Desktop, Cursor and anything else that reads a JSON config:
{
"mcpServers": {
"reelmoney": {
"type": "http",
"url": "https://reel.money/mcp",
"headers": {
"Authorization": "Bearer rm_your_key"
}
}
}
}
A raw check with curl, useful when a client is quiet about why it failed:
curl -X POST https://reel.money/mcp \
-H "Authorization: Bearer rm_your_key" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
The tools
| Tool | What it does | Kind | Scope |
|---|---|---|---|
get_account | Read the account behind this API key: masked email, plan name and capabilities (slideshow quota used and remaining), credits when the plan shows them, brands and key scopes. | read only | brand:read |
get_brand | Read the brand this key belongs to: name, description, website, language, categories, slideshow settings (default context, slide overrides, append slots) and which social platforms are connected. | read only | brand:read |
list_media | Browse media: source own (this brand's uploads), packs (media pack contents) or stock (the shared catalog, searched semantically when you pass a query). | read only | media:read |
upload_media | Upload a file in two steps. | writes | media:write |
create_slideshow | Start an AI slideshow generation for this brand and get back a job. | writes | content:write |
update_slideshow | Edit a generated slideshow: title, caption, tags, aspect ratio, gradient settings or the slides themselves (text overlays are normalized server side). | writes | content:write |
create_video | Start a hook and demo (UGC) video: an avatar clip speaks the hook_text, then your product demo clips play. | writes | content:write |
render_video | Render a generated slideshow into an MP4 video. | writes | content:write |
get_job | Poll a generation or render job by the job_id a create tool returned. | read only | brand:read |
list_shorts | List this brand's shorts (slideshows and videos), newest first. | read only | brand:read |
get_short | Read one short in full: status, URLs, type_data (slides and overlays for a slideshow) and its shares (posts) so far. | read only | brand:read |
list_connections | List the social accounts connected to this brand with token status, posting rate limit headroom and a ready_to_post verdict per account. | read only | brand:read |
create_connection_link | Build the OAuth authorize URL a person opens once in a browser to connect a social account to this brand. | read only | brand:read |
validate_post | Dry run a post before you commit to it: same arguments as schedule_post, returns a per-account verdict (postable short, fresh tokens, caption and title lengths, platform rate limits, schedule sanity). | read only | posts:read |
schedule_post | Publish a short now, or schedule it, to connected accounts. | destructive, ask a person first | posts:write |
cancel_post | Cancel a scheduled post (a share id from schedule_post results or get_short) before it goes out. | destructive, ask a person first | posts:write |
get_analytics | Read post analytics. | read only | analytics:read |
explain_error | Look up any error code another tool or the REST API returned and get its cause, whether a retry can help, and the concrete fix. | read only | any key |
Every tool carries a title and the standard annotations, so a client can tell a read from a write before it calls anything.
Rules a client should know
- A missing scope does not hide a tool. Every key sees all 18 tools. A tool the key lacks the scope for answers at call time with a structured
missing_scopeerror that names the scope and how to add it. Predictable beats surprising. - **
brand_idpicks the brand, when the key allows it.** Every brand facing tool takes an optionalbrand_idargument. Omit it and the tool works on the key's own brand. A key with thebrands:allscope may pass any brand id the account owns (get_accountlists them); without the scope a foreignbrand_idanswers a structuredmissing_scopeerror, and an id the account does not own answersnot_found. - Two tools are marked destructive.
schedule_postandcancel_postcarrydestructiveHintand_meta: {"anthropic/requiresUserInteraction": true}. Publishing to an audience and pulling a post back are decisions a person should confirm. Treat the prompt as the point of the annotation, not as a formality. - GET /mcp answers 405. The server is stateless, so there is no session to attach a server sent event stream to. Use POST.
DELETE /mcpanswers 200 and does nothing, since there is no session to end. - Bad key, 401 at the transport. Authentication happens before any protocol handling, so an invalid key answers HTTP 401 with
WWW-Authenticate: Bearer realm="ReelMoney", error="invalid_token"and the usual error envelope, not a JSON-RPC error. - Rate limits are shared with REST. The same per key ceilings apply. See authentication.
Result size and pagination
Tool results are token budgeted, around 25k tokens in Claude Code, and a blown budget wastes a whole turn. So:
- Lists come back capped at 20 items with a note. Pass
pageto walk further instead of asking for everything. - Prefer a list tool with a filter over a list tool without one.
list_shortswithshort_typeandstatusbeats reading the whole library. get_shortreturns full detail including slides and overlays. Call it for one record, not in a loop over a list.get_analyticswithout arguments returns account summaries; addsocial_data_idonly when you need post by post numbers.
A working loop
get_account. Read the plan and how much quota is left. Stop here if there is not enough.get_brandand, when you need a specific look or a media pack,list_media.create_slideshoworcreate_video. Both answer with ajob_id.get_job, no faster thanpoll_after_seconds, until it readssucceededorfailed.render_videowhen a caller wants an MP4 of a slideshow. Never create a second slideshow for that.list_connections, thenvalidate_post, thenschedule_post. Read every verdict before you post, and every result after.get_analyticsa day or two later to see what it did.explain_errorfor any code you do not recognise, instead of guessing from the message.
Reading this as an agent? Every page is also plain markdown: /api-docs/mcp.md