Skip to main content
Glama
Podcast MCP
by calebn

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-extras installs every pip extra (dev, gui, relay, object-store, prosody).

  • A bare podcast bootstrap installs Whisper, RNNoise, the word aligner and the speaker model, and so does Studio's Get ready card. podcast bootstrap --component word-aligner installs 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

src/podcast_mcp/

Python package — CLI, MCP, services, domain, GUI API, Extensions SPI

podcast_online

Optional private/provider extension, installed independently when needed; its source is not part of this repository

src/podcast_relay/

FOSS reverse-tunnel edge (podcast-relay)

gui/web/

ShareCut Studio viewer (React + Vite)

deploy/relay/

FOSS host-online share relay (Docker Compose examples)

contracts/

Published caps / feature-id contract artifacts

.agents/

Skills, rules, MCP template, pipeline defaults

docs/

Architecture and feature docs

tests/

Pytest suite and fixtures (aligned_dialogue, …)

schemas/

episode.sharecut JSON Schema

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.sharecut

ShareCut Studio (editor):

uv sync --extra gui
cd gui/web && npm install && npm run build && cd ../..
podcast gui --project /path/to/my_episode/episode.sharecut

Release 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.json

Runtime 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

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 JSON

Testing

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.md

GUI 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 tools
add_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

create_review_share_toolB

Create a review share URL (Anyone with the link by default).

role: review-link role, as in Google Docs. viewer views and plays; commenter also comments and suggests edits that wait for an editor or the host; editor also edits directly and approves or rejects suggestions. with_mcp: also mint an MCP URL ({base}/mcp/{token}/mcp) with the role's powers. general_access: link (default) or restricted (ACL + sign-in). require_sign_in: force login even on link shares. invite_emails: comma-separated emails to add to the ACL.

Inputs: version_id (required), role, with_mcp, project_path, +4 more. 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

social_clip_report_toolB

Return a Markdown listing of social clip candidates.

Inputs: project_path. 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

    C2.4/5.0

    Scored across 183 tools

    Disambiguation1/5

    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.

    Naming Consistency2/5

    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.

    Tool Count1/5

    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.

    Completeness4/5

    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

    ActivityActive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      A 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.
      88
      MIT
    • A
      license
      B
      quality
      D
      maintenance
      This 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.
      40
      MIT
    • F
      license
      A
      quality
      D
      maintenance
      MCP 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
      -