---
title: "Media-as-a-Tool — give your AI agent the power to make finished media, mid-task"
tier: hero
format: agent-integration
theme: developer | agent | automation | infrastructure
persona: agent builder, AI engineer, automation team, dev-rel, indie hacker
duration: "add in 1 line → media tool calls in any agent run"
budget_usd: "per-asset metered (images ~$0.03–0.10, video ~$0.05–0.30); cap with max_cost_usd"
caps: ["create_media", "generate_project", "ffmpeg-concat", "ffmpeg-mux", "hyperframes-render", "list_capabilities", "get_cost_report"]
skills: ["base", "finishing-quality"]
showcases: ["/chapters/agent-media-tool-example.html"]
status: "live — the wedge playbook. Livepeer Agent is an MCP server; any MCP-capable agent (Claude, CLI, your own) can call create_media / generate_project / finishing tools as ordinary tool calls, mid-workflow, and get a finished asset back."
reliability: 4.6 # core image/finishing path is deterministic + metered; only the video tier inherits fal latency
---

# Media-as-a-Tool — the one nobody else can offer

Every competitor is a **destination app** — you leave your work, go to their website, make a clip, come back. Livepeer Agent
is an **MCP server**: an AI agent calls it as a *tool*, in the middle of doing something else, and gets a **finished,
text-legible, reproducible** asset back — no app, no human in the loop. This is the differentiator the whole product
rests on, and it's the easiest thing to try.

## The 60-second try

Add Livepeer Agent to any MCP client (Claude Desktop, the CLI, your own agent) with one entry:

```jsonc
{ "mcpServers": { "livepeer-agent": {
  "type": "http", "url": "https://agent.livepeer.org/api/mcp",
  "headers": { "Authorization": "Bearer sk_…" } } } }
```

Now your agent can, mid-task:

```
list_capabilities()                      # 105+ models across providers, live
create_media({ action:"generate", prompt:"…", max_cost_usd:0.10 })
generate_project({ title, scenes:[…], aspect_ratio:"9:16" })   # multi-scene
create_media({ model_override:"hyperframes-render", html, background_video_url })  # legible text over video
create_media({ model_override:"ffmpeg-concat", … })            # finish to one MP4
get_cost_report({ … })                   # programmatic spend visibility
```

## What you'll get

- **A finished asset URL** — an MP4 or an image your agent can hand straight to the next step, not a punch-list of clip URLs to assemble
- **A structured tool result** — url + cost + elapsed + capability, as data your agent can branch on
- **A hard spend ceiling** — `max_cost_usd` refuses an over-budget call *before* it runs, and `get_cost_report` accounts for what did
- **Safe retries** — `idempotency_key` means at-least-once delivery never double-spends
- **Legible text when it carries text** — the `hyperframes-render` HTML layer, so captions / prices / tickers are pixel-perfect instead of glyph soup
- **A one-line install** — one MCP server entry; no app to visit, no human in the loop

## Fill in your BRIEF

```yaml
asset_goal:            # what the agent needs, in one line — e.g. "a 16:9 hero image for
                       # the release-notes post", "a 20s vertical explainer clip about X"
asset_kind:            # image | video | audio | multi-scene project
aspect_ratio:          # 16:9 | 9:16 | 1:1 — match the surface it lands on
max_cost_usd: 0.10     # the hard ceiling; the call is refused before it runs if over
idempotency_key:       # a stable key from YOUR workflow (task id / row id / commit sha)
                       # so a retry replays instead of double-spending
overlay_text:          # OPTIONAL — text/UI that must be LEGIBLE (a title card, a price,
                       # a stat). Goes in the hyperframes-render HTML layer, never the model.
finishing:             # what "done" means — e.g. "one stitched MP4", "1080×1920 export",
                       # "watermarked with our logo". Blank = a single raw asset.
model_preference:      # OPTIONAL — a named cap (e.g. flux-dev, pixverse-i2v) or "auto"
                       # to let routing + sibling fallback pick
run_mode: sync         # sync (returns the asset) | async (submit_creative_job + poll, for
                       # >15s video or multi-scene so the tool call doesn't block)
mcp_client:            # where it's calling from — Claude Desktop | Claude Code | the CLI |
                       # your own agent | CI / cron
```

## Why an agent wants this (use cases)

- **A coding/research agent** that needs a diagram, a hero image, or an explainer clip *as a step* — not a detour to a web app.
- **A content pipeline** (cron / CI / queue) that renders N branded assets per run, unattended, with `max_cost_usd` caps.
- **A support/marketing bot** that turns a doc or a data row into a shareable reel inline.
- **A multi-agent system** where one agent plans and another renders — the renderer is just a tool surface.

## The contract that makes it agent-safe

- **Metered + capped** — every call has a USD price; pass `max_cost_usd` to refuse over-budget calls before they run; `get_cost_report` for accounting.
- **Idempotent** — pass `idempotency_key` so at-least-once delivery / retries don't double-spend.
- **Deterministic finishing** — `ffmpeg-*` / `hyperframes-render` give a *delivered* asset (an MP4, a captioned video), not a punch-list of clip URLs.
- **Model-agnostic + fallback** — name a cap or let it route; siblings cover outages.
- **Structured results** — URLs + cost + elapsed come back as data an agent can branch on.

## The pattern (any agent)

```
agent is doing a task
  → needs an asset (asset_goal) → list_capabilities (or just call)
  → create_media / generate_project  (asset_kind, aspect_ratio, model_preference,
                                      max_cost_usd, idempotency_key)
  → if overlay_text: hyperframes-render overlay for legible text/UI
  → if finishing:    ffmpeg-concat / mux / export → one finished file
  → get the URL back as a tool result → use it in the larger workflow
       (run_mode: async → submit_creative_job + poll instead of blocking)
```

## Quality bar (definition of done)

- ✅ The agent never leaves its workflow — media is a tool call, not an app visit.
- ✅ Every call is cost-visible and cap-able.
- ✅ The output is a **finished** asset (text legible if it carries text), not raw clips.
- ✅ Retries are idempotent; outages fall back to a sibling cap.

## Watch-outs

- The **video tier inherits fal latency/flakiness** — for agent-critical paths prefer image + finishing (deterministic) or set generous timeouts + idempotency.
- Long renders (>15s video, multi-scene) → use the async tools (`submit_creative_job` / `get_creative_job`) so the tool call doesn't block.
- Keep the agent's system prompt thin — it sees the tool schemas already; don't restate them.
