mcp-agent-transcriber
An MCP server that turns tube-platform links (YouTube, Vimeo, Dailymotion, Twitch, TikTok, ...) into agent-friendly transcripts — either by grabbing existing captions or by downloading audio and transcribing locally with Whisper.
Discover platforms —
supported_platforms()lists known tube hosts and whether the installed yt-dlp has an extractor for each.Inspect videos —
video_info(url)returns platform, title, duration, uploader, caption tracks, and available audio formats in one metadata pass.List captions —
list_available_transcripts(url)shows language codes and whether each track is manual or auto-generated, with no download.Fetch captions directly —
fetch_transcript(url, language, want_vtt, prefer_auto)grabs a cleaned transcript without touching the media (YouTube via youtube-transcript-api, others via the yt-dlp caption pass), writing.txt(and optional.vtt) to the output dir.Download audio —
download_audio(url, quality, output_format)pulls the audio track via yt-dlp atbest/high/standard/low, keeping the original container or re-encoding to mp3/wav/m4a/opus/flac/aac.Check Whisper readiness —
transcriber_status()reports model, device (cuda/cpu), cache/load state, and ffmpeg availability without loading the ~1.6 GB checkpoint.Transcribe a local file —
transcribe_file(path, language, want_vtt, return_segments)runs Whisper turbo, loading the model lazily and caching it.One-call video transcription —
transcribe_video(url, method="auto"|"captions"|"whisper", quality, language, want_vtt, keep_audio, prefer_auto, return_segments)tries captions first and falls back to Whisper only when needed.Utility —
get_current_datetime()returns local and UTC ISO 8601 timestamps.All tools return JSON; known failures (private video, disabled captions, unknown platform, sign-in required, network) come back as structured
status: failedpayloads with sanitized, path-free reasons.
Allows retrieving Dailymotion video transcripts from platform captions or via local Whisper transcription of downloaded audio.
Allows retrieving TikTok video transcripts from platform captions or via local Whisper transcription of downloaded audio.
Allows retrieving Twitch video transcripts from platform captions or via local Whisper transcription of downloaded audio.
Allows retrieving Vimeo video transcripts from platform captions or via local Whisper transcription of downloaded audio.
Allows fetching YouTube video transcripts directly from available captions or by downloading the audio and transcribing it locally with Whisper.
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., "@mcp-agent-transcriber transcribe this YouTube video: https://youtu.be/abc123"
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.
mcp-agent-transcriber
Video transcription for agents, as a local MCP server. Point an MCP-aware harness at any common tube-platform link (YouTube, Vimeo, Dailymotion, Twitch, TikTok, ...) and get an agent-friendly transcript — either by grabbing the platform's own captions directly (fast, no download, no model) or by downloading the audio at a preferred quality and transcribing it locally with OpenAI Whisper (turbo, CUDA/CPU).
This is the standalone whisper_transcriber (a terminal-menu CLI) rebuilt as
an MCP tool for the agent-tools stack, plus the caption-grabbing workflow its
history documented for YT downloads. The interactive REPL became MCP tools:
probe a URL, download audio, or transcribe — callable by any harness over
stdio.
Two paths
Path | How | Cost | Use when |
direct |
| no model, no download | captions exist and speed matters |
whisper |
| ~1.6 GB model, downloads audio | captions missing, or fidelity matters |
transcribe_video(url, method="auto") runs the whole route: captions first,
Whisper fallback when the platform has none.
Related MCP server: TranscriptMCP
Tool surface
Domain | Tools |
Info |
|
Transcript (direct) |
|
Download |
|
Transcribe (Whisper) |
|
Utility |
|
All tools return JSON. Unexpected errors are sanitized to the tool name +
exception class; the full traceback stays in the server log. Known conditions
(private video, disabled captions, unknown platform, sign-in required,
network) come back as structured status: failed payloads with a static,
path-free reason — exception messages are never forwarded because they can
leak local paths.
Requirements
Python 3.13+
ffmpeg on PATH (Whisper and audio postprocessing both need it)
NVIDIA GPU + CUDA 12.8 driver for GPU transcription (CPU fallback automatic)
Install
git clone <repo-url> mcp_agent_transcriber
cd mcp_agent_transcriber
uv syncuv sync installs the CUDA build of PyTorch automatically: pyproject.toml
pins torch to PyTorch's official CUDA 12.8 wheel index (pytorch-cu128) via
[tool.uv.sources]. To switch CUDA versions, change the index URL.
Usage
Run as an MCP server (stdio — what harnesses expect)
uv run mcp-agent-transcriberOverride paths via environment variables (defaults resolve relative to the project root, never the process CWD):
Var | Default | Purpose |
|
| Where transcript |
|
| Where audio downloads land |
|
| Rotating DEBUG logs (5×5 MB) |
|
| Whisper checkpoint (turbo / large-v3 / medium / ...) |
|
| Default caption language for direct grabs |
To serve over HTTP (streamable-http) instead:
uv run mcp-agent-transcriber serve --http --port 8000Register in an MCP client
{
"mcpServers": {
"mcp-agent-transcriber": {
"command": "uv",
"args": ["--project", "C:/path/to/mcp_agent_transcriber", "run", "mcp-agent-transcriber"]
}
}
}CLI commands
Command | Purpose |
| Run the MCP server. |
| Offline diagnostics: paths, engine state, ffmpeg, yt-dlp |
Workflow
1. supported_platforms() → is the host a known tube platform?
2. video_info(url) → platform, title, caption tracks, audio formats
3. fetch_transcript(url) → direct transcript when captions exist
4. download_audio(url, "best")→ audio track for the whisper path
5. transcribe_video(url, method="auto") → one call, captions then WhisperThe Whisper checkpoint is never loaded at server startup — it loads on the
first transcribe_* call (~1.6 GB) and stays cached for the process
lifetime, so caption-only workflows never touch the model. Transcripts are
written as {title-slug}_{lang}_{timestamp}.txt (plus .vtt on request)
into TRANSCRIBER_OUTPUT_DIR and returned inline so the model gets the text
even without a filesystem view.
Model weights
The turbo checkpoint (large-v3-turbo.pt, ~1.6 GB) resolves through Whisper's
standard cache (~/.cache/whisper/ on Windows). It auto-downloads on first
use and is then reused. Offline machines can place the .pt file into that
cache by hand.
Output quality
Download quality presets map to yt-dlp format selectors:
Preset | Selector |
|
|
|
|
|
|
|
|
download_audio(output_format=...) keeps the platform's container (orig) by
default, or re-encodes with ffmpeg to mp3/wav/m4a/opus/flac/aac.
Caption text is cleaned for agent consumption (ported from the original
workflow): inline <...> timing tags are stripped, cue timestamps dropped,
consecutive duplicate lines collapsed (the rolling word-by-word caption
artifact), and whitespace normalized.
Development
uv run ruff check .
uv run pyright
uv run pytest -qTests cover config path resolution, caption cleaning, platform discovery, yt-dlp metadata/download (mocked), the transcript grabbers (mocked APIs), the pipeline routes, and the full tool surface — no network, no model load.
Type checking
pyright resolves imports against the project venv via [tool.pyright] in
pyproject.toml. That section is load-bearing: without venvPath/venv it
falls back to the system interpreter and reports every third-party import as
missing, which buries the real findings under hundreds of phantom errors. Keep
it at 0 errors — the last run surfaced two genuine bugs that the test suite
passed straight over.
Four call sites use cast(Any, ...) around yt_dlp.YoutubeDL(...) and
ydl.prepare_filename(...) — three in download.py, one in transcript.py.
Do not "clean these up" by typing the options dict as
yt_dlp.YoutubeDL._Params. That name exists only inside a typeshed-fallback
stub bundled with pyright, so the import satisfies the type checker and then
raises ImportError at server startup — the LSP goes green and the server
dies. The stub is wrong besides: it declares skip_download as str | None,
where yt-dlp tests it for truthiness and documents it as a boolean flag. The
casts are deliberate, and each carries its reason inline.
Security advisories
Two Dependabot alerts have been triaged and dismissed, both not_used:
Alert | CVE | Why not used |
| CVE-2025-3000 | The vulnerability is in |
| CVE-2026-59890 | Transitive build-time dependency of torch. This project builds with |
The torch dismissal is the fragile one, because it is a claim about the
code rather than a fixed property of a pinned artifact: the day a TorchScript
path appears, "not used" is false and Dependabot stays silent, having been told
to stop looking. tests/test_security_invariants.py is what keeps that honest —
it fails the build if torch.jit ever enters src/, naming the file, line and
symbol, and telling you to re-open the alert. It parses the AST rather than
grepping, so a comment about the CVE cannot trip it. The second half of the
claim — that openai-whisper stays TorchScript-free — is covered by uv.lock
pinning the exact version, so an upgrade that changed it surfaces as a
reviewable diff.
License
MIT © 2026 Christof Milius — this repository ships only hand-authored source and configuration; nothing else.
No redistributed dependencies. torch (BSD-3), openai-whisper (MIT), yt-dlp (Unlicense), youtube-transcript-api (MIT) and friends are declared in
pyproject.tomland installed by uv — never vendored into this repo.No model weights. The Whisper checkpoint is not included; it is downloaded at runtime into
~/.cache/whisperon first use and subject to its own license terms. The transcription machinery is MIT regardless.No licensed media. Transcribed caption/audio content is produced at runtime by the tool; no copyrighted media ships in the repository.
Available Tools
9 toolsdownload_audioA
Download a video's audio track into the downloads dir via yt-dlp.
quality: "best" (default, highest bitrate), "high" (>=128 kbps floor), "standard" (<=128 kbps, smaller), or "low". output_format: "orig" keeps the platform's container; one of mp3/wav/m4a/opus/flac/aac re-encodes with ffmpeg as a postprocess.
Inputs: url (required), quality, output_format. Returns: result
fetch_transcriptA
Grab an agent-friendly transcript for a video URL without downloading the media. YouTube uses youtube-transcript-api (fast); every other platform falls back to the yt-dlp caption pass. Writes a .txt (plus .vtt on request) into the output dir and returns the cleaned text.
Inputs: url (required), language, want_vtt, prefer_auto. Returns: result
get_current_datetimeA
Return the current local and UTC date/time in ISO 8601 format.
Inputs: no named parameters. Returns: result
list_available_transcriptsA
List the caption tracks a video URL exposes: language codes plus whether each is a manual or auto-generated track. Uses yt-dlp metadata only — no download.
Inputs: url (required). Returns: result
supported_platformsA
List the common tube platforms (YouTube, Vimeo, Dailymotion, Twitch, TikTok, ...) and whether the installed yt-dlp ships an extractor for each. Use before evaluating an unfamiliar host.
Inputs: no named parameters. Returns: result
transcribe_fileA
Transcribe a local video/audio file with Whisper (turbo). The model loads on first use and stays cached. Writes a .txt (plus .vtt on request) into the output dir and returns the transcript.
language: ISO code to force (e.g. "en"); None auto-detects.
Inputs: path (required), language, want_vtt, return_segments. Returns: result
transcriber_statusA
Report Whisper runtime readiness: model, device (cuda/cpu), whether the checkpoint is already cached/loaded, and ffmpeg availability. Does NOT load the model.
Inputs: no named parameters. Returns: result
transcribe_videoA
One-call video → transcript. method: "auto" (default) grabs the platform's captions first and falls back to Whisper only when none exist; "captions" uses captions only; "whisper" downloads the audio (quality: best/high/standard/low) and transcribes locally. keep_audio=true retains the downloaded audio file in the downloads dir; otherwise it is deleted after transcription.
Inputs: url (required), method, quality, language, +4 more. Returns: result
video_infoA
Resolve a video URL with one yt-dlp metadata pass: platform, title, duration, uploader, available caption tracks, and the audio formats found. Returns JSON; known failures (unsupported URL, private video, sign-in required, network) come back as a status:failed payload.
Inputs: url (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 9 tools
Most tools have distinct purposes: metadata, caption listing, transcript fetching, audio download, Whisper status, and transcription. However, fetch_transcript and transcribe_video (with method 'captions') overlap in functionality, though their descriptions clarify the use cases. The get_current_datetime tool is unrelated but not confusable with others.
Naming mixes verb-first patterns (get_current_datetime, list_available_transcripts, fetch_transcript, download_audio, transcribe_file, transcribe_video) with noun-first patterns (video_info, supported_platforms, transcriber_status). Verbs also vary (get, list, fetch, download, transcribe). The inconsistency is noticeable but not chaotic.
Nine tools is reasonable for a transcription server covering platform checks, metadata, caption handling, audio download, and Whisper integration. The inclusion of get_current_datetime feels out of scope but does not significantly bloat the set. The count is well within the typical range for a focused domain.
The server covers the full transcription workflow: verifying platform support, retrieving video metadata, listing captions, fetching caption transcripts, downloading audio, checking Whisper readiness, transcribing local files, and doing end-to-end video transcription. Minor gaps include no explicit language selection for transcribe_video and no file management, but these are not critical for core use.
Maintenance
Related MCP Connectors
YouTube transcripts, search, channel browsing, and playlists for AI agents via MCP.
OCR, transcription, file extraction, and image generation for AI agents via MCP.
Real-time video transcripts, RAG captions, metadata, search & comments MCP. OAuth or API key.
YouTube transcripts, search, channel/playlist listings and upload tracking for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceFetches YouTube video transcripts with timestamps and provides them to LLM agents via MCP, enabling natural language access to video content.99 npm4MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to download YouTube videos and transcribe them locally using OpenAI's Whisper speech recognition model.MIT
- AlicenseNot gradedqualityFmaintenanceGives MCP clients access to YouTube video transcripts and metadata. It lets AI agents read and summarize video content from a URL.4 npmMIT
- AlicenseAqualityCmaintenanceEnables MCP clients to transcribe audio/video files locally, generate SRT subtitles, and burn captions into videos via tool calls, without a cloud API.3MIT