{
  "markdown": "<!-- mcp-name: com.transcriptout/youtube-transcript-and-youtube-search -->\n\n<p align=\"center\">\n  <a href=\"https://transcriptout.com\">\n    <img src=\"public/brand/logo-512.png\" width=\"120\" height=\"120\" alt=\"TranscriptOut\" />\n  </a>\n</p>\n\n<h1 align=\"center\">YouTube Transcript &amp; Search MCP Server</h1>\n\n<p align=\"center\">\n  <b>Let your AI agent read YouTube.</b><br/>\n  Transcripts in five formats, native video and channel search, channel and playlist listings,\n  and background jobs that deliver up to 4,000 transcripts at a time. 14 tools behind one hosted\n  endpoint. Nothing runs on your machine.\n</p>\n\n<p align=\"center\">\n  <a href=\"https://cursor.com/en/install-mcp?name=transcriptout&config=eyJ1cmwiOiJodHRwczovL2FwaS50cmFuc2NyaXB0b3V0LmNvbS9tY3AifQ==\"><img alt=\"Install in Cursor\" src=\"https://img.shields.io/badge/Cursor-Install_MCP-000000?style=for-the-badge&logo=cursor&logoColor=white\"/></a>\n  <a href=\"https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%7B%22name%22%3A%22transcriptout%22%2C%22url%22%3A%22https%3A%2F%2Fapi.transcriptout.com%2Fmcp%22%7D\"><img alt=\"Install in VS Code\" src=\"https://img.shields.io/badge/VS_Code-Install_MCP-0098FF?style=for-the-badge&logo=visualstudiocode&logoColor=white\"/></a>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://transcriptout.com\"><img src=\"https://img.shields.io/badge/Website-transcriptout.com-FF3B00?style=for-the-badge\" alt=\"Website\"/></a>\n  <a href=\"https://transcriptout.com/docs\"><img src=\"https://img.shields.io/badge/Docs-API_Reference-06B6D4?style=for-the-badge&logo=readthedocs&logoColor=white\" alt=\"Docs\"/></a>\n  <a href=\"./LICENSE\"><img src=\"https://img.shields.io/badge/License-MIT-4CAF50?style=for-the-badge\" alt=\"MIT License\"/></a>\n</p>\n\n<p align=\"center\">\n  <a href=\"#-why\">Why</a> ·\n  <a href=\"#-quick-start\">Quick start</a> ·\n  <a href=\"#-the-14-tools\">Tools</a> ·\n  <a href=\"#-install-in-your-client\">Install</a> ·\n  <a href=\"#-recipes\">Recipes</a> ·\n  <a href=\"#-pricing-and-limits\">Pricing</a> ·\n  <a href=\"#-when-a-call-fails\">Errors</a>\n</p>\n\n---\n\n## 🎬 Why\n\nEveryone who works with an agent has run this exchange at least once.\n\n```txt\nYou:   Summarize this. https://www.youtube.com/watch?v=kCc8FmEb1nY\nAgent: I'm not able to watch videos. If you paste the transcript here, I'll gladly help!\n```\n\nThe transcript is precisely the thing the agent cannot get on its own. With this server\nconnected, the same message simply resolves.\n\n```txt\nYou:   Summarize this. https://www.youtube.com/watch?v=kCc8FmEb1nY\nAgent: → get_transcript(video=\"kCc8FmEb1nY\", video_metadata=true)      1 credit\n\n       That's \"Let's build GPT: from scratch, in code, spelled out\" by Andrej\n       Karpathy, 1:56:20. He starts from an empty file and a bigram model,\n       derives self-attention step by step, and ends with a working GPT that...\n```\n\nReading one video is rarely where the job ends. Here is how the three ways of getting YouTube\ndata into an agent actually compare.\n\n|                          | This server | Local yt-dlp / scraper MCP | Google YouTube Data API |\n| ------------------------ | ----------- | -------------------------- | ----------------------- |\n| Transcripts              | ✅ any public video, 5 formats | ⚠️ blocked on datacenter IPs, breaks when YouTube changes markup | ❌ not served at all |\n| Setup                    | ✅ a URL and an API key | ❌ local install, binaries to keep alive | ❌ Cloud project, OAuth consent screens |\n| YouTube search           | ✅ native, 1 credit per page | ❌ | ⚠️ 100 quota units per search |\n| Channels & playlists     | ✅ 100 videos/page, or 500 bare IDs | ❌ one video at a time | ⚠️ quota-metered per item |\n| Bulk transcripts         | ✅ 4,000 per background job | ❌ | ❌ |\n| RAG-ready chunking       | ✅ 20-5,000 chars, word-level timestamps | ❌ | ❌ |\n| When YouTube changes     | ✅ fixed server-side, nothing to update | ❌ you patch and redeploy | ✅ |\n| Failed calls             | ✅ credits refund themselves | ❌ your retry logic | ⚠️ quota spent anyway |\n\n---\n\n## ⚡ Quick start\n\n**1. Get an API key.** Sign up at [transcriptout.com](https://transcriptout.com) and create a key\nin the [dashboard](https://transcriptout.com/dashboard). New accounts receive 100 free credits and\nno card is asked. Keys start with `sk_` and are shown once.\n\n**2. Point your client at the server.** It speaks streamable HTTP and authenticates with one\nBearer header.\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"url\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": { \"Authorization\": \"Bearer YOUR_API_KEY\" }\n    }\n  }\n}\n```\n\nOne-click buttons for Cursor and VS Code sit at the top of this page. Exact snippets for the rest\nlive under [Install in your client](#-install-in-your-client).\n\n**3. Paste a link.**\n\n```txt\nSummarize this talk and pull the three strongest quotes.\nhttps://www.youtube.com/watch?v=dQw4w9WgXcQ\n```\n\nThe agent picks `get_transcript` on its own, reads the timed text and answers from it. Every\nresponse carries an `X-Credits-Remaining` header, so the budget stays in view the whole session.\n\n---\n\n## 🧰 The 14 tools\n\nAll 14 tools are exposed automatically once you connect. **Most calls cost 1 credit.** Credits\nare refunded automatically when a call fails before reaching YouTube (validation errors, rate\nlimits, our own capacity), so you pay for answers, not for failures. A definitive \"this video has no\ncaptions\" is an answer and is billed like one.\n\n### 1. `get_transcript` · 1 credit\n\nFetch the transcript of any YouTube video. `format=text` (default) returns plain readable text,\ncheapest for a model to reason over, and `format=json` returns timed segments.\n\n| Parameter        | Type    | Default      | Description                                                    |\n| ---------------- | ------- | ------------ | -------------------------------------------------------------- |\n| `video`          | string  | **required** | YouTube URL (full or short) or 11-char video ID                |\n| `lang`           | string  | `\"en\"`       | Language code of the track (`en`, `de`, ...)                   |\n| `format`         | string  | `\"text\"`     | `\"text\"` (plain text), `\"json\"` (segments with `start`/`duration` in seconds), `\"srt\"`/`\"vtt\"` (subtitle file body), `\"srv3\"` (raw YouTube XML) |\n| `kind`           | string  | auto-detect  | `\"manual\"` or `\"auto\"`. Left out, a manual track wins and auto is the fallback |\n| `segment`        | integer | see below    | Max characters per segment. 500-1500 makes RAG-ready chunks    |\n| `video_metadata` | boolean | `false`      | Add title, channel, duration and views in the SAME call, same 1 credit |\n\nLeft out, `segment` cuts auto-generated tracks into ~180-character segments and returns manual\ntracks exactly as their author broke them. Pass it whenever you need one size regardless of which\ntrack answers.\n\n**Example output (`format=json`):**\n\n```json\n{\n  \"video_id\": \"dQw4w9WgXcQ\",\n  \"language\": \"en\",\n  \"kind\": \"manual\",\n  \"transcript\": [\n    { \"text\": \"Never gonna give you up\", \"start\": 18.0, \"duration\": 4.12 },\n    { \"text\": \"Never gonna let you down\", \"start\": 22.12, \"duration\": 3.85 }\n  ]\n}\n```\n\n> `srt` and `vtt` come back as complete subtitle file bodies, ready to be written to disk by the\n> agent. `srv3` is the raw source XML and does not combine with `segment`.\n\n### 2. `get_video_info` · 1 credit\n\nMetadata for one video (title, channel, duration, views, thumbnails) plus the list of available\ntranscript languages, WITHOUT downloading the subtitles.\n\n| Parameter | Type   | Default      | Description                |\n| --------- | ------ | ------------ | -------------------------- |\n| `id`      | string | **required** | YouTube video ID or URL    |\n\n> **Credit hygiene:** if you are going to fetch the transcript anyway, call `get_transcript` with\n> `video_metadata=true` instead. It returns both for one credit where these are two calls and two.\n\n### 3. `search_youtube` · 1 credit/page\n\nSearch YouTube for videos or channels. Paginate with `next_page_token`. `has_more` tells you\nwhether another page exists.\n\n| Parameter         | Type    | Default   | Description                          |\n| ----------------- | ------- | --------- | ------------------------------------ |\n| `q`               | string  | required* | Search query (*unless paginating)    |\n| `type`            | string  | `\"video\"` | `\"video\"` or `\"channel\"`             |\n| `limit`           | integer | `20`      | Results per page, 1-50               |\n| `next_page_token` | string  |           | Token from a previous result         |\n\n### 4. `list_channel_videos` · 1 credit/page\n\nList videos from a channel's Videos tab, newest first. Accepts an `@handle`, a channel name, a\n`UC...` channel ID or a channel URL.\n\n| Parameter         | Type    | Default   | Description                                        |\n| ----------------- | ------- | --------- | -------------------------------------------------- |\n| `name`            | string  | required* | `@handle`, channel name, `UC...` ID or URL         |\n| `limit`           | integer | `100`     | Page size, up to 500 with `ids_only`               |\n| `ids_only`        | boolean | `false`   | Return just `video_ids[]`, up to 500 per page      |\n| `next_page_token` | string  |           | Token from a previous result                       |\n\n> `ids_only=true` is the cheap way to feed `submit_transcripts_job`.\n\n### 5. `search_channel_videos` · 1 credit/page\n\nSearch inside one channel using YouTube's native relevance search. A result whose title lacks the\nquery word is normal. Results are ranked by relevance, not by substring.\n\n| Parameter         | Type    | Default   | Description                          |\n| ----------------- | ------- | --------- | ------------------------------------ |\n| `name`            | string  | required  | `@handle`, channel name, `UC...` ID or URL |\n| `q`               | string  | required  | Query to search within the channel   |\n| `limit`           | integer | `30`      | Results per page, 1-100              |\n| `next_page_token` | string  |           | Pagination token                     |\n\n### 6. `latest_channel_videos` · 1 credit\n\nThe ~15 most recent videos of a channel from its RSS feed. The fastest and cheapest way to check\nwhat a channel published recently.\n\n| Parameter | Type   | Default      | Description                                |\n| --------- | ------ | ------------ | ------------------------------------------ |\n| `name`    | string | **required** | `@handle`, channel name, `UC...` ID or URL |\n\n### 7. `list_playlist_videos` · 1 credit/page\n\nEvery video of a playlist in playlist order. Accepts a `PL...` playlist ID or a URL with `list=`.\n\n| Parameter         | Type    | Default   | Description                                   |\n| ----------------- | ------- | --------- | --------------------------------------------- |\n| `id`              | string  | required* | Playlist ID or URL                            |\n| `limit`           | integer | `100`     | Page size, up to 500 with `ids_only`          |\n| `ids_only`        | boolean | `false`   | Return just `video_ids[]`, up to 500 per page |\n| `next_page_token` | string  |           | Pagination token                              |\n\n### 8. `search_playlist_videos` · 1 credit\n\nFind videos inside a playlist by a substring of the title (case-insensitive). YouTube has no native\nplaylist search, so this scans up to 500 playlist items. `truncated=true` means there may be more\nmatches beyond the scanned window.\n\n| Parameter | Type    | Default  | Description                        |\n| --------- | ------- | -------- | ---------------------------------- |\n| `id`      | string  | required | Playlist ID or URL                 |\n| `q`       | string  | required | Substring to match in video titles |\n| `limit`   | integer | `30`     | Max matches, 1-100                 |\n\n### 9. `submit_transcripts_job` · 1 credit per video\n\nQueue transcripts for MANY videos at once (up to 4,000) and get a `job_id` back immediately. The\nwork continues in the background at your rate limit's pace. Use this instead of calling\n`get_transcript` in a loop for more than a handful of videos.\n\n| Parameter         | Type     | Default      | Description                                          |\n| ----------------- | -------- | ------------ | ---------------------------------------------------- |\n| `videos`          | string[] | **required** | Video IDs or URLs, up to 4,000. Duplicates collapse BEFORE billing |\n| `lang`            | string   | `\"en\"`       | One language for the whole job                       |\n| `format`          | string   | `\"text\"`     | `\"text\"`, `\"json\"`, `\"srt\"`, `\"vtt\"` or `\"srv3\"`, one for the whole job |\n| `kind`            | string   | auto-detect  | `\"manual\"` or `\"auto\"`                               |\n| `segment`         | integer  |              | One segment size for the whole job                   |\n| `video_metadata`  | boolean  | `false`      | Metadata per video, no extra cost                    |\n| `idempotency_key` | string   |              | Resubmitting the same list with the same key returns the SAME job, no double charge |\n\nRequires a user key (`sk_...`). Credits are charged on submit and refunded per video when a video\ncould not be delivered through our fault.\n\n### 10. `get_transcripts_job` · free\n\nProgress of a batch job: status (`queued`/`running`/`done`/`cancelled`), how many videos are ready,\nfailed and pending. Polling a job you already paid for costs nothing.\n\n### 11. `get_transcripts_results` · free\n\nFinished transcripts from a batch job, in the order submitted, paged with `next_page_token`\n(`limit` 1-500, default 100). Results appear as they are fetched, so you can read before the job is\ndone. Each entry is exactly what `get_transcript` returns for that video, plus its status.\n\n### 12. `get_transcripts_result` · free\n\nOne video's result out of a batch job, by its video id, without paging through the whole result\nset. A 404 means the job does not exist or this video has not finished yet, so check\n`get_transcripts_job` before concluding anything.\n\n| Parameter  | Type   | Default      | Description                                    |\n| ---------- | ------ | ------------ | ---------------------------------------------- |\n| `job_id`   | string | **required** | Job id from `submit_transcripts_job`           |\n| `video_id` | string | **required** | One of the video ids the job was submitted with |\n\n### 13. `cancel_transcripts_job` · free\n\nCancel a batch job. Credits are refunded ONLY for videos not started yet. Anything already fetched\nstays in the results and stays paid for.\n\n### 14. `get_credits` · free\n\nThe remaining credit balance of the key, with no parameters. The balance also rides in the\n`X-Credits-Remaining` header of every response, but headers are invisible to the model, so the\nnumber a user actually asks about needs a tool. Handy right before a large batch too, since the\nbatch charges 1 credit per video on submit.\n\n---\n\n## 🔌 Install in your client\n\nThe server is remote, so every install below is a config entry and nothing more. All of them want the same two values, the URL and the Bearer header from [Quick start](#-quick-start).\n\n> **Worth doing once, a standing rule for your client**\n>\n> With this in your client's rules/instructions, pasting a YouTube link is enough and the word\n> \"transcript\" never has to be typed:\n>\n> ```txt\n> Whenever a YouTube link or video ID appears in my message, call the\n> transcriptout get_transcript tool first and answer from the transcript,\n> whether I asked for a summary, a quote, a translation or a question.\n> ```\n\n<details>\n<summary><b>Install in Cursor (One-Click / Manual)</b></summary>\n\n**One-Click Install:**\n\n[![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=transcriptout&config=eyJ1cmwiOiJodHRwczovL2FwaS50cmFuc2NyaXB0b3V0LmNvbS9tY3AifQ==)\n\nAfter installing, open the server settings and add the `Authorization` header with your key.\n\n**Manual configuration** (`~/.cursor/mcp.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"url\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Claude Code (CLI)</b></summary>\n\n```sh\nclaude mcp add --transport http transcriptout https://api.transcriptout.com/mcp \\\n  --header \"Authorization: Bearer YOUR_API_KEY\"\n```\n\n</details>\n\n<details>\n<summary><b>Claude Desktop & Claude Web</b></summary>\n\nClaude's custom connectors authenticate remote servers via OAuth, which TranscriptOut does not\noffer yet (API keys only). On desktop, use **Claude Code** (see above), which supports API-key\nheaders. OAuth support is on the roadmap. Watch the [changelog](https://transcriptout.com/changelog).\n\n</details>\n\n<details>\n<summary><b>Install in VS Code</b></summary>\n\n[<img alt=\"Install in VS Code\" src=\"https://img.shields.io/badge/VS_Code-Install_TranscriptOut_MCP-0098FF?style=for-the-badge&logo=visualstudiocode&logoColor=white\">](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%7B%22name%22%3A%22transcriptout%22%2C%22url%22%3A%22https%3A%2F%2Fapi.transcriptout.com%2Fmcp%22%7D)\n\nOr add this to VS Code user settings (`settings.json`):\n\n```json\n\"mcp.servers\": {\n  \"transcriptout\": {\n    \"type\": \"http\",\n    \"url\": \"https://api.transcriptout.com/mcp\",\n    \"headers\": {\n      \"Authorization\": \"Bearer YOUR_API_KEY\"\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in OpenAI Agent Builder</b></summary>\n\n1. Create a new Agent\n2. Under \"Actions\" or \"Tools\", add a new **MCP Server**\n3. URL: `https://api.transcriptout.com/mcp`\n4. Auth Type: **API Key**\n5. Paste your API key from the [dashboard](https://transcriptout.com/dashboard)\n\n</details>\n\n<details>\n<summary><b>Install in Windsurf</b></summary>\n\nAdd to `~/.codeium/windsurf/mcp_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"serverUrl\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Cline</b></summary>\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"url\": \"https://api.transcriptout.com/mcp\",\n      \"type\": \"streamableHttp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Zed</b></summary>\n\nIn Zed `settings.json`:\n\n```json\n{\n  \"context_servers\": {\n    \"transcriptout\": {\n      \"source\": \"remote\",\n      \"url\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Roo Code</b></summary>\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"type\": \"streamable-http\",\n      \"url\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Amp</b></summary>\n\n```sh\namp mcp add transcriptout https://api.transcriptout.com/mcp --header \"Authorization: Bearer YOUR_API_KEY\"\n```\n\n</details>\n\n<details>\n<summary><b>Install in Augment Code</b></summary>\n\nIn `settings.json` under `augment.advanced`:\n\n```json\n\"augment.advanced\": {\n  \"mcpServers\": [\n    {\n      \"name\": \"transcriptout\",\n      \"url\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  ]\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Kilo Code</b></summary>\n\nIn `.kilocode/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"type\": \"streamable-http\",\n      \"url\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in JetBrains AI Assistant</b></summary>\n\nIn Settings → Tools → AI Assistant → MCP:\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"url\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Gemini CLI</b></summary>\n\nIn `~/.gemini/settings.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"httpUrl\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Qwen Coder</b></summary>\n\nIn `~/.qwen/settings.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"httpUrl\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Google Antigravity</b></summary>\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"serverUrl\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Trae</b></summary>\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"url\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in LM Studio</b></summary>\n\nIn `mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"transcriptout\": {\n      \"url\": \"https://api.transcriptout.com/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer YOUR_API_KEY\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Warp</b></summary>\n\nIn Settings → AI → MCP:\n\n```json\n{\n  \"transcriptout\": {\n    \"url\": \"https://api.transcriptout.com/mcp\",\n    \"headers\": {\n      \"Authorization\": \"Bearer YOUR_API_KEY\"\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Install in Perplexity Desktop</b></summary>\n\nIn Settings → Connectors → Advanced:\n\n```json\n{\n  \"url\": \"https://api.transcriptout.com/mcp\",\n  \"headers\": {\n    \"Authorization\": \"Bearer YOUR_API_KEY\"\n  }\n}\n```\n\n</details>\n\n---\n\n## 🧩 Install as an Agent Plugin\n\nThis repository root is a conformant **[Agent Plugins 1.0.0](https://agent-plugins.org/specification)**\npackage, the portable format supported by ChatGPT, Codex, Cursor, GitHub Copilot, Kiro and VS Code.\nOne install gets you the MCP server **and** a bundled `youtube` skill that teaches your agent when\nto use each tool and how not to waste credits.\n\n```text\nplugin.json                # manifest\nmcp.json                   # hosted MCP server, streamable-http\nskills/youtube/SKILL.md    # when + how to use the 14 tools\n```\n\n**VS Code.** Command Palette → **Chat: Install Plugin From Source**, then paste:\n\n```txt\nhttps://github.com/artemchuikin/youtube-mcp\n```\n\nOr register a local clone in `settings.json`:\n\n```json\n\"chat.pluginLocations\": { \"/absolute/path/to/youtube-mcp\": true }\n```\n\n**Cursor.** **Customize** in the sidebar → find the plugin → **Install**. For a local clone:\n\n```bash\ngit clone https://github.com/artemchuikin/youtube-mcp ~/.cursor/plugins/local/transcriptout\n```\n\nThen **Developer: Reload Window**.\n\n**ChatGPT, Codex, GitHub Copilot, Kiro, any other client.** Point your client's plugin mechanism at\nthis repository, or at a local clone. Agent Plugins 1.0.0 standardizes the *package format*, not\ninstallation, so each client owns its own install flow.\n\nThere are **no credentials in this package**, Agent Plugins 1.0.0 forbids embedded secrets. The\nserver authenticates with an API key you add in your client's MCP settings (see\n[Keys and security](#-keys-and-security)). Verify the package yourself:\n\n```bash\ncurl -sO https://agent-plugins.org/schemas/1.0.0/plugin.schema.json\ncurl -sO https://agent-plugins.org/schemas/1.0.0/mcp.schema.json\nnpx ajv-cli@5 validate --spec=draft2020 -s plugin.schema.json -d plugin.json\nnpx ajv-cli@5 validate --spec=draft2020 -s mcp.schema.json    -d mcp.json\n```\n\n---\n\n## 🔑 Keys and security\n\n- A key is shown once, at creation. Keep it in an environment variable and out of version control.\n- A leaked key dies the moment you revoke it in the [dashboard](https://transcriptout.com/dashboard).\n  An account holds up to 20 keys, so give every machine its own.\n- Prefer to stay in the chat? An agent with the companion\n  [youtube-skills](https://github.com/artemchuikin/youtube-skills) installed can open the account\n  and mint the key for you, by email and a 6-digit code, no browser involved.\n- There is no OAuth flow yet, so clients whose connectors cannot send a custom header (Claude\n  Desktop and Claude Web) should go through Claude Code for now.\n\n## 🐳 Run it locally\n\nThe hosted endpoint needs no install, but stdio-only clients, sandboxes and container platforms\nsometimes want a process of their own. The repo carries one: `server.js` is a complete local MCP\nserver (official SDK, stdio transport) whose 14 tools each make one HTTPS call to the TranscriptOut\nREST API — the same shape as any SaaS-backed MCP server.\n\n```bash\n# as a container\ndocker build -t transcriptout-mcp https://github.com/artemchuikin/youtube-mcp.git\ndocker run -i -e TRANSCRIPTOUT_API_KEY=sk_your_key transcriptout-mcp\n\n# or straight from a checkout (Node 20+)\nnpm install && TRANSCRIPTOUT_API_KEY=sk_your_key node server.js\n```\n\nWithout a key it still connects and lists all tools; tool calls answer with a clear 401 that says\nwhere to get one. Tool definitions ship in `tools.json` and refresh from the live catalog at\nstartup when the network allows, so the local list never goes stale.\n\n---\n\n## 🍳 Recipes\n\nEvery prompt below is paste-able as written.\n\n| Use Case                        | Example Prompt                                                                                 |\n| ------------------------------- | ---------------------------------------------------------------------------------------------- |\n| 📝 **Summarize a video**        | \"Summarize the key points from this video: [URL]\"                                              |\n| 🔍 **Research a topic**         | \"Search YouTube for the 5 most-watched videos on neural radiance fields and summarize each.\"      |\n| 🧠 **Study notes**              | \"Create study notes from this MIT lecture series playlist: [PLAYLIST URL]\"                     |\n| ⚖️ **Compare perspectives**     | \"Compare arguments in these two videos: [URL1] [URL2]\"                                         |\n| 🌐 **Translate**                | \"Translate this video's transcript to Spanish: [URL]\"                                          |\n| ✍️ **Repurpose content**        | \"Turn this video into a 1,500-word blog post: [URL]\"                                           |\n| 📡 **Monitor a creator**        | \"Each morning, list new uploads from @kurzgesagt and tell me which to watch.\"                 |\n| 🏛️ **Build a content database** | \"Pull every video ID from @3blue1brown and queue a transcript batch for all of them.\"          |\n| 🎯 **Competitor analysis**      | \"Search inside @fireship for any video about [competitor product] and summarize the takeaways.\" |\n| 🧩 **RAG ingestion**            | \"Fetch this playlist's transcripts as JSON with segment=1000 and load them into the index.\"    |\n\n**The bulk recipe spelled out.** \"Archive a whole channel\" is four tool calls, not a script:\n\n1. `list_channel_videos` with `ids_only=true`: up to 500 video IDs per page\n2. `submit_transcripts_job` with those IDs (up to 4,000, duplicates dropped before billing,\n   `idempotency_key` makes a retry free)\n3. `get_transcripts_job` until `status` is `done`. The job paces itself inside your rate limit\n4. `get_transcripts_results` page by page, readable while the job still runs\n\nAnything the service fails to deliver is refunded per video, so the bill matches the archive.\n\n---\n\n## 💳 Pricing and limits\n\n| Plan             | Price                  | Credits                     | Rate Limit  |\n| ---------------- | ---------------------- | --------------------------- | ----------- |\n| **Free**         | $0                     | 100 on signup (one-time)    | 200 req/min |\n| **Starter**      | $4.49/month            | 1,000/month                 | 200 req/min |\n| **Starter Annual** | $45.29/year (~$3.77/mo) | 1,000/month               | 200 req/min |\n| **Scale**        | slider up to $198.99/mo | up to 100,000/month        | 200 req/min |\n\n- Subscriptions are a slider from 1,000 to 100,000 credits/month in steps of 1,000, and the per-1,000\n  rate falls with volume (10,000/mo is $27.49, not $44.90). The annual discount grows with volume,\n  from ~16% to ~35%.\n- **1 credit = 1 answered request.** Calls that fail before reaching YouTube (validation, rate\n  limit, our capacity) are refunded automatically. The running balance rides in the\n  `X-Credits-Remaining` header.\n- One-time credit packs that never expire can be bought on top of an active subscription.\n- [View pricing](https://transcriptout.com/#pricing) · [Manage billing](https://transcriptout.com/billing)\n\n---\n\n## 🧯 When a call fails\n\n<details>\n<summary><b>Authentication errors (401)</b></summary>\n\n- Verify your API key starts with `sk_`\n- Check for extra spaces when copying\n- Ensure the key is active in your [dashboard](https://transcriptout.com/dashboard)\n- Revoked keys fail immediately. Issue a new one in the dashboard\n</details>\n\n<details>\n<summary><b>No credits (402)</b></summary>\n\n- Check your balance in the [dashboard](https://transcriptout.com/dashboard)\n- Subscribe or buy a credit pack at [transcriptout.com/billing](https://transcriptout.com/billing)\n</details>\n\n<details>\n<summary><b>Video not available (404 / 410 / 451)</b></summary>\n\n- `404`: the video has no captions on the requested language/track, or the ID is wrong. This is a\n  definitive answer, retrying won't change it.\n- `410`: the video was removed.\n- `451`: age-restricted or members-only content.\n</details>\n\n<details>\n<summary><b>Rate limiting (429) and capacity (503)</b></summary>\n\n- Respect the `Retry-After` header. Both are refunded automatically\n- For bulk work use `submit_transcripts_job`: it paces itself inside your rate limit instead of\n  bouncing off it\n</details>\n\n<details>\n<summary><b>Errors are structured</b></summary>\n\nEvery error body is `{\"ok\": false, \"code\": \"...\", \"detail\": \"...\", \"request_id\": \"req_...\"}`.\nBranch on the machine-readable `code`, not on the human text. Include `request_id` when contacting\nsupport.\n</details>\n\n---\n\n## 🌐 Prefer plain REST?\n\nBuilding an app instead of an agent? The same backend ships as a JSON REST API, with the same\nfive transcript formats plus raw file download (`download=true`).\n\n|                 | MCP                    | REST API                                              |\n| --------------- | ---------------------- | ----------------------------------------------------- |\n| **Best for**    | AI assistants & agents | Apps & backend services                               |\n| **Setup**       | Add a URL + key        | Code integration                                      |\n| **Get started** | This README            | [API docs →](https://transcriptout.com/docs)          |\n\nBase URL: `https://api.transcriptout.com/v1`\n\n---\n\n## 🔗 Links\n\n- 🌐 **Website:** [transcriptout.com](https://transcriptout.com)\n- 📚 **Docs:** [transcriptout.com/docs](https://transcriptout.com/docs)\n- 🧰 **Agent skills (same backend, no MCP required):** [github.com/artemchuikin/youtube-skills](https://github.com/artemchuikin/youtube-skills)\n- 💬 **Contact:** support@transcriptout.com\n\n---\n\n## 📇 MCP Registry\n\nThis server is published to the official [Model Context Protocol Registry](https://registry.modelcontextprotocol.io/)\nunder the name:\n\n```\ncom.transcriptout/youtube-transcript-and-youtube-search\n```\n\n---\n\nTranscriptOut is an independent service and is not affiliated with, endorsed by, or sponsored by\nYouTube or Google LLC. \"YouTube\" is a trademark of Google LLC.\n\n<p align=\"center\">\n  <sub>© 2026 TranscriptOut · Released under the <a href=\"./LICENSE\">MIT License</a></sub>\n</p>\n",
  "bytes": 32072,
  "sha": "39e7f344e6f039147fac10bab8f4812319df57a9f01eda67d97ee6d130d1ffcf",
  "repo_slug": "artemchuikin/youtube-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_com_transcriptout_youtube_transcript_and_2bde71f6/readme"
}