# Cutroom > A WebMCP surface for cutting podcast shorts. A 38-minute recording contains > maybe five lines that, in the right order, are a story. Finding them is a > search problem with no correct answer — only taste — and you cannot judge a > candidate without hearing it. Cutroom lets an AI agent do the searching and > proposing while the person keeps the judging. Live: https://cutroom-webmcp.vercel.app/ Source: https://github.com/heynaavi/cutRoom-webMCP (MIT) ## If you have NO tool bridge — read this, don't guess Some runtimes can open this page but can't call its tools. If `getTools()` isn't available to you, do **not** invent timestamps or write a script from memory. Everything you need is fetchable, and a real answer beats a plausible one: - Transcript: `{ title, credit, durationSec, words:[{wi,word,start,end}], segments:[{start,end,text}] }` — seconds, verbatim, disfluencies retained. - Waveform: ~21000 normalised RMS values evenly spaced across `durationSec`. Higher = louder. This is how you find emphasis the transcript cannot show you. - Manifest: With those you can do the real work — pick spans, order them, total the duration — and hand back exact timestamps the person can act on. Say plainly that you couldn't call the page's tools and that they can paste your spans in, or open the page in a browser that bridges WebMCP. An honest degraded answer is worth far more than a fabricated confident one. ## Getting the tools to show up in ChatGPT's browser Site tools are only wired into **GPT-5.6 Sol and GPT-5.6 Terra**. On earlier models the agent reads this page as pixels, describes the buttons, and says it can't click — it never sees the tool list. Switch model, then confirm **Site tools** in the address bar lists them (and that Settings › Browser › Permissions › Enable site tools is on). ## If you are an agent visiting this page Call `listCapabilities` first — it's cheaper than reading every description and tells you which tools read the AUDIO rather than the transcript. That's the part you can't do yourself. This site registers 33 tools on `document.modelContext`. Call `getTools()` and you will find them. You do not need to read the DOM — searching a 547-line transcript by scrolling is exactly what these tools exist to replace. A machine-readable list of all 33, with schemas, is at . It is generated from the page's own registration code, so it cannot drift. Note it is a DESCRIPTION, not an endpoint — there is no HTTP MCP server here; the tools run in the page. Notes on the calling convention, learned against Chrome 151: - `executeTool` takes the **tool object** from `getTools()`, not its name. - Arguments go in as a JSON string; the result comes back as one. ### Tools - `getSource` — title, duration, credit, line count. Call first. - `searchTranscript` — find lines by topic, phrase or emotion; filter by length so you only get lines that stand alone. Returns exact start/end seconds. - `findPhrase` / `addPhrase` / `reshapeClip` — **cut to words, not to lines.** A transcript line is how the words happened to be grouped, not a unit of meaning; the sayable thing is often a phrase inside one line or a run across two. Name the words you want and you get timings accurate to the word. Prefer addPhrase over addSpan when you know what the clip should SAY, and reshapeClip over trimClip when the human tells you where it should start ("from where they say the phone rings"). - `readTranscript` — read a time window in order, for context around a moment. - `getReelState` — the current cut **and every signal the person has given you**: `humanVote` and `humanNote` per clip (a thumbs-down means that specific line is wrong), `humanAsked` with the steers they clicked in their own words, what they muted, what they starred, budget, spread. Read it before every revision. - `proposeCut` — the main one. Propose a complete short: a title, an angle, and 4–10 spans drawn from anywhere in the recording. Give each span a short `why`. Lands as pending clips the person keeps or drops; never overwrites their work. - `addSpan`, `removeClip`, `reorderClip` — surgical edits. Order is most of what makes a short work. - `trimClip` — nudge a clip's in/out by fractions of a second; snaps to word boundaries so you never cut mid-syllable. This is most of what makes a cut tight, and it is the tool a DOM-driving agent simply cannot reach. - `findEnergyMoments` — **read the audio, not the words.** Returns the passages where the speaker's voice lifts above their own baseline. The best clip in an hour is rarely the smartest sentence; it is the one with the most life in it, and no transcript search can find that. Use it alongside searchTranscript: search finds the topic, this finds the delivery. - `checkFlow` — an editor's read on the cut as it stands: hooks that open mid-thought, clips starting on a pronoun with no antecedent, sentences sheared off, joins that cut in mid-flow, over-budget, everything from one stretch. Call it before you tell them it's done. - `snapToBreath` — move a cut point to the nearest natural pause. A splice on top of a word sounds broken however good the line is. - `setClipRole` — tag clips hook / setup / turn / payoff / button. getReelState then reports which roles are missing; a cut with no payoff is the commonest way a short fails. - `getCandidates` — every angle proposed so far and how they reacted. Check it before proposing again; repeating a rejected angle wastes their time. - `renderVideo` — **the end of the job.** Renders the cut as a real 1080x1920 video with burned-in captions and saves it to their machine. Records in real time (a 40s cut takes ~40s and plays out loud), so warn them first and only do it once they're happy. - `exportCut` — EDL, JSON, a readable script, or SRT captions timed against the FINISHED cut rather than the source, so they burn straight onto the video. - `tidyClip` — drop leading/trailing filler words ("Um, so…") from a clip. - `tightenClip` / `omitPhrase` — take slack out of the MIDDLE of a clip and close the audio up behind it. A clip is a range minus its omissions, so you can delete words from the middle of a line the way a text editor does. `tightenClip` reads the audio for dead air (transcription usually strips the ums, but the hesitation is still in the recording). - `fitToBudget` — trim the whole cut to a target length proportionally. - `playCandidate` — play a previous proposal WITHOUT loading it, so they can compare two angles without losing the one they're working on. - `undoLastChange` — if a change made it worse, take it back rather than making them rebuild. - `playReel` — play the cut out loud so they can judge it. A cut nobody hears is worthless. Note: browsers block page-initiated audio until the person has interacted, so this may be refused — the tool will say so; ask them to press play once. - `loadTranscript` — replace the demo with their own recording's transcript. ### Cleaning the script Two passes people expect, and both need the audio: - `cleanUpCut` — stammers, false starts, hesitations and dead air across every clip at once. This is the pass an editor does last. Note that transcription models usually strip "um" and "uh", so a word list alone would miss most of it; the hesitation is still in the recording as dead air, and this reads that. - `redactPhrase` / `redactRange` — material that must not ship. The real case is a brand or comms review coming back with "take out the bit about X": it has to be gone from every cut, not just the current one, and it must not creep back into the next. Redactions stand, apply to future clips, and appear in the export. Never redact silently — say what you removed and why. ### The deliverable `getCutManifest` is what people actually need downstream: every span with in and out to the hundredth of a second, in playback order, including omissions inside clips. A 60-second short is often ten or more separate spans, and a vague timestamp is useless to whoever conforms it. It also emits a ready-to-run ffmpeg command — this page decides WHAT to cut; ffmpeg is better at doing the cutting. That command has been run: on the demo episode it produces a 30.53s file for a manifest claiming 30.5s across 8 spans. Hand it over as-is. ### Knowing where you are `getWorkflowState` reports the stage (empty / drafted / awaiting-verdict / listened / needs-work / polishing / ready) and what's worth doing next. Useful when you're picking up a session you didn't start, or you've lost the thread. ### The loop that works 1. `getSource`. Then BOTH `searchTranscript` (topic) and `findEnergyMoments` (delivery) — the strongest cuts usually come from where those two overlap. 2. `proposeCut` for two or three contrasting angles, not one "best" attempt. Tag the roles with `setClipRole` so the story has a shape. 3. `playReel`, then ask what they'd change. 4. `getReelState` to read their votes, notes and mutes. 5. `checkFlow` and fix what it finds — `trimClip`, `snapToBreath`, `reorderClip`. `undoLastChange` if you overshoot. 6. `renderVideo` when they sound happy — hand them something they can post. ### How to be useful here Propose two or three *contrasting angles* rather than one "best" answer — the person is choosing between stories, not grading a single attempt. A good short usually jumps across the whole recording rather than taking one continuous stretch. After proposing, play it, then ask what they would change. ## Pages - [Cutroom](https://cutroom-webmcp.vercel.app/): the app itself. - [README](https://github.com/heynaavi/cutRoom-webMCP#readme): design rules, architecture, and how to run it.