Podcast MCP
Provides audio processing, rendering, mixing, format conversion, and playback capabilities via FFmpeg.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Podcast MCP transcribe the host track and find long pauses"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Podcast MCP
FOSS podcast production toolkit: multitrack projects, per-track transcription, transcript-driven tightening, FFmpeg processing, ShareCut Studio (a full DAW-style editor in the browser and the desktop app), and agent skills under .agents/. The scope of the current beta is in docs/beta-plan.md.
Requirements: Python 3.11+, uv recommended (install.sh falls back to .venv + pip), and a matching FFmpeg/FFprobe 9.0.2 or later 9.x pair for source use. Desktop packaging selects a pinned prebuilt 9.0.2 pair. The release catalog pins the same platform archives for CI and desktop packaging.
Quick start
git clone <repo-url> && cd sharecut-studio
./install.sh
source .venv/bin/activate # or: uv run podcast …
podcast doctor
# Whisper defaults to large-v3-turbo (~1.6 GB, first transcribe). Smaller: ./install.sh --whisper-model small.en./install.sh installs a contributor set (dev + gui + relay). Optional downloads and extras: docs/setup.md.
Choose a downloaded Whisper model for one standalone transcription with podcast transcribe --project … --model small.en; use podcast setup --whisper-model small.en or PODCAST_WHISPER_MODEL to make that choice the machine default.
podcast transcribe reports the number of tracks processed by that run. When there are no dialogue tracks to process, it reports Transcribed 0 track(s). and warns on stderr.
No supported system pair? Use the prebuilt importer. Offline validation uses an explicit pinned archive through the same importer. Pair selection and the tested release policy, including process-local reuse of successful unchanged admission, are documented in docs/setup.md. Explicit health checks still run fresh bounded version probes.
Agent config is tool-agnostic under .agents/ (skills, rules, MCP template). Register MCP per docs/setup.md. With podcast gui running on loopback, Connect agent… (home or Menu) copies http://127.0.0.1:8765/mcp for URL-only clients. Use the podcast-setup skill when onboarding.
Codex UI edits have project-local Impeccable design hooks. Review and trust them in Codex Settings → Hooks after cloning or updating their definitions.
Related MCP server: AI Sound MCP Server
Maximal install (all extras)
Every pip extra, plus the models podcast bootstrap fetches: about 360 MB for the word aligner and about 80 MB for the speaker model. No extra pulls torch. Prefer the Quick start above for everyday CLI/MCP/GUI work.
git clone <repo-url> && cd sharecut-studio
uv sync --all-extras
source .venv/bin/activate # or: uv run …
podcast bootstrap
podcast doctor
# Optional ShareCut Studio UI (needs Node 24+):
cd gui/web && npm ci && npm run build && cd ../..Notes (verified in a disposable Linux Docker image):
uv sync --all-extrasinstalls every pip extra (dev,gui,relay,object-store,prosody).A bare
podcast bootstrapinstalls Whisper, RNNoise, the word aligner and the speaker model, and so does Studio's Get ready card.podcast bootstrap --component word-alignerinstalls just the aligner; once downloaded, precise word boundaries (transcribe.forced_alignment.enabled, English) turn on by default; until then they stay unavailable and the pipeline reports word times as Whisper-only (Studio: download it next to the Pipeline tab's Precise word boundaries field).Without
uv:python3 -m venv .venv && .venv/bin/pip install -e ".[all]"then the same bootstrap/doctor steps.
Detail: docs/setup.md § Maximal install. Operators can use the read-only public mirror check to verify bootstrap object availability without downloading payloads.
The frontend CI suite uses a locked exporter dependency group for its four generated-file checks. Browser suites keep the full GUI environment.
Repo layout
Path | Purpose |
| Python package — CLI, MCP, services, domain, GUI API, Extensions SPI |
| Optional private/provider extension, installed independently when needed; its source is not part of this repository |
| FOSS reverse-tunnel edge ( |
| ShareCut Studio viewer (React + Vite) |
| FOSS host-online share relay (Docker Compose examples) |
| Published caps / feature-id contract artifacts |
| Skills, rules, MCP template, pipeline defaults |
| Architecture and feature docs |
| Pytest suite and fixtures ( |
|
|
Episode workspace
podcast episode init --dir /path/to/my_episode
podcast track add --project /path/to/my_episode/episode.sharecut --id host --file raw/host.wav --role dialogue
podcast pipeline run --project /path/to/my_episode/episode.sharecutShareCut Studio (editor):
uv sync --extra gui
cd gui/web && npm install && npm run build && cd ../..
podcast gui --project /path/to/my_episode/episode.sharecutRelease wheels include the web build (the release-wheel workflow runs npm run build before uv build). A wheel built without it makes podcast gui warn at startup and / explain how to build it and set PODCAST_GUI_DIST (docs/setup.md). Hot reload: podcast gui --project … --dev --no-open plus cd gui/web && npm run dev. Agents: MCP open_gui_tool / skill podcast-open-gui (or podcast gui --background). Details: docs/gui-integration.md, docs/setup.md.
For the development-only UI component catalog, run cd gui/web && npm ci && npm run storybook; see docs/design-system.md for publishing setup.
A clean clone needs no relay, account, object store, CDN, or signing credentials for local editing. Before enabling collaboration or building a downstream desktop distribution, validate only that mode’s configuration:
podcast config check --mode local
podcast config check --mode self-hosted --relay-config config/relay.example.yaml
podcast config check --mode distributor --distribution-profile /path/to/distribution.jsonRuntime secrets belong in environment variables or
~/.config/podcast_mcp/relay.yaml; public desktop identity belongs in a validated
distribution profile. See docs/setup.md.
Edit transcription vocabulary with podcast transcript context set: pass
--project PATH --term NAME or remove entries with --remove-term NAME / --remove-guest-name NAME.
Host MCP agents can read and replace it with revision checks. See the
transcript workflow.
Documentation
ShareCut Studio Extensions — public plugin SPI (absent = no render); seams
Host-online relay — Docker share edge, tunnel, capability-scoped remote MCP (via the FOSS collaboration extension)
Share tokens and registry backups — create a new private backup with
podcast review backup-registry;--destrequires an unused name in an existing trusted private directory.Recording session (design) — record links, full-quality recording on each device, mix-minus monitor, consent
UX onboarding pack — shareable brief, screens, glossary, backlog (live site; See the UI)
UI philosophy — trust-first beta design principles for automation, recovery, and the free core workflow
Communication philosophy — voice, terminology, control placement, and the mobile ergonomics checklist for user-facing UI
Interaction system — one path per interaction (selection, targets, menus, sheets, feedback, keyboard and touch equivalents), the registries, and the checklist a new interaction passes
Setup — install, extras, optional downloads, MCP, bootstrap, play, GUI
Architecture — layers and timebase
Contributing — where new code goes; Git workflow (feature branch → PR → the base branch in
config/branches.json)Agent instructions — SOLID/DRY, tests-as-you-go, docs in sync
Episode format v2 — canonical
episode.sharecut(see also project-format.md)Multitrack ingest & alignment — raw files → one track per speaker
Transcript workflow — reconcile → precorrect → refine → audition
Session sync — agent ↔ DAW transport
GUI integration — viewer API, layers, live reload
Timeline comments — review feedback + action items (MCP/CLI/DAW)
CI workflow defines the frontend browser matrix and its job timeouts, including the Chromium and WebKit compatibility jobs.
Editor profiling:
npm --prefix gui/web run profile:remainingruns disposable workload profiles;profile:comparefreezes or applies local diagnostic budgets;make profile-seek-trim OUT=/tmp/seek-trimprofiles ruler seek and clip trim. See the profiling commands and limits.
Diagnostics and report-submission orchestration live in
services/support/; pipeline execution,
configuration, and component bootstrap live in
services/pipeline/. Contributor import
rules are in Contributing.
Support
Bugs: GitHub Issues. Attach a sanitized diagnostics zip from Home → Help → Report a problem → Create diagnostics bundle or podcast doctor --bundle (writes ~/Downloads/sharecut-diagnostics-<UTC>-<nonce>.zip). Nothing is uploaded automatically — there is no telemetry. Do not attach episode audio or project JSON. Minted shares may transit the relay; GitHub issue attachments are public. Detail: docs/setup.md § Troubleshooting.
Privacy
Beta policy (local audio unless you mint a share; relay is a pass-through that does not store audio but share audio/media may transit while the share is active; no telemetry): sudo.science/privacy.html.
Play audio (listen while developing)
podcast play --project tests/fixtures/aligned_dialogue/episode.sharecut \
--source processed:reference --start 0 --end 15 # edits + FX (stem or segment render)
podcast play --project ... --source track:guest --start 0 --end 15 # raw alignment
podcast play --project ... --compare --start 18 --end 28 # alignment check
podcast play --project ... --query documented # after transcript is seeded
podcast play --project ... --dry-run # extract WAV only; see "tier" in JSONTesting
Tests run with a 95% minimum coverage gate (see docs/testing.md):
make test # full suite + coverage gate (parallel)
make test-fast # quick inner loop, no coverage
make e2e # aligned_dialogue fixture; see docs/e2e-fixture-manual.mdGUI frontend unit tests (session dedupe, etc.): cd gui/web && npm test.
GUI browser tests use npm --prefix gui/web run test:e2e; its wrapper owns private
registry and identity state. make ux-demo-screens captures host and guest views
from a disposable copy of the existing showcase fixture.
License
MIT
Available Tools
183 toolsadd_chapter_toolC
Add a chapter marker at a timeline time.
Inputs: title (required), at_time (required), project_path. Returns: result
add_comment_action_toolC
Append an action item TODO to an existing comment.
Inputs: text (required), comment_id (required), project_path. Returns: result
add_comment_reply_toolC
Append a flat reply under an existing timeline comment (threaded discussion).
Inputs: body (required), author (required), comment_id (required), project_path. Returns: result
add_comment_toolA
Add a timeline review comment (instant or span).
Times are timeline seconds (session/deliverable clock), like chapters - not source-media time. Use search_transcript_tool's timeline_start/end when anchoring to dialogue. track_ids / action_texts are optional string lists. Empty track_ids = session-wide. Undoable via history. Pass edit_decision_id to open the single Ask thread for a pending cut (unique per decision; later notes must use add_comment_reply_tool).
Inputs: body (required), author (required), timeline_start (required), track_ids, +4 more. Returns: result
add_effect_toolC
Add an effect (or preset) to a track or speaker's effect chain.
Inputs: effect, params, preset, speaker, +2 more. Returns: result
align_brief_toolB
Return the alignment acceptance brief: what the agent must check before marking done.
Inputs: project_path. Returns: result
align_done_toolC
Mark the conversation-clock alignment acceptance gate done, with optional notes.
Inputs: notes, project_path. Returns: result
align_retained_bleed_toolB
Align supported complete direct phrases locally while keeping uncertain audio intact.
Preview with apply=False. Saved manual/declined decisions take priority. Legacy placement overrides require an explicit timeline window.
Inputs: apply, end_sec, track_id, start_sec, +2 more. Returns: result
align_status_toolB
Report the conversation-clock alignment acceptance gate status (pending/done/waived).
Inputs: project_path. Returns: result
align_waive_toolC
Waive the alignment acceptance gate with a recorded reason.
Inputs: reason (required), project_path. Returns: result
analyze_cleanup_toolC
Analyze a track for cleanup opportunities (silence, clicks, hum).
Inputs: speaker, track_id, project_path. Returns: result
apply_bleed_suppression_toolC
Suppress mic-bleed words (dry_run previews without applying).
Inputs: apply, words, dry_run, end_sec, +5 more. Returns: result
apply_edit_plan_toolC
Stage cuts from an edit-plan list; applied entries undergo fresh cut assessment.
Inputs: edits (required), project_path, review_required, use_inaudible_opt. Returns: result
apply_editsC
Auto-apply non-review REMOVE/MUTE decisions whose reason starts filler: or pause:.
Inputs: project_path. Returns: result
apply_fade_recommendations_toolC
Apply a list of fade recommendations (from recommend_fades_tool) to the project.
Inputs: recommendations (required), project_path. Returns: result
apply_low_audibility_suppression_toolC
Suppress low-audibility transcript words, optionally only words; leaves audio unchanged.
Inputs: words, speaker, track_id, project_path. Returns: result
apply_suggested_actions_toolA
Apply every pending sound's own suggested action in one undo step.
Each tighten proposal carries a label and a suggested_action (propose_edits
shows them). This applies all of them, or only ids: cut and shorten cut
(a cut held by the automatic audio checks stays pending and is named in held),
lower turns a laugh down while another speaker talks over it (otherwise it is left),
leave dismisses the proposal and keeps the audio. overrides maps a decision id to
another action for that sound. Returns applied by action, cut_over_speaker,
held (ids still pending) and a summary sentence.
When the user says to apply the held ones anyway, repeat with
override_audio_checks=true (recorded in History and the edit log).
To change one sound after the batch (say a cut to leave) without undoing the rest, call
again with revise=true and overrides={id: action} and no ids: it steps back
to before the latest batch (which must still be the latest edit) and applies it again
with that change, as one undo step. Otherwise it refuses with
no_suggested_batch_to_revise.
Inputs: ids, revise, overrides, project_path, +1 more. Returns: result
apply_transcript_cleanup_toolB
Batch word + phrase fixes in one undoable history step.
corrections: {"words": [{word_index, text}], "phrases": [{start_word_index, end_word_index, text}]}
Inputs: track_id (required), corrections (required), project_path. Returns: result
apply_transcript_gate_toolB
Apply an acoustic bleed plan to fresh dialogue stems and persist its source scope.
Retained speech and unresolved audio stay open. Later renders reuse the plan's policy and scope. Supported local retained-bleed alignment runs by default and respects saved timing choices. Alignment can trigger normal transcript reconciliation.
Inputs: apply, dry_run, end_sec, speaker, +5 more. Returns: result
approve_edits_toolA
Approve pending edits by id (or every pending proposal), applying them to the timeline.
To give every pending sound its own suggested action at once, use
apply_suggested_actions_tool.
all_pending=true approves every pending proposal; ids approves those. Either way
the edits that pass the automatic audio-quality and cut-position checks apply, and
held lists the ones stopped (each with its finding) and left pending. When the user says to approve a held cut anyway, repeat with
override_audio_checks=true: it skips those checks for this call and records the
override (actor and surface) in History and the edit log.
Inputs: ids, all_pending, project_path, override_audio_checks. Returns: result
approve_social_clips_toolC
Approve social clips by id.
Inputs: ids (required), project_path. Returns: result
audibility_map_toolC
Return per-word audibility scores for a track or speaker.
Inputs: speaker, track_id, project_path. Returns: result
audio_diagnostics_toolC
Run audio diagnostics (clipping, hum, level) on a time window.
Inputs: end_sec, speaker, track_id, start_sec, +1 more. Returns: result
audition_context_toolA
Caption each dialogue track in a timeline window + clip-skew / render freshness.
detail: summary (default) includes comments, active effects, edits, and
windowed hum/clip hypotheses; full expands edit/comment payloads;
visual adds waveform/spectrogram PNGs (slower). Returns
audition_context.v2 (typed hypotheses, suggested_listen, explicit clocks).
Each track also carries a prosody window (pitch, rate, energy, prominent
words, phrase boundaries) read from the pipeline's cached profile
(analyze_prosody step); status is missing/stale with a hint
when no fresh profile is cached yet, or unavailable (redacted error)
when the cache cannot be read. Top-level prosody_notes has up to
8 one-line summaries. Times are timeline (session) seconds. Does not play audio.
Inputs: end_sec (required), start_sec (required), detail, project_path, +1 more. Returns: result
bleed_words_toolC
List words contaminated by another speaker's microphone bleed.
Inputs: end_sec, speaker, track_id, start_sec, +1 more. Returns: result
bounce_audio_toolA
Bounce selected (or all) stems to export/bounces/ without mastering.
Times are timeline seconds. track_ids lists the stems, or omit for all
non-muted mixable tracks. formats lists extensions (e.g. ["wav", "mp3"]);
default wav only.
Inputs: end_s, formats, start_s, track_ids, +1 more. Returns: result
build_edit_contextB
Build the JSON edit-planning context: utterances with word indexes for cut_* tools.
Inputs: project_path, max_utterances. Returns: result
check_loudness_toolC
Measure LUFS and report artifact and dialogue-balance staleness without refreshing.
pass judges loudness; stale and stale_reason judge known project
artifact age. balance reports per-dialogue-track measurement freshness for
tracked project audio. An explicit unrelated file has stale=None.
Inputs: audio_path, project_path. Returns: result
copy_segment_toolA
Copy [start, end) timeline seconds the way Studio Copy / Cut fill the clipboard.
Read-only. Returns {duration, extracts}: the clips of every track in range, or
only track_ids. Pass it to paste_segment_tool, which takes
the edit mode. To cut and paste, copy first, then cut (propose_range_cut_tool, or
delete_clips_tool with its mode).
Inputs: end (required), start (required), track_ids, project_path. Returns: result
correct_transcript_phrase_toolB
Replace a word range's text with corrected phrase text.
Pass expected_text (the space-joined words you read for this range) to refuse the fix
if those words changed meanwhile; omit to skip.
source_id names the recording whose words word_index counts; it is required on a
track recorded as several takes, and the refusal is word_source_required.
Inputs: new_text (required), track_id (required), end_word_index (required), start_word_index (required), +3 more. Returns: result
correct_transcript_toolA
Fix the text of one transcript word without changing its timing.
Pass expected_text (the word text you read) to refuse the fix if the word at
word_index changed meanwhile (for example a GUI edit shifted indices); omit to skip.
source_id names the recording whose words word_index counts; it is required on a
track recorded as several takes, and the refusal is word_source_required.
Inputs: new_text (required), track_id (required), word_index (required), source_id, +2 more. Returns: result
create_record_room_toolC
Mint a recording room: guest + producer /rec/ links (design: docs/recording-session.md).
Inputs: expires_at, project_path, public_base_url. Returns: result
crossfade_joins_toolC
Add crossfades at edit joins on a track; dry_run previews without applying.
Inputs: dry_run, fade_ms, speaker, track_id, +1 more. Returns: result
cut_text_match_toolB
Stage a pending cut for the first text match, or every match with match_all=True.
Inputs: query (required), speaker, track_id, match_all, +3 more. Returns: result
cut_time_range_toolB
Stage a pending cut of a time range on a track; applies after approve_edits.
Inputs: end (required), start (required), track_id (required), reason, +3 more. Returns: result
cut_utterance_toolC
Stage a pending cut of one utterance by its index.
Inputs: utterance_index (required), project_path, review_required, use_inaudible_opt. Returns: result
cut_words_toolC
Stage a pending cut of a word-index range on a track.
Inputs: track_id (required), end_word_index (required), start_word_index (required), source_id, +3 more. Returns: result
delete_clips_toolA
Delete whole clips by id, as the Studio clip Delete and Ripple delete do.
clip_ids lists the clips to delete (see list_clips_tool).
mode="gap" leaves silence where each clip was and moves nothing else;
mode="ripple" closes the clips' spans on every dialogue track, so speakers stay
in sync. A ripple that would cut speech outside the deleted clips (another track's,
or an unselected clip's on the same track) changes nothing and returns
needs_confirmation; repeat with override_audio_checks=true to apply it
anyway (recorded). Submits DeleteClip on the document plane; undoable.
For a time range across tracks use ripple_delete_tool.
Inputs: clip_ids (required), mode, project_path, override_audio_checks. Returns: result
delete_comment_toolC
Delete a timeline review comment (undoable via history).
Inputs: comment_id (required), project_path. Returns: result
duplicate_segment_toolC
Duplicate a timeline segment at a new time.
Inputs: insert_at (required), source_end (required), source_start (required), project_path. Returns: result
edit_impact_report_toolC
Report pending-review and applied edits, with seconds cut in total and by track.
Inputs: markdown, project_path. Returns: result
episode_createC
Create a new episode project in a workspace directory and return its path.
Inputs: workspace_dir (required), name. Returns: result
export_audio_toolB
Encode mastered audio to export/ using pipeline.yaml formats, or formats objects.
All or nothing: files replace export/ only after every one is written. When the client
cancels the request (notifications/cancelled) the encode stops, the tool raises
CancelledProgress("Export cancelled") and an earlier export is left untouched. Do not
wait for a reply to the cancelled request (over JSON-RPC there is none); check export/.
Inputs: formats, project_path. Returns: result
export_social_clips_toolB
Export specified clips, or all approved and non-review-required drafts when IDs are omitted.
Inputs: ids, project_path. Returns: result
export_transcriptC
Export the transcript as Markdown and return the file path.
Inputs: project_path. Returns: result
fade_joins_toolC
Add fades at edit joins on a track; dry_run previews without applying.
Inputs: dry_run, fade_ms, speaker, track_id, +1 more. Returns: result
fill_with_room_tone_toolC
Fill a track's silences with its own room tone.
Inputs: speaker, track_id, project_path. Returns: result
find_replace_transcript_toolA
Replace a literal word or phrase everywhere in the transcript (Studio Find and replace).
Matches whole words across every track and recording; punctuation around a word is
kept. dry_run returns the preview (matches, count, skipped_words)
and changes nothing. Otherwise every previewed match is replaced through
ReplaceTranscriptMatches in one undo step, and replaced gives the count.
For one word use correct_transcript_tool.
Inputs: search (required), replacement (required), dry_run, match_case, +1 more. Returns: result
flagged_words_toolC
List words flagged for review (suppressed, low-audibility, or bleed).
Inputs: speaker, track_id, project_path. Returns: result
gate_overreach_toolC
Report where noise gating muted speech on a track.
Inputs: speaker, track_id, project_path. Returns: result
get_comment_toolB
Fetch one timeline comment by id (full action_items and resolve metadata).
Inputs: comment_id (required), project_path. Returns: result
get_session_presence_toolB
Who is in the Sharecut Studio session: display names, cursor, selection, viewport, transport, follow relationships.
viewport is the time window a follower should show. Near the start of a
phone's fixed-playhead timeline it begins at 0 and can be wider than what
is on that screen.
Inputs: project_path. Returns: result
get_session_state_toolB
Read shared DAW/agent session state (playhead, region, mode, selection).
Inputs: project_path. Returns: result
get_transcriptC
Fetch the transcript, combined or per-track, in text or JSON format.
Inputs: format, combined, project_path. Returns: result
get_transcript_vocabulary_toolC
Read project terms, guest names, revision, and re-transcription status.
Inputs: project_path. Returns: result
history_diff_toolC
Diff two history indices, showing what changed between them.
Inputs: to_index, from_index, project_path. Returns: result
history_goto_toolC
Jump the project state to a history index.
Inputs: index (required), rerender, project_path. Returns: result
history_listC
List the project's history entries (index, label, mutation type).
Inputs: project_path. Returns: result
history_recordB
Record a named history checkpoint for the current project state.
Inputs: label, project_path. Returns: result
history_redoB
Redo the last undone project mutation.
expected_head_id guards it like history_undo (error_code history_stale).
Inputs: rerender, project_path, expected_head_id. Returns: result
history_status_toolB
Report history cursor, total, undo/redo availability, and current label.
Inputs: project_path. Returns: result
history_undoA
Undo the last project mutation (timeline, transcript, or settings).
Pass expected_head_id (history_status_tool's head_id) to undo only the change you looked at: if another edit landed since, the call refuses with error_code history_stale and nothing changes.
Inputs: rerender, project_path, expected_head_id. Returns: result
ingest_import_folder_toolC
Scan a recorder export folder and write ingest.yaml (audio-only, no copy).
Inputs: audio_dir (required), dry_run, out_manifest, speakers_override. Returns: result
ingest_suggest_alignment_toolC
Propose session_start offsets for multitrack ingest before consolidate.
Inputs: audio_dir (required), manifest_path (required), diag_dir, sweep_step, +5 more. Returns: result
ingest_verify_alignment_toolC
Audit consolidated dialogue tracks with VAD overlap on a timeline window.
Inputs: diag_dir, project_path, window_end_sec, write_waveforms, +1 more. Returns: result
insert_gap_toolB
Open pure silence on the timeline (split + shift).
Do not use to fake a beat after a tight handoff unless the user asks —
prefer keeping existing room tone via suggest_handoff_cut_tool bounds.
Inputs: at_time (required), duration_sec, project_path. Returns: result
join_label_toolC
Record a pass/fail label for a join to train the join-quality ranker.
Inputs: verdict (required), join_sec (required), note, play, +6 more. Returns: result
join_qa_sweep_toolC
Score all joins on a track (or the whole project) for QA review.
Inputs: track_id, project_path. Returns: result
join_quality_toolC
Score an existing or proposed cut join for audibility artifacts (clicks, glitches).
Inputs: cut_end, speaker, join_sec, timebase, +3 more. Returns: result
list_applied_edits_toolC
List applied edits in a timeline window.
Inputs: track_id, project_path, timeline_end, timeline_start. Returns: result
list_chapters_toolC
List chapter markers in timeline order.
Inputs: project_path. Returns: result
list_clips_toolA
List clips in timeline order for one track or all tracks when track_id is omitted.
Inputs: track_id, project_path. Returns: result
list_comments_toolA
List timeline review comments sorted by timeline_start.
Pass include_resolved=false for an agent work queue, or open_actions_only=true for incomplete action items. Each row includes id, body, author, track_ids, action_items, resolved_*.
Inputs: project_path, include_resolved, open_actions_only. Returns: result
list_edit_decisions_toolB
List pending decisions; use list_applied_edits_tool for archived approved edits.
Inputs: applied, project_path, reason_prefix, review_required. Returns: result
list_effects_toolC
List the effect chain for a track or speaker.
Inputs: speaker, track_id, project_path. Returns: result
list_review_versions_toolC
List frozen review mix versions (includes active flag).
Inputs: project_path. Returns: result
list_social_clips_toolC
List proposed social clips, optionally filtered by approved status.
Inputs: approved, project_path. Returns: result
low_audibility_words_toolC
List words too quiet to hear relative to the mix.
Inputs: speaker, track_id, project_path. Returns: result
low_confidence_words_toolB
List words below a confidence threshold for human review.
Inputs: threshold, project_path. Returns: result
move_by_text_toolC
Move a transcript-matched segment before or after another transcript match.
Inputs: source_query (required), destination_query (required), position, project_path. Returns: result
move_clips_toolA
Move clips in session time and/or onto another track (no neighbor ripple).
clips is a list of {clip_id, timeline_start, track_id}.
Inter-track moves keep the originating media via source_id. Unlike
move_segment_tool, this does not cut a range on every dialogue lane.
Inputs: clips (required), project_path. Returns: result
move_segment_toolC
Cut a timeline segment and reinsert it at a new time (ripple move).
Inputs: insert_at (required), source_end (required), source_start (required), project_path. Returns: result
mute_off_speaker_toolA
Mute a track wherever another speaker is talking and its own speaker is not.
Use after transcript reconcile on a call recording whose track still carries another
person's voice. A stretch is muted when another dialogue track has words there, this
track has none, and this track holds nothing louder than a copy of that speaker.
Each stretch is a visible muted region in Studio (Restore brings it back); History
undoes the whole command. Preview with dry_run=true.
Inputs: apply, dry_run, speaker, track_id, +1 more. Returns: result
open_gui_toolA
Start the read-only DAW web viewer (background) and return its URL.
Idempotent: if a healthy viewer is already listening on host:port, reuses it
and optionally opens the browser to this project. Requires the gui extra
(uv sync --extra gui) and a built gui/web dist for the HTML UI.
Inputs: host, port, open_browser, project_path. Returns: result
overlap_duplicates_toolC
Find duplicate words across tracks in an overlap window.
Inputs: end_sec, start_sec, project_path. Returns: result
paste_segment_toolA
Paste a copy_segment_tool clipboard at insert_at timeline seconds (Studio Paste).
mode="ripple" opens duration of time on every dialogue track at
insert_at, then places each extract on its own track. mode="gap" pastes
over: it replaces [insert_at, insert_at + duration) on the pasted tracks only,
and nothing moves. The same clipboard can be pasted again. A clipboard naming an
unknown track or source, or an impossible range, is rejected with a paste_*
code. Submits PasteSegment on the document plane; undoable.
Inputs: clipboard (required), insert_at (required), mode, project_path. Returns: result
pipeline_analyze_toolC
Heuristic Analyze: propose pipeline param patches from audio diagnostics.
Inputs: apply, project_path. Returns: result
pipeline_get_config_toolB
Return effective pipeline config, step metadata, and param schema (same as GUI).
forced_alignment is the resolved Precise word boundaries state (enabled,
requested, installed, blocked, reason): on by default when the word
aligner is downloaded, unavailable until then (#780).
Inputs: project_path. Returns: result
pipeline_runA
Run the production pipeline. Optional skip_steps (step names) / config (object) override yaml.
When use_working_set is true (default), also reads/writes the GUI session
working set so agents and Sharecut Studio share the same visible config.
Omit unattended to leave the working-set Batch mode unchanged.
Existing transcripts are reused; force_transcribe=true re-runs ASR for this run
only (not persisted). retime_words=true re-times stored transcripts with the forced
aligner from their ASR cache for this run only (no Whisper; hand-edited transcripts are
skipped); check transcript_timing.json → forced_alignment.retime for skipped and
failed tracks; not with force_transcribe. It fails before changing any transcript
when the word aligner is not downloaded (the error names
podcast bootstrap --component word-aligner). Forced alignment is otherwise on by
default whenever that model is installed (transcribe.forced_alignment.enabled unset);
forced_alignment.reason in transcript_timing.json says what a run resolved to.
Replacing edited transcripts is refused when
unattended; run attended, or the user confirms with Studio Re-transcribe.
Returns Completed through <step>; when this run exported, the next lines are
the export QC verdict (same as CLI pipeline run).
Inputs: config, from_step, only_step, skip_steps, +5 more. Returns: result
pipeline_set_config_toolC
Update the shared GUI/agent pipeline working set (visible params).
Inputs: reset, config, unattended, project_path, +1 more. Returns: result
play_ab_toolA
Extract the same range at two history indices, then play A→gap→B once.
Prefer this over history_goto → play → goto → play for before/after probes.
Leaves the history cursor on after_index. Default gap is 0.4s.
Inputs: after_index (required), before_index (required), source, dry_run, +5 more. Returns: result
play_ab_wavs_toolB
Play two existing WAVs back-to-back with a short silence gap (one concat).
Inputs: wav_a (required), wav_b (required), dry_run, gap_sec, +1 more. Returns: result
play_audio_toolC
Extract and optionally play audio (processed:, track:, premix, export).
Inputs: raw, query, source, compare, +8 more. Returns: result
play_compare_toolC
Play each dialogue track then premix for the same timeline range.
Inputs: dry_run, end_sec, rerender, start_sec, +1 more. Returns: result
play_compose_toolB
Mix selected tracks for a timeline window and optionally play (no project mutation).
tier is processed (edits+FX stems) or raw (source media). Times are
timeline (session) seconds. Does not change mute/solo/FX on the project.
Inputs: end_sec (required), start_sec (required), track_ids (required), tier, +3 more. Returns: result
play_pending_preview_toolB
Hear Current vs Suggested vs A/B full mix for a pending remove or mute.
Suggested renders the window after approving the edit on a snapshot: the same ripple, paced pad, fades and mute that approving ships. Splits have no Suggested side. Does not mutate the project.
Inputs: edit_id (required), mode, dry_run, gap_sec, +3 more. Returns: result
play_transcript_query_toolC
Search transcript for query and play that span (NL: play where they talk about X).
Inputs: query (required), dry_run, rerender, processed, +3 more. Returns: result
precorrect_transcript_toolB
Apply automatic transcript precorrections; dry_run previews without changing words.
Inputs: dry_run, project_path. Returns: result
preview_inaudible_cut_toolA
Dry-run local inaudible-cut snap (~±80ms) for a proposed range.
Not a multi-second narrative handoff planner. For leave-a-beat / clean-up-the-
transition / punchline-to-pivot bounds use suggest_handoff_cut_tool.
Inputs: end (required), start (required), speaker, timeline, +2 more. Returns: result
propose_editsA
Propose filler/pause tighten edits for review (does not apply them).
Returns a JSON object {operation, edits, skip_counts, summary} (not a
bare array — breaking vs older list-of-decisions clients). operation is
propose_edits. Each edit also carries label (plain words, e.g. "Laugh")
and suggested_action (cut / shorten / lower / leave) from
one table (edits/cut_safety.py). skip_counts maps discourse:{token} to kept uses
and backchannel:{phrase} to kept acknowledgments (uh huh).
word_probe:unavailable is a missing Whisper model; word_probe:failed
is a span whose decode raised. The summary names both.
edit_mode is ripple (default, from tighten.edit_mode) or mute.
Mute proposes EditDecisionType.MUTE filler hits and skips pause
candidates (muting a pause is a no-op). A pause: trim is shrunk to the air inside
the pause, labelled :air_edges when it differs from the span pacing proposed, and
proposed only when it removes at least a tenth of its pause (imperceptible skips
the rest). It is reviewed or applied by the checks a filler gets. intensity is light /
medium / aggressive (default from tighten.intensity, else medium):
a deterministic preset over existing tighten keys (light = clustered um/uh
only and >=0.5 s pause air; medium also proposes a lone um/uh; aggressive =
isolated and borderline discourse markers, 0.3 s solo pauses). Unknown
values raise. Suggest a tier from the episode (interview -> light, solo
monologue -> aggressive); the pipeline itself never chooses. Pipeline
auto-tighten stays off; listen-first review before apply_edits /
approve_edits. Not NL cut-by-text (cut_* tools) or narrative focus (focus
tools).
Inputs: edit_mode, intensity, project_path. Returns: result
propose_range_cut_toolA
Propose an exact range cut for host review (Studio range Cut), replay-safe.
start / end are timeline seconds; track_ids lists the lanes
(default every dialogue lane). The cut leaves a hole: later clips keep their places.
This never applies audio: it creates a pending exact cut that the host auditions and
approves (podcast edit approve also can). Reuse command_id only when retrying the
same range. For a ripple cut across lanes use ripple_delete_tool.
Inputs: end (required), start (required), command_id (required), track_ids, +1 more. Returns: result
propose_range_mute_toolA
Propose an exact range mute for host review, with replay-safe command identity.
Pass a serialized ExactRangeTarget from bleed preview or the range editor. This never applies audio or approves the proposal. Reuse command_id only when retrying the same target. The host auditions and approves or rejects it.
Inputs: target (required), command_id (required), project_path. Returns: result
propose_social_clips_toolC
Propose short-form social clips for a platform, limited to max_clips.
Inputs: platform, max_clips, project_path. Returns: result
publish_review_version_toolA
Freeze the current premix/mastered mix as a review version under artifacts/review/.
Comments created while a version is active stamp review_version_id. prefer: "premix" (default) or "mastered". Refuses a project with no mix yet (code no_mix: Refresh first), a premix that's stale vs the project (Refresh first) or a master not mastered from the current premix (export first).
Inputs: label (required), prefer, set_active, project_path. Returns: result
recommend_fades_toolC
Recommend fades at joins to hide edit artifacts.
Inputs: speaker, track_id, project_path. Returns: result
reconcile_transcript_toolC
Re-run transcript/timeline reconciliation; dry_run previews without applying.
Inputs: dry_run, end_sec, speaker, track_id, +2 more. Returns: result
reconciliation_status_toolC
Report transcript/timeline reconciliation status (stale vs current).
Inputs: project_path. Returns: result
record_discard_take_toolB
Delete a terminal take (refused while its full-quality recordings are still saving to the project).
Inputs: take_index (required), project_path. Returns: result
record_land_toolC
Land saved full-quality recordings and live comments on the timeline.
Inputs: project_path. Returns: result
record_marker_toolB
Host Marker: stamp the open take now; record_land_tool lands it as a comment.
Inputs: body, project_path. Returns: result
record_pause_toolC
Host Pause for the current take.
Inputs: project_path. Returns: result
record_resume_toolC
Host Resume for a paused take.
Inputs: project_path. Returns: result
record_start_toolC
Host Start for the current record room (blocked until guests consent).
Inputs: project_path. Returns: result
record_state_toolB
Read the live recording-room snapshot (roster, take clock, consent).
Inputs: project_path. Returns: result
record_stop_toolD
Host Stop for the current take.
Inputs: project_path. Returns: result
reject_edits_toolB
Reject pending edits by id, discarding them without applying.
Inputs: ids (required), project_path. Returns: result
reject_social_clips_toolC
Reject social clips by id.
Inputs: ids (required), project_path. Returns: result
remove_chapter_toolC
Remove a chapter marker by title.
Inputs: title (required), project_path. Returns: result
remove_effect_toolC
Remove an effect from a track or speaker's effect chain.
Inputs: effect, speaker, track_id, project_path. Returns: result
render_finalC
Render the final mastered export and return its path.
Inputs: project_path. Returns: result
render_previewC
Render a preview mix and return its status and path.
Inputs: rerender, project_path. Returns: result
render_status_toolC
Report stem freshness and whether dialogue balance measurements are stale.
Inputs: project_path. Returns: result
resolve_comment_toolA
Mark a comment resolved (or reopen with resolved=false).
Always pass by= identity (e.g. "agent" or the human name). Records resolved_by / resolved_at. Prefer resolving after action items are done.
Inputs: by (required), comment_id (required), resolved, project_path. Returns: result
revert_applied_edit_toolB
Restore an ordinary source mute; clip removals require whole-action History Undo.
Inputs: record_id (required), project_path. Returns: result
revoke_record_room_toolC
End a recording room: revoke guest and producer tokens.
Inputs: session_id (required), project_path. Returns: result
ripple_delete_text_toolB
Ripple-delete the first timeline span matching a transcript text query.
The matched speaker's words are the cut; other tracks' speech in the span needs
confirmation.
The automatic audio checks hold a harsh or other-speaker cut and name the finding;
override_audio_checks=true applies it anyway and records the override.
Inputs: query (required), project_path, use_inaudible_opt, override_audio_checks. Returns: result
ripple_delete_toolA
Ripple-delete a timeline range across every dialogue track.
Default inaudible opt absorbs trailing quiet air to ~0.4s before the next
word. For punchline-to-pivot / leave-a-beat handoffs, call
suggest_handoff_cut_tool first and pass use_inaudible_opt=false so
local snap does not pull mid-silence bounds onto speech. track_ids
names the tracks whose speech you mean to cut; speech on any
other track in the range needs confirmation. Omitted, the cut names no track,
so speech on every track needs confirmation (a whole-session time cut).
The automatic audio-quality and cut-position checks run first: a cut that lands
mid-word, makes an audible join or cuts another track's speech stays unchanged and
comes back with the finding. When the user wants that exact cut anyway (or names the
position themselves), repeat with override_audio_checks=true; it keeps the bounds as
given and records who overrode in History and the edit log.
Inputs: end (required), start (required), track_ids, project_path, +2 more. Returns: result
roll_clip_join_toolA
Roll the join between two neighbouring clips by delta_sec source seconds.
Positive moves the join later: the left clip gains material and the right clip
starts later in its source, so the pair keeps its length and later clips stay put.
Same operation as the Studio roll seam (RollClipJoin); undoable. The clips must
abut (touch within the join tolerance, see clips_abut); across a gap the call is
refused with error_code roll_needs_abutting_clips and nothing changes. Use
trim_clip_edge_tool to move one edge and ripple instead.
Inputs: delta_sec (required), left_clip_id (required), right_clip_id (required), project_path. Returns: result
search_transcript_toolC
Search the transcript for text, optionally scoped to a track or speaker.
Inputs: query (required), speaker, track_id, project_path. Returns: result
seek_session_toolC
Seek the open DAW playhead (no OS audio). Optional selection highlights a modifier.
Inputs: playhead_sec (required), selection, project_path. Returns: result
set_active_review_version_toolC
Set or clear review.active_version_id (pass null/omit to clear).
Inputs: version_id, project_path. Returns: result
set_clip_fade_toolB
Set the fade-in and fade-out duration of a single clip.
Dialogue fades cap at render.join_fade_max_ms. Each fade fits in the clip, and
fade-out is limited to what fade-in leaves.
Inputs: clip_id (required), fade_in_ms (required), fade_out_ms (required), project_path. Returns: result
set_clip_join_toolA
Set the join between two neighbouring clips: mode plus fades (TOOL_TIMEBASE: na).
mode is fade | crossfade | cut. Crossfade sets left fade-out and right fade-in to
length_ms (default tighten.crossfade_ms); cut zeroes both fades; fade sets both
(or keeps them). Prefer this over set_join_mode_tool, which changes the mode only
and leaves a crossfade with no fades to blend.
Inputs: mode (required), left_clip_id (required), right_clip_id (required), length_ms, +1 more. Returns: result
set_comment_action_done_toolB
Check or uncheck a comment action item; records completed_by / completed_at.
Agents should pass by="agent" (or a stable agent label) when finishing work.
Inputs: by (required), action_id (required), comment_id (required), done, +1 more. Returns: result
set_effect_bypass_toolC
Toggle bypass on one chain effect by index (TOOL_TIMEBASE: na).
Inputs: bypass (required), effect_index (required), speaker, track_id, +1 more. Returns: result
set_envelopeA
Set the volume automation envelope for a track from [{time, value}] points.
Submits a SetEnvelope document command (same lock, conflict check, undo
history, and GUI fanout as a DAW edit). expected_points is the
[{id, time, value}] list you last read; if the envelope changed since,
the call fails with a conflict instead of overwriting the edit. When
omitted, the envelope as read at call time is the baseline.
Inputs: points (required), track_id (required), project_path, expected_points. Returns: result
set_join_mode_toolA
Set join_in_mode on one clip: fade | crossfade | cut (TOOL_TIMEBASE: na).
Mode only: fades are untouched, so a crossfade with no fades renders as a plain
join; the result's join_crossfade_blocked says why. Prefer set_clip_join_tool.
Inputs: clip_id (required), join_in_mode (required), project_path. Returns: result
set_retained_bleed_alignment_mode_toolB
Save a timing choice for an applied decision or a proposal from the same window.
Manual and declined choices prevent later automatic correction; auto resets that choice.
Inputs: mode (required), decision_id (required), end_sec, track_id, +3 more. Returns: result
set_session_mode_toolC
Set DAW audition mode: mix | fx | raw.
Inputs: mode (required), project_path. Returns: result
set_session_playing_toolB
Start or pause DAW browser transport (no OS audio).
Inputs: playing (required), project_path. Returns: result
set_session_region_toolC
Highlight a timeline region in the DAW; optionally start browser playback.
Inputs: end_sec (required), start_sec (required), query, playing, +2 more. Returns: result
set_session_selection_toolC
Highlight a DAW modifier: selection {kind, id?, track_id?, time?}; null or omit to clear.
Inputs: selection, project_path. Returns: result
set_transcript_vocabulary_toolA
Replace vocabulary using the revision returned by get_transcript_vocabulary_tool.
Pass null only when that read returned a null revision. A stale revision rejects the write; the existing show title and other transcript context stay unchanged. This changes future transcription prompts, not existing transcript words.
Inputs: terms (required), guest_names (required), base_revision (required), project_path. Returns: result
set_word_automatic_toolA
Clear one word's suppression lock; suppressed waits for the next reconcile (#824).
A word set directly by set_word_suppressed_tool, an explicit-list suppress-bleed /
low-audibility apply, or Studio's Suppress toggle stays audibility_locked until this
call. It does not itself change suppressed — run reconcile_transcript_tool after
to get the computed target. Pass expected_text (the word text you read) to refuse the
unlock if the word at word_index changed meanwhile; omit to skip. TOOL_TIMEBASE: source.
source_id names the recording whose words word_index counts; it is required on a
track recorded as several takes, and the refusal is word_source_required.
Inputs: track_id (required), word_index (required), source_id, project_path, +1 more. Returns: result
set_words_ignored_toolA
Strike through and mute (or restore) a word range at render, without a cut.
Text-and-audio hide (#633): unlike suppress, the words stay in the combined
transcript; only their audio is muted, computed at render time and never
written to Clip.mute_regions. TOOL_TIMEBASE: source.
Pass expected_text (the space-joined words you read for this range) to refuse the
toggle if those words changed meanwhile; omit to skip.
source_id names the recording whose words word_index counts; it is required on a
track recorded as several takes, and the refusal is word_source_required.
Inputs: ignored (required), track_id (required), end_word_index (required), start_word_index (required), +3 more. Returns: result
set_word_suppressed_toolB
Toggle suppressed on one per-track word (TOOL_TIMEBASE: source).
Pass expected_text (the word text you read) to refuse the toggle if the word at
word_index changed meanwhile; omit to skip.
source_id names the recording whose words word_index counts; it is required on a
track recorded as several takes, and the refusal is word_source_required.
Inputs: track_id (required), suppressed (required), word_index (required), source_id, +2 more. Returns: result
set_word_timing_toolA
Set one transcript word's start and end in source seconds (Studio Adjust word timing).
word_index indexes the track's transcript, or the source_id recording's
transcript when given. Pass expected_text to refuse the change if the word was
edited meanwhile. Bounds are checked against the recording; a word that overlaps
its neighbours comes back in context.warnings. Submits
SetTranscriptWordTiming; undoable.
Inputs: end (required), start (required), track_id (required), word_index (required), +3 more. Returns: result
shorten_gaps_toolA
Shorten word gaps longer than max_gap_sec across the timeline.
Each shortened pause ripples every dialogue track; another speaker talking in a
pause needs confirmation. A ripple that cuts another track's speech stays unchanged
until you repeat with override_audio_checks=true (recorded).
Inputs: max_gap_sec, project_path, use_inaudible_opt, override_audio_checks. Returns: result
speaker_attribute_toolC
Attribute speaker labels across the project from voiceprints (dry_run by default).
Inputs: dry_run, project_path. Returns: result
speaker_compare_pair_toolC
Compare the voices in two time windows to check they are the same speaker.
Inputs: end_a (required), end_b (required), start_a (required), start_b (required), +3 more. Returns: result
speaker_compare_window_toolC
Compare speaker identity across tracks in a time window.
Inputs: end_sec (required), start_sec (required), project_path. Returns: result
speaker_doctor_toolB
Check the speaker-identification backend is configured and working.
Inputs: no named parameters. Returns: result
speaker_enroll_toolC
Enroll voiceprints from a segment, a whole track, or every media-backed track.
Inputs: end_sec, track_id, start_sec, speaker_id, +2 more. Returns: result
speaker_gate_track_toolB
Suppress transcript words from other speakers on home tracks; use apply_transcript_gate_tool to mute audio.
Inputs: dry_run, track_id, project_path. Returns: result
speaker_label_toolC
Assign the window's speaker label on a track (dry_run by default).
Inputs: end_sec (required), track_id (required), start_sec (required), dry_run, +1 more. Returns: result
speaker_move_lane_span_toolB
Move a source span from one speaker-split lane to a sibling lane (one undo step).
TOOL_TIMEBASE: source.
Inputs: to_lane (required), from_lane (required), source_end (required), source_start (required), +1 more. Returns: result
speaker_profiles_toolB
List enrolled speaker voiceprint profiles.
Inputs: project_path. Returns: result
speaker_score_toolC
Score how strongly a time window matches the expected speaker.
Inputs: end_sec (required), track_id (required), start_sec (required), project_path. Returns: result
speaker_set_count_toolC
Set the expected number of speakers in the project.
Inputs: expected_speaker_count (required), project_path. Returns: result
speaker_split_toolA
Split a one-track recording of several speakers into a lane per speaker (dry_run by default).
Needs the speaker count (or one set with speaker_set_count_tool). enrollment maps
a speaker's name to [start, end] source-second spans of only that speaker, for some or
all speakers; the rest are clustered. Every lane plays the same media, muted where the
others talk. Flagged crosstalk plays on the likeliest speaker's lane (owner), on
every talking speaker's lane (both, twice in the mix) or on a shared lane
(lane). One undo step.
Inputs: track_id (required), names, dry_run, enrollment, +4 more. Returns: result
split_clip_toolB
Split clip(s) at a timeline timecode.
Pass track_ids for multi-track blade cuts.
When omitted, uses track_id / speaker, or all dialogue tracks.
Submits SplitAtTime on the document plane (same path as Sharecut Studio blade).
Inputs: at_time (required), speaker, track_id, track_ids, +1 more. Returns: result
stop_session_toolB
Pause DAW transport in place and clear the highlight region (GUI Stop / K also returns to the play start; this tool does not).
Inputs: project_path. Returns: result
strip_silence_toolB
Rebuild a track from speech islands between detected silences.
Silence is audio under the track's own audibility floor (its voice floor) plus
over_voice_floor_db. A track whose voice does not stand out of its room has no
silence to strip, whatever over_voice_floor_db is.
use_inaudible_opt is accepted for API compatibility but ignored.
Inputs: speaker, track_id, project_path, min_duration_sec, +2 more. Returns: result
suggest_handoff_cut_toolA
Propose retain-then-snap ripple bounds for a narrative handoff.
Omit track_id and speaker to require quiet across every dialogue lane, including muted lanes. Either selector limits analysis to one lane.
Use when cleaning up a transition, leaving a beat, or punchline-to-pivot —
not word timestamps and not preview_inaudible_cut_tool (local snap +
~0.4s absorb). Times are timeline seconds. Keeps about retain_sec
of existing air on each keep, snaps onto RMS silence islands (not
transcript gaps), and returns use_inaudible_opt: false — lock those
bounds on ripple_delete_tool.
Inputs: keep_left_end (required), keep_right_start (required), hop_ms, speaker, +4 more. Returns: result
track_addC
Add an audio track to the project from a media file.
Inputs: track_id (required), file_path (required), role, label, +2 more. Returns: result
track_add_empty_toolC
Add an empty (silent placeholder) track to the project.
Inputs: track_id (required), role, label, speaker, +1 more.
track_remove_toolC
Remove a track from the project.
Inputs: track_id (required), project_path.
track_reorder_toolC
Move a track to a new position in the track order.
Inputs: index (required), track_id (required), project_path.
track_set_media_toolC
Replace the media file backing an existing track.
Inputs: track_id (required), file_path (required), project_path.
track_set_meta_toolC
Update a track's label, role, or speaker metadata.
Inputs: track_id (required), role, label, speaker, +1 more.
track_set_mute_toolA
Mute or unmute a track in the saved mix.
Play and bounce leave a muted track out at once, and the premix after the next re-mix (Refresh). The track stays on the timeline: edits and analysis still cover it. Undoable. Solo is a per-listener GUI control, not saved.
Inputs: muted (required), track_id (required), project_path.
track_set_volume_toolA
Set a track's saved volume in dB (-60 to +12), on top of its staging gain.
The mix plays the track at gain_db + fader_db; the pipeline's balance
step never changes the fader. Undoable; stales the premix until re-mixed.
Inputs: fader_db (required), track_id (required), project_path.
transcribe_trackA
Transcribe one track, or all dialogue tracks when track_id is omitted, into word-level timestamps.
Runs even when a transcript exists, but reuses the ASR disk cache when the audio, model and prompt are unchanged (the pipeline's force_transcribe skips that cache). Replaces only those transcripts (others and extra-source transcripts are kept) and warns when it replaces a hand-edited one; the pipeline's transcribe_tracks step reuses existing transcripts instead.
Inputs: track_id, project_path. Returns: result
transcript_refine_brief_toolB
Return the transcript-refine brief: what to review before marking done.
Inputs: project_path. Returns: result
transcript_refine_done_toolC
Mark transcript refinement done, with optional notes.
Inputs: notes, project_path. Returns: result
transcript_refine_status_toolB
Report the transcript-refine gate status (blocking approve_edits while open).
Inputs: project_path. Returns: result
transcript_refine_waive_toolC
Waive transcript refinement with a recorded reason.
Inputs: reason (required), project_path. Returns: result
trim_clip_edge_toolA
Move one clip's in or out edge to source_sec (source-media seconds).
mode="ripple" moves every dialogue track by the duration change, so speakers
stay in sync: a track with a clip edge at the same instant (a session-wide cut)
moves that edge too, and every other track loses or gains the same span.
mode="gap" moves only the grabbed edge and leaves silence or fills the gap to
the neighbouring clip; nothing else moves. Expansion is clamped to unused source
between the neighbouring clips. The fix for a speech_crosses_cut hypothesis
from audition_context_tool is its evidence.fix (clip, edge, source_sec,
mode). Same operation as the DAW trim handle (TrimClipEdge); undoable. Follow
with render_preview.
The automatic audio checks hold a harsh edge or another speaker's speech and name the
finding; override_audio_checks=true moves the edge to exactly source_sec anyway
and records the override.
Inputs: edge (required), clip_id (required), source_sec (required), mode, +2 more. Returns: result
update_comment_toolB
Update comment body, tracks, and/or timeline anchor. Times are timeline seconds.
track_ids=[] makes the comment session-wide; omit it to keep the tracks.
Inputs: comment_id (required), body, track_ids, project_path, +2 more. Returns: result
update_pending_edit_toolB
Adjust the start/end bounds of a pending edit before approval.
override_audio_checks=true keeps the exact bounds given (no snapping or holds from the
automatic cut-position checks) and records the override.
Inputs: end (required), start (required), edit_id (required), snap, +2 more. Returns: result
verify_transcript_toolC
Apply bulk corrections and mark words verified on a track's transcript.
Inputs: track_id (required), corrections (required), project_path. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 183 tools
With 183 tools, there are many overlapping clusters: multiple cut/ripple tools (cut_time_range_tool, cut_text_match_tool, ripple_delete_tool, delete_clips_tool), speaker tools (speaker_enroll_tool, speaker_label_tool, speaker_split_tool), and comment tools (add_comment_tool, add_comment_reply_tool, add_comment_action_tool). The descriptions do not sufficiently distinguish when to use which, causing high risk of misselection.
Most tools use snake_case, but some include a _tool suffix while others do not (e.g., apply_edits, transcribe_track, get_transcript, propose_edits, episode_create, track_add). Verb styles vary between verb_noun and noun_verb, and the suffix is applied inconsistently across 183 names.
183 tools is far beyond the typical 3-15 range and creates an unwieldy surface. Even for a complex domain like podcast production, this many tools suggests poor scoping and will overwhelm agents.
The surface covers an enormous range: recording, editing, transcription, speaker ID, effects, rendering, export, comments, review, pipeline, history, etc. Most CRUD and lifecycle operations appear present, though there may be minor gaps (e.g., no list_episodes or delete_project).
Maintenance
Related MCP Connectors
Remote MCP server for audio stem separation, denoise, reverb, and MIDI export.
An MCP server that provides tools to discover and retrieve podcast episodes transcripts.
Create, co-edit, analyze, publish, and export collaborative step-sequencer sessions through MCP.
Podcast intelligence for agents: transcripts, clips, speaker diarization, mention tracking.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that exposes REAPER digital audio workstation functionality through a clean API interface, enabling programmatic control of 169+ REAPER operations across track management, MIDI editing, effects, automation and more.88MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to programmatically edit, analyze, and export audio projects through MCP tools, including multi-track editing, effects, transcription, and semantic search.1-
- AlicenseBqualityDmaintenanceThis MCP server enables AI assistants to control a live REAPER DAW instance, including transport, tracks, FX, MIDI, media, markers, rendering, and project state, with an escape hatch for arbitrary ReaScript commands.40MIT
- FlicenseAqualityDmaintenanceMCP server for controlling REAPER digital audio workstation from natural language. It enables AI agents to create tracks, import audio, adjust mix parameters, and manage sessions through typed operations and a REAPER bridge.22-
social_clip_report_toolB
Return a Markdown listing of social clip candidates.
Inputs: project_path. Returns: result