---
title: MCP tools
description: Every invideo MCP tool with what it takes and what it returns, the media ops, the job statuses and the refusal codes.
---
The invideo MCP server is a remote server that your agent connects to once. Through it the agent generates video, images, voice and music with the models in `find_models`, edits timelines, and exports. It is the route for clients without a shell: Claude on the web, ChatGPT, the Gemini app, VS Code, Gemini CLI and any other MCP client. Terminal agents such as Claude Code, Codex, Cursor and Antigravity use the CLI instead; see [invideo for AI agents](/agents). A generic client config looks like this:

```json
{
  "mcpServers": {
    "invideo": { "url": "https://mcp.invideo.io/mcp" }
  }
}
```

| Setting | Value |
| --- | --- |
| Server URL | `https://mcp.invideo.io/mcp` |
| Transport | Streamable HTTP (JSON-RPC 2.0 over POST) |
| Sign-in | OAuth in the browser when you connect, or a device code with no browser |

There are no API keys. Every call runs as the signed-in person, in the workspaces they chose. For other clients, see [invideo for AI agents](/agents).

## Rules for every tool

Four rules hold across the tools. Read them before the tool list.

- **A URL is the handle.** Every tool takes a URL as `url`, and every result gives the URLs to use next. Give each URL to the person: it opens exactly that in invideo. Nothing is remembered between calls.
- **Register a name, then pass `as`.** In a project, call `register` once with a `name`, like `scout`. Then pass that name as `as` on every call there. Without it, you act as the agent that every unnamed call from your client shares.
- **Follow `next`.** Every result carries `next`: what to do from here, with the tools and URLs. It is advice, not orders.
- **Read `structuredContent`.** Results come as structured content, with JSON text too. Check `isError` and the status before you treat a request as done.

These are the URL shapes the tools take:

| What | URL |
| --- | --- |
| A workspace | `https://invideo.io/@<workspace>` |
| A project | `https://invideo.io/@<workspace>/<project>` |
| A notebook page | `…/notebook/page-2` |
| A thread on a page | `…/notebook/page-2#thread-9` |
| A sequence (one generation, upload or stock result) | `…/notebook/seq-9.1` |
| A timeline on a branch | `…/tree/main/seq-9.1` |
| The project's context, and one entry | `…/context`, `…/context/world/kai.md` |
| A brief | `…/briefs/3` |
| The project's files, a folder, one file | `…/assets`, `…/assets/downloads`, `…/assets/downloads/poster.jpg` |
| Export pages, and one of them | `…/exports`, `…/exports/<id>` |

## Tools at a glance

The tools come in the same groups as the server's own guide, which `get_help` returns. Each tool lists what it takes and what it returns.

### Projects

Projects live in a workspace. Pass the workspace's URL from `list_workspaces`.

| Tool | Takes | Returns |
| --- | --- | --- |
| `list_projects` | A workspace `url`, an optional `query` on the title, and `offset` for the next page. | The workspace's projects, newest first, each with its URL. |
| `new_project` | A workspace `url` and a `title`. | The new project's URL. |

### Read anything

One tool reads any URL.

| Tool | Takes | Returns |
| --- | --- | --- |
| `read` | Any `url`: a project, page, thread, sequence, timeline, context entry, brief, file or folder. | What is there. A project gives its pages, threads, sequences, context, briefs and newest files. A sequence gives its status, a fresh download URL, and a `picture` once completed. Every item has its URL, status, maker and `judgement`. |

### Mark and rename

These tools change what the person sees in the notebook.

| Tool | Takes | Returns |
| --- | --- | --- |
| `mark_sequence` | A sequence `url`, `status` (`accepted` or `rejected`) and an optional `reason`. | The mark, which `read` shows as `judgement`. Mark only when the person asks or agrees. |
| `rename` | A page, thread or sequence `url`, and a `name`. With your own agent URL, it renames you. | A `read` of what it renamed. |

### Briefs and context

Context entries and briefs are markdown documents that the project's agents work from.

| Tool | Takes | Returns |
| --- | --- | --- |
| `new_brief` | A project `url`, a `name` and a `description`. | The brief's URL. |
| `edit` | An entry or brief `url`, `old_text` quoted exactly as `read` shows it, `new_text`, and optional `replace_all`. | The changed document. |
| `write` | An entry or brief `url`, the whole `markdown`, the `revision` from your read, and an optional `description`. | The written document. A write at a new entry URL makes the entry. Empty markdown deletes an entry or archives a brief. |

