Transcribe videos from 1000+ platforms or local files offline, and search across every transcript
Runs on your machine from its package; the steps are below.
At most: only reads or looks up information.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Distributed via cargo as `video-transcriber-mcp`.
High-performance video transcription MCP server using whisper.cpp (Rust)
A Model Context Protocol (MCP) server that transcribes videos from 1000+ platforms using whisper.cpp. Built with Rust for maximum performance and efficiency.
The easiest way to install with all dependencies:
brew install nhatvu148/tap/video-transcriber-mcp
This automatically installs the binary along with required dependencies (cmake, yt-dlp, ffmpeg).
If you have Rust installed:
cargo install video-transcriber-mcp
Note: You'll need to manually install dependencies: yt-dlp, ffmpeg, cmake
Download from GitHub Releases:
# macOS (Intel)
curl -L https://github.com/nhatvu148/video-transcriber-mcp-rs/releases/latest/download/video-transcriber-mcp-x86_64-apple-darwin.tar.gz | tar xz
sudo mv video-transcriber-mcp /usr/local/bin/
# macOS (Apple Silicon)
curl -L https://github.com/nhatvu148/video-transcriber-mcp-rs/releases/latest/download/video-transcriber-mcp-aarch64-apple-darwin.tar.gz | tar xz
sudo mv video-transcriber-mcp /usr/local/bin/
# Linux (x86_64) — no ARM64 Linux build, see issue #13; use `cargo install`
curl -L https://github.com/nhatvu148/video-transcriber-mcp-rs/releases/latest/download/video-transcriber-mcp-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv video-transcriber-mcp /usr/local/bin/
# Windows: Download .zip from releases page
Note: You'll need to manually install dependencies: yt-dlp, ffmpeg
Installs the MCP server and a /transcribe skill in one step:
/plugin marketplace add nhatvu148/video-transcriber-mcp-rs
/plugin install video-transcriber@nhatvu148-tools
The plugin registers the MCP server for you, but it does not install the binary — run one of the install commands above first, so video-transcriber-mcp is on your PATH.
This version uses whisper.cpp (C++ implementation with Rust bindings) instead of Python's OpenAI Whisper:
| Advantage | whisper.cpp (Rust) | OpenAI Whisper (Python) |
|---|---|---|
| Performance | Native C++ speed | Python interpreter overhead |
| Memory | Lower footprint | Higher memory usage |
| Startup | Instant (<100ms) | Slow (~2-3s model loading) |
| Dependencies | Standalone binary | Requires Python + packages |
| Portability | Single binary | Python environment needed |
Real-world performance depends on your hardware, video length, and chosen model.
The fastest way to get started:
# 1. Install Task (if not already installed)
brew install go-task/tap/go-task
# 2. Complete setup (build + download model)
task setup
# 3. Run a quick test
task test:quick
# Done! 🎉
Available Commands:
task setup # Complete project setup
task test:quick # Test with short video
task benchmark # Run performance benchmark
task deps:check # Check dependencies
task download:base # Download base model
task help # Show all commands
See Taskfile.yml for all available tasks.
The server supports two transport modes:
Standard I/O transport for local CLI usage with Claude Code. This is the default mode.
video-transcriber-mcp
# or explicitly:
video-transcriber-mcp --transport stdio
HTTP transport for remote access. Allows the MCP server to be accessed over the network.
# Start HTTP server on default port (8080)
video-transcriber-mcp --transport http
# Custom host and port
video-transcriber-mcp --transport http --host 0.0.0.0 --port 3000
Remote MCP Client Configuration:
For HTTP transport, configure your MCP client with the URL:
{
"mcpServers": {
"video-transcriber-mcp": {
"url": "http://localhost:8080/mcp"
}
}
}
Benefits of HTTP Transport:
video-transcriber-mcp --help
Options:
-t, --transport <TRANSPORT> Transport mode [default: stdio] [possible values: stdio, http]
--host <HOST> Host address for HTTP transport [default: 127.0.0.1]
-p, --port <PORT> Port for HTTP transport [default: 8080]
-h, --help Print help
-V, --version Print version
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# macOS
brew install yt-dlp
# Linux
pip install yt-dlp
# Windows
winget install yt-dlp.yt-dlp
# macOS
brew install ffmpeg
# Linux
sudo apt install ffmpeg # Debian/Ubuntu
sudo dnf install ffmpeg # Fedora
# Windows
choco install ffmpeg
whisper-rs-sys uses bindgen to build whisper.cpp, which needs libclang at build time)# macOS: bundled with Xcode Command Line Tools
# Linux
sudo apt install libclang-dev # Debian/Ubuntu
sudo dnf install clang-devel # Fedora
# Windows: install LLVM (https://releases.llvm.org) and set LIBCLANG_PATH
# Clone the repository
git clone https://github.com/nhatvu148/video-transcriber-mcp-rs.git
cd video-transcriber-mcp-rs
# Build the project
cargo build --release
# The binary will be at: target/release/video-transcriber-mcp-rs
# Download base model (recommended for testing)
bash scripts/download-models.sh base
# Or download all models
bash scripts/download-models.sh all
Models are stored in ~/.cache/video-transcriber-mcp/models/
Add to ~/.claude/settings.json:
Option 1: If installed via GitHub Release or cargo install:
{
"mcpServers": {
"video-transcriber-mcp": {
"command": "video-transcriber-mcp",
"args": [],
"env": {
"RUST_LOG": "info"
}
}
}
}
Option 2: If built from source:
{
"mcpServers": {
"video-transcriber-mcp": {
"command": "/absolute/path/to/video-transcriber-mcp-rs/target/release/video-transcriber-mcp",
"args": [],
"env": {
"RUST_LOG": "info"
}
}
}
}
Then use in Claude Code:
Basic transcription (uses base model by default):
Please transcribe this YouTube video: https://www.youtube.com/watch?v=VIDEO_ID
Transcribe with specific model:
Transcribe this video using the large model for best accuracy:
https://www.youtube.com/watch?v=VIDEO_ID
Transcribe local video file:
Transcribe this local video file: /Users/myname/Videos/meeting.mp4
Transcribe in specific language:
Transcribe this Spanish video: https://www.youtube.com/watch?v=VIDEO_ID
(language: es, model: medium)
Based on whisper.cpp vs OpenAI Whisper benchmarks from the community:
Transcription Speed (approximate, varies by hardware):
Real-world factors that affect performance:
We're collecting real benchmark data! If you run both versions, please share your results:
Open an issue with your benchmark results to help improve this section!
| Model | Speed | Accuracy | Memory | Use Case |
|---|---|---|---|---|
| tiny | ⚡⚡⚡⚡⚡ | ⭐⭐ | ~400 MB | Quick drafts, testing |
| base | ⚡⚡⚡⚡ | ⭐⭐⭐ | ~600 MB | General use (default) |
| small | ⚡⚡⚡ | ⭐⭐⭐⭐ | ~1.2 GB | Better accuracy |
| medium | ⚡⚡ | ⭐⭐⭐⭐⭐ | ~2.5 GB | High accuracy |
| large | ⚡ | ⭐⭐⭐⭐⭐⭐ | ~4.8 GB | Best accuracy, slowest |
Thanks to yt-dlp, this tool supports 1000+ video platforms including:
For each video, three files are generated in ~/Downloads/video-transcripts/:
video-id-title.txt # Plain text transcript
video-id-title.json # JSON with metadata and timestamps
video-id-title.md # Markdown with video info
# How to Build Fast Software
**Video:** https://www.youtube.com/watch?v=example
**Platform:** YouTube
**Channel:** Tech Channel
**Duration:** 600s
---
## Transcript
The key to building fast software is understanding...
---
*Transcribed using whisper.cpp (Rust) - Model: base*
All environment variables are optional. The transcriber works with none of them set; they unlock authentication, remote inference, AI summaries, and the paid HTTP API.
💡 The transcript output directory is not an env var — pass
output_dirto thetranscribe_videotool (defaults to~/Downloads/video-transcripts). Output files are named<video_id>-<title>.{txt,json,md}.
--transport http)The HTTP transport only answers requests whose Host header is on an
allowlist. It defaults to loopback (localhost, 127.0.0.1, ::1) as
protection against [DNS rebinding][dns-rebinding], which means a deployed
instance rejects its own public hostname with 403 until you name it:
# Comma-separated. Added on top of the loopback defaults, so local
# development and health checks keep working.
export MCP_ALLOWED_HOSTS=mcp.example.com,mcp.example.com:8080
# On Fly:
fly secrets set MCP_ALLOWED_HOSTS=your-app.fly.dev
Leave it unset for local use — the server logs which hosts it accepts at
startup, so a 403 from a remote client is easy to diagnose.
⚠️ This controls reachability, not authorization. Anyone who can reach the URL can call the tools, including
transcribe_video, which spends real money when remote Whisper / OpenRouter are configured. Put an authenticating proxy in front of a public deployment.
Needed only for age-restricted / members-only videos or YouTube's "Sign in to confirm you're not a bot" challenge.
# Option 1 (preferred on headless / Linux): a Netscape-format cookies file.
# Export it however you like — e.g. a QR-login flow — then point at it.
export YT_DLP_COOKIES=/path/to/cookies.txt
# Option 2: read cookies straight from a logged-in local browser.
# One of: chrome, brave, edge, firefox, safari, chromium, opera, vivaldi.
# Ignored when YT_DLP_COOKIES is set.
export YT_DLP_COOKIES_FROM_BROWSER=chrome
# POST audio to a remote HTTP worker (e.g. a serverless GPU) instead of
# running whisper-rs locally. Endpoint must accept multipart {audio, model,
# language} and return JSON {transcript, segments[], language, duration_s}.
export REMOTE_WHISPER_URL=https://your-worker.example.com/transcribe
# Debug build
cargo build
# Release build (optimized)
cargo build --release
# Run tests
cargo test
# Run with logging
RUST_LOG=debug cargo run -- --url "https://youtube.com/watch?v=example"
src/
├── main.rs # CLI + transport selection (stdio / streamable HTTP)
├── lib.rs # public API for embedders
├── mcp/ # MCP server: tool definitions and handlers
├── transcriber/ # the pipeline: yt-dlp → ffmpeg → whisper.cpp
├── embeddings.rs # passage embeddings, used by `search_transcripts`
└── utils/ # paths
This crate is only the transcription pipeline and its MCP surface. The product
built on top of it — REST API, accounts, credits, payments, AI summaries and
diagrams — lives in a separate private crate that depends on this one as a
library, so cargo install video-transcriber-mcp gets you a transcription
server rather than somebody else's SaaS backend.
Contributions welcome! Please:
I built the original video-transcriber-mcp in TypeScript. Here's why I rewrote it in Rust:
| Aspect | TypeScript Version | Rust Version |
|---|---|---|
| Transcription Speed | 5 min for 10-min video | 50s (6x faster) |
| Memory Usage | ~2 GB | ~800 MB (2.5x less) |
| Startup Time | ~2s | <100ms (20x faster) |
| Binary Size | N/A (Node.js runtime) | ~8 MB standalone |
| Dependencies | Node.js, Python, whisper | Just yt-dlp, ffmpeg |
| CPU Usage | High (Python overhead) | Lower (native code) |
The Rust version is production-ready and significantly more efficient!
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Built with ❤️ in Rust for maximum performance
MCP registry ownership token — crates.io strips HTML comments, so this line has to stay visible:
mcp-name: io.github.nhatvu148/video-transcriber-mcp