The MCP server

The MCP server gives your agent eight tools. watch_video is the one it reaches for by default, and it covers the complete video unless you name a window. The rest cover the jobs that are a different shape: many videos at once, a finished document, the words, a live stream, your balance, and a method for a recurring job.

Last updated

The tools

Your agent picks between them from what you asked. Three of them touch no video at all, and cost nothing.

MCP tools at a glance
ToolReturnsCost
watch_videoThe reading, in words, with the second of every moment it names. Plus the session_id for the next question about the same video.About 2,500 tokens of context for a first look, and a few hundred for a question that carries the session_id.
watch_videosOne answer per video, together, each with the session_id of its own video.One reading per video, the same price as asking one by one. What it saves is the round trips and the waiting.
run_playtoolA finished document: the same result the tool's page on tryplayhead.com produces, with its share link, embed snippet and editor link.A few minutes of work, priced per tool. The call waits while it can and hands back a run_id with live progress.
get_transcriptPlain text, optionally with word-level timings, plus whether the audio was speech at all.No pictures are read, so this is the cheapest call there is.
attach_streamA stream id, and the address to send to when the encoder is yours.Charged for as long as the stream is open, so stop it when the event ends.
detach_streamWhat the event saw, and what it cost.Nothing. It ends the charge that attach_stream started.
get_accountWhich plan is connected, credits left, and what recent calls cost.Nothing. No video is touched.
get_playbookA method for one recurring job: the call order, what is measurable, and where the judgement is yours.Nothing. No video is touched.

watch_video(url?, question?, session_id?, …)

The default, and the right answer to almost any question about what is on screen. Without a question it covers the complete video.

urlstring
A link to the video, an upl_… id from an upload, or a path to a file on your own machine when the server runs over stdio. Leave it out when you pass a session_id.
questionstring
What you want to know. Leave it out for what happens across the complete video. Ask for one thing and you get that one thing, faster and for less.
session_idstring
The handle from an earlier answer about the same video. Pass it and the next question reads what was already found instead of looking again.
contextstring[]
What you already know and the video cannot show: what you are building, and what you were asked. Plain sentences. It costs almost nothing and the answer is better for it.
windownumber[]
The seconds to read, [start, end], from the start of the file. Use it for a moment the first answer did not cover. Reading four seconds costs what four seconds cost, not what the video costs.
regionnumber[]
The part of the picture to read, [left, top, right, bottom], as fractions of the width and the height. [0.5, 0, 1, 0.5] is the top right quarter. It makes small text large enough to read.
depthglance | read | full
How many moments of the video are read. Every depth dates every second the same way, so a glance is shorter and never vaguer. Absent is full. Use glance to find out whether a video is worth reading properly: it costs about a sixth of a full reading.
schemaobject
A JSON Schema. Send one and the answer carries an object in that shape under the prose, so your code reads values instead of parsing sentences. A field the video cannot fill comes back in unanswered with its reason.
instructionsstring
How the answer reads, in your words instead of ours. It changes the wording and nothing else: what was looked at and what was found stay the same. Use it for the voice, the language, and what to leave out.
rewatchboolean
Watch the whole video again and pay for it again. Ask without it first: the answer states the price and starts nothing.

watch_videos(urls, question?, schema?, batch_id?)

The same question about several videos: a folder of adverts, a set of webinar recordings, a week of uploads. Use it instead of calling watch_video in a loop.

urlsstring[]
The videos: links, upl_… ids, or paths to files on your own machine over stdio. Required to start a batch, ignored with batch_id.
questionstring
What you want to know about each one. The same question goes to every video. To ask each one something different, call watch_video per video.
schemaobject
A JSON Schema every answer comes back in. This is what a batch is for: twenty videos read into the same fields can be stacked and compared, and twenty paragraphs are a folder.
contextstring[]
What you already know that the videos cannot show. Plain sentences.
batch_idstring
A batch to keep waiting on, from an earlier call. The call waits while it can and hands back progress if videos are still running.

run_playtool(tool, url?, prompt?, run_id?, …)

You want the product rather than an answer in the chat. sop turns a screen recording into a step-by-step guide with screenshots. prompt turns a clip into the brief to remake it with a generator.

toolsop | prompt
Which PlayTool to run.
urlstring
The video to run it on: a link, an upl_… id, or a local path over stdio. Required to start a fresh run.
promptstring
What you want, in your own words. For prompt: which generator you write for, and what should be different about the video. sop ignores it.
run_idstring
A run to keep waiting on, from an earlier call.
sop_idstring
An existing document to redo one step of, with step. The document keeps its share link.
stepstring
Which step to redo, for example "step-3". Needs sop_id beside it.

get_transcript(url, words?, language?)

The question is about what is said rather than what is shown.