### Pages, timelines and media in

These tools add pages, timelines and files to a project.

| Tool | Takes | Returns |
| --- | --- | --- |
| `new_page` | A project `url` and a `title`. | The new page's URL. |
| `new_timeline` | A page or project `url`, and optional `name`, `width`, `height` and `fps`. | The timeline's URL, in a thread of its own. |
| `add_media` | A `url` (page, thread or timeline) and one source: `media_url`, `file`, `upload_id` or `stock`. Optional `file_name`, `mime_type` and `timeline_id`. | The file's sequence URL. On a timeline, also its media bin entry with the asset id. A font or a document goes to the project's files. On a timeline URL, a font also goes into the bin, and its id is the font that `add_text` takes. A `.cube` LUT on a timeline URL goes into the bin, and its id is the `lut` that `apply_lut` takes. |
| `start_upload` | A `file_name`. | An `upload_id` and an `upload_url`. PUT the raw bytes to the URL, then call `add_media` with the `upload_id`. |

### Libraries

One tool searches the voice and stock libraries.

| Tool | Takes | Returns |
| --- | --- | --- |
| `search_library` | A `url`, a `library` (`<model>_voices`, `stock_video`, `stock_image` or `stock_music`), a `query`, and `cursor` for voices. | Items with an `id` and a low-resolution `preview`; exports use the clean file. |

### Generate

These tools find a model, show its inputs and run it. See [Models](/reference/models).

| Tool | Takes | Returns |
| --- | --- | --- |
| `find_models` | A `url`, and optional `output` (`video`, `image`, `audio`, `three_d`) and `query`. | Models with an id, a name and a price. |
| `get_model` | A `url` and a `model` id. | The model's description, capabilities, price by its inputs, and its inputs as a JSON Schema. |
| `generate` | A `url`, a `model`, `inputs`, `max_credits`, `dry_run` and `idempotency_key`. | With `dry_run`, the price and nothing started. Otherwise the thread's URL at once, and the sequences' URLs once they appear. |

### Read and check a timeline

These tools read a timeline without changing it.

| Tool | Takes | Returns |
| --- | --- | --- |
| `get_timeline` | A timeline `url`, `mode` (`overview`, `window`, `collection`, `inspect`), and the fields for that mode. | Tracks, clips and media with short ids, the revision, and the `state_token` that edits need. |
| `inspect_objects` | A timeline `url` and `ids`. | Each object with every property `edit_timeline` can change. |
| `timeline_catalog` | A `url`, and optional `ops`, `effects`, `audio_effects`, `transitions` or `guides` by name. | With no names, every op, effect and transition with one line each. With names, their exact fields and settings. |
| `check_timeline` | A timeline `url`. | Structural findings, each with what is wrong and how to fix it. It does not judge the edit. |

### Edit and keep history

These tools change a timeline and keep its branches and checkpoints.

| Tool | Takes | Returns |
| --- | --- | --- |
| `edit_timeline` | A timeline `url`, `timeline_id`, `expected_state_token`, `operations`, and optional `dry_run`. | The new state. The operations land all or none. See [Timeline edit operations](/reference/edit-operations). |
| `timeline_history` | A timeline `url` and an `action`: `list`, `checkpoint`, `restore`, `create_branch`, `edit_from_here`, `create_tag`, `rename`, `archive`, `unarchive`, `set_default` or `declare_final`. | Branches and checkpoints with their URLs, or the timelines an action saved or changed. Every action but `list` and `unarchive` needs `expected_state_token`. |

### Look and make new files

These tools render frames of a timeline and work on single files.

| Tool | Takes | Returns |
| --- | --- | --- |
| `capture` | A timeline `url`, `at_seconds`, and an optional `timeline_id`. | Rendered frames of the timeline as it looks now, with every layer, effect and text. |
| `media` | A `url` and an `op`, with that op's fields. | A read of the file, a transcript, or a new sequence. See the `media` ops below. |

### Your cursor

People watching the timeline see your cursor under your client's name.

