Model Context Protocol · shipped and running
Connect your AI agent to Aperture.
Aperture ships a working MCP server. One JSON snippet in your client's config, one API token — and your agent gets 14 live tools against the real platform: search every word ever spoken, upload and transcribe footage, run the free tools, create and render edit sequences, export platform kits, publish to YouTube. Everything the agent does runs through your API token: tenant-scoped, rate-limited, fully audited.
What MCP is, in one minute
MCP (Model Context Protocol) is the open standard for connecting AI agents to real software. Instead of pasting context into a chat, the agent calls tools: your client (Claude Desktop, Cursor, Codex, any MCP host) launches a small local server process, and the agent can list and invoke that server's tools to read data and take actions — with structured inputs and outputs, not copy-paste.
Aperture's MCP server is a small binary (aperture-mcp) that speaks the protocol over stdio and translates every tool call into the same /v1 REST API the web app uses — authenticated with an API token (apt_…), never a password. There is no second auth system, no shadow database, no sync: the agent sees exactly what your token is allowed to see, and the platform's audit trail records everything it does.
# the whole transport, no magic:
agent ⇄ stdio (JSON-RPC 2.0) ⇄ aperture-mcp ⇄ HTTPS Bearer apt_… ⇄ https://aperture.castomo.com/v1
The 14 tools your agent gets
| Tool | What it does |
|---|---|
| aperture_whoami | Identity check — which tenant and user the token belongs to. The first thing an agent should call. |
| aperture_list_assets | List library assets — text query on titles/tags, filter by kind (video / audio / image / document). |
| aperture_get_asset | One asset's metadata plus a 30-minute presigned playback URL. |
| aperture_search_transcripts | Semantic + lexical search over every spoken word — timecoded hits, optional speaker filter (S1, S2…). |
| aperture_upload_asset | Upload a local file into the library (multipart, same as the web uploader). |
| aperture_transcribe_asset | Queue Whisper transcription and poll until done — returns timecoded, speaker-labelled segments. |
| aperture_list_timelines | List edit sequences (timelines) in the workspace. |
| aperture_get_timeline | Fetch one sequence with its full editable document — clips, lanes, keyframes, captions. |
| aperture_create_timeline | Create a new empty edit sequence. |
| aperture_render_timeline | Render a sequence to video — draft, GIF, audio-only, per-lane stems, −14 LUFS loudnorm, 9:16/1:1/16:9 reframe. Polls the render job and returns the result. |
| aperture_export_kit | Export a platform kit (master + captions + description + hashtags + thumbnail) for TikTok, YouTube or Instagram — writes the zip locally. |
| aperture_publish_youtube | Publish the latest render of a sequence to the connected YouTube channel; returns the video id. |
| aperture_free_tool | Run any of the 15 free tools (trim, compress, stack, GIF, subtitles…) end-to-end: job → upload inputs → run → poll → result URLs. The agent can do full media ops in one call. |
| aperture_api | Power tool: raw request to any /v1 endpoint — webhooks, workflow rules, shares, collections, stock, usage, audit. For everything the dedicated tools don't cover. |
Setup — four steps
Step 1 — create an API token. Open the editor → Admin → API tokens → create (name it e.g. mcp). The token apt_… is shown once — copy it. The token defines what the agent can see and do; an editor-role token can't touch admin surfaces.
Step 2 — get the server binary. From the repo: GOOS=darwin GOARCH=arm64 go build -o aperture-mcp ./cmd/aperture-mcp (Go 1.24+). Any machine that can reach the platform over HTTPS works — the agent runs it locally.
Step 3 — add one JSON block to your client's config (below, per client). Step 4 — restart the client. The agent lists 14 Aperture tools; ask it "who am I in Aperture?" to confirm.
Claude Desktop
Config file: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows). Add inside the top-level object:
{
"mcpServers": {
"aperture": {
"command": "/path/to/aperture-mcp",
"env": {
"APERTURE_BASE_URL": "https://aperture.castomo.com",
"APERTURE_TOKEN": "apt_…"
}
}
}
}
Save, restart Claude Desktop, open a new chat — the tools appear under the 🔨 menu.
Cursor
File: ~/.cursor/mcp.json (project-level: .cursor/mcp.json). Same block:
{
"mcpServers": {
"aperture": {
"command": "/path/to/aperture-mcp",
"env": {
"APERTURE_BASE_URL": "https://aperture.castomo.com",
"APERTURE_TOKEN": "apt_…"
}
}
}
}
Codex / CLI agents / anything else
The server is a plain stdio program — any MCP host that spawns a command works. Smoke-test it by hand:
# speak the protocol directly:
APERTURE_TOKEN=apt_… ./aperture-mcp \
<<'EOF'
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
EOF
What agents actually do with it
aperture_search_transcripts with semantic query, timecoded hits, speaker labels. The agent then quotes the exact second.aperture_list_timelines → aperture_render_timeline with reframe 9:16 → aperture_export_kit tiktok. Zip with master, captions, hashtags lands on disk.aperture_free_tool trim on both → aperture_free_tool stack (top/bottom, audio from clip ①). Result URLs are ready in a minute.aperture_render_timeline (loudnorm) → aperture_publish_youtube unlisted. Video id comes back; the audit trail has every step.Security model
- Token, not password. The agent authenticates with an
apt_API token. Tokens are scoped to their tenant, can be revoked in one click, and every tool call lands in the platform audit trail with the token's identity. - No new credentials. The MCP server holds no database access and no server-side state — it's a translation layer to the same HTTPS API the editor uses.
- Least privilege by design. Give the agent an editor-role token and admin surfaces (users, quotas, settings) are out of reach even for the raw
aperture_apipassthrough — the API enforces it, not the client. - Ephemeral by default. Free-tool results are no-account jobs: download URLs expire, artifacts are deleted within 24 h on a best-effort schedule, and only a claim (a real sign-in) moves results into a library.
apt_ value is shown once at creation. If it leaks, revoke it in Admin → API tokens and issue a new one — the agent's config is the only thing to update.Troubleshooting
HTTP 401 not signed in/invalid-token— the token is missing, revoked, or the env block isn't reaching the process. Re-check the config, restart the client.- Tools don't appear in the client — the config JSON isn't valid or the client wasn't restarted. Validate the JSON (a trailing comma is enough to break it) and check the client's MCP logs.
tenant admin role required— that endpoint is admin-only; use a token whose account is an admin, or stay off admin surfaces.- Render/subtitle calls "still running" — long jobs are polled, not blocked; call the same tool again with a longer
timeout_seconds, or pollaperture_apiwithGET /v1/jobs/{id}. - Upload fails with 413 — 100 MB per file. Split or compress first (yes, the agent can do that itself with the free tools).
The server is part of the Aperture platform — source in the repo, built from backend/cmd/aperture-mcp. The full REST surface behind it is documented at /docs.html and /v1/openapi.json.