{"id":50772918,"url":"https://github.com/realiti4/youtube-context-mcp","last_synced_at":"2026-06-11T21:00:37.349Z","repository":{"id":363306606,"uuid":"1262733147","full_name":"realiti4/youtube-context-mcp","owner":"realiti4","description":"MCP server that gives AI agents YouTube transcripts, so they can summarize and answer questions about any video.","archived":false,"fork":false,"pushed_at":"2026-06-08T14:13:04.000Z","size":144,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-08T14:21:40.543Z","etag":null,"topics":["captions","mcp","mcp-server","python","transcript","youtube","youtube-api","youtube-captions","youtube-transcript","youtube-video"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/realiti4.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-08T09:12:48.000Z","updated_at":"2026-06-08T14:16:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/realiti4/youtube-context-mcp","commit_stats":null,"previous_names":["realiti4/youtube-captions-mcp","realiti4/youtube-context-mcp"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/realiti4/youtube-context-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realiti4%2Fyoutube-context-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realiti4%2Fyoutube-context-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realiti4%2Fyoutube-context-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realiti4%2Fyoutube-context-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/realiti4","download_url":"https://codeload.github.com/realiti4/youtube-context-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realiti4%2Fyoutube-context-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34217312,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["captions","mcp","mcp-server","python","transcript","youtube","youtube-api","youtube-captions","youtube-transcript","youtube-video"],"created_at":"2026-06-11T21:00:24.338Z","updated_at":"2026-06-11T21:00:37.328Z","avatar_url":"https://github.com/realiti4.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# youtube-context-mcp\n\nAn [MCP](https://modelcontextprotocol.io) server that gives agents rich context about any\nYouTube video — what's said, what's popular, and what's on screen:\n\n- **Transcript** — plain or `[mm:ss]`-timestamped text, with optional translation\n- **Deep links** — `watch?v=…\u0026t=…` URLs that jump straight to a moment\n- **Metadata** — title, channel, upload date, duration, view/like counts, chapters, tags\n- **Most-replayed moments** — the peaks of YouTube's viewer-interest heatmap\n- **Visuals** (for multimodal models) — a still frame at any moment, or a tiled preview sheet\n  of the whole video\n\nAgents use it to answer questions about a video, summarize it, pull quotes, surface highlights,\nread what's on screen, or link you to exactly where something is said.\n\nIt builds on [`youtube-transcript-api`](https://github.com/jdepoix/youtube-transcript-api)\n(transcripts) and [`yt-dlp`](https://github.com/yt-dlp/yt-dlp) (metadata), which do the actual\nfetching, and shapes them into a focused set of MCP tools designed for agents.\n\n\u003e Transcripts are a video's **existing captions/subtitles** — it does **not** transcribe audio\n\u003e (no Whisper/ASR). Videos without captions have no transcript to return.\n\n## Install\n\nRun it on demand with [uv](https://docs.astral.sh/uv/) (no install needed):\n\n```bash\nuvx youtube-context-mcp@latest\n```\n\nOr install it:\n\n```bash\npip install youtube-context-mcp\n```\n\n## Use it with an agent\n\nAdd it to your MCP client config:\n\n```json\n{\n  \"mcpServers\": {\n    \"youtube-context\": {\n      \"command\": \"uvx\",\n      \"args\": [\"youtube-context-mcp@latest\"]\n    }\n  }\n}\n```\n\nOr, in Claude Code:\n\n```bash\nclaude mcp add youtube-context -- uvx youtube-context-mcp@latest\n```\n\n### Running over HTTP\n\nBy default the server talks **stdio** (the client launches it). If your client runs on a\ndifferent host — for example LM Studio on Windows while this server runs in WSL2 — run it as a\nlong-lived HTTP server instead and point the client at a URL:\n\n```bash\nyoutube-context-mcp --transport http --host 0.0.0.0 --port 8000\n```\n\nThen add it by URL:\n\n```json\n{\n  \"mcpServers\": {\n    \"youtube-context\": { \"url\": \"http://localhost:8000/mcp\" }\n  }\n}\n```\n\n(`--host 0.0.0.0` makes it reachable from the Windows side; WSL2 forwards `localhost`.)\n\n## Tools\n\nIn every tool, `video` accepts a full YouTube URL (watch, youtu.be, shorts, embed, live) or a\nbare 11-character video ID.\n\n### `get_transcript`\n\n`get_transcript(video, languages=[\"en\"], include_timestamps=False, translate_to=None)`\n\nReturns the transcript as plain text. Set `include_timestamps=True` to group it into ~15s\n`[mm:ss]` blocks — handy for locating a topic and building a link; `translate_to` takes an ISO\nlanguage code.\n\n### `build_video_link`\n\n`build_video_link(video, start)`\n\nBuilds a `watch?v=…\u0026t=\u003cseconds\u003e` URL that opens the video at a moment, so a user can click\nstraight to it. `start` is seconds or a `\"mm:ss\"` / `\"h:mm:ss\"` string. Pairs with\n`get_transcript(include_timestamps=True)` to turn \"where is X mentioned?\" into a clickable link.\n\n### `list_transcripts`\n\n`list_transcripts(video)`\n\nLists available transcripts (language, code, manual vs auto-generated, translatable) plus the\ntranslation targets. Use it when `get_transcript` can't find your language.\n\n### `get_video_metadata`\n\n`get_video_metadata(video, include_description=False)`\n\nReturns the video's title, channel, upload date, duration, view/like counts, chapters and tags —\nanswers \"what's this video / who made it?\" without fetching the transcript. Set\n`include_description=True` to also include the (often long) description.\n\n### `get_most_replayed`\n\n`get_most_replayed(video, top_n=8)`\n\nReturns the video's **most-replayed moments** (YouTube's viewer-interest heatmap) as up to\n`top_n` distinct high-interest content regions — each with a `peak_label`/`region_label`\n(mm:ss), a clickable jump `url`, the chapter it falls in, and a `relative_intensity` (0–1 within\nthe video, 1.0 = its single most-rewatched moment — not a view count). Use it for \"what are the\nbest parts?\" or to weight a summary by what viewers actually rewatch.\n\nA peak flagged `is_opening: true` sits at the start (t≈0) — usually a playback-start artifact,\nnot a real rewatch; it's returned *in addition to* `top_n` so it can't crowd out the content\npeaks. `has_data` is `false` when YouTube has no heatmap (common for newer/low-traffic videos\nand some Shorts).\n\n### `get_video_frame`\n\n`get_video_frame(video, at, max_width=640)`\n\nCaptures a single still **frame** (screenshot) at a moment and returns it as an image, so a\nmultimodal model can answer \"what's on screen here?\" — read a slide, a burned-in caption, or a\nUI being demoed. `at` is seconds or a `\"mm:ss\"` / `\"h:mm:ss\"` string; the frame is the nearest\nkeyframe at/just before it and is downscaled to `max_width` (clamped 64–1280) to stay cheap on\nthe image budget. Pairs with `get_most_replayed` / `get_transcript(include_timestamps=True)` to\npick the moment first. **Requires [ffmpeg](#media-tools-ffmpeg).**\n\n### `get_video_preview`\n\n`get_video_preview(video, tiles=12, tile_width=320, start=None, end=None)`\n\nReturns a **contact sheet**: `tiles` frames sampled evenly across the whole video, composited\ninto one tiled grid image, plus a text legend mapping each tile to its `mm:ss` timestamp — a\ncheap visual overview of the entire video (a 4×3 sheet costs about 3× one frame). Pass `start` /\n`end` (seconds or `\"mm:ss\"` / `\"h:mm:ss\"`) to preview just a window of the video — e.g. zoom into\nthe part an overview sheet or `get_most_replayed` flagged as interesting. Tiles are small by\ndesign: spot scene changes and pick a moment here, then zoom in further with `get_video_frame`\nat a tile's timestamp. **Requires [ffmpeg](#media-tools-ffmpeg).**\n\n## Media tools (ffmpeg)\n\n`get_video_frame` and `get_video_preview` are the only tools that need an\n[`ffmpeg`](https://ffmpeg.org/) binary (everything else is metadata/transcript only). yt-dlp\nresolves the video stream and ffmpeg grabs downscaled JPEGs; images come back as MCP image\ncontent, so the client/model must be able to display images (e.g. a multimodal model such as\nGemma in LM Studio).\n\nThe system ffmpeg is used when it's on `PATH`. The optional `media` extra installs\n[`imageio-ffmpeg`](https://pypi.org/project/imageio-ffmpeg/), whose wheel bundles a static ffmpeg,\nmaking the install self-contained:\n\n```bash\npip install \"youtube-context-mcp[media]\"   # or: uvx youtube-context-mcp[media]@latest\n# or bring your own: apt install ffmpeg | brew install ffmpeg | see ffmpeg.org\n```\n\nIf neither is available, only the two media tools are affected and they return a clear error.\n\n## Proxies (optional)\n\nYouTube blocks most datacenter/cloud IPs, so on a server you may hit `RequestBlocked` /\n`IpBlocked` (transcripts) or a \"Sign in to confirm you're not a bot\" block (metadata). Locally\nthis is rarely needed. The same env vars route both transcript and metadata requests through a\nproxy:\n\n| Env var | Purpose |\n| --- | --- |\n| `WEBSHARE_PROXY_USERNAME`, `WEBSHARE_PROXY_PASSWORD` | Use [Webshare](https://www.webshare.io/) rotating residential proxies. |\n| `WEBSHARE_PROXY_LOCATIONS` | Optional CSV of country codes, e.g. `us,de`. |\n| `YT_TRANSCRIPT_HTTP_PROXY`, `YT_TRANSCRIPT_HTTPS_PROXY` | Use a generic HTTP/HTTPS proxy instead. |\n| `YT_TRANSCRIPT_TIMEOUT` | Per-request timeout in seconds (default `20`). |\n\nWith no env set, requests go out directly.\n\n## Troubleshooting\n\n- **`RequestBlocked` / `IpBlocked`** — YouTube blocked the IP. Set the proxy env vars above.\n- **No transcript found** — call `list_transcripts` to see which languages exist for that video.\n- **Transcripts disabled** — the uploader turned captions off; nothing can be fetched.\n- **\"ffmpeg is not installed\"** — the media tools need it; install it or use the `[media]` extra\n  ([Media tools](#media-tools-ffmpeg)).\n- **Frame/preview returns but no image shows** — the MCP client/model must support image\n  content; text-only setups drop it silently.\n\n## Development\n\n```bash\nuv sync\nuv run ruff check . \u0026\u0026 uv run ruff format --check .\nuv run pytest\nuv run mcp dev src/youtube_context_mcp/server.py --with-editable .   # interactive inspector\n```\n\n## License\n\nMIT\n\n## Credits\n\nTranscript fetching is done by [`youtube-transcript-api`](https://github.com/jdepoix/youtube-transcript-api)\nby Jonas Depoix, and metadata by [`yt-dlp`](https://github.com/yt-dlp/yt-dlp). This project is\nthe MCP adapter that wires them together for agents.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frealiti4%2Fyoutube-context-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frealiti4%2Fyoutube-context-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frealiti4%2Fyoutube-context-mcp/lists"}