| Tool | Takes | Returns |
| --- | --- | --- |
| `point_at` | A timeline `url`, a short `text`, and `at_seconds` or clip `ids`. | Your cursor at that place, with the text beside it. |
| `leave_timeline` | A timeline `url`. | Your cursor off the timeline. |

### Export

Exports are free and need the person's export permission on the project.

| Tool | Takes | Returns |
| --- | --- | --- |
| `export` | A timeline `url`, a `format` (`video`, `premiere`, `final_cut`, `davinci` or `invideo`), `options`, and an `idempotency_key`. | The export's thread URL at once, and its card's URL once it appears. `read` the card for its status, then its files or its export page. |

For `video`, `options` takes `mode` (`video`, `audio`, `image`), `quality` (`240`, `480`, `720`, `1080`), `file_name`, `start`, `end`, `fps`, `encode_quality` (`draft`, `good`, `best`), `target_lufs`, `audio_format` (`aac`, `opus`, `wav`), `still_at` and `timeline_id`. For `premiere`, `final_cut` and `davinci`, it takes `media_packaging` (`folder`, `zip`, `none`). `export` with `format` set to `premiere`, `davinci` or `final_cut` makes a project file that Premiere Pro, DaVinci Resolve or Final Cut Pro opens.

### Export pages

Export pages are where people watch, comment on and download what was made.

| Tool | Takes | Returns |
| --- | --- | --- |
| `add_to_export_page` | A project `url`, sequence or timeline `urls`, and `page` for an existing page, or `title` and `kind` (`playlist`, `canvas`, `doc`) for a new one. | The page, with its URL and object ids. A new page is private. |
| `edit_export_page` | An export page `url`, and `remove`, `order` or `title`. | The changed page. |
| `share_export_page` | An export page `url`, `visibility` (`public`, `shared`, `private`), `permissions` and `team_access`. | The page's new sharing. Ask the person before you make a page public. |

### Account

These tools say who is signed in and where they can work.

| Tool | Takes | Returns |
| --- | --- | --- |
| `current_user` | Nothing. | The person's name and email, and `credits_remaining` in the default workspace. |
| `list_workspaces` | Nothing. | The workspaces this connection can use, each with its URL. |

### Feedback

These tools send a report to the invideo team.

| Tool | Takes | Returns |
| --- | --- | --- |
| `report_bug` | A `url`, a `summary`, `what_happened`, and optional `tool`, `kind` and `expected`. | The filed report. Use it when a call fails for a reason you cannot see, or a description left you guessing. |
| `request_feature` | A `url`, a `summary`, and optional `details` and `workaround`. | The filed request. Use it for something the person needs that the tools cannot do. |

### Other tools

The server has six more tools. The guide's table does not list them, but its text and the tool schemas do.

| Tool | Takes | Returns |
| --- | --- | --- |
| `get_help` | An optional `topic`. | The server's guide to working with invideo, or one section of it. |
| `status` | A project `url` and a list of job `urls` from that project. | Each job's status and `retry_after_s`, in one call. |
| `register` | A project `url`, a `name`, and an optional `model`. | Your name in the project, and the agents already there. |
| `message` | An agent's `url` and `text`. | The sent message. Its answer comes to your inbox. Messaging Agent Two starts its work, and Agent Two's work and the media it makes use credits. |
| `inbox` | A project `url`, and an optional `before`. | The messages sent to your `as` name, oldest first. |
| `import-claude-motion-from-url` | A video `url`, a `download_token`, and optional `title` and `claude_design_project_id`. | An MP4 video imported into invideo. |

## The media tool

