manage_transcript
Maintain source transcript text/speakers when the user explicitly requests source repair; also supports deprecated low-level transcript variant inspection. For caption/subtitle spelling, wording, grouping, emphasis, presets, style, layout or translation, start with read_captions and edit_captions instead. Caption polish does not require editing shared source transcription. Finding timestamps remains in find_transcript.
For ordinary user-facing requests like "turn on bilingual captions", "translate my captions to English", or "show Chinese + English subtitles", use edit_captions action translate. It explicitly creates/refreshes the translation and switches caption visibility in one caption-tool call. In those requests, languageCode / targetLanguage means the TRANSLATION TARGET language, not the original language: English original + Chinese/English captions means target zh, not en.
Actions
fix
Correct ASR mistakes or speaker assignments in an asset's source transcript. This changes transcript truth only; it does not edit timeline playback or remove audible content.
Input fields: asset required; content required with FIX / SPEAKER commands; optional preview.
content command format, one command per line:
FIX [sN]: wordIdx -> "newText"— replace EXACTLY ONE word: the word at 0-basedwordIdxwithin segment[sN](segment ids exactly as shown in read_script's timeline.md / library files) becomesnewText; every other word in the segment is untouched. To change several words, write one FIX per word — never put a whole phrase into a single FIX. Examples: segment[s3] I'm Ben Atkins here→FIX [s3]: 2 -> "Adkins"; segment[s8] 从肚子到杯子到底经历了什么→FIX [s8]: 1 -> "豆子"(only 肚子 changes; CJK words are indexed by the same whitespace/word tokens shown in read_script).SPEAKER [sN]: nameorSPEAKER [sN-sM]: name— assign those segments to a speaker (created if missing). Example:SPEAKER [s2-s6]: Alice. Timestamps and text-search forms (FIX "old" -> "new") are NOT accepted. Before any multi-command batch, and whenever unsure of wordIdx, run withpreview: truefirst — it shows the old word each command would touch without writing, so a wrong index can never become a bad write. All indexes in one call address the transcript before that call. Use""to remove a word's text without removing audio; this does not shift later commands in the same batch. Quoted replacements use JSON string escapes. Reread indexes after committing. Invalid command lines prevent the entire batch from being applied; preview reports them without writing.
To rename an existing diarized speaker label everywhere (e.g. "that's Jon, not John"), do not reassign segments — use edit_project action speaker-update with the speaker id returned by the transcript workflow.
retry_transcription
Force-retry ASR for an audio/video asset after transcription is stuck, timed out, or failed. Input fields: asset required. External MCP agents that already hold prepared audio bytes may pass audioBase64 plus audioMimeType and optional audioFilename / audioStartTimestampSec; ChatCut uploads that audio and uses it for the retry. This bypasses backend duplicate locks safely and starts a new fenced transcription run; it does not wait for completion. Before reading transcript/captions, call track_progress once with target: "transcription", action: "status", and the returned asset id. If it is non-terminal, check again only after the returned interval.
translation_list / translation_read
Inspect original + translation transcript variants for a source scope. Pass json with exactly one scope: assetId, itemId, trackId, or allSpoken:true. translation_read can include targetLanguage to narrow one language.
Scope window semantics
itemId, trackId, and allSpoken only translate the speech the timeline actually USES — the source-media window each item plays (its in/out trim), not the whole asset. So a 1-hour source with only a 1-minute clip on the timeline translates roughly that minute's sentences, picked at full sentence boundaries (never a half sentence). assetId is the explicit "translate the ENTIRE asset" escape hatch — use it when you deliberately want the whole source covered regardless of what's on the timeline.
translation_ensure
Deprecated write-only transcript-variant preparation: translates only the in-window sentences that are missing OR stale (source edited since translation), and reuses the ones already translated and current — no LLM cost for those. This is for compatibility/debugging only. For viewer-facing translations use edit_captions translate, which writes native caption tracks/items from saved caption text, not legacy captions_item.translations. Caption reads and edits require topology v2; on v1 first call edit_captions {action:"refresh"} to convert saved captions without regeneration. The result reports translatedUtteranceCount (new/changed sentences translated this run) and skippedExistingUtteranceCount (already-current sentences reused).
translation_create
Force-regenerate the in-window transcript-variant sentences for targetLanguage, overwriting their prior translation rows. Existing translations for sentences OUTSIDE this scope's window are left intact. Compatibility/debugging only; ordinary caption retranslation must use edit_captions translate with force:true so card-owned translations update.
Translation scope json examples
{"trackId":"V1","targetLanguage":"en"}— only the speech V1's items keep{"source":{"assetId":"<id>"},"targetLanguage":"es","sourceLanguage":"en"}— the whole asset{"allSpoken":true,"targetLanguage":"en"}— every used window across the timeline
Translation result
translation_ensure and translation_create are lower-level compatibility actions. They return captionVisibility.visibleInCaptions:false and no longer return a caption-visibility follow-up. For normal agent behavior, do not chain these manually; call edit_captions translate. Do not invent a captions source shape and do not store translations in caption word overrides.
Translation reliability
The model translates sentence-delimited transcript chunks naturally; the backend computes caption word rows locally for rendering. Silence markers are preserved locally. If a batch misses any sentence, the backend retries missing sentences one-by-one before writing rows. If any speech sentence is still missing after retry, the action fails as a full or partial translation failure; treat either as no usable translation write and retry once or narrow the scope.
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"action": "<action>"
},
"name": "manage_transcript"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| json | No | JSON with exactly one scope plus targetLanguage for write actions. Example: {"trackId":"V1","targetLanguage":"en"}. | |
| asset | No | For action=fix or retry_transcription: asset id/prefix. | |
| action | Yes | One of: fix, retry_transcription, translation_create, translation_ensure, translation_list, translation_read | |
| content | No | For action=fix: FIX / SPEAKER commands, newline-separated, e.g. FIX [s3]: 2 -> "word" | SPEAKER [s2-s5]: Alice. Segment ids are the [sN] ids from read_script; wordIdx is the 0-based index of the ONE word to replace (newText replaces that word only, not a span). Run preview:true before a batch. | |
| preview | No | For action=fix: preview only, no changes applied. | |
| projectId | No | Full project UUID. Required for external browser work; internal agents may omit. Execution/explicit-timeline calls never change later calls' target. | |
| timelineId | No | Full timeline UUID, not a prefix. Required for browser work, even unplaced assets. Get it from read_project or manage_timelines action="list". Never switches visible timeline. | |
| audioBase64 | No | For action=retry_transcription: optional prepared audio bytes as base64 or a data:audio/...;base64 URL. External MCP only; use when the asset has no remoteUrl or you already extracted audio. | |
| audioFilename | No | For action=retry_transcription with audioBase64: optional filename, e.g. extracted-audio.wav. | |
| audioMimeType | No | For action=retry_transcription with audioBase64: MIME type, e.g. audio/wav, audio/mpeg, audio/ogg, audio/mp4, audio/webm. | |
| idempotencyKey | No | Stable key for this browser execution. Reuse only with identical scope and parameters after a lost acknowledgement; applies only to this call. | |
| browserProfileId | No | Optional browser profile override. Omit to select automatically; do not ask the user to choose. | |
| audioStartTimestampSec | No | For action=retry_transcription with audioBase64: optional source-video timestamp offset for the first audio sample. |