Content
# YouTube Transcript MCP Server
> [!NOTE]
> This project is being coded by a beginner.
A MCP server that retrieves subtitles and metadata from YouTube URLs or video IDs.
Can be used with Claude Desktop / OpenAI Codex to summarize, translate, note, and confirm video content.
## Main Features
- Supports YouTube URL / 11-character video ID
- Prioritizes manual subtitles, falls back to auto-generated subtitles if not available
- Subtitle languages prioritized: `ja` / `en` / `ko` (auto-selected), timestamp addition is optional
- Outputs subtitles in Markdown format
- Retrieves title, author, upload date, and other metadata
- Supports local caching (stdio connection)
## Provided Tools
| Tool | Purpose |
| --- | --- |
| `youtube_get_transcript` | Retrieves subtitles and returns in Markdown format |
| `youtube_get_video_info` | Returns video metadata in JSON |
| `youtube_get_frame` | Returns a single frame image at a specified timestamp |
## Setup
### Prerequisites
- Python 3.10 or higher
- [uv](https://docs.astral.sh/uv/) available
### Installation
```bash
cd yt-transcript-mcp
uv sync
```
This will install all dependencies, including `yt-dlp`. No need to install `yt-dlp` separately.
> [!IMPORTANT]
> `yt-dlp` is a tool that continues to work by following YouTube's specification changes.
> If left unchanged, metadata retrieval may break.
> If broken (or periodically), run the following:
```bash
uv lock --upgrade-package yt-dlp && uv sync
```
## Client Configuration
### Claude Desktop
Add to `~/.claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"yt-transcript-mcp": {
"command": "uv",
"args": [
"run",
"--directory",
"/path/to/yt-transcript-mcp",
"python",
"server.py"
]
}
}
}
```
### OpenAI Codex
Add to `~/.codex/config.toml`:
```toml
[mcp_servers.yt-transcript-mcp]
command = "uv"
args = ["run", "--directory", "/path/to/yt-transcript-mcp", "python", "server.py"]
```
## Usage
Send a request with a YouTube URL to the MCP client:
```text
Summarize this video: https://www.youtube.com/watch?v=xxxxx
```
### `youtube_get_transcript`
| Parameter | Default | Description |
| --- | --- | --- |
| `url` | Required | YouTube URL or 11-character video ID |
| `include_timestamps` | `false` | Add timestamps to each line if `true` |
Subtitle language is auto-selected from `ja` / `en` / `ko`, falls back to available subtitles if not found.
Metadata (title, author, etc.) is always included.
Timestamps are off by default in inline output, but on in written `.md` files.
Example output:
```markdown
# Video Title
- Author: Channel Name
- URL: https://www.youtube.com/watch?v=xxxxx
- Video ID: xxxxx
- Transcript language: ja
- Transcript source: auto-generated
- Upload date: 2025-01-15
- Duration: 12m30s
- Transcript file: /abs/path/.transcript_cache/xxxxx.md
## Transcript
Hello, today...
```
`Transcript file` is the absolute path to the written `.md` file.
### `youtube_get_frame`
Used for scenes without subtitles (slides, code on screen, charts, demo without subtitles).
| Parameter | Default | Description |
| --- | --- | --- |
| `url` | Required | YouTube URL or 11-character video ID |
| `timestamp` | Required | Seconds (`90`), `MM:SS` (`01:30`), `HH:MM:SS` (`00:01:30`) |
Pass the timestamp value from `youtube_get_transcript` with `include_timestamps=true`.
No video download required. Resolves stream URL with `yt-dlp`, reads required range with `ffmpeg`.
Saved as JPEG in `.transcript_cache/{video_id}_frame_{timestamp}.jpg`.
## Troubleshooting
### Subtitles not retrieved
- Video may not have subtitles
- Subtitle language prioritized: `ja` / `en` / `ko`, falls back to available subtitles
- Private, age-restricted, or region-restricted videos may not be retrieved
### Metadata is `Unknown`
- Check `metadata_error` in `youtube_get_video_info` JSON
- If `type` is `yt_dlp_not_found`, run `uv sync`
- If `stderr` indicates YouTube specification changes, update `yt-dlp` with `uv lock --upgrade-package yt-dlp && uv sync`
## Development
```bash
uv sync --dev
uv run python -m unittest discover -s tests
uv run ruff format . && uv run ruff check --fix . && uv run mypy .
```
## Future Extensions
- [ ] Whisper integration for videos without subtitles
- [ ] Playlist URL batch processing
- [ ] Explicit cache deletion and update options