`media` works on one file without a timeline. The file is a sequence URL, a file under the project's `…/assets`, or, for reads, a bin asset (the timeline's URL and `asset_id`) or a stock result (the project's URL and `stock`). Pick the job with `op`.

Which ops take which file:

- **Reads take `asset_id`.** `metadata`, `video.frames`, `audio.waveform`, `audio.loudness`, `audio.content`, `audio.onsets`, `audio.markers`, `audio.key`, `audio.sections` and `audio.beats` accept a bin asset.
- **Paid and file-making ops take a sequence URL.** `audio.transcript`, the model ops and every tool op below refuse `asset_id` with `not_found`. Pass the file's sequence URL (`…/notebook/seq-N.M`) as `url`. `add_media` returns that URL, and so does `invideo asset upload` on the CLI.

```json
{
  "url": "https://invideo.io/@acme/launch-reel/notebook/seq-9.1",
  "op": "audio.transcript",
  "dry_run": true
}
```

### Reads, free

Reads answer at once and cost nothing.

| Op | What it gives |
| --- | --- |
| `metadata` | What a file is: streams, duration, size. |
| `video.frames` | Frames of a file at the times in `at_seconds`. |
| `audio.waveform` | A file's audio levels, as peaks. |
| `audio.loudness` | A file's loudness: integrated, true peak, range. |
| `audio.content` | Where the sound is speech, music, effects or silence. |
| `audio.onsets` | Where each hit or transient starts and peaks. |
| `audio.markers` | Tempo, beats, phrases and drops. |
| `audio.key` | The musical key. |
| `audio.sections` | The musical structure, coarse to fine. |
| `audio.beats` | Where the strong and weak beats fall. |

### Transcript and media understanding

The transcript is kept on the file. The first call starts it and returns its status with `retry_after_s`. Call again with the same file for the words. Only the first call spends credits, so run it with `dry_run` first and pass `max_credits`.

| Op | What it gives |
| --- | --- |
| `audio.transcript` | Every word said, with its time and speaker. `start_seconds`, `end_seconds`, `offset` and `limit` page through the words. |
| `describe` | What is seen and heard across the whole file: a summary, chapters and captions. Costs credits; `dry_run` prices it, `max_credits` caps it. |
| `ask` | Answers one `question` about the stretch from `start_seconds` to `end_seconds`, inside the call. Costs credits; `dry_run` prices it, `max_credits` caps it. |

### Document pages

This op turns a document in the project's files into images. The dry run shows its price before anything starts.

| Op | What it gives |
| --- | --- |
| `document.pages` | An image sequence of each page of a PDF or office document, on the page or thread `to` names, or the project's first page. |

### Model ops

A model op makes a new sequence beside the file, followed like a generation. It runs the op's default model, or the one you name in `model`, with `inputs` for that model's extras. It costs credits: pass `dry_run` first, then `max_credits` and an `idempotency_key`. A model named in this table is a good pick, not a promise. Models retire. If one is refused as not found, leave `model` out for the op's default, or run `find_models` with the job in words, and tell the person.

| Op | What it makes | Models it takes |
| --- | --- | --- |
| `audio.separate` | The sound split into stems. | `audio_separation` |
| `audio.clean` | A cleaned voice. | `clean_voice.clean_audio`, `clean_voice.clean_video` |
| `video.upscale` | An upscaled video. | `topaz_proteus_natural`, `pixverse_upscale`, `topaz_video_upscale`, `seedvr_video_upscale`, `flashvsr_video_upscale`, `bytedance_video_upscale`, `byteplus_vod_upscale`, `flux_3_video_upscale`, `topaz_astra_2`, `topaz_starlight_precise_26`, `topaz_gaia_2_animation` |
| `image.upscale` | An upscaled image. | `clarity_upscaler`, `crystal_upscaler`, `topaz_bloom_2`, `magnific_upscaler_creative`, `magnific_upscaler_precision_v2`, `pruna_p_image_upscale`, `byteplus_ultra_hd` |
| `video.removeBackground` | A video without its background. | `bria_video_bg_remove`, `veed_video_bg_remove.veed_bg_standard`, `veed_video_bg_remove.veed_bg_fast`, `pixelcut_video_bg_remove`, `ben_v2_video_bg_remove` |
| `image.removeBackground` | An image without its background. | `bria_bg_remove`, `birefnet_bg_remove` |

### Tool ops

A tool op makes a new file without a model. The dry run shows its price before anything starts. Its options are fields under their own names. `video.stitch`, `audio.concat` and `image.collage` take their files as a list of sequence URLs. A project file or a stock result has no thread, so `add_media` it first.

| Op | What it makes | Its fields |
| --- | --- | --- |
| `video.trim` | A video cut to a time range. | `start_time`, `end_time` |
| `video.reverse` | The video played backwards. | none |
| `video.changeSpeed` | The video sped up, slowed down or ramped. | `start_speed`, `end_speed` |
| `video.stitch` | Videos of the same aspect ratio joined into one. | `video_array`, `aspect_ratio` |
| `video.sceneSplit` | The video split into its scenes. | `threshold` |
| `video.loop` | The video looped to a target length. | `target_duration` |
| `video.extractFrameFirst` | The first frame, as an image. | none |
| `video.extractFrameLast` | The last frame, as an image. | none |
| `video.extractFrameByNumber` | One frame by its number, as an image. | `frame_number` |
| `video.extractFrameAtTime` | The frame at a time, as an image. | `time_seconds` |
| `video.extractFrameInterval` | Every Nth frame, as images. | `frame_interval` |
| `video.extractMsInterval` | A frame every N milliseconds, as images. | `interval_ms` |
| `video.replaceAudio` | The video with its sound replaced. | `audio_input` |
| `video.addAudioTrack` | The video with an audio file mixed into its sound. | `audio_input`, `volume` |
| `video.resize` | The video as MP4 at a target height. | `resolution` |
| `video.contactSheet` | One image of frames across the video, in a grid. | `rows`, `columns`, `resolution`, `style`, `start_offset_ms` |
| `audio.toVideo` | An audio file as a video with a blank picture. | `aspect_ratio`, `fps` |
| `audio.trim` | An audio file cut to a time range. | `start_time`, `end_time` |
| `audio.extract` | A video's sound, as an audio file. | `format` |
| `audio.concat` | Audio files joined into one. | `audio_array`, `gap_duration` |
| `audio.addAudioTrack` | One audio file mixed over another. | `overlay_audio_input`, `start_time`, `volume` |
| `image.collage` | Images combined into one collage. | `image_array`, `aspect_ratio` |
| `image.crop` | A cropped image. | `x`, `y`, `w`, `h` |
| `image.resizeAspectRatio` | An image resized to an aspect ratio. | `aspect_ratio`, `max_height` |
| `image.resizeFit` | An image resized to fit a width and height. | `max_width`, `max_height` |
| `image.rotate` | A rotated image. | none |

## Statuses

Generations, imports, exports and model ops run in the background. Follow one with `read` on its URL, or with `status` for several URLs at once. Look again after `retry_after_s`.

| Status | What it means | What to do |
| --- | --- | --- |
| `queued` | The job waits to start. | Check again after `retry_after_s`. |
| `running` | The job is under way. | Check again after `retry_after_s`. |
| `completed` | The job is over and its result is ready. | `read` the URL for the files. For a `premiere`, `final_cut` or `davinci` export, read it again until the files list is there; `completed` can come before the media package. |
| `failed` | The job did not finish. | `read` the URL for the reason. |
| `held` | A safety review holds the job. It is not over. | Tell the person, and check again later. |
| `needs_confirmation` | Only the person can confirm the job, in invideo. | Ask the person to confirm it. |

Never call `generate` or `export` again to check on a job. The transcript and beats in `media` are the one exception: calling again with the same file is how you follow them.

## Refusals

A refused call returns `status`, `code` and `message`. The `code` is stable, for your logic. The `message` says what to do next. If the same refusal comes back after you fix it once, stop, tell the person, and file `report_bug`.

| Answer | What it means | What to do |
| --- | --- | --- |
| `status: refused` | Nothing took effect. | Read the `message`, fix the request, and send it once more. |
| `status: completion_unknown` | The call may have landed. | Retry the identical request with the same `expected_state_token` or `idempotency_key`. |
| `code: unavailable` | The timeline is starting. | Retry the same request in a few seconds. |
| `code: timeout` | A read, a capture or a media look timed out. Nothing changed. | Read again. |
| `code: failed` | The request did not go through. | Try it once more. If it fails again, file `report_bug` with the tool, the URL and what you sent. |
| A stale state token | Someone's edit landed first. | Read again with `get_timeline`, and rebuild the change. |
| `get_model` or `generate` refuses the model as not found | Models retire. | Run `find_models` with the job in words, use the best match, and tell the person which model you used. |

## Related

- [invideo for AI agents](/agents)
- [Timeline edit operations](/reference/edit-operations)
- [Models](/reference/models)
- [CLI commands and flags](/reference/cli)
- [Know the cost before you spend](/how-to/cost-before-you-spend)