{"_id":"@thenavidm/youtube-mcp-cli","_rev":"4-d32c333dd53ef30508a86b20d8c1eceb","name":"@thenavidm/youtube-mcp-cli","dist-tags":{"latest":"3.0.2"},"versions":{"2.0.0":{"name":"@thenavidm/youtube-mcp-cli","version":"2.0.0","keywords":["mcp","model-context-protocol","youtube","youtube-api","transcript","mcp-server","claude","claude-code","ai-agents","llm-tools","cli","youtube-cli"],"author":{"url":"https://navid.me","name":"Navid Moazzez"},"license":"MIT","_id":"@thenavidm/youtube-mcp-cli@2.0.0","maintainers":[{"name":"thenavidm","email":"n@navid.me"}],"homepage":"https://navid.me","bugs":{"url":"https://github.com/thenavidm/youtube-mcp-cli/issues"},"bin":{"youtube-cli":"dist/index.js","youtube-mcp":"dist/index.js"},"dist":{"shasum":"613146b782bbf4b515ff067f56c8aa1c57fa8cbb","tarball":"https://registry.npmjs.org/@thenavidm/youtube-mcp-cli/-/youtube-mcp-cli-2.0.0.tgz","fileCount":58,"integrity":"sha512-BgTxbkoKF+OjM4fYaDiezxgCFs1iDmjfv5/0pw1h2UoHm6zXL2MTH5sQYi10/ZpJhtSMwkVWZRJMmdTwuap/rQ==","signatures":[{"sig":"MEUCIQDxVZLgK5z4C4NxtR+pSADVSQUkETKsZUEgkb7qqLxICAIgTAGlk8sh7BNVNl63iBnE3kx1qgGRyJvWlHJplHuXY+k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":276885},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"b93378ac64c690a7a7c3776703964d167f7386be","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit","build:mcpb":"bash desktop-extension/build.sh","test:watch":"vitest","check:counts":"node scripts/check-counts.mjs","prepublishOnly":"npm run build"},"_npmUser":{"name":"thenavidm","email":"n@navid.me"},"repository":{"url":"git+https://github.com/thenavidm/youtube-mcp-cli.git","type":"git"},"_npmVersion":"10.9.8","description":"YouTube MCP server and CLI for Claude Code, Codex and AI agents. 16 tools for transcripts, search, channel research, comments, analytics and multi-channel management.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"zod":"^3.23.8","zod-to-json-schema":"^3.24.1","@modelcontextprotocol/sdk":"^1.18.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.7.0","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/youtube-mcp-cli_2.0.0_1790492477933_0.7510610750418005","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"@thenavidm/youtube-mcp-cli","version":"3.0.0","keywords":["mcp","model-context-protocol","youtube","youtube-api","transcript","mcp-server","claude","claude-code","ai-agents","llm-tools","cli","youtube-cli","mcp-cli","transcripts","youtube-data-api","slipway"],"author":{"url":"https://navid.me","name":"Navid Moazzez"},"license":"MIT","_id":"@thenavidm/youtube-mcp-cli@3.0.0","maintainers":[{"name":"thenavidm","email":"n@navid.me"}],"homepage":"https://navid.me","bugs":{"url":"https://github.com/thenavidm/youtube-mcp-cli/issues"},"bin":{"youtube-cli":"dist/index.js","youtube-mcp":"dist/index.js","youtube-mcp-cli":"dist/npx.js"},"dist":{"shasum":"c27a2aea98878b083df40d5b4e7182b52bf43ebd","tarball":"https://registry.npmjs.org/@thenavidm/youtube-mcp-cli/-/youtube-mcp-cli-3.0.0.tgz","fileCount":67,"integrity":"sha512-Mmokut/x8Ea2w9vWi9V0LV+7JUr0HbaKr6VxpxUx+78arZyoFxH3DxEvfJvob5cmcbxTRG5wuzq2RyyNuEckWg==","signatures":[{"sig":"MEUCICdVVOFEDmD9g5eTb+66trvpU6+7LGpEDPCyz4BE8N5BAiEAw96pzFfcCb1gIlSDW+OQHaPM3v6uO2RcrLZQtzBf30Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIC4tbt314Y7n3b70gz542SjcJ04939BnwlVk/BDwcR/VAiAIHAwpzXOBs/RvGioQRnw/6KL0OzG5Tgj6TqkqFsRq5g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":287335},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"gitHead":"b910dd30935f5a57c88cd89a4aac01450f25d637","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit","build:mcpb":"bash desktop-extension/build.sh","test:watch":"vitest","check:counts":"node scripts/check-counts.mjs","prepublishOnly":"npm run build"},"_npmUser":{"name":"thenavidm","email":"n@navid.me"},"repository":{"url":"git+https://github.com/thenavidm/youtube-mcp-cli.git","type":"git"},"_npmVersion":"10.9.8","description":"YouTube MCP server and CLI for Claude Code, Codex and AI agents. 16 tools for transcripts, search, channel research, comments, analytics and multi-channel management.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"zod":"^4.2.0","@thenavidm/slipway":"^0.1.10"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.7.0","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/youtube-mcp-cli_3.0.0_1791168234001_0.13591649323314736","host":"s3://npm-registry-packages-npm-production"}},"3.0.1":{"name":"@thenavidm/youtube-mcp-cli","version":"3.0.1","keywords":["mcp","model-context-protocol","youtube","youtube-api","transcript","mcp-server","claude","claude-code","ai-agents","llm-tools","cli","youtube-cli","mcp-cli","transcripts","youtube-data-api","slipway"],"author":{"url":"https://navid.me","name":"Navid Moazzez"},"license":"MIT","_id":"@thenavidm/youtube-mcp-cli@3.0.1","maintainers":[{"name":"thenavidm","email":"n@navid.me"}],"homepage":"https://navid.me","bugs":{"url":"https://github.com/thenavidm/youtube-mcp-cli/issues"},"bin":{"youtube-cli":"dist/index.js","youtube-mcp":"dist/index.js","youtube-mcp-cli":"dist/npx.js"},"dist":{"shasum":"0b7aea742b6067f714ea4a435d834a7d33476de2","tarball":"https://registry.npmjs.org/@thenavidm/youtube-mcp-cli/-/youtube-mcp-cli-3.0.1.tgz","fileCount":52,"integrity":"sha512-YwhuQWjosiSoy4Z8Zmk7IGSNg55n/EByfc7/NsCRyPfVCBObQ7vmdlmqZ2I4hYwUZ8+deijR+fIdamEqggo4Gw==","signatures":[{"sig":"MEUCIQDR1Xz082Zf7Wn4bMvl4jBafTBCsUAK08d2jbnqHPO/xgIgNmuf1gTOR09idq5HtSXDvMW+kdntNauYyGr3l7fisXg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCD42O2h8CbTAx8pYCgLcED5fG6e1fJC2wmQLCX/ZIcOAIgFxVh+fQ7FJle4fvdZSQ+1mD060UN30aGdxVP5r6Nqq0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":230774},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"gitHead":"be8ef4715a3a976caa805c91963d8406cf2159b9","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit","build:mcpb":"bash desktop-extension/build.sh","test:watch":"vitest","check:counts":"node scripts/check-counts.mjs","prepublishOnly":"node -e \"fs.rmSync('dist', { recursive: true, force: true })\" && npm run build"},"_npmUser":{"name":"thenavidm","email":"n@navid.me"},"repository":{"url":"git+https://github.com/thenavidm/youtube-mcp-cli.git","type":"git"},"_npmVersion":"10.9.8","description":"YouTube MCP server and CLI for Claude Code, Codex and AI agents. 16 tools for transcripts, search, channel research, comments, analytics and multi-channel management.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"zod":"^4.2.0","@thenavidm/slipway":"^0.1.10"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.7.0","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/youtube-mcp-cli_3.0.1_1791170195477_0.6980472244692548","host":"s3://npm-registry-packages-npm-production"}},"3.0.2":{"_id":"@thenavidm/youtube-mcp-cli@3.0.2","bin":{"youtube-cli":"dist/index.js","youtube-mcp":"dist/index.js","youtube-mcp-cli":"dist/npx.js"},"bugs":{"url":"https://github.com/thenavidm/youtube-mcp-cli/issues"},"dist":{"shasum":"e6a8647f31128673fdd90e585e6c9c51a2c2b16a","tarball":"https://registry.npmjs.org/@thenavidm/youtube-mcp-cli/-/youtube-mcp-cli-3.0.2.tgz","fileCount":52,"integrity":"sha512-VNfjGGzdxZSREVJl9z/ehJZ9h5vo3Zo5ThTvRQYMiUJ+LHqaH1SgHajrbOhu7VoiQ1dJwPjzTjMH5aGJiZT5dA==","signatures":[{"sig":"MEUCIBGGeENrpyd4i7zYDVUDUv/RipRz8YkOhF2iv949incBAiEAriilMeu/sYfCwgOH+K/c4JeryN7Kan55rBNLgvpQOJQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICRtBvbljDCkW6ecGtzgXMJ82oE4JtrTFYo22d7MB35KAiEA2FIzkiBZQ5K6Vie5OfmLiOa7Dtlxyp1tEhEKa9z4Dho="}],"unpackedSize":230801},"main":"./dist/index.js","name":"@thenavidm/youtube-mcp-cli","type":"module","types":"./dist/index.d.ts","author":{"url":"https://navid.me","name":"Navid Moazzez"},"engines":{"node":">=22"},"gitHead":"a6fa0a30e3b36edb68dab501e0e3b8b05328b198","license":"MIT","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit","build:mcpb":"bash desktop-extension/build.sh","test:watch":"vitest","check:counts":"node scripts/check-counts.mjs","prepublishOnly":"node -e \"fs.rmSync('dist', { recursive: true, force: true })\" && npm run build"},"version":"3.0.2","_npmUser":{"name":"thenavidm","email":"n@navid.me"},"homepage":"https://navid.me","keywords":["mcp","model-context-protocol","youtube","youtube-api","transcript","mcp-server","claude","claude-code","ai-agents","llm-tools","cli","youtube-cli","mcp-cli","transcripts","youtube-data-api","slipway"],"repository":{"url":"git+https://github.com/thenavidm/youtube-mcp-cli.git","type":"git"},"_npmVersion":"10.9.8","description":"YouTube MCP server and CLI for Claude Code, Codex and AI agents. 16 tools for transcripts, search, channel research, comments, analytics and multi-channel management.","directories":{},"maintainers":[{"name":"thenavidm","email":"n@navid.me"}],"_nodeVersion":"22.23.1","dependencies":{"zod":"^4.2.0","@thenavidm/slipway":"^0.1.17"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.7.0","@types/node":"^22.10.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/youtube-mcp-cli_3.0.2_1791188891205_0.24351654864048333"}}},"time":{"created":"2026-09-27T07:01:17.706Z","modified":"2026-10-05T08:28:11.434Z","2.0.0":"2026-09-27T07:01:18.077Z","3.0.0":"2026-10-05T02:43:54.095Z","3.0.1":"2026-10-05T03:16:35.573Z","3.0.2":"2026-10-05T08:28:11.284Z"},"bugs":{"url":"https://github.com/thenavidm/youtube-mcp-cli/issues"},"author":{"url":"https://navid.me","name":"Navid Moazzez"},"license":"MIT","homepage":"https://navid.me","keywords":["mcp","model-context-protocol","youtube","youtube-api","transcript","mcp-server","claude","claude-code","ai-agents","llm-tools","cli","youtube-cli","mcp-cli","transcripts","youtube-data-api","slipway"],"repository":{"url":"git+https://github.com/thenavidm/youtube-mcp-cli.git","type":"git"},"description":"YouTube MCP server and CLI for Claude Code, Codex and AI agents. 16 tools for transcripts, search, channel research, comments, analytics and multi-channel management.","maintainers":[{"name":"thenavidm","email":"n@navid.me"}],"readme":"<img src=\"https://cdn.navid.me/connectors/youtube-icon.png\" alt=\"YouTube\" width=\"88\">\n\n# YouTube MCP Server & CLI\n\n[![npm](https://img.shields.io/npm/v/@thenavidm%2Fyoutube-mcp-cli?color=orange&label=npm)](https://www.npmjs.com/package/@thenavidm/youtube-mcp-cli)\n[![License](https://img.shields.io/badge/License-MIT-green)](./LICENSE)\n[![YouTube](https://img.shields.io/badge/YouTube-@thenavidm-red?logo=youtube&logoColor=white)](https://youtube.com/@thenavidm?sub_confirmation=1)\n[![X](https://img.shields.io/badge/X-@thenavidm-black?logo=x)](https://x.com/thenavidm)\n[![LinkedIn](https://img.shields.io/badge/LinkedIn-thenavidm-0A66C2?logo=linkedin&logoColor=white)](https://linkedin.com/in/thenavidm)\n\nYouTube MCP server and CLI for Claude Code and AI agents. 16 tools for transcripts, search, channel research, comments, analytics and multi-channel management.\n\nOne install gives you both surfaces, the same tools under the same names.\n\nRead the transcript of any public YouTube video, with nothing set up. Search\nresults come back with view counts attached, which YouTube's own search endpoint\ndoes not return.\n\nConnect as many channels as you run, with one login each and no config file.\n\nBuilt and maintained by [Navid Moazzez](https://navid.me?utm_source=github&utm_medium=referral&utm_campaign=youtube-mcp-cli&utm_content=readme). Built on [Slipway](https://github.com/thenavidm/slipway), which turns one definition of each tool into the MCP server and the CLI.\n\n```\nYou: what does this video actually say about pricing?\n     https://youtu.be/dQw4w9WgXcQ\n\nClaude: [search_transcript] Three mentions.\n\n        [2:14] \"we never charge for the first seat\"\n        [7:41] \"the pricing page is deliberately one number\"\n        [11:02] \"annual is not a discount, it is a commitment\"\n\n        Jump straight to 7:41 for the reasoning.\n```\n\n## Two ways to use it\n\n### Command line\n\n`youtube-cli` in your terminal, for scripting, cron, pipes, or a quick question\nwithout opening anything:\n\n```bash\nyoutube-cli                                                  # every command, one line each\nyoutube-cli get-transcript --video https://youtu.be/dQw4w9WgXcQ\nyoutube-cli list-transcript-languages dQw4w9WgXcQ\nyoutube-cli search-videos \"local-first software\"             # with view counts\nyoutube-cli list-comments --video-id dQw4w9WgXcQ --limit 20\nyoutube-cli login                                            # connect a channel, once each\nyoutube-cli list-my-videos --account thenavidm --limit 10\nyoutube-cli <command> --help                                 # what any command takes\n```\n\n`--confirm` is the shell spelling of the confirmation that replying to a comment\nand deleting a video require. `--agent` gives compact JSON with no prompts, and\nerrors are JSON on stderr whichever output you pick.\n\n`youtube-cli schema <command>` prints the exact JSON Schema an MCP client\nreceives for that tool, which is how you can check the two surfaces really are\none thing.\n\n### MCP server, for your AI app\n\n`youtube-mcp` is what Claude Code, Claude Desktop, Cursor and the rest launch.\nYou never run it by hand:\n\n```bash\nclaude mcp add youtube -- npx -y @thenavidm/youtube-mcp-cli@latest\n```\n\nThen just ask: _\"which of this channel's last 30 videos actually overperformed?\"_\n\nReplying to a comment and deleting a video wait for your approval in the client,\nas [section 9](#9-writing-safely-) explains.\n\nChannels you connected with `youtube-cli login` on this machine are read\nautomatically, so the command needs no credentials. Every other client is in\n[section 4](#4-connect-your-client-).\n\n### Which one\n\n| Where you are | What you can reach |\n|---|---|\n| An agent that can run shell commands, like Claude Code or Cursor | Both. The CLI is the cheaper one: it costs almost nothing until you type it |\n| claude.ai, the Claude Desktop chat tab, or a phone | The server only. There is no shell to run a command in |\n| A terminal, a script, cron or CI | The CLI only. There is no MCP client in a shell |\n\nThey are the same program reading the same tool definitions, so anything one\ncan do, the other can.\n\n## Features\n\nEvery tool is both a command and an MCP tool, with the same name. The command\nis the tool name with dashes.\n\n| Capability | CLI command | MCP tool |\n|---|---|---|\n| Transcripts of any public video, no credentials | `youtube-cli get-transcript` / `get-transcripts` / `search-transcript` / `list-transcript-languages` | `get_transcript` / `get_transcripts` / `search_transcript` / `list_transcript_languages` |\n| Research any channel or video | `youtube-cli search-videos` / `get-channel` / `analyze-channel` / `get-video` | `search_videos` / `get_channel` / `analyze_channel` / `get_video` |\n| Your channels and their numbers | `youtube-cli list-accounts` / `get-my-channel` / `get-channel-analytics` / `list-my-videos` | `list_accounts` / `get_my_channel` / `get_channel_analytics` / `list_my_videos` |\n| Comments | `youtube-cli list-comments` / `reply-to-comment` | `list_comments` / `reply_to_comment` |\n| Edit or delete your videos | `youtube-cli update-video` / `delete-video` | `update_video` / `delete_video` |\n| Connect a channel or an API key | `youtube-cli login` / `logout` | not tools |\n| Check your setup | `youtube-cli doctor` | not a tool |\n\nAll 16 are in [section 7](#7-tools-%EF%B8%8F).\n\n## Contents\n\n| # | Section | What is in it |\n|---|---|---|\n| 1 | [What you can ask it](#1-what-you-can-ask-it-) | Real prompts, not features |\n| 2 | [Quick install](#2-quick-install-) | One line, no account needed |\n| 3 | [Set up your account](#3-set-up-your-account-) | API key, then your channels |\n| 4 | [Connect your client](#4-connect-your-client-) | Claude, Cursor, Windsurf, the rest |\n| 5 | [Check it worked](#5-check-it-worked-) | And the two things that fail |\n| 6 | [Which surface, and what each costs](#6-which-surface-and-what-each-costs-) | Measured in Claude Code, and how to spend less |\n| 7 | [Tools](#7-tools-%EF%B8%8F) | All 16, grouped by what they need |\n| 8 | [Output and exit codes](#8-output-and-exit-codes-) | What scripts branch on |\n| 9 | [Writing safely](#9-writing-safely-) | What is guarded and what is not |\n| 10 | [Several channels](#10-several-channels-) | Login once each, pick by name |\n| 11 | [Notes and gotchas](#11-notes-and-gotchas-%EF%B8%8F) | How YouTube really behaves |\n| 12 | [Your data](#12-your-data-) | What is stored, and where |\n| 13 | [Troubleshooting](#13-troubleshooting-) | Symptom to cause |\n| 14 | [FAQ](#14-faq-) | Including what an MCP server is |\n\n## 1. What you can ask it 💬\n\n- Summarize this video in five bullets.\n- Find where she talks about retention in this talk.\n- Pull the transcripts of these six videos and tell me what the openings have in common.\n- Which of this channel's last 30 videos actually overperformed?\n- Compare how these two channels title their videos.\n- Show me videos about local-first software from the last year with over 50,000 views.\n- Read the comments on this video and group them by what people are asking for.\n- What did my last video do on watch time versus the one before?\n- Fix the typo in the title of that video.\n- Which of my videos are still unlisted?\n\nThe one thing that is impossible without this: reading what was said in somebody\nelse's video. YouTube's Captions API only serves videos you own, so every\nofficial route stops at your own channel. Transcripts here come from the public\ncaption tracks instead, so any public video is readable, and it needs no\ncredentials at all.\n\n## 2. Quick install ⚡\n\nNode 20 or newer, and `yt-dlp` for transcripts.\n\n```bash\nnpx -y @thenavidm/youtube-mcp-cli@latest --version\n```\n\nThat is the whole install for an MCP client. `npx` fetches it on demand, so\nthere is nothing to update later.\n\nFor the command line, install it globally:\n\n```bash\nnpm install -g @thenavidm/youtube-mcp-cli\nyoutube-cli\n```\n\nThat gives you two commands: `youtube-mcp` is the server your AI tools launch,\n`youtube-cli` is the one you type. They are one program, and the name only\ndecides what happens when you pass no arguments.\n\nTranscripts also need `yt-dlp`, because YouTube stopped serving caption text\ndirectly:\n\n```bash\nbrew install yt-dlp        # macOS\npipx install yt-dlp        # everywhere else\n```\n\n### Before you start\n\n| You need | Check with | If missing |\n|---|---|---|\n| Node 20 or newer | `node -v` | [nodejs.org](https://nodejs.org) |\n| yt-dlp, for transcripts | `yt-dlp --version` | `brew install yt-dlp` or `pipx install yt-dlp` |\n| A Google Cloud project, for search and your channels | [console.cloud.google.com](https://console.cloud.google.com) | Free, no card, see section 3 |\n\n## 3. Set up your account 🔑\n\nThree levels. Pick the one that matches what you want, because most people never\nneed the third.\n\n**Transcripts need nothing.** Skip this whole section. It already works.\n\n**Search, research and comments need an API key.** About ten minutes.\n\n**Your own channels need OAuth.** About half an hour, most of it forms.\n\n[INSTALL.md](INSTALL.md) is the long version, with every click and every failure\nworth knowing about in advance.\n\n### An API key\n\n1. In the [Google Cloud console](https://console.cloud.google.com), create a project.\n2. In **APIs & Services > Library**, enable **YouTube Data API v3**. Add\n   **YouTube Analytics API** too if you will want watch time later.\n3. In **APIs & Services > Credentials**, choose **Create credentials > API key**,\n   then click **Restrict key** and limit it to the YouTube APIs.\n4. Save it:\n\n```bash\nyoutube-cli login --api-key AIza...\n```\n\nIt is stored encrypted on this machine, and every MCP client here picks it up.\nOn another machine, set `YOUTUBE_API_KEY` in the client config instead.\n\n### Your own channels\n\n1. Go to **Google Auth platform > Branding**, click **Get Started**, choose\n   **External** as the audience, and finish.\n2. Open **Audience**, and under **Test users** add the Google address that owns\n   each channel. Skipping this is the single most common reason login fails.\n3. Go to **Google Auth platform > Clients**, click **Create Client**, choose\n   **Desktop app**, and copy the client ID and secret.\n4. Connect each channel:\n\n```bash\nexport YOUTUBE_CLIENT_ID=...apps.googleusercontent.com\nexport YOUTUBE_CLIENT_SECRET=...\nyoutube-cli login\n```\n\nA browser opens, you pick the channel, and it is saved. **Run `youtube-cli\nlogin` once per channel.** Then `youtube-cli list-accounts` shows them all.\n[Section 10](#10-several-channels-) covers using several.\n\nYou do not need Google to verify the app, but do click **Publish app** under\n**Audience**. An app left in testing issues refresh tokens that expire after\nseven days, so login would stop working every week.\n\n## 4. Connect your client 🔌\n\nEvery block below is complete on its own. Pick your client, paste, done.\n\nIf you ran `youtube-cli login` on the same machine, leave the `env` block out\nentirely: the server reads your saved channels and API key itself. Otherwise put\nin whichever of these you have: `YOUTUBE_API_KEY`, and for your channels\n`YOUTUBE_CLIENT_ID`, `YOUTUBE_CLIENT_SECRET` and `YOUTUBE_ACCOUNTS` (the entry\n`youtube-cli login --print` prints).\n\n### Claude Code\n\n```bash\nclaude mcp add youtube -- npx -y @thenavidm/youtube-mcp-cli@latest\n```\n\nWith credentials in the environment instead:\n\n```bash\nclaude mcp add youtube \\\n  -e YOUTUBE_API_KEY=your-key \\\n  -e YOUTUBE_CLIENT_ID=your-client-id \\\n  -e YOUTUBE_CLIENT_SECRET=your-client-secret \\\n  -e YOUTUBE_REFRESH_TOKEN=your-refresh-token \\\n  -- npx -y @thenavidm/youtube-mcp-cli@latest\n```\n\nRun `/mcp` inside Claude Code and `youtube` should be listed. Remove it later\nwith `claude mcp remove youtube`.\n\n### Claude Desktop\n\nThe quickest route is the extension: download the\n[`.mcpb`](https://github.com/thenavidm/youtube-mcp-cli/releases/latest) and\ndouble-click it. It carries its own dependencies and asks for your API key and\nchannels in a form, so there is no config file to edit.\n\nTo wire it up by hand instead, open **Settings**, then **Developer**, then\n**Edit Config**. That reveals `claude_desktop_config.json`. Or go straight there:\n\n| System | Config file |\n|---|---|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\nOn macOS, `open -e ~/Library/Application\\ Support/Claude/claude_desktop_config.json`\nopens it in TextEdit.\n\nIf the file is empty, paste all of this. If you ran `youtube-cli login`, drop\nthe `env` block:\n\n```json\n{\n  \"mcpServers\": {\n    \"youtube\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@thenavidm/youtube-mcp-cli@latest\"],\n      \"env\": {\n        \"YOUTUBE_API_KEY\": \"your-key\"\n      }\n    }\n  }\n}\n```\n\nIf the file already has other servers, add only the `\"youtube\"` block inside\n`\"mcpServers\"` and put a comma after the entry before it. One bad comma stops\nevery server loading, not just this one.\n\nThen quit Claude Desktop completely and reopen it. On macOS use **Cmd+Q**,\nclosing the window is not enough. It only reads that file at startup.\n\nTo confirm, open a new chat, click the tools icon and look for `youtube`, then\nask: _\"list the caption languages of https://youtu.be/dQw4w9WgXcQ\"_.\n\n> [!TIP]\n> Claude Desktop does not inherit your shell PATH, so if `npx` is not found, run\n> `which npx` and use that absolute path as `command`.\n\nWhen it does not show up, the log says why:\n\n| System | Log |\n|---|---|\n| macOS | `tail -f ~/Library/Logs/Claude/mcp*.log` |\n| Windows | `%APPDATA%\\Claude\\logs\\` |\n\nThe two usual causes are Node not being on the PATH the app sees, which the tip\nabove fixes, and malformed JSON, which a missing or extra comma causes.\n\n### Cursor\n\nEdit `~/.cursor/mcp.json` for every project, or `.cursor/mcp.json` inside one:\n\n```json\n{\n  \"mcpServers\": {\n    \"youtube\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@thenavidm/youtube-mcp-cli@latest\"]\n    }\n  }\n}\n```\n\nThen reload the window: **Cmd+Shift+P**, **Developer: Reload Window**. The\nserver appears under **Settings > MCP**.\n\n### Windsurf\n\nEdit `~/.codeium/windsurf/mcp_config.json`, with the same `mcpServers` block as\nCursor. Then press the refresh button in the MCP panel, or restart Windsurf.\n\n### VS Code\n\nRun **MCP: Add Server** from the command palette, or create `.vscode/mcp.json`\nin a project:\n\n```json\n{\n  \"servers\": {\n    \"youtube\": {\n      \"type\": \"stdio\",\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@thenavidm/youtube-mcp-cli@latest\"]\n    }\n  }\n}\n```\n\nVS Code shows a **Start** link above the entry. Click it, then open Copilot Chat\nin agent mode and the tools are listed.\n\n### Anything else\n\nZed, Cline, Continue and any other MCP client over stdio all work. They each\nwant the same three things: `command` (`npx`), `args`\n(`[\"-y\", \"@thenavidm/youtube-mcp-cli@latest\"]`), and `env`.\n\n### Docker\n\nNo image is published, so build it yourself. The image includes `yt-dlp`.\n\n```bash\ngit clone https://github.com/thenavidm/youtube-mcp-cli.git && cd youtube-mcp-cli\ndocker build -t youtube-mcp-cli .\ndocker run -i --rm -e YOUTUBE_API_KEY=your-key youtube-mcp-cli\n```\n\nA container cannot read the channels you saved on the host, so pass them as\n`YOUTUBE_ACCOUNTS`, with `YOUTUBE_CLIENT_ID` and `YOUTUBE_CLIENT_SECRET`.\n\n### Self-hosted over HTTP\n\nFor a machine that is always on:\n\n```bash\nYOUTUBE_HTTP_TOKEN=a-long-random-string youtube-mcp --http --port=8787\n```\n\nIt binds to `127.0.0.1` and serves `/health`. To reach it from elsewhere, set\n`YOUTUBE_HTTP_HOST=0.0.0.0` together with `YOUTUBE_HTTP_TOKEN`, and put it\nbehind TLS.\n\n> [!CAUTION]\n> The HTTP transport holds live credentials for your channels. A connected\n> refresh token can delete videos. Binding it beyond localhost without a token\n> hands your channels to anyone who finds the port.\n\n## 5. Check it worked 🩺\n\n```bash\nyoutube-cli doctor\n```\n\nOr, without a global install, `npx -y @thenavidm/youtube-mcp-cli@latest doctor`.\n\nIt reports each layer separately, transcripts, the API key, then every channel\nby name, so you can see how far you got.\n\nTwo failures happen far more than the rest. **`yt-dlp not found`** means\ntranscripts cannot work until you install it, though everything else still will.\n**`unauthorized_client`** on a channel means that token was issued by a different\nOAuth client than the one used now, which reads like a revoked grant but is\nnot: check the client before reconnecting anything.\n\n## 6. Which surface, and what each costs 💰\n\nBoth surfaces are the same program with the same 16 tools. The\ndifference is when the model pays for them. Measured in Claude Code:\n\n| Cost | MCP server | CLI |\n|---|---|---|\n| Every message, with every tool loaded | 4,500 tokens | nothing |\n| Every message, Claude Code's default | 490 tokens | nothing |\n| When YouTube comes up | nothing more, or the tools it picks | 2,350 tokens for `SKILL.md`, once |\n| 20 messages with YouTube in 1, every tool loaded | 90,000 tokens | 2,350 tokens |\n\nClaude Code's [tool search](https://code.claude.com/docs/en/mcp#scale-with-mcp-tool-search)\nis on by default: it sends only the tool names and the server instructions,\nand loads a tool's full definition when the model reaches for it. An app that\nloads every tool up front pays the first line on every message, whether\nYouTube comes up or not. With the skill added, Claude Code also lists its\none-line description, about 160 tokens.\n\nTo spend less, turn the server off when you are not using it, which in Claude\nCode is the `/mcp` panel. `YOUTUBE_READ_ONLY=1` takes the 3 write tools off the list, leaving 13.\nOr install the CLI and add the server on the days it earns its place.\n\nMeasured on 2026-10-05 with Claude Code 2.1.286 on Claude Opus 5.5: one\nshort prompt with and without the server connected, once with\n`ENABLE_TOOL_SEARCH=false` and once with the default, the difference read\nfrom the API's own usage figures. `SKILL.md` was measured the same way. Other\napps and models count tokens a little differently.\n\nAgainst 2.0.0, measured the same day: every tool loaded costs 4,458 tokens\ninstead of 4,984, tool search 489 instead of 493, and `SKILL.md` 93 more,\nbecause it now says how approval works over MCP and lists every exit code. In\nCodex 0.159.3 on gpt-6.1-sol, the same task, \"find the command that scores a\nchannel's recent videos against that channel's own median, and the flags it\nrequires\", read a median of 83,295 input tokens on 3.0.0 against 83,565 on\n2.0.0 over the CLI, five runs each: Codex now asks `which` instead of reading\nthe full command list, and the general help is shorter. Over MCP, Codex prints\nthe tool list with a script and answers from that printout, 6,133 tokens on\n3.0.0 against 6,126; the 7 more are the description of `confirm` on the two\nirreversible tools. The input totals, a median of 45,053 against 44,924, also\ncarry the model's reasoning into its second request, which three of the five\n2.0.0 runs skipped; the two that kept it read 45,065 and 45,074.\n\n## 7. Tools 🛠️\n\nEvery tool is also a command: the tool name with dashes. `*` marks a write, `!`\none that needs `--confirm` in the terminal or `confirm: true` through MCP.\n\n### Transcripts\n\nNo credentials. Reads any public video.\n\n| Command | MCP tool | What it does |\n|---|---|---|\n| `get-transcript` | `get_transcript` | The full transcript, as prose or timestamped lines |\n| `list-transcript-languages` | `list_transcript_languages` | Every caption language, and whether it is auto-generated |\n| `search-transcript` | `search_transcript` | Find a phrase, get timestamps that link to the second |\n| `get-transcripts` | `get_transcripts` | Up to 20 videos in one call |\n\n### Research\n\nNeeds an API key. Reads anyone's public data.\n\n| Command | MCP tool | What it does |\n|---|---|---|\n| `search-videos` | `search_videos` | Search, with view counts and duration joined on |\n| `get-channel` | `get_channel` | Subscribers, total views, video count, uploads playlist |\n| `analyze-channel` | `analyze_channel` | Recent videos scored against that channel's own median |\n| `get-video` | `get_video` | Full detail for one video |\n\n### Your channels\n\nNeeds `youtube-cli login`. `list-comments` also works on any public video with\njust an API key.\n\n| Command | MCP tool | What it does |\n|---|---|---|\n| `list-accounts` | `list_accounts` | Every connected channel |\n| `get-my-channel` | `get_my_channel` | Your exact subscriber count, not the rounded public one |\n| `get-channel-analytics` | `get_channel_analytics` | Watch time, retention, traffic sources, subscriber change |\n| `list-my-videos` | `list_my_videos` | Your videos, including private and unlisted |\n| `list-comments` | `list_comments` | Comment threads on a video |\n| `update-video` * | `update_video` | Title, description, tags, privacy |\n| `reply-to-comment` ! | `reply_to_comment` | A public reply |\n| `delete-video` ! | `delete_video` | Permanent |\n\nThat is 13 read tools and 3 write tools.\n\n### Setup commands\n\nThese belong to the command line only, since they are what you run before\nanything works.\n\n| Command | What it does |\n|---|---|\n| `youtube-cli login` | Connect a channel through OAuth. Run once per channel |\n| `youtube-cli login --api-key KEY` | Save an API key for search and research |\n| `youtube-cli logout <channel>` | Forget a saved channel |\n| `youtube-cli doctor` | Check every layer of the setup |\n\n## 8. Output and exit codes 📤\n\nEverything a script needs to branch on.\n\n| Flag | What you get |\n|---|---|\n| none | compact text for reads, shaped for a model and readable in a terminal |\n| `--json` | JSON, always |\n| `--compact` | the same JSON on one line |\n| `--agent` | compact JSON, no prompts, no color, in one flag |\n| `--select a,b.c` | only the named fields of a JSON result, dotted paths descend |\n\nResults go to stdout. Errors go to stderr, always as JSON, so one parse handles\nboth outcomes. `code` names the kind of failure, and `hint` and `details`, such\nas Google's own reason, come along when there is one:\n\n```json\n{\n  \"error\": \"No API key is configured. Run `youtube-cli login --api-key KEY` or set YOUTUBE_API_KEY for public data, or `youtube-cli login` for your own channels.\",\n  \"code\": \"not_configured\"\n}\n```\n\n| Code | Means |\n|---|---|\n| `0` | it worked |\n| `1` | an unexpected error |\n| `2` | you typed it wrong, an unknown command, a write hidden by `YOUTUBE_READ_ONLY`, or a guarded write refused for want of `--confirm` |\n| `3` | not found |\n| `4` | authentication failed: reconnect the channel |\n| `5` | an API error upstream |\n| `7` | rate limited or out of quota: wait |\n| `10` | nothing configured: run `youtube-cli login` or `login --api-key`, or install yt-dlp for transcripts |\n\nSo a script can tell a mistake it should fix from a failure it should retry:\n\n```bash\nyoutube-cli list-comments --video-id \"$ID\" --limit 50 --agent > comments.json\ncase $? in\n  0) ;;\n  7) echo \"quota or rate limit, retry later\" >&2 ;;\n  10) echo \"run youtube-cli login first\" >&2; exit 1 ;;\n  *) echo \"failed\" >&2; exit 1 ;;\nesac\n```\n\n## 9. Writing safely 🛟\n\nWrites work by default, because managing a channel is the point.\n\nTwo tools are guarded: `reply_to_comment`, because it is public the moment it\nlands and notifies someone, and `delete_video`, because YouTube removes a video\nimmediately with no trash and no undo. Both wait for your approval. The CLI goes\nthrough the same guard as the server, so the rules are identical.\n\nOver MCP a person approves each of the two where the client can ask: Claude Code\n(2.1.246 and later) shows its own prompt, and a client that can show forms asks\nwith an approval form whose one box starts unticked. Each approval is signed,\nbound to that exact call and works once. Where a client can do neither, the\nmodel's `confirm: true` counts, and it should pass it only when you asked for\nthat exact reply or delete. `YOUTUBE_CONFIRM=model` makes `confirm: true` enough\neverywhere, for an agent with no person to ask. In a terminal it is `--confirm`,\nwhich `--agent` never adds.\n\n`update_video` is not guarded. A title is one keystroke to put back, and asking\nto approve reversible things teaches people and models to approve everything\nreflexively, which is worse protection than not asking.\n\n| Setting | Effect |\n|---|---|\n| `YOUTUBE_READ_ONLY=1` | Every write disappears from the tool list and the command list |\n| `YOUTUBE_ALLOW_DESTRUCTIVE=0` | `update_video` stays, the two irreversible tools are blocked |\n| `YOUTUBE_AUDIT_LOG=<path>` | One JSON line per attempted write, allowed and blocked alike, and who approved it |\n\nComments, titles, descriptions and transcripts are written by other people. The\ntool descriptions and the shipped `SKILL.md` tell the model to treat them as\ndata, never as instructions. Keep that in mind before wiring this into anything\nthat runs unattended.\n\n## 10. Several channels 📺\n\n### Set them up\n\nRun `youtube-cli login` once per channel, picking a different one in Google's\nchooser each time. Brand channels on the same Google account show up there too.\n\n```bash\nyoutube-cli login        # your main channel\nyoutube-cli login        # the clips channel\nyoutube-cli list-accounts\n```\n\nEach one is saved to `~/.youtube-mcp-cli/channels.json` with the OAuth client\nthat connected it, so channels connected through different clients still work\nside by side.\n\n### Using them\n\nPass `--account` in the terminal, or `account` through MCP:\n\n```bash\nyoutube-cli list-my-videos --account thenavidm\nyoutube-cli get-channel-analytics --account clips --start-date 2026-08-01 --end-date 2026-08-31\n```\n\nWith two or more connected, every account command refuses without it and names\nthe choices. That is deliberate: acting on the wrong channel is not something\nyou can take back, so nothing ever picks one for you.\n\n### How a name is matched\n\nThe saved name is the channel's handle without the `@`, or its title when it\nhas no handle. `--account` matches that exactly first, then the channel title,\nthen a partial match, so `--account navid` finds `thenavidm` when nothing else\ndoes.\n\n### Channels from the environment\n\n`YOUTUBE_ACCOUNTS` (a JSON array) or `YOUTUBE_REFRESH_TOKEN` (one channel) still\nwork, for a container or another machine. They are read alongside the saved\nones, and an environment channel wins over a saved one with the same name.\n\n`youtube-cli logout <name>` forgets a saved channel. Revoke it at\n[Google Account permissions](https://myaccount.google.com/permissions) to cut\naccess completely.\n\n## 11. Notes and gotchas ⚠️\n\n- **YouTube stopped serving caption text directly.** The track URL now answers\n  200 with an empty body unless the request carries a proof-of-origin token. The\n  language list still comes from the watch page; the text comes through `yt-dlp`.\n  That is why it is a dependency rather than a nicety.\n- **Search has its own daily allowance.** 100 calls a day, separate from the\n  10,000-unit pool the other endpoints share. It is almost always search that\n  runs out first, so do not call it speculatively.\n- **Analytics exists only for your own channels.** Watch time, retention and\n  traffic sources are not public for anyone else, at any price. No tool here can\n  work around that, and a proxy metric would be a worse answer than none.\n- **Analytics lags about two days.** An empty result for yesterday usually means\n  the data has not landed yet, not that nothing happened.\n- **Public subscriber counts are rounded.** YouTube rounds above 1,000 in its\n  public API, so `get_channel` and `get_my_channel` disagree on your own channel.\n  The second one is exact.\n- **`update_video` replaces the whole snippet.** Passing only a title would blank\n  the description, so the current values are read back and merged first. This is\n  handled, but it is why the tool makes an extra call.\n- **A refresh token only works with the client that issued it.** Rebuild the\n  OAuth client and every existing token dies with `unauthorized_client`, which\n  looks exactly like a revoked grant and sends people reconnecting in circles.\n- **Video tags are only visible to the owner.** `get_video` shows them on your\n  own videos and returns nothing for anyone else's. The API does this, not a\n  permission you are missing.\n- **Shorts skew channel analysis.** Their view counts are not comparable to\n  long-form on the same channel, so `analyze_channel` flags them rather than\n  quietly averaging them in.\n\n## 12. Your data 💾\n\nThere is no backend. Every request goes from your machine to Google directly,\nand nothing is collected or sent anywhere else.\n\nTwo things are written to disk, both only when you ask:\n\n| What | Where | When |\n|---|---|---|\n| Saved channels and API key | `~/.youtube-mcp-cli/channels.json`, or `YOUTUBE_MCP_HOME` | `youtube-cli login` |\n| Audit log | wherever `YOUTUBE_AUDIT_LOG` points | only when set |\n\nThe channel file is written 0600 and encrypted with AES-256-GCM under a key\nderived from your OS account and this machine, which is never stored. A copied\nfile is useless elsewhere. It is not a vault: code running as you on this\nmachine can derive the same key, which is the same exposure as an environment\nvariable. [SECURITY.md](SECURITY.md) has the detail.\n\n## 13. Troubleshooting 🔧\n\nRun `youtube-cli doctor` first. It checks each layer separately and most answers\nare in its output.\n\n| Symptom | Cause |\n|---|---|\n| `yt-dlp is not installed` | Transcripts need it. `brew install yt-dlp` or `pipx install yt-dlp` |\n| Exit code 10, \"No API key is configured\" | Run `youtube-cli login --api-key KEY`, or set `YOUTUBE_API_KEY` |\n| Exit code 10, \"No account is configured\" | Run `youtube-cli login` for that channel |\n| `redirect_uri_mismatch` at login | The OAuth client is a Web client. Use a Desktop app client, or add `http://localhost:8765/callback` |\n| `Access blocked` at the consent screen | The channel's Google address is not in **Test users** |\n| `unauthorized_client` | The token came from a different OAuth client than the one used now |\n| No refresh token returned | Google issues one on first consent only. Revoke at Google Account permissions, then `youtube-cli login` again |\n| The token dies after seven days | The app is still in testing. Publish it under **Audience**, or log in again |\n| 403, API not enabled | YouTube Data API v3 is off in that Cloud project |\n| 403 on captions or comments | The token predates the `force-ssl` scope. Run `youtube-cli login` again |\n| `quotaExceeded` | The pool resets at midnight Pacific |\n| Search stops working before anything else | Search has its own 100-call daily allowance |\n| HTTP 429 on a transcript | YouTube is rate limiting your IP. Waiting is the only fix |\n| A command refuses and lists your channels | Two or more are connected. Pass `--account` |\n| Every write command has vanished | `YOUTUBE_READ_ONLY=1` is set |\n| Server missing in Claude Desktop | Use the absolute path to `npx`, check the JSON, and fully quit the app |\n| \"will not run without --confirm\" | Working as intended: a reply is public and a delete is permanent. See [section 9](#9-writing-safely-) |\n| `claude -p` will not reply or delete | Headless Claude Code refuses tools that need a person. Give that agent `YOUTUBE_CONFIRM=model` |\n| No approval form appears | The client cannot show forms, so the model's `confirm: true` counts, and only for an action you asked for |\n| YouTube asks yt-dlp to prove it is not a bot | Set `YOUTUBE_YTDLP_COOKIES` to a cookies.txt exported from a browser signed in to YouTube |\n| A piped request gets no answer | Stdin closed before the answer. The MCP stdio binding stops a server when its input ends; keep stdin open until you read the answer, or use the CLI |\n\n## Environment variables\n\nNone are needed for transcripts, and none are needed at all on a machine where\nyou ran `youtube-cli login`.\n\n**Credentials**\n\n| Variable | Default | What it does |\n|---|---|---|\n| `YOUTUBE_API_KEY` | the saved key | Public search, channel lookup and comments |\n| `YOUTUBE_CLIENT_ID` | none | Your OAuth client, needed by `login` and by env channels |\n| `YOUTUBE_CLIENT_SECRET` | none | Its secret |\n| `YOUTUBE_OAUTH_CLIENT_ID` | none | The same, under the other common spelling |\n| `YOUTUBE_OAUTH_CLIENT_SECRET` | none | The same, under the other common spelling |\n| `YOUTUBE_ACCOUNTS` | none | JSON array, several channels at once |\n| `YOUTUBE_REFRESH_TOKEN` | none | One channel |\n| `YOUTUBE_ACCESS_TOKEN` | none | One channel, short-lived, for testing |\n| `YOUTUBE_CHANNEL_NAME` | `default` | What to call that one channel |\n\n**Safety**\n\n| Variable | Default | What it does |\n|---|---|---|\n| `YOUTUBE_READ_ONLY` | `0` | `1` hides every write |\n| `YOUTUBE_ALLOW_DESTRUCTIVE` | `1` | `0` blocks the two irreversible tools |\n| `YOUTUBE_AUDIT_LOG` | none | Append-only log of every attempted write, and who approved it |\n| `YOUTUBE_CONFIRM` | `human` | `model` lets `confirm: true` alone approve over MCP, for an agent with no person to ask |\n\n**Tuning**\n\n| Variable | Default | What it does |\n|---|---|---|\n| `YOUTUBE_REQUEST_TIMEOUT_MS` | `30000` | Per-request deadline |\n| `YOUTUBE_TRANSCRIPT_LANG` | `en` | Default transcript language |\n| `YOUTUBE_YTDLP_PATH` | `yt-dlp` on PATH | Where yt-dlp is |\n| `YOUTUBE_YTDLP_COOKIES` | none | A cookies.txt from a browser signed in to YouTube, for when YouTube asks yt-dlp to prove it is not a bot |\n| `YOUTUBE_MCP_HOME` | `~/.youtube-mcp-cli` | Where `login` saves channels |\n| `YOUTUBE_OAUTH_PORT` | `8765` | The localhost port `login` listens on |\n| `YOUTUBE_HTTP_PORT` | `8787` | For `--http` |\n| `YOUTUBE_HTTP_HOST` | `127.0.0.1` | For `--http` |\n| `YOUTUBE_HTTP_TOKEN` | none | Bearer token for `--http`. Any address but localhost refuses to start without one |\n| `YOUTUBE_HTTP_ALLOWED_ORIGINS` | none | Comma-separated browser origins allowed to connect; a page from any other site is refused |\n| `YOUTUBE_SURFACE` | `full` | `search` lists three tools that find, describe and run the rest |\n| `YOUTUBE_TOOL_TIMEOUT_MS` | none | Give up on any tool after this long |\n| `YOUTUBE_DEBUG` | `0` | `1` prints debug lines on stderr |\n\n## Versions\n\nSee [CHANGELOG.md](CHANGELOG.md).\n\n## 14. FAQ ❓\n\n<details>\n<summary><b>What is an MCP server?</b></summary>\n\nAn MCP server is a standard way to give an AI assistant real access to a tool, so\nit can act rather than guess. You install it once, your assistant gains the\ntools, and it works in Claude, Cursor and anything else speaking MCP.\n\n</details>\n\n<details>\n<summary><b>What is the CLI?</b></summary>\n\n`youtube-cli` is the same program as the MCP server, run as commands. AI agents that run commands, like Claude Code, Codex and OpenCode, use it on their own, and you can type the same commands in a terminal, a script or a cron job. Every tool is a command with dashes, so `get_transcript` runs as `youtube-cli get-transcript`.\n\n</details>\n\n<details>\n<summary><b>Should I use the MCP server or the CLI?</b></summary>\n\nUse the MCP server in an app with no terminal, like Claude Desktop's chat. Use the CLI anywhere commands run: an agent like Claude Code, Codex or OpenCode, a script or a cron job. The MCP server's tools take up context on every message, and the CLI costs nothing until it runs.\n\n</details>\n\n<details>\n<summary><b>What is the YouTube Data API?</b></summary>\n\nThe YouTube Data API is Google's official interface to YouTube, covering videos,\nchannels, playlists and comments. It is what this uses for everything except\ntranscripts, which the API does not offer for videos you do not own.\n\n</details>\n\n<details>\n<summary><b>Do I need to be technical?</b></summary>\n\nYou need to run a command or paste a few lines into a config file. Transcripts\nwork with no setup whatsoever, so you can install it, try it, and only do the\ncredential work if you want search or your own channel.\n\n</details>\n\n<details>\n<summary><b>Can I connect more than one channel?</b></summary>\n\nYou can connect as many as you run. Run `youtube-cli login` once per channel,\nand pass `--account` to pick one. With two or more connected the tools refuse to\nguess, which is deliberate: acting on the wrong channel is not something you can\ntake back.\n\n</details>\n\n<details>\n<summary><b>Is my data sent anywhere?</b></summary>\n\nYour credentials stay on your machine and go only to Google. There is no\nbackend, nothing is collected, and nothing phones anywhere. The code is here to\nread.\n\n</details>\n\n<details>\n<summary><b>What can it do that youtube.com cannot?</b></summary>\n\nIt reads the transcript of any public video as text you can search, compare and\nfeed to a model. The site shows you captions one video at a time. Pulling twenty\ntranscripts to find what their openings have in common is a minute here and an\nafternoon by hand.\n\n</details>\n\n<details>\n<summary><b>Can it delete one of my videos by accident?</b></summary>\n\nIt cannot delete anything without your approval: Claude Code shows its own\nprompt for each delete, a client that can show forms asks with one, and\nelsewhere the model has to pass `confirm: true` deliberately after reading a\ndescription saying the action is permanent. If you want the possibility gone\nentirely, set `YOUTUBE_READ_ONLY=1` and every write disappears.\n\n</details>\n\n<details>\n<summary><b>Does it cost anything?</b></summary>\n\nIt costs nothing. The package is MIT, and the YouTube Data API is free within a\ndaily quota that ordinary use does not come near. Google does not ask for a card.\n\n</details>\n\n<details>\n<summary><b>Does it work with ChatGPT and Cursor?</b></summary>\n\nIt works with any client that speaks MCP, including Cursor, Windsurf and VS Code.\n[Section 4](#4-connect-your-client-) has a block for each one.\n\n</details>\n\n<details>\n<summary><b>What happens when my token expires?</b></summary>\n\nAccess tokens last an hour and are refreshed automatically, so you will not\nnotice. A refresh token lasts until you revoke it, with one exception: an OAuth\napp still in testing issues refresh tokens that expire after seven days. Publish\nthe app to stop that, or run `youtube-cli login` again when it happens.\n\n</details>\n\n<details>\n<summary><b>Can it reply to a comment without me asking?</b></summary>\n\nIt replies when you ask it to. A reply is public the moment it lands and\nnotifies the person you replied to, so each one waits for your approval in the\nclient, as a delete does. `YOUTUBE_READ_ONLY=1` removes replying, editing and\ndeleting from the list entirely.\n\n</details>\n\n<details>\n<summary><b>How do I disconnect it?</b></summary>\n\nRemove the server from your client's config, run `youtube-cli logout` for each\nchannel, and revoke the app at\n[Google Account permissions](https://myaccount.google.com/permissions). Deleting\nthe Cloud project removes the API key and the OAuth client together.\n\n</details>\n\n## Questions\n\nRun into a problem or have a question? [Open an issue](https://github.com/thenavidm/youtube-mcp-cli/issues) and I will help.\n\n## About the author\n\nNavid Moazzez is a leading AI business strategist, and the host of the AI Creator Summit, watched by 100,000+ creators. He helps creators and founders master AI and build their own AI Operating System (AI OS) to automate their business and life. He creates useful free tools, MCP servers and CLIs that creators and founders can use in their own workflows.\n\n**Links**\n\n- Personal website: [navid.me](https://navid.me?utm_source=github&utm_medium=referral&utm_campaign=youtube-mcp-cli&utm_content=readme)\n- Link in bio: [navid.bio](https://navid.bio?utm_source=github&utm_medium=referral&utm_campaign=youtube-mcp-cli&utm_content=readme)\n- Navid Media: [navid.media](https://navid.media?utm_source=github&utm_medium=referral&utm_campaign=youtube-mcp-cli&utm_content=readme)\n- YouTube: [@thenavidm](https://youtube.com/@thenavidm?sub_confirmation=1) and [@thenavidai](https://youtube.com/@thenavidai?sub_confirmation=1)\n- X: [@thenavidm](https://x.com/thenavidm)\n- Instagram: [@thenavidm](https://instagram.com/thenavidm)\n- LinkedIn: [thenavidm](https://linkedin.com/in/thenavidm)\n\nIf this is useful, star the repo and come say hi on [X](https://x.com/thenavidm).\n\n## Dependencies\n\n| Library | License | What it does |\n|---|---|---|\n| [Slipway](https://github.com/thenavidm/slipway) | Apache-2.0 | The MCP server and the CLI from one definition of each tool, with the write guard |\n| [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) | Apache-2.0 | The MCP protocol and transports, through Slipway |\n| [zod](https://github.com/colinhacks/zod) | MIT | Tool argument schemas and validation |\n\n[yt-dlp](https://github.com/yt-dlp/yt-dlp) is an optional external command, used\nonly to fetch caption tracks. It is not bundled and is never loaded into this\nprocess.\n\n## License\n\n[MIT](./LICENSE). Free to use, modify, and share.\n\nNot affiliated with, endorsed by, or connected to Google LLC. YouTube is a\ntrademark of Google LLC.\n\n---\n\n© 2026 [Navid Media](https://navid.media?utm_source=github&utm_medium=referral&utm_campaign=youtube-mcp-cli&utm_content=readme). Made with ❤️ by [Navid Moazzez](https://navid.me?utm_source=github&utm_medium=referral&utm_campaign=youtube-mcp-cli&utm_content=readme).\n","readmeFilename":"README.md"}