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.
| Tool | Returns | Cost |
|---|---|---|
watch_video | The 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_videos | One 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. |
compare_videos | One answer about the videos, with the seconds, read on one clock: two side by side, or three and four in a 2x2 grid, one per corner. | What reading the pair costs. A grid of four is one video as long as the longest, so it costs about what reading one of them costs. |
analyze_ads | A card for each ad, and for a set, a comparison over the cards: what they share, where they differ, and what transfers. Every analysis is saved to the dashboard. | One reading per ad. A run takes a few minutes. The call waits while it can and then hands back a run id with live progress. |
get_ads_analysis | A list of analyses with their ids and dashboard links, or one analysis in full, or the answer to a new question about one. | Nothing to find or read an analysis. A new question about a set reads the cards and opens no video. |
get_transcript | Plain 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. |
get_account | Which plan is connected, credits left, and what recent calls cost. | Nothing. No video is touched. |
get_playbook | A method for one recurring job: the call order, what is measurable, and where the judgement is yours. | Nothing. No video is touched. |
search_library | The saved videos that match, a line each: the brand, the opening line, the market number, the length, how far it is read, and the address on the dashboard. | No reading and no credits. A few hundred tokens of context. |
list_boards | Every board with its count, or what is new on one board. | No reading and no credits. |
save_videos | A line per video: saved, or saved already, with its address on the dashboard. | A quick read of each video, part of the plan. read: full takes the credit a full reading costs. |
add_to_board | How many videos went onto the board. | No reading and no credits. |
find_outliers | The videos of one brand or account that stand out: ads by how long they ran, posts by times their account's usual views. | No reading and no credits. |
follow | The follow, and what Playhead found of it on the first check. | No reading. A quick read of each new video, part of the plan. |
list_following | Every brand and account the team follows, with what is new. | No reading and no credits. |
find_breakouts | The videos that ran far above their channel's usual views, with the factor, across every follow, a niche, the library or a board. | Across the follows, no request and no credits. In a niche, a search on each platform. |
find_similar | For a YouTube video or channel: the channels YouTube shows beside it that make the same kind of video, each measured, and their videos of the last 30 days. For anything else, and for other niches: videos and creators made like it, each with how alike it is and in what. Both end with the next step. | A YouTube link in its own niche: no credits, seconds, kept a day. Anything else: a quick reading of the reference and of up to eight matches, and the searches. About a minute. |
search_videos | Videos for words on YouTube, TikTok and Instagram, with the channel, the views, the day it went up, the views per day since then and its factor. | No reading. A search is kept for a day. |
search_ads | Video ads from the Meta Ad Library, with the days each ran, its copies, its copy, its button, its landing page and its angle. | No reading. A search is kept for a day. |
find_creators | The channels behind the videos for words, each measured from its own newest 30 videos, with its best recent outliers. | No reading. Each channel is measured the first time and kept for a day. |
write_brief | The brief's id and its address on the dashboard. It is written in the background. | One writing call over readings already stored. |
get_brief | One brief in full, or the list of briefs. | No reading and no credits. |
analyze_virality | The map of why a video works: the hook and its jobs, every part with its seconds and why people stay, the question it keeps open, and the techniques. Saved to the dashboard. | One full reading. The call waits while it can and then hands back a run id. |
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.
- string
- 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.
- string
- 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.
- string
- 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.
- string[]
- 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.
- number[]
- 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.
- number[]
- 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.
- glance | 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.
- object
- A JSON Schema, for code that reads values. Send one and the answer is an object in that shape instead of prose, with every moment of the reading and its second under it. For a question a person asked, send no schema: the prose answer holds more. A field the video cannot fill comes back in unanswered with its reason.
- string
- 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.
- boolean
- 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.
- string[]
- The videos: links, upl_… ids, or paths to files on your own machine over stdio. Required to start a batch, ignored with batch_id.
- string
- 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.
- object
- 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.
- string[]
- What you already know that the videos cannot show. Plain sentences.
- string
- 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.
compare_videos(a, b, c?, d?, question?, labels?, instructions?, schema?, depth?)
A remake against its original, two cuts of one ad, or a person's video beside the best matches find_similar named. Name what to compare for the sharpest answer: the title, the price, the logo.
- string
- The first video, drawn on the left: a link or an upl_… id.
- string
- The second video, drawn on the right: a link or an upl_… id.
- string
- A third video, bottom left of a grid.
- string
- A fourth video, bottom right of a grid. Only with c.
- string
- What to compare. Leave it out and you get where the two differ.
- string[]
- What the videos are called on the picture, one per video, like ["original", "remake"]. A, B… when absent.
- string
- How the answer reads, in your words.
- object
- The JSON shape the answer has to take.
- glance | read | full
- How much of the pair to read. full when absent.
analyze_ads(ads, ask?)
Take one ad apart, or compare a set of them. Use it for an ad instead of watch_video when the person wants a record they can open, share and ask about again.
- object | object[]
- The ads, 1 to 50. Each one is { url, label?, note? }: a link or an upl_… id, what the person calls it, and their own numbers for it, quoted and never checked. One ad may be sent without a list around it.
- string
- What the person said, in their words. Without it the run describes the ads. With it, the run also says what to change.
get_ads_analysis(query?, run_id?, ask?, limit?)
Before analyze_ads, whenever the person refers to work that was already done. Also how to keep waiting on a run that analyze_ads handed back.
- string
- Words to find an analysis by: a brand, an ad title, a label or a word from the link. Leave everything out to list the newest.
- string
- One analysis (trun_…), read in full.
- string
- A new question about the set that run_id names, answered from its cards.
- number
- How many to list, 1 to 50. 10 when absent.
get_transcript(url, words?, language?)
The question is about what is said rather than what is shown.
- string
- The same source as watch_video.
- boolean
- Include word-level timestamps.
- string
- Name the language, for example "en". auto detects it. Name it when you already know it and the audio is mostly music or noise.
get_account(history?, limit?)
Before an expensive pass over something long, or when a call was refused for want of credit.
- boolean
- Include recent jobs and what they cost.
- number
- 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.
- enum
- Which playbook.
- string
- One section of it, fetched only when you ask for it.
search_library(query?, board?, brand?, kind?, winners_only?, sort?, since_days?, mine_only?, limit?)
What the team already saved: the winners on a board, the ads of one brand, the person's own videos.
- string
- Words to find. A sentence works too.
- string
- Only the videos of this board, by its name or id.
- string
- Only the videos of this brand or account.
- ad | post
- Only ads, or only posts.
- boolean
- Only ads that ran 60 days or more, and posts at three times their account's usual views.
- newest | longest_running | most_views
- newest when absent.
- number
- Only the videos saved in the last N days.
- boolean
- Only the person's own videos. false for only the videos of others.
- number
- How many lines. 20 when absent.
list_boards(board?, since_days?, limit?)
What is on a board, and what was saved to it this week.
- string
- A board by its name or id.
- number
- How far back. 7 when absent.
- number
- How many lines. 20 when absent.
save_videos(urls, own?, board?, read?)
Keep a video in the library, on a board. The person's own cuts go in with own: true, so they can be compared with the rest.
- string | string[]
- Links, upl_… ids, or paths on your own machine when the server runs over stdio. 20 at most.
- boolean
- true when these are the person's own videos.
- string
- The board, by name or id. Made when it does not exist.
- quick | full
- quick when absent.
add_to_board(item_ids, board)
Put videos already in the library onto a board.
- string[]
- The ids of the saved videos.
- string
- The board, by name or id. Made when it does not exist.
find_outliers(brand, limit?)
Name the outliers of one brand or account.
- string
- The brand or account, by its name or handle.
- number
- How many. 10 when absent.
follow(url?, page_id?, name?, board?, save_now?)
Watch a brand's ads or an account's posts: Playhead checks every morning and saves what is new.
- string
- The account link, or a Meta page or Ad Library link.
- string
- A Meta page id, for a brand.
- string
- What to call it.
- string
- Where new videos go, by board name or id.
- boolean
- Also save what it ran or posted lately, now.
list_following()
Who the team follows.
find_breakouts(from?, query?, board?, since?, min_factor?, platform?, limit?)
What performed today or this week: in the accounts the person follows, in a niche they name, in the library, or on a board.
- following | niche | library | board
- following when absent.
- string
- The niche or topic, for from: niche.
- string
- The board's name, for from: board.
- day | week | month
- week when absent.
- number
- Times the usual views at least. 3 when absent.
- all | youtube | tiktok | instagram
- For from: niche.
- number
- How many lines. 15 when absent.
find_similar(url?, scope?, want?, platform?, since?, run_id?)
Find channels that make videos like this one, videos like mine, or creators who make what I make, in my niche and in others. The first step of "what does my video do wrong".
- string
- A video, a channel or an account link, an upl_… id, or a local path over stdio.
- both | niche | format
- both when absent. format finds the same way of making in other niches.
- both | videos | creators
- What to list. both when absent.
- all | youtube | tiktok | instagram
- all when absent.
- day | week | month | year
- Only videos that went up in this window.
- string
- A run this tool handed back, to keep waiting for it.
search_videos(query, platform?, since?, sort?, min_factor?, min_views?, limit?)
What runs in a niche right now, and the videos furthest above their channel.
- string
- Words, a niche or a topic.
- all | youtube | tiktok | instagram
- all when absent.
- day | week | month | year
- Only videos that went up in this window.
- relevance | views | newest | factor
- factor puts the videos furthest above their channel first.
- number
- Only videos at this many times their channel's usual views or more.
- number
- Only videos with this many views or more.
- number
- How many lines. 15 when absent.
search_ads(query, min_days?, sort?, angle?, country?, limit?)
What a brand runs right now, the longest running ads of a niche, which offers a market uses.
- string
- Words in the ads, or a brand's name.
- number
- Only ads that ran this many days or more.
- longest | variants
- longest when absent.
- string
- Only ads of this angle, such as promotion.
- string
- Two capitals, for example DE.
- number
- How many lines. 15 when absent.
find_creators(query, platform?, size?, breaking_out?, sort?, limit?)
Who makes what works in a niche, and small channels that are breaking out.
- string
- Words, a niche or a topic.
- all | youtube | tiktok | instagram
- all when absent.
- small | mid | large | huge
- By followers: under 10K, to 100K, to 1M, over 1M.
- boolean
- Only channels with an outlier in the last 90 days.
- outliers | smallest | usual
- outliers when absent.
- number
- How many. 8 when absent.
write_brief(what, idea?, references?, board?, runs_on?, length_max?, facts?)
A brief for a creator, an editor or an AI, from videos in the library or the winners of a board.
- string
- What to make, in the person's words.
- string
- The one idea the video is built on.
- string[]
- Ids of videos in the library, 12 at most.
- string
- A board whose winners are the references, when no ids are given.
- string
- Where the video runs.
- number
- The longest it may be, in seconds. 35 when absent.
- string
- What is true about the product. The brief uses only these.
get_brief(id?)
Read a brief that write_brief started, or see which briefs exist.
- string
- A brief id, brf_… Leave it out for the list.
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.
Add it to your client
Playhead runs the server for you. Every client connects to the same address, and you sign in once.
claude mcp add --transport http playhead https://mcp.tryplayhead.com/mcpOther clients take the same address as a custom connector or a remote MCP server. Connect an agent has the steps for each one.
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?
- No. Playhead runs the MCP server for you at mcp.tryplayhead.com/mcp, and every client connects to that address. You sign in once, and your own account pays for the work.