CueFrame

Quickstart

Intent to rendered video in three steps over MCP.

The 60-second path

Point an MCP client at CueFrame (a browser opens to sign you in — no API key), then ask your agent for a video:

claude mcp add --transport http cueframe https://api.cueframe.ai/v1/mcp

Make a 9:16 clip from https://example.com/interview.mp4 — reframe on the speaker, word-timed captions, render it.

That's the whole loop. The rest of this page is the same three steps — ingest → compose → render — spelled out tool by tool, for agents (or humans) that want to drive each one deliberately. Other surfaces and auth options are in Setup.

CueFrame is async-first. Every long-running step returns a job you poll with wait_job, or you register a webhook (compose.completed, render.completed, media.completed). The snippets below are MCP tool calls as your agent issues them — not runnable JavaScript — and each maps one-to-one onto the REST surface in the API reference, where you can run them live.

Ingest

Mint a project, then get media in. import_media pulls from a public URL; generate_media creates it from a prompt. Both are async.

const { id: projectId } = await create_project({
  name: "launch clip",
  format: { aspectRatio: "9:16", resolution: "4k" },
});

const { id: mediaId } = await import_media({
  url: "https://example.com/interview.mp4",
  filename: "interview.mp4",
  contentType: "video/mp4",
});

get_media_context(mediaId) returns detected faces and the transcript, so your reframing, captions, and timing line up with what's actually in the footage.

Compose

Seed the composition with apply_composition — add the media as a clip and express intent (reframe to follow the speaker, captions, ordering). Pass dry_run: true to validate a batch for free without persisting.

await apply_composition({
  projectId,
  ops: [
    { type: "clip.add", newTrack: true, clip: { /* media clip + reframe */ } },
  ],
});

Then let the Director — CueFrame's authoring engine — take it from your seeded composition: it drafts several candidate edits, a server-side judge scores each against your intent, and the winner is saved.

const { composeJobId } = await compose({
  projectId,
  fromComposition: true,
});
const winner = await wait_job({ kind: "compose", id: composeJobId, projectId });

Clipping a long video instead? Run suggest_briefs on the media, then compose({ suggestionId }) — the two paths are mutually exclusive.

Render

Queue the render and wait for the MP4 download URL.

const { id: renderId } = await create_render({
  projectId,
  format: { aspectRatio: "9:16", resolution: "4k" },
});
const { downloadUrl } = await wait_job({ kind: "render", id: renderId, projectId });

Re-render the same composition to any other aspect ratio — the variant is baked from the same authored truth, so you ship every platform from one compose.

On this page