# Connect Decodx over MCP

> Connect Decodx to Claude, ChatGPT, Claude Code, Codex, Cursor, Gemini CLI, and VS Code over MCP.

# Connect Decodx over MCP

Create videos and docs directly from your AI agent. Decodx exposes an [MCP](https://modelcontextprotocol.io)
server, so any MCP-capable client can drive it — every output stays a spec you can review, edit, and
re-render.

:::note Connection URL
The MCP server lives on the Decodx API — the same URL for every client:

```
https://api.decodx.ai/mcp
```
:::

## Two ways to authenticate

- **Service token (available now).** Mint a Decodx **service token** (Settings → API tokens) and
  pass it as an `Authorization: Bearer` header. This works today with clients that let you set a
  header — **Claude Code, Cursor, Codex, VS Code** (see below).
- **OAuth sign-in (coming).** A "sign in to Decodx → Allow" browser flow for clients that only do
  OAuth (**Claude Desktop, ChatGPT**). Not available yet — use the service-token path meanwhile.

Every tool call runs as the token's **org and scopes** — the agent can only touch what the token is
allowed to.

---

## Connect Claude Code (service token)

1. Mint a **service token** in Decodx (Settings → API tokens) with the scopes you want the agent to
   have; copy the `ddx_svc_…` value.
2. Add the server, passing the token as an auth header:

   ```bash
   claude mcp add --transport http decodx https://api.decodx.ai/mcp \
     --header "Authorization: Bearer ddx_svc_<token>"
   ```

3. Confirm: `claude mcp list` shows **decodx ✓ connected**. Try it in a chat: "use decodx to run
   whoami".

## Connect Cursor (service token)

Add the server + header to `.cursor/mcp.json`, then restart Cursor and use an **Agent** chat:

```json
{
  "mcpServers": {
    "decodx": {
      "url": "https://api.decodx.ai/mcp",
      "headers": { "Authorization": "Bearer ddx_svc_<token>" }
    }
  }
}
```

## Connect Codex (service token)

```toml
# ~/.codex/config.toml
[mcp_servers.decodx]
url = "https://api.decodx.ai/mcp"
headers = { Authorization = "Bearer ddx_svc_<token>" }
```

Then run `/mcp` in Codex to confirm **decodx** is listed.

## Connect VS Code (service token)

Requires GitHub Copilot. Create `.vscode/mcp.json`, restart VS Code, use a **Copilot Agent** chat:

```json
{
  "servers": {
    "decodx": {
      "type": "http",
      "url": "https://api.decodx.ai/mcp",
      "headers": { "Authorization": "Bearer ddx_svc_<token>" }
    }
  }
}
```

## Claude Desktop / ChatGPT (OAuth — coming)

These clients connect over **OAuth** (a "sign in → Allow" browser flow) with no place to paste a
token. That flow is being built (Plan 49 §3). Until it ships, use the service-token clients above.

---

:::info Every output stays editable
The MCP server creates and edits the **spec**, not an opaque render. Whatever an agent produces is a
Decodx project you (or the AI) can review, diff, and re-render deterministically.
:::

---

## What the Decodx MCP exposes

Agents operate on the **authored scene graph** (Decodx's spec), then render deterministically — no
model in the render loop. Every write produces spec; `render_project` queues a job over the exact same
pipeline the web app uses. Every tool runs as the token's org and scopes.

### Identity & search

- `whoami` — the org/workspace identity this connection is acting as
- `find` — search the org's videos and docs by keyword

### Projects & workspaces

- `create_project` — a new blank draft project
- `get_project` / `list_projects` — read one, or list the workspace's projects
- `update_project` — rename a project
- `duplicate_project` — clone a project (scene graph + settings) into a new draft
- `delete_project` — soft-delete a project (removed from listings; restorable)
- `list_workspaces` — the workspaces in the org

### Draft from a prompt

- `create_with_prompt` — draft a whole project (scenes + narration) from a plain-language brief, then
  review and `render_project`. Produces spec, never a render.

### Scenes

- `add_scenes` — append scenes (`video` · `image` · `title` · `gradient` — a colored/
  gradient background scene needing no image provider, e.g. `background_preset: midnight-indigo` ·
  `avatar` — a fullscreen talking-head presenter scene; needs the project presenter enabled first,
  see `set_avatar` · `cli` — a pasted terminal transcript rendered as a styled command/output
  window via `transcript`; nothing is executed)
- `get_scene` — read one scene
- `update_scenes` — patch fields on existing scenes by id. Any non-`avatar` scene also accepts
  `avatar_coverage` (`inherit` | `off` | `corner` | `full`) — a picture-in-picture or fullscreen
  presenter overlay layered on top of that scene's own background
- `remove_scene` — delete a scene (a project keeps ≥1)
- `reorder_scenes` — set the play order (intro/outro pins are honoured)

### Sources & media

- `add_source` — upload a **local image or video** into the library and get back an asset id to use
  as a scene's `source_asset_id`. Three ways to hand over the file: inline base64 `data` (image or
  short clip, ≤25 MB), a **public https URL** the server fetches (≤200 MB), or an `upload_key` from
  `create_upload` after you PUT a large video to its presigned URL (≤2 GB). The type is verified by
  magic bytes (image png/jpeg/webp, video mp4/mov)
- `create_upload` — get a presigned URL to upload a **large local video** (over the 25 MB inline cap,
  up to 2 GB): PUT the bytes to `upload_url`, then call `add_source` with the returned `upload_key`
- `ingest_recording` — scaffold a project from a video source with auto-narration (the transcript is
  filled from the clip at render time)

### Narration & voice

- `set_narration` — set a scene's spoken script
- `set_voice` — project-wide voice + speaking speed (0.7–1.2)
- `set_avatar` — configure the project's presenter (avatar): enable/disable, HeyGen avatar id +
  optional voice override, and the default overlay placement/position/size. Enabling requires the
  workspace to have a HeyGen credential configured — set one up first, then retry
- `estimate_duration` — estimate the finished video length from the scenes

### Templates

- `list_templates` / `create_template` — reusable video/doc recipes
- `apply_template` — apply a template's look (voice, aspect, captions, density) to a project
- `update_template` / `delete_template` — edit or remove an org template (built-ins are read-only)

### Docs & review

- `get_document` / `update_document` — read and rewrite a doc's sections (markdown)
- `list_documents` — list the org's documents
- `add_comment` / `list_comments` — leave and read review comments on a video or doc
- `resolve_comment` — mark a comment resolved (or reopen it)

### Library & output

- `get_video` — a finished video's status + presigned playback/thumbnail URLs (by video or project id)
- `list_sources` — the media library (images + videos) you can reference as `source_asset_id`
- `download_asset` — a short-lived download URL for a **source original** (an uploaded image or
  video) by asset id: GET the returned url to fetch the file bytes (expires in a few minutes). For a
  finished render, use `get_video` instead
- `list_jobs` — recent render jobs

### Render

- `render_project` — compose the scene graph and queue a render job; returns a job id
- `get_job` — poll a render job's status
- `cancel_job` — cancel a queued or running render

### Sharing

- `create_share` — publish a video/doc to a public `/public/{slug}` link (returns the URL)
- `list_shares` — the org's share links

**Typical flow:** `create_with_prompt` (or `create_project` → `add_scenes`) → `set_narration` →
`set_voice` → `apply_template` → `render_project` → `get_job` → `get_video` → `create_share`.

> **Note on `add_source`:** with `url`, the server fetches the URL you give it, so only **public
> https** URLs are allowed and requests to private/loopback/link-local addresses are refused — it's the
> one place the API makes an outbound request on your behalf, so treat the URL as untrusted input. The
> `data` (inline) and `upload_key` (post-`create_upload`) paths make no outbound request.
