{
  "markdown": "# youtube-mcp\n\nOAuth-authenticated YouTube MCP for channel owners. Edit video metadata, reply to and moderate comments, manage playlists, query channel analytics, and generate or set AI thumbnails via a ComfyUI bridge. Goes beyond the read-only Data API v3 wrappers that dominate this space.\n\n[![youtube-mcp MCP server](https://glama.ai/mcp/servers/miller-joe/youtube-mcp/badges/card.svg)](https://glama.ai/mcp/servers/miller-joe/youtube-mcp)\n\n[![GitHub Sponsors](https://img.shields.io/github/sponsors/miller-joe?style=social&logo=github)](https://github.com/sponsors/miller-joe)\n[![Ko-fi](https://img.shields.io/badge/Ko--fi-Support-ff5e5b?logo=kofi&logoColor=white)](https://ko-fi.com/indivisionjoe)\n\n## The pitch\n\nMost existing YouTube MCPs use an API key against Data API v3. Search videos, fetch public metadata, read-only. This one uses OAuth 2.0 (Authorization Code + PKCE) so it can actually write to your channel: update video titles, descriptions and tags, reply to comments, moderate spam, manage playlists. It also hits the separate YouTube Analytics API for channel stats, and generates a thumbnail via ComfyUI and pushes it to YouTube in a single MCP call.\n\n```\nClaude, use generate_and_set_thumbnail on video abc123:\n  prompt: \"cyberpunk hacker at keyboard, neon blue and pink, high contrast\"\n```\n\nComfyUI renders 1280×720, youtube-mcp fetches the bytes, and POSTs to `thumbnails.set`. Done.\n\n## Install\n\n```bash\n# npx, no install\nnpx @miller-joe/youtube-mcp --help\n\n# Docker\ndocker run -p 9120:9120 \\\n  -e YOUTUBE_CLIENT_ID=... \\\n  -e YOUTUBE_CLIENT_SECRET=... \\\n  -e YOUTUBE_TOKEN_FILE=/token/token.json \\\n  -v $PWD/token:/token \\\n  ghcr.io/miller-joe/youtube-mcp:latest\n```\n\n## Setup: Google Cloud one-time (~10 min)\n\n1. **Google account plus YouTube channel.** Use a personal account, not a workspace one you might lose.\n2. **Google Cloud project** at https://console.cloud.google.com. Call it whatever you want (e.g. `youtube-mcp`).\n3. **Enable APIs:**\n   - YouTube Data API v3\n   - YouTube Analytics API\n4. **OAuth consent screen:** External, App name, support email. In Scopes, add:\n   - `youtube.upload`\n   - `youtube.force-ssl`\n   - `yt-analytics.readonly`\n5. Stay in **Testing** mode. Add yourself as a **test user** (required). As the project owner, your refresh token won't expire.\n6. **Create OAuth Client ID:** Application type = **Desktop app**. Download the JSON.\n7. **Run the interactive auth flow:**\n\n   ```bash\n   npx @miller-joe/youtube-mcp --auth --client-secret-file ./client_secret.json\n   ```\n\n   A browser opens, you log in to the Google account tied to your YouTube channel, and grant the requested scopes. On success, a refresh token is saved to `~/.config/youtube-mcp/token.json`.\n\n8. **Start the server:**\n\n   ```bash\n   npx @miller-joe/youtube-mcp --client-secret-file ./client_secret.json\n   ```\n\n   Or provide the client credentials via env: `YOUTUBE_CLIENT_SECRET_FILE`, or `YOUTUBE_CLIENT_ID` + `YOUTUBE_CLIENT_SECRET`.\n\n## Connect an MCP client\n\n```bash\nclaude mcp add --transport http youtube http://localhost:9120/mcp\n```\n\nOr point your MCP gateway at the Streamable HTTP endpoint.\n\n## Configuration\n\n| CLI flag | Env var | Default | Notes |\n|---|---|---|---|\n| `--client-secret-file` | `YOUTUBE_CLIENT_SECRET_FILE` | (none) | Path to Google OAuth JSON |\n| `--client-id` | `YOUTUBE_CLIENT_ID` | (none) | Alternative to the secret file |\n| `--client-secret` | `YOUTUBE_CLIENT_SECRET` | (none) | Alternative to the secret file |\n| `--token-file` | `YOUTUBE_TOKEN_FILE` | `~/.config/youtube-mcp/token.json` | Refresh token storage |\n| `--host` | `MCP_HOST` | `0.0.0.0` | Bind host (HTTP mode only) |\n| `--port` | `MCP_PORT` | `9120` | Bind port (HTTP mode only) |\n| `--stdio` | `MCP_TRANSPORT=stdio` | (unset) | Speak MCP over stdio instead of HTTP. Use when launched as a subprocess by a stdio-first MCP client (Claude Desktop, mcp-inspector). |\n| `--comfyui-url` | `COMFYUI_URL` | *(unset, bridge disabled)* | ComfyUI HTTP URL for bridge tools |\n| (no flag) | `COMFYUI_DEFAULT_CKPT` | `sd_xl_base_1.0.safetensors` | Default checkpoint for bridge tool |\n\n### Transports\n\nThe server speaks streamable HTTP by default (great for Claude Code, MetaMCP, raw `fetch`). Pass `--stdio` (or set `MCP_TRANSPORT=stdio`) to switch into stdio mode, which is what stdio-first clients like Claude Desktop and the MCP Inspector expect:\n\n```json\n// claude_desktop_config.json\n{\n  \"mcpServers\": {\n    \"youtube\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@miller-joe/youtube-mcp\", \"--stdio\"],\n      \"env\": {\n        \"YOUTUBE_CLIENT_SECRET_FILE\": \"/path/to/client_secret.json\",\n        \"YOUTUBE_TOKEN_FILE\": \"/path/to/token.json\"\n      }\n    }\n  }\n}\n```\n\nStdio mode skips the OAuth-token preflight check — the server boots even without a stored token and surfaces auth errors at tool-call time. Run `youtube-mcp --auth --client-secret-file <path>` once in HTTP mode to seed the refresh token before pointing Claude Desktop at it.\n\n## Tools\n\n### Videos\n\n- `list_my_videos`: paginated list of the authenticated channel's uploads.\n- `get_video`: full detail for one video.\n- `update_video_metadata`: title, description, tags, category, privacy.\n- `delete_video`: permanently delete a video. Requires `confirm_video_title` to match the current title exactly, as a guard against deleting the wrong video.\n\n### Captions\n\n- `list_captions`: list caption tracks on a video (language, name, status, draft flag).\n- `upload_caption`: upload an SRT or WebVTT caption track to a video.\n- `delete_caption`: delete a caption track.\n\n### Shorts\n\n- `list_my_shorts`: find Shorts in recent uploads (filters by duration ≤60s).\n- `get_shorts_analytics`: YouTube Analytics query restricted to Shorts (`creatorContentType==SHORTS`).\n\n### Playlists\n\n- `create_playlist`: create a playlist (default private).\n- `add_to_playlist`: add a video to an existing playlist.\n\n### Comments\n\n- `list_comments`: top-level comment threads on a video.\n- `reply_to_comment`: reply to a top-level comment.\n- `moderate_comment`: hold, approve, or reject a comment.\n\n### Analytics\n\n- `query_channel_analytics`: date-ranged metrics with optional dimensions and filters.\n\n### Bridge (when `COMFYUI_URL` is configured)\n\n- `generate_and_set_thumbnail`: generate a thumbnail via ComfyUI and set it on a video in one call.\n\n## Quota notes\n\nYouTube Data API free tier = 10,000 units/day. Key operation costs:\n\n- `videos.list`, `commentThreads.list`: 1 unit each.\n- `videos.update`, `comments.insert`, `thumbnails.set`: 50 units each.\n- `videos.insert` (upload): 1,600 units, so about 6 uploads per day on the free tier.\n\nMost creator-ops workflows stay well under the free cap.\n\n## Architecture\n\n```\n┌────────────────┐     ┌──────────────────┐     ┌─────────────────┐\n│  MCP client    │────▶│  youtube-mcp     │────▶│  YouTube APIs   │\n│  (Claude etc.) │◀────│  (this server)   │◀────│  (Data/Analytics)│\n└────────────────┘     └────────┬─────────┘     └─────────────────┘\n                                │\n                                │ (bridge tools only)\n                                ▼\n                       ┌──────────────────┐\n                       │  ComfyUI         │\n                       │  (txt2img)       │\n                       └──────────────────┘\n```\n\nOAuth refresh tokens are cached locally and refreshed just-in-time before expiry. The bridge tool downloads image bytes from ComfyUI internally, so ComfyUI does not need to be publicly reachable.\n\n## Development\n\n```bash\ngit clone https://github.com/miller-joe/youtube-mcp\ncd youtube-mcp\nnpm install\nnpm run dev\nnpm run build\nnpm test\n```\n\nRequires Node 20+.\n\n## Roadmap\n\nShipped:\n\n- Videos: list, get, update metadata, delete with title-match confirm guard.\n- Captions: upload, list, delete.\n- Shorts: `list_my_shorts` (duration filter) and `get_shorts_analytics` (creatorContentType==SHORTS).\n- Playlists: create, add-to.\n- Comments: list, reply, moderate.\n- Analytics: channel analytics query.\n- ComfyUI thumbnail bridge: `generate_and_set_thumbnail`.\n\nPlanned:\n\n- Video upload (`video_upload`) with resumable-upload support.\n- Reporting API for bulk historical data exports.\n\n## License\n\nMIT © Joe Miller\n\n## Support\n\nIf this saves you time, consider supporting development:\n\n[![GitHub Sponsors](https://img.shields.io/github/sponsors/miller-joe?style=social&logo=github)](https://github.com/sponsors/miller-joe)\n[![Ko-fi](https://img.shields.io/badge/Ko--fi-Support-ff5e5b?logo=kofi&logoColor=white)](https://ko-fi.com/indivisionjoe)\n",
  "bytes": 8504,
  "sha": "39b7f536b2e13955373b471799c2c2a7b812f552ae885711b49a4df37fb82917",
  "repo_slug": "miller-joe/youtube-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_miller_joe_youtube_mcp_3aafbfc3/readme"
}