DocsGet started
MCP server
Connect Claude Code, Claude Desktop, Cursor, VS Code or another MCP client with your API key, or a client that signs in with OAuth, so an AI assistant can check commands and run jobs.
Videxo has an MCP server. An AI assistant or agent that speaks the Model Context Protocol (opens in a new tab) can write an ffmpeg command, check it, run it as a job and wait for the result, all through the same API, account and limits as your code.
The server is at:
https://api.videxo.io/mcpCopy failed. The text is selected; copy it with your keyboard.
It speaks Streamable HTTP and keeps no session between requests.
Authentication#
The server takes either of two credentials in the Authorization header. Without one it answers
401.
Sign in with OAuth#
A client that follows the MCP authorization specification signs in by itself: it gets the 401,
reads where to sign in from https://api.videxo.io/.well-known/oauth-protected-resource/mcp, and opens Videxo in a browser. You choose an
organization, see what the app asks for, and allow it. The app can then do what you allowed and
what your role in that organization holds, read again on every request. If your role changes or
you leave the organization, so does the app's access.
| Scope | What it lets the app do | Tools | Roles that hold it |
|---|---|---|---|
jobs:read | Read your jobs and their outputs | get_job, list_jobs, wait_for_job | Owner, Admin, Developer, Viewer |
jobs:run | Run and cancel jobs, which uses credits. Includes jobs:read. | create_job, cancel_job, probe_media | Owner, Admin, Developer |
files:write | Upload files for jobs | create_upload | Owner, Admin, Developer |
usage:read | See usage and the credit balance | get_usage | every role |
webhooks:read | See webhook deliveries | list_webhook_deliveries | Owner, Admin, Developer |
Access tokens last an hour and the client refreshes them; a connection unused for 30 days ends. OAuth tokens work on the MCP server only, never on the REST API.
To see or end an app's access, open Settings, Connected apps in the dashboard. It lists each
app with the member who connected it and what it may do, and each member sees their own; Owners and
Admins see every member's. After you revoke an app, its next request answers 401 and it cannot get
a new token; connecting it again takes a new sign-in and consent. Each sign-in from a program on a
computer is its own row, so one app on two computers shows twice. An app's name is its own claim: the
page marks it unverified and names the host that published it, as the sign-in page does.
Use an API key#
Send your API key the way the REST API takes it:
Authorization: Bearer <your key>Copy failed. The text is selected; copy it with your keyboard.
Create the key in the dashboard under API keys, as in the Quickstart. The assistant
then acts for your account with every right of the key: the jobs it creates count against your
plan's credits and limits. A key that is unknown, revoked or expired is rejected with 401, and so
is an empty header, so a client whose key variable is empty fails at once.
Without an account#
The tools that need no account have a public address of their own: check_command,
compile_job, list_presets, list_fonts, estimate_cost and list_allowed. It takes no
credential, and offers these tools whatever you send.
https://api.videxo.io/mcp/publicCopy failed. The text is selected; copy it with your keyboard.
When a request is refused#
| Answer | What it means | What a client does |
|---|---|---|
401 missing_credentials | No Authorization header. | Signs in, from the WWW-Authenticate header. |
401 invalid_token | The token is malformed or unknown, or was not issued for this server. A revoked token usually reads this way. | Signs in again. |
401 token_expired | The access token has expired. | Refreshes it. |
401 token_revoked | The app's access has ended: it was revoked, the member left, or the organization was deleted. | Signs in again. |
403 insufficient_scope | The token lacks a scope this call needs and your role holds. WWW-Authenticate names the scopes. | Signs in again and asks for them. |
403 account_disabled | An administrator disabled the account. | Stops: contact support. |
tool error role_insufficient | Your role does not hold what this tool needs. | Stops: signing in again would not help. Ask an owner or admin. |
A sign-in itself answers OAuth's own errors (such as invalid_grant or invalid_target), which
clients read by themselves. Every other answer here is problem details.
Connect a client#
Every example reads the key from the VIDEXO_API_KEY environment variable or asks for it, so the key
never sits in a file you might commit.
claude mcp add --transport http videxo https://api.videxo.io/mcp \
--header "Authorization: Bearer $VIDEXO_API_KEY"Copy failed. The text is selected; copy it with your keyboard.
{
"mcpServers": {
"videxo": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.videxo.io/mcp",
"--header",
"Authorization:${VIDEXO_AUTH}"
],
"env": {
"VIDEXO_AUTH": "Bearer <your key>"
}
}
}
}Copy failed. The text is selected; copy it with your keyboard.
{
"mcpServers": {
"videxo": {
"url": "https://api.videxo.io/mcp",
"headers": {
"Authorization": "Bearer ${env:VIDEXO_API_KEY}"
}
}
}
}Copy failed. The text is selected; copy it with your keyboard.
{
"inputs": [
{
"type": "promptString",
"id": "videxo-key",
"description": "Videxo API key",
"password": true
}
],
"servers": {
"videxo": {
"type": "http",
"url": "https://api.videxo.io/mcp",
"headers": {
"Authorization": "Bearer ${input:videxo-key}"
}
}
}
}Copy failed. The text is selected; copy it with your keyboard.
- Claude Code: run the command in a shell where
VIDEXO_API_KEYis set. Add--scope userto use the server in every project. - Claude Desktop: its config file starts local servers only, so the
mcp-remotepackage bridges to the remote one (it needs Node). Put the config inclaude_desktop_config.json(Settings, Developer, Edit Config) and restart the app. The header has no space after the colon because some clients split arguments on spaces. - Cursor: put the config in
~/.cursor/mcp.json, or.cursor/mcp.jsonin a project, withVIDEXO_API_KEYset where Cursor starts. - VS Code: put the config in
.vscode/mcp.json. VS Code asks for the key once and stores it.
Other clients need the URL, the http (Streamable HTTP) transport and the header.
Tools#
"Needs a key" means https://api.videxo.io/mcp with an API key or a sign-in with the tool's scope.
| Tool | Needs a key | What it does |
|---|---|---|
check_command | no | Validates a command request against the command rules without creating a job: the problems to fix, or the inputs, outputs, filters and ffmpeg_command of a valid command. |
compile_job | no | Compiles a JSON operations body (or a per-operation body with operation) to the command a job would run and its ffmpeg_command, as POST /v1/jobs/compile does. Creates nothing. |
list_presets | no | The named output settings (web-720p, poster, ...) with their options, as GET /v1/presets lists them. |
list_fonts | no | The fonts a text layer can name, as GET /v1/fonts lists them. |
estimate_cost | no | The pricing calculator: credits for a monthly volume of one job type and the cheapest plan that fits. An estimate. |
list_allowed | no | The supported options, filters, formats, codecs and limits of a command. |
create_upload | yes | Creates a one-time signed URL to PUT a file to, and the input_url to pass as a job input. |
create_job | yes | Takes a command body or an operations body, as POST /v1/jobs does, checks it and queues the job. With an idempotency key, the same key and request within 24 hours return the same job, also across POST /v1/jobs; without one, a key is generated and returned. |
probe_media | yes | Reads the container, duration and streams of one file, as POST /v1/probe does: waits up to 25 seconds and returns the job and the document. |
get_job | yes | One job: state, progress, error, outputs and usage. |
list_jobs | yes | The account's jobs, newest first, by state and creation time, a page at a time. |
wait_for_job | yes | Waits up to 50 seconds for the job to end, then returns it; call again to keep waiting. |
cancel_job | yes | Cancels a queued or running job. If cancellation cannot be confirmed, read the job before retrying. |
get_usage | yes | The same as GET /v1/credits: the balance, the credits running jobs hold and the grants with credits left. |
list_webhook_deliveries | yes | A job's webhook deliveries and their attempts. |
A rejected call is a tool error whose content is the REST API's problem details
body, such as invalid_request with errors that point at the wrong arguments, command_invalid
with its problems, or not_found with the reason job, so the assistant can fix the request.
A refusal that REST answers with 429 or 503 also carries retry_after_seconds, the tool's
Retry-After.
Docs and prompts#
The server offers these docs pages as resources (videxo://docs/quickstart,
videxo://docs/commands and so on), so a client can read the rules without leaving the session.
The prompt build_video_job turns a task in plain words into a JSON operations body checked with
compile_job; the prompt write_ffmpeg_command turns it into an ffmpeg command body, with the
command rules attached.
Limits#
Each tool call counts as one request against your plan's rate limit, like a
REST request, by API key or by signed-in app; a rejected call returns rate_limited with the
seconds to wait. At the public address, tool calls are limited to 60 a minute per
IP address. Connecting, listing tools and reading the docs do not count.
Files#
The keyed create_upload tool returns a one-time PUT URL and an input_url for create_job.
Complete the PUT first. Direct uploads are limited to 100 MB. Job tools return signed download
URLs on each retained output. See Files for limits and expiry.