urlstring
The same source as watch_video.
wordsboolean
Include word-level timestamps.
languagestring
Name the language, for example "en". auto detects it. Name it when you already know it and the audio is mostly music or noise.

attach_stream(url?, road?, protocol?, question?, label?)

A live event rather than a recording: an HLS playlist, a camera, or your own encoder. Playhead watches it minute by minute until you stop it.

urlstring
The address of the stream: an HLS playlist, an RTSP camera, or an SRT or RTMP address you own. Leave it out and pass road: push instead.
roadpull | push
pull opens an address, and is the default when you pass a url. push hands you back an address and a stream key for your own encoder to send to.
protocolrtmp | srt
Which one a push event listens on. RTMP unless you asked for SRT.
questionstring
What you are watching this event for. It is set once and applies to every minute.
labelstring
A name for this event, for your dashboard.

detach_stream(stream_id)

The live event has ended. Nothing stops on its own.

stream_idstring
The event id, from attach_stream.

get_account(history?, limit?)

Before an expensive pass over something long, or when a call was refused for want of credit.

historyboolean
Include recent jobs and what they cost.
limitnumber
How many recent jobs to list. Default 10.

get_playbook(task, section?)

A job with a known shape, such as an ad teardown, a caption audit or a render check, rather than a one-off question.

taskenum
Which playbook.
sectionstring
One section of it, fetched only when you ask for it.

How much comes back at once

This is a property of MCP clients rather than of Playhead, and it is the single most common surprise when building on the server.

An MCP client caps one tool result, and a result over that cap is dropped whole rather than shortened. Every answer here is words, a few kilobytes at most, so no call comes near it.

In practice this costs you nothing. An answer in words is a few kilobytes whatever the video is, so one call covers a two hour recording as easily as a fifty second advert.

Sessions covers what a second question costs, which is the number to plan around.

Running it yourself

The npm package is MIT. It calls the hosted API, so a key or a token still pays for the work.

Remote HTTP transport: the default, and what the connect buttons usebash
claude mcp add --transport http playhead https://mcp.tryplayhead.com/mcp
stdio, which also takes a path to a file on your own machinebash
npx -y @playhead/mcp
# or, with Claude Code:
claude mcp add playhead -e PLAYHEAD_API_KEY=sk_live_… -- npx -y @playhead/mcp
claude_desktop_config.jsonjson
{
  "mcpServers": {
    "playhead": {
      "command": "npx",
      "args": ["-y", "@playhead/mcp"],
      "env": {
        "PLAYHEAD_API_URL": "https://api.tryplayhead.com",
        "PLAYHEAD_API_KEY": "sk_live_…"
      }
    }
  }
}

Configuration

Environment variables read by the npm package. CLI flags --api-url, --api-key, --http and --port override them.

Environment variables for @playhead/mcp
VariableDefaultPurpose
PLAYHEAD_API_URLhttps://api.tryplayhead.comREST API base URL.
PLAYHEAD_API_KEYnot setYour API key. On the remote transport the sign-in wins over it.
PLAYHEAD_MCP_CACHE_DIR~/.cache/playheadWhere answers are kept on your disk, for 7 days. A repeated question is free.
PLAYHEAD_MCP_IMAGE_DELIVERYautoauto, same-turn or next-turn. Some clients show an attachment one turn late, and this settles it.
MCP_TRANSPORTstdiostdio or http.
PLAYHEAD_MCP_REQUIRE_AUTHfalseReject unauthenticated remote calls.
PLAYHEAD_MCP_MAX_RESULT_BYTES950000The largest tool result to send. Too low and you lose part of an answer. Above your client's own cap and you lose all of it.

Questions

What is an MCP server?
Model Context Protocol is a standard way to give an AI agent tools it can call. An MCP server publishes a set of tools with typed arguments, and your agent decides when to call them from what you asked. Playhead publishes eight.
How much of my context does one answer take?
About 2,500 tokens for a first look at a video, and a few hundred for a question that carries the session id. The answer is words, so it does not grow with the length of the video. A two hour recording answers in about as much text as a thirty second advert.
Do I choose how closely Playhead looks?
Only if you want to. Ask a question and you get an answer. depth is there when you want to spend less: glance reads fewer moments of the video and costs about a sixth of a full reading, which is the cheap way to find out whether a video is worth reading properly.
Can I get the answer as JSON instead of prose?
Yes. Send a JSON Schema as schema and the answer carries an object in that shape beside the words, so your code reads values instead of parsing sentences. A field the video cannot fill comes back in unanswered with the reason.
Can I run the MCP server myself?
Yes. npx -y @playhead/mcp runs it over stdio, and --http --port=8787 runs the HTTP transport. Both call the hosted API, so an API key or an OAuth token is still what pays for the work.