loading…
Search for a command to run...
loading…
An MCP server (stdio + HTTP/SSE) that fetches video transcripts/subtitles via yt-dlp, with pagination for large responses. Supports YouTube, Twitter/X, Instagra
An MCP server (stdio + HTTP/SSE) that fetches video transcripts/subtitles via yt-dlp, with pagination for large responses. Supports YouTube, Twitter/X, Instagram, TikTok, Twitch, Vimeo, Facebook, Bilibili, VK, Dailymotion. Whisper fallback — transcribes audio when subtitles are unavailable (local or OpenAI API). Works with Cursor and other MCP host
Dockerhub smithery badge GitHub License
An MCP server (stdio; remote HTTP/SSE via mcp-proxy) that fetches video transcripts/subtitles via yt-dlp, with pagination for large responses. Supports YouTube, Twitter/X, Instagram, TikTok, Twitch, Vimeo, Facebook, Bilibili, VK, Dailymotion, Reddit. Whisper fallback — transcribes audio when subtitles are unavailable (local or OpenAI API). Works with Cursor and other MCP hosts.
This repository primarily ships a stdio MCP server (node dist/mcp.js):
docker-compose.example.yml.It also includes an optional REST API (Fastify), but MCP is the primary focus.
Unlike YouTube-only tools, Transcriptor MCP works across 11 major video platforms:
YouTube · Twitter/X · Instagram · TikTok · Twitch · Vimeo · Facebook · Bilibili · VK · Dailymotion · Reddit
All URL-based tools (get_transcript, get_raw_subtitles, get_available_subtitles, get_video_info, get_video_chapters, get_playlist_transcripts) accept video URLs from any supported platform. The search_videos tool is YouTube-specific (yt-dlp ytsearch).
Transcriptor MCP is the best choice when you need transcripts and metadata for AI, summarization, or content analysis — without downloading video or audio files:
Use the sections in this README for setup, tools, and deployment patterns.
Choose one of these two main paths:
Best when you want a fast local setup without Node on host.
docker run --rm -i artsamsonov/transcriptor-mcp:latest
Cursor MCP config:
{
"mcpServers": {
"transcriptor": {
"command": "docker",
"args": ["run", "--rm", "-i", "artsamsonov/transcriptor-mcp:latest"]
}
}
}
Detailed local + self-hosted HTTP/SSE instructions are in How to connect and MCP quick start.
https://server.smithery.ai/samson-art/transcriptor-mcpapiToken (header token issued via Google Form)Smithery maps session apiToken to upstream X-MCP-Api-Token. Keep the token secret (do not commit or log).
Full Smithery setup steps and examples are in How to connect.
Other directories and one-click listings:
GET /metrics); MCP tool counters (mcp_*) are updated inside the MCP Node process but this repo no longer exposes GET /metrics on the MCP image.You can enable these features independently; both are off by default.
WHISPER_MODE, WHISPER_BASE_URL, WHISPER_API_KEY, etc.CACHE_MODE=redis and CACHE_REDIS_URL.For full setup options (Local Docker, Smithery remote, and self-hosted HTTP/SSE with mcp-proxy), use:
| Tool | Purpose |
|---|---|
get_transcript |
Cleaned plain text (first chunk) |
get_raw_subtitles |
Raw SRT/VTT, paginated |
get_available_subtitles |
List official/auto languages |
get_video_info |
Extended metadata |
get_video_chapters |
Chapter markers |
get_playlist_transcripts |
Batch transcripts from playlist |
search_videos |
YouTube search |
All URL-based tools share the same base input:
url (string, required) – Video URL from a supported platform or YouTube video ID. Supported: YouTube, Twitter/X, Instagram, TikTok, Twitch, Vimeo, Facebook, Bilibili, VK, Dailymotion, Reddit.get_raw_subtitles supports pagination; get_transcript returns the first chunk only (no pagination input). Pagination parameters for get_raw_subtitles:
response_limit (number, optional) – max characters per response, default 50000, min 1000, max 200000.next_cursor (string, optional) – opaque offset returned from the previous page; pass it to fetch the next chunk.Each tool returns:
content – human-readable text (for MCP chat UIs).structuredContent – strongly typed JSON payload you can consume from automations or code.get_transcriptPurpose: Fetch cleaned subtitles as plain text (no timestamps, HTML, or speaker metadata).
Input: Only url (video URL or ID). Type and language are auto-discovered; the tool returns the first chunk with default size (no pagination parameters).
Structured response:
videoId – resolved YouTube ID.type, lang – effective subtitle type and language.text – current text chunk.is_truncated – true if more text is available.total_length – total length of the full transcript.start_offset, end_offset – character offsets of this chunk.next_cursor – present in response when truncated (omitted on the last page). Not accepted as input for this tool.get_raw_subtitlesPurpose: Fetch raw subtitle file content (SRT or VTT) with pagination support.
Extra input fields:
type – "official" or "auto", optional.lang – subtitle language code, optional.response_limit, next_cursor – pagination (optional).Structured response:
videoId, type, lang – same semantics as above.format – "srt" or "vtt" (auto-detected from content).content – raw subtitle text for this page.is_truncated, total_length, start_offset, end_offset, next_cursor – same pagination fields as get_transcript.get_available_subtitlesPurpose: Inspect which languages are available for a video, split into official vs auto-generated tracks.
Input:
url – YouTube URL or video ID.Structured response:
videoId – resolved YouTube ID.official – sorted list of language codes with official subtitles.auto – sorted list of language codes with auto-generated subtitles.This is useful to first discover languages and then pick type/lang for get_raw_subtitles (or other tools).
get_video_infoPurpose: Fetch extended metadata about a video (based on yt-dlp JSON output).
Input:
url – YouTube URL or video ID.Structured response (key fields):
videoId – resolved YouTube ID.title, description.uploader, uploaderId.channel, channelId, channelUrl.duration – in seconds.uploadDate – YYYYMMDD string if available.webpageUrl.viewCount, likeCount, commentCount.tags, categories.liveStatus, isLive, wasLive, availability.thumbnail – primary thumbnail URL.thumbnails – list of thumbnail variants { url, width?, height?, id? }.See src/mcp-core.ts and src/youtube.ts for the full JSON schema used by the MCP SDK.
get_video_chaptersPurpose: Get chapter markers extracted by yt-dlp.
Input:
url – YouTube URL or video ID.Structured response:
videoId – resolved YouTube ID.chapters – array of { startTime: number; endTime: number; title: string }.If the video has no chapters, chapters is an empty array; if yt-dlp cannot fetch chapter data at all, the tool returns an MCP error instead of structured chapters.
get_playlist_transcriptsPurpose: Fetch cleaned transcripts for multiple videos from a playlist in one call.
Input:
url (string, required) – Playlist URL or watch URL with list= (e.g. https://www.youtube.com/playlist?list=XXX).type – "official" or "auto", optional.lang – Subtitle language code, optional.format – Subtitle format (srt, vtt, ass, lrc), optional.playlistItems – yt-dlp -I spec (e.g. 1:5, 1,3,7, -1), optional.maxItems – Max videos to process, optional.Structured response:
results – array of { videoId, text } for each video in the playlist.search_videosPurpose: Search videos on YouTube via yt-dlp (ytsearch). Returns a list of videos with metadata.
Input:
query (string, required) – Search query.limit (number, optional) – Max results (default 10, max 50).offset (number, optional) – Skip first N results (pagination).uploadDateFilter (string, optional) – Filter by upload date: hour, today, week, month, or year.response_format (string, optional) – Human-readable format: json (default) or markdown.Structured response:
results – array of { videoId, title, url, duration, uploader, viewCount, thumbnail }.The repository also ships an HTTP API (Fastify).
docker build -t transcriptor-mcp-api -f Dockerfile --target api .
docker run -p 3000:3000 transcriptor-mcp-api
For a more complete REST quick start (including docker-compose and local Node.js), use REST API (optional) and API Documentation.
Once the REST API is running, interactive API docs are available at:
http://localhost:3000/docs
If you change PORT / HOST, adjust the URL accordingly, e.g. http://<HOST>:<PORT>/docs.
If yt-dlp is blocked by age gate, sign-in, or region restrictions, you will likely need
an authenticated cookies.txt file and the COOKIES_FILE_PATH environment variable.
The root of this repository includes a sample [cookies.example.txt](cookies.example.txt)
showing the expected Netscape cookies format. For a full guide on:
keep credentials local and use COOKIES_FILE_PATH with a non-committed cookie file.
docker run -d -p 3000:3000 --name transcriptor transcriptor-mcp-api
Before publishing Docker images, you can run a small e2e smoke test that:
POST /subtitles with a stable YouTube videoPOST /mcp with initialize), and SSE (GET /sse) against mcp-proxy + stdio (same stack as docker-compose.example.yml)Run the smoke test (requires built images):
npm run build
docker build -t artsamsonov/transcriptor-mcp-api:latest -f Dockerfile --target api .
docker build -t artsamsonov/transcriptor-mcp:latest -f Dockerfile --target mcp .
npm run test:e2e:api
Environment variables:
| Variable | Default | Description |
|---|---|---|
SMOKE_IMAGE_API |
— | Full API image reference (overrides name/tag). |
DOCKER_API_IMAGE / TAG |
artsamsonov/transcriptor-mcp-api, latest |
API image name and tag. |
SMOKE_API_URL / SMOKE_API_PORT |
http://127.0.0.1:33000, 33000 |
API base URL and port. |
SMOKE_VIDEO_URL |
https://www.youtube.com/watch?v=dQw4w9WgXcQ |
Video used for /subtitles check. |
SMOKE_SKIP_MCP |
— | Set to 1 (or true/yes) to skip MCP checks. |
SMOKE_MCP_IMAGE |
— | Full MCP image reference (overrides name/tag). |
DOCKER_MCP_IMAGE / TAG |
artsamsonov/transcriptor-mcp, latest |
MCP image name and tag. |
SMOKE_MCP_URL / SMOKE_MCP_PORT |
http://127.0.0.1:4200, 4200 |
MCP base URL and port. |
SMOKE_MCP_AUTH_TOKEN |
— | If set, sent as Authorization: Bearer on MCP HTTP requests (for smoke against an edge that requires Bearer; the default smoke stack does not enforce it). |
Example: skip MCP and use a custom video:
SMOKE_SKIP_MCP=1 SMOKE_VIDEO_URL="https://www.youtube.com/watch?v=YOUR_ID" npm run test:e2e:api
docker logs -f transcriptor
docker stop transcriptor
docker rm transcriptor
For detailed REST API endpoint documentation (request/response schemas, examples, etc.), use the built-in Swagger UI at:
http://localhost:3000/docs
or use REST API (optional).
The MCP server runs on stdio (dist/mcp.js) and can be used via:
docker run --rm -i artsamsonov/transcriptor-mcp:latest)node dist/mcp.js)mcp-proxy (/mcp and /sse)Use How to connect as the main guide for MCP setup variants and auth notes (apiToken/X-MCP-Api-Token for Smithery vs Bearer on your own edge).
yt-dlp to download subtitles with the specified parameters:yt-dlp command call with explicit type (--write-subs or --write-auto-subs) and language (--sub-lang)/subtitles) or raw content (for /subtitles/raw)The app version is read from package.json at runtime ([src/version.ts](src/version.ts)). When cutting a release, update the version field in package.json, then create a git tag (e.g. v0.4.7). Changelog entries under [Unreleased] should be moved to the new version before tagging.
npm run build - Build the TypeScript projectnpm start - Run the compiled applicationnpm run dev - Run with hot reload using ts-node-devnpm run start:mcp - Run the MCP server (stdio)npm run dev:mcp - Run the MCP server with hot reloadnpm test - Run testsnpm run test:watch - Run tests in watch modenpm run test:coverage - Run tests with coverage reportnpm run lint - Lint the codenpm run lint:fix - Fix linting errorsnpm run type-check - Type check without buildingnpm run format - Format code with Prettiernpm run format:check - Check code formatting├── src/
│ ├── index.ts # HTTP API (Fastify)
│ ├── mcp.ts # MCP server (stdio)
│ ├── mcp-core.ts # MCP tools registration
│ ├── validation.ts # Request validation
│ ├── youtube.ts # Subtitle download and parsing (yt-dlp)
│ ├── yt-dlp-check.ts # yt-dlp availability checks
│ ├── whisper.ts # Whisper API client
│ ├── whisper-jobs.ts # Async Whisper jobs
│ ├── cache.ts # Response / subtitle caching
│ ├── metrics.ts # Prometheus metrics (/metrics)
│ ├── lifecycle.ts # Graceful shutdown hooks
│ ├── instrument.ts # Sentry initialization
│ ├── logger-sentry-breadcrumbs.ts
│ ├── errors.ts # Error types and HTTP mapping
│ ├── env.ts # Environment configuration
│ ├── version.ts # App version (from package.json)
│ ├── changelog.ts # Changelog data for API
│ ├── e2e/ # API / MCP smoke tests (Docker)
│ │ ├── api-smoke.ts
│ │ ├── mcp-smoke.ts
│ │ ├── docker-utils.ts
│ │ └── smoke-env.ts
│ └── *.test.ts # Unit tests (Jest), co-located
├── dist/ # Compiled JavaScript (npm run build)
├── load/ # Load-test scripts (k6)
├── scripts/ # Maintenance scripts (e.g. generate-server-card.mjs)
├── .github/workflows/ # CI and Docker Hub publish
├── Dockerfile # API and MCP images (--target api|mcp)
├── docker-compose.example.yml # Example API + MCP stack
├── docker-compose.yml
├── package.json
├── tsconfig.json
├── eslint.config.mjs
├── jest.config.cjs
├── smithery.yaml
└── README.md
Data and keys: Video URLs are sent to yt-dlp for subtitle extraction. Keys and tokens are stored only in your environment; we never log or share them.
Do not commit or log sensitive values. Use environment variables or a secret manager (e.g. vault, cloud secrets) for:
**WHISPER_API_KEY** – required when using Whisper API; never log or expose in client responses.**CACHE_REDIS_URL** – Redis connection string when CACHE_MODE=redis; may contain credentials.**COOKIES_FILE_PATH** – path to cookies; ensure the file is not committed and has restricted permissions.Use cookies.example.txt as a format template and keep real cookies outside git.
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)Please make sure your code passes all tests and linting checks before submitting.
MIT License
Copyright (c) 2025 samson-art
See LICENSE file for details.
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"transcriptor-mcp": {
"command": "npx",
"args": []
}
}
}Transcripts, channel stats, search
AI image generation using various models.
Unified GPU inference API with 30 AI services (LLM, image gen, video, TTS, whisper, embeddings, reranking, OCR) as MCP tools. Pay-per-use via x402 USDC or API k
A powerful image generation tool using Google's Imagen 3.0 API through MCP. Generate high-quality images from text prompts with advanced photography, artistic,