MCP Support
Remix Studio exposes a streamable HTTP Model Context Protocol (MCP) endpoint at /mcp. It lets an external client work with the same user-scoped libraries, projects, models, storage summaries, campaigns, and posts used by the web interface.
The in-app assistant is built on the same tool registry, but authentication and write confirmation differ.
Capabilities
Available MCP capabilities include:
- Create libraries and create text prompts, including batch prompt creation.
- Search library items across libraries, or browse a single library with pagination and tag filters.
- Update a single text prompt's content, title, or tags with
update_prompt. - Delete a single text prompt from a text library with
delete_prompt. - Inspect storage usage, albums, libraries, library items, and usable model/provider pairings.
- Browse the items inside a project album with
get_album_items, including each item's filename, prompt, tags, format, aspect ratio, size, and storage keys, plus atagCountsroll-up of every tag in the album. Filter withtagsandtag_match. - Read one item by ID with
get_album_item(its full prompt and, for a text project, the full generated text, with the project's name and link) orget_library_item(the full text, or the storage key of a media item, with the library's name, type and link). Both take the IDs from a reference the user copied with Copy ID for AI — see item references. - Tag album items with
tag_album_items—add,remove, orreplacetags on the ids given initem_ids, or on every item in the album withall_items, optionally narrowed byfilter_tagsandaspect_ratios. - Rename album items with
rename_album_items— rename specific items withupdates, or batch-replace / prepend / strip filename prefixes acrossitem_idsorall_itemswithold_prefixandnew_prefixwhile keeping storage keys, thumbnails, optimized files, and originating job records in sync. - Download stored files with
get_file_urls, which converts internal storage keys into temporary presigned URLs (optionally as save-as download links). - Upload image, video and audio files with
create_upload, then add them to a library (add_files_to_library), pin them in a project workflow (uploadIdonupdate_project/create_project_with_workflowitems), or post them to a campaign (create_posts_from_files,add_media_to_post). See file uploads. - Export a project album as a .zip with
export_project_album, or a whole project as a portable bundle withexport_project. - Create and update workflow-backed projects, including Civitai projects.
- Stage and run generation:
draft_jobsbuilds draft jobs from a project's workflow,start_jobsqueues all of them or a chosen number, andget_project_job_countsreports drafts, queue depth, completed runs, and album totals. - Monitor the queue across every project with
get_queue_status, which returns the counts behind the queue monitor page — running, queued, failed, and provider slots — withbreakdownreproducing either tab of that page (providersfor each provider queue's slots, limit, and depth;projectsfor each project holding jobs), and never the job list itself. - Clear failed jobs with
clear_failed_jobs, the same action as the queue monitor's clear buttons — scoped to one project (projectId), one provider queue (providerId), or the whole account when neither is given.
Write and destructive tools are confirmation-gated. Prompt deletion is scoped to one item in a text library and requires an explicit confirmed tool call, and so does clearing failed jobs.
Exports
export_project_album archives the media saved in a project's album — the entire album by default, or just the ids passed in item_ids. export_project archives a whole project (settings, workflow, album metadata, and every media file they reference) as a bundle another Remix Studio installation can import.
Both are queued in the background, exactly like an export started from the web interface:
- The call waits up to
wait_seconds(default 120, max 600) and returnsdownloadUrlonce the archive is ready — a temporary link valid for about 24 hours. - If the archive is still building when the wait runs out, the response carries
status,filesArchived/filesTotal, and ataskId. Re-call the same tool withtask_idto keep waiting; do not start a second export. - Finished archives appear in the user's exports list and count against their storage quota, so an export can be refused with a storage-limit error.
File access
Read tools return storage keys, not links. To fetch, view, or download a file, pass those keys to get_file_urls:
- Accepts up to 50 keys per call, with
expires_inbetween 60 and 86400 seconds (default 1 hour) anddownload: truefor an attachment (save-as) URL. - Signs a key only when it is still referenced by media the authenticated user owns — library items, album items, job outputs, project workflow items, or campaign post media. Everything else is returned under
deniedwith a reason, and values that are already absolute URLs are rejected as needing no signing. - Returned URLs are temporary; request new ones rather than reusing expired links. When the deployment sets
S3_PUBLIC_CUSTOM_DOMAIN, storage returns a direct public URL instead of a signed one.
File uploads
File bytes never travel inside a tool call. A client that has the file on disk (a shell, a script, a code sandbox) stages it first and attaches it second:
- Stage.
create_uploadtakes each file'sfilename,mimeTypeand exactsizein bytes and returns anuploadIdand a one-timeuploadUrl, plus a readycurlcommand. It needs no confirmation, because staging changes nothing the user can see. - Send the bytes.
PUTthe raw file to theuploadUrl—curl -sS -T hero.png "<uploadUrl>". NoAuthorizationheader and no multipart encoding: the single-use token in the URL is the credential. A successful upload answers200with"status": "ready". - Attach. Pass the
uploadIdto one of the attach tools, which go through the normal confirmation protocol:
| Destination | Tool | What it creates |
|---|---|---|
| Image, video or audio library | add_files_to_library | A library item per file; the title defaults to the file name |
| Project workflow | update_project, create_project_with_workflow | An image, video or audio item with uploadId instead of value |
| Campaign | create_posts_from_files | One draft post per image or video, with the post watermark applied |
| Existing post | add_media_to_post | A post media item, processed in the background |
Rules the server enforces:
- Supported types are images (PNG, JPEG, WebP, GIF; up to 50 MB), videos (MP4, MOV, WebM, MKV; up to 200 MB) and audio (MP3, AAC, M4A, WAV, OGG, WebM; up to 50 MB) — the same limits as uploads in the web app.
- The type is detected from the file's bytes. A file declared as an image whose contents are audio is refused, and so is a body whose length differs from the declared
size. - An
uploadUrlaccepts onePUTand expires after 15 minutes. A staged file can be attached any number of times for 24 hours; each attach makes its own copy, then the staged file is deleted. - Staged files count toward the storage quota until they are deleted, and
create_uploadrefuses files that would not fit.get_storage_usagereports them understaging. get_uploadreports each upload's status:awaiting_upload,processing,ready, orfailedwith anerror.
These tools are offered to external MCP clients only. The in-app assistant has no way to send file bytes, so it does not see them.
Civitai projects
create_project_with_workflow and update_project take type civitai. Set providerId to a Civitai provider — list_available_models lists them under civitaiAccounts — leave modelConfigId out, and put the shared settings in civitaiSettings, including mediaType: "video" and video (engine, resolution, length…) for a video project. The workflow also takes:
| Item type | Holds |
|---|---|
checkpoint | Images only; exactly one item, whose models lists one or more checkpoints by Civitai link or AIR — one per job |
lora | Any number; each lists one or more LoRAs, LyCORIS, DoRAs or embeddings with their strengths — one per job |
negative_text, negative_text_library | Text or a text library that feeds the negative prompt |
Models are resolved with the project's Civitai account and reused as they are when carried forward from get_project. draft_jobs drafts Civitai combinations like any other.
ComfyUI projects are set up in the app, since they start from an exported workflow graph; an agent can read them, draft their jobs and start them.
Item references
Copy ID for AI in the app copies a reference that names the item and its parent, because every tool that acts on an item needs both:
| Reference | Tools it fills |
|---|---|
library:<libraryId>/item:<itemId> | get_library_item, update_library_item, update_prompt, delete_prompt |
project:<projectId>/album-item:<itemId> | get_album_item, tag_album_items, rename_album_items, export_project_album (item_ids) |
campaign:<campaignId>/post:<postId> | get_post, get_post_text, update_post, update_post_text, add_media_to_post, schedule_post |
The server's instructions describe these shapes to the client, so a user can paste one into the chat and the agent reads or changes exactly that item.
Live page updates
Open Remix Studio pages show what an MCP client changes without a reload: a library the client creates appears in the libraries list, prompts it adds appear on the library page, a workflow it replaces with update_project appears in the open project, and posts it creates or edits appear on the campaign and post pages. Each signed-in browser tab keeps one change feed for its user; see live updates.
Record links
Tools return absolute Remix Studio links next to the raw ids, so a client can show the user where a record lives instead of quoting an id:
url— the library, project, campaign, or post the call is about (list_librariesentries,get_project,create_campaign,get_post, …).libraryUrl/projectUrl/campaignUrl— the parent record when it is context for something else (search_library_itemsresults,get_album_items, post tools).
The origin comes from APP_URL when it is configured; otherwise the server falls back to the origin of the incoming MCP request (honoring X-Forwarded-Proto / X-Forwarded-Host). Set APP_URL to the browser-visible origin of your deployment so the links are shareable.
Authentication
MCP requests require a bearer token obtained through either:
- OAuth 2.0 authorization code flow, with PKCE support and refresh tokens.
- A personal access token (PAT) created in Remix Studio.
Manage connections under Assistant Settings → MCP. PATs are shown only when created, are stored as hashes, can have an expiry, and can be revoked. All MCP tools use the mcp:tools scope and enforce the authenticated user's ownership in their handlers.
OAuth discovery metadata is available at:
/.well-known/oauth-authorization-server/.well-known/oauth-protected-resource
The related endpoints are /register, /authorize, and /token. Dynamically registered clients are tied to the account that created them. The server rotates OAuth refresh tokens and detects reuse outside its recovery grace window.
Client Configuration with a PAT
{
"mcpServers": {
"remix-studio": {
"type": "http",
"url": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer YOUR_MCP_TOKEN"
}
}
}
}Replace the origin with the public APP_URL of your deployment. Use HTTPS outside local development because the token grants access to your Remix Studio data.
For clients without MCP support — scripts, curl, a language with no MCP SDK — the endpoint can be driven as plain JSON-RPC over HTTP. See Calling MCP Tools over HTTP.
Tool Catalog
The exact schemas are returned by MCP tool discovery. At the current source version, the catalog is:
| Area | Read tools | Write/destructive tools |
|---|---|---|
| Account | get_current_account | — |
| Libraries | list_libraries, get_library_items, get_library_item, search_library_items | create_library, update_library, create_prompt, batch_create_prompts, update_prompt, update_library_item, batch_update_library_items, delete_prompt |
| Projects | get_project, list_albums, get_album_items, get_album_item, list_available_models, get_storage_usage | create_project_with_workflow, update_project, tag_album_items, rename_album_items, export_project, export_project_album |
| Jobs | get_project_job_counts, get_queue_status | draft_jobs, start_jobs, clear_failed_jobs |
| Files | get_file_urls, get_upload | create_upload, add_files_to_library, create_posts_from_files |
| Campaigns | list_social_accounts, list_campaigns | create_campaign, update_campaign |
| Posts | list_posts, get_post, get_post_text | create_post, update_post, update_post_text, add_media_to_post, schedule_post |
Important boundaries:
get_current_accountreports the account the token resolves to — the same account every other tool reads and writes. It never exposes secrets (no password hash, no token material) and cannot look up other users.- Prompt creation/deletion is for text libraries.
update_library_itemcan update text content only for a text library; batch updates change titles/tags only and accept at most 100 items.update_projectreplaces the entire workflow whenworkflowItemsis supplied. Callget_projectimmediately beforehand and carry forward every step that should remain.draft_jobstakes its prompts, provider, model, and generation settings from the project itself — set them withupdate_projectfirst. It creates at most 10000 drafts per call; call it again for larger batches.start_jobsconsumes drafts oldest first and runs generation against the user's provider, which costs credits. Omitcountto start every draft.clear_failed_jobsdeletes failed job records only — drafts, queued, running, and completed jobs are untouched, and album items already saved survive. A cleared failure can no longer be retried.projectIdandproviderIdare alternatives, not filters to combine; omitting both clears every failed job in the account. Pending jobs in an affected project are re-enqueued, so a project stalled behind failures resumes on its own.tag_album_itemstakes exactly one ofadd,remove, orreplaceper call.replacediscards whatever other tags the items carried, andreplace: []clears them entirely. Tags are normalised on write — trimmed, de-duplicated case-insensitively, capped at 64 characters each and 30 per item.- Export tools are confirmation-gated writes because the archive they produce consumes the user's storage quota. Polling with
task_idgoes through the same protocol. - Media added to a post must be an internal storage key already owned by the authenticated user and valid for that campaign, or an
uploadIdfromcreate_upload. - Image, video and audio workflow items may only name storage keys the authenticated user already owns (from
get_project,get_library_itemsorget_album_items). UseuploadIdto pin a new file. - Scheduling requires a valid time, an active channel on the campaign, and ready media.
Write Confirmation Protocol
External MCP writes use an argument-bound two-call protocol:
- Call the tool with the desired arguments and without
confirmed: true. - The server returns a preview containing a summary, normalized arguments, and
confirmationHash; no mutation has occurred. - Show that exact action to the user.
- If approved, call the same tool again with the same arguments plus
confirmed: trueand the returnedconfirmationHash.
The hash binds approval to the tool name and normalized arguments. If any argument changes, the hash is rejected and a new preview is required.
Read-only tools do not need this protocol. External clients cannot use the in-app assistant's per-conversation approved-tools list.
Workflow Update Safety
Project workflow updates are replacement operations, not patches to one step. A safe client sequence is:
- Call
get_project. - Start from the newly returned
workflowItems. - Apply the requested edit while preserving order, selected tags, and disabled state.
- Preview
update_project. - Confirm the exact replacement.
This prevents a long-running conversation from silently dropping workflow edits made elsewhere.
Inspecting the Server
During local development:
npm run mcp:inspectThe script launches the MCP Inspector against http://localhost:3000/mcp. Sign in or provide a token as required by the inspector.
For source-level details, see server/mcp/tool-definitions.ts and server/mcp/tool-confirmation.ts.