| name | youtube |
| description | Manage your YouTube channel — upload, list, edit metadata, schedule/unschedule videos, set thumbnails, download your own private videos, get transcripts, generate AI chapter summaries, and post comments (with a Chrome-automation playbook for pinning). Use when asked to upload to YouTube, schedule a video, edit video metadata, download a private YouTube video, get a transcript, generate chapters, or post/pin a comment. |
YouTube Channel Management
Use the youtube CLI tool to manage your YouTube channel: upload videos, list uploads, edit metadata, schedule/unschedule publication, set thumbnails, download your own videos (including private ones), get transcripts, and generate AI chapter summaries.
Architecture
Three separate systems:
- YouTube Data API v3 + OAuth 2.0 — upload, list, update, schedule, thumbnails
- yt-dlp + browser cookies — download your own videos (including private)
- youtube_transcript_api + Gemini — transcripts (fetches existing captions) and AI chapter generation
The YouTube Data API does not have a download endpoint for uploaded video files. Download is handled separately via yt-dlp with authenticated cookies. Transcripts are fetched from YouTube's existing captions (no AI needed). Chapter generation uses Google Gemini.
Setup
1. OAuth Credentials (Required for API operations)
Create OAuth 2.0 credentials in the Google Cloud Console:
- Create a project (or use an existing one)
- Enable the YouTube Data API v3
- Create OAuth 2.0 Client ID (type: Desktop app)
- Download the client secret JSON
Provide credentials via one of:
cp ~/Downloads/client_secret_*.json ~/.youtube_client_secret.json
export YOUTUBE_CLIENT_ID="your_client_id"
export YOUTUBE_CLIENT_SECRET="your_client_secret"
export YOUTUBE_CLIENT_SECRETS_FILE="/path/to/client_secret.json"
Then authenticate:
youtube auth
This opens a browser for Google login and saves the token to ~/.youtube_oauth_token.json.
2. yt-dlp (Required for download only)
pip install yt-dlp
brew install yt-dlp
Commands
| Command | Description |
|---|
youtube auth | Authenticate via OAuth 2.0 (opens browser) |
youtube upload | Upload a video with metadata |
youtube list | List your uploaded videos |
youtube update | Edit metadata of an existing video |
youtube schedule | Schedule a private video for future publication |
youtube unschedule | Revert a scheduled video to private draft |
youtube reschedule | Change the scheduled publish time |
youtube set-thumbnail | Set or replace a video thumbnail |
youtube download | Download a video using yt-dlp (supports private videos) |
youtube transcribe | Get transcript of a YouTube video (fetches existing captions) |
youtube chapters | Generate AI chapter summaries using Gemini |
youtube comment | Post a top-level comment on a video (API cannot pin — see Chrome playbook below) |
Not supported: youtube delete — deletion is explicitly excluded. Pinning comments is also not supported by the YouTube Data API; it must be done in Studio UI (see the Chrome automation playbook below).
Note: transcribe and chapters do NOT require YouTube OAuth. transcribe works with any public video. chapters requires GEMINI_API_KEY.
Usage
Upload a Video
youtube upload --file video.mp4 --title "My Video" --description "Description here"
youtube upload --file video.mp4 --title "My Video" --tags "tag1, tag2" --publish-at 2026-04-10T16:00:00Z
youtube upload --file video.mp4 --title "My Video" --privacy public -v
List Uploads
youtube list
youtube list -n 50
youtube list --json
youtube list -v
Update Metadata
youtube update --id VIDEO_ID --title "New Title"
youtube update --id VIDEO_ID --title "New Title" --description "New desc" --tags "a, b, c"
youtube update --id VIDEO_ID --privacy unlisted
youtube update --id VIDEO_ID --category 28
Safe updates: The tool always fetches the current video first, merges your changes, and sends a complete payload — preserving required fields like title and categoryId.
Schedule / Unschedule / Reschedule
youtube schedule --id VIDEO_ID --publish-at 2026-04-10T16:00:00Z
youtube unschedule --id VIDEO_ID
youtube reschedule --id VIDEO_ID --publish-at 2026-04-11T16:00:00Z
Scheduling rules: publishAt only works on private videos that have never been published. You cannot reschedule a previously-public video.
Set Thumbnail
youtube set-thumbnail --id VIDEO_ID --file thumbnail.jpg
Download Videos
By default, youtube download automatically extracts cookies from Chrome for authentication.
This means you just need to be logged into YouTube in Chrome — no manual cookie export needed.
youtube download --id VIDEO_ID
youtube download --url "https://youtu.be/VIDEO_ID"
youtube download --id VIDEO_ID -o ~/Downloads/video.mp4
youtube download --id VIDEO_ID --cookies-from-browser firefox
youtube download --id VIDEO_ID --cookies-from-browser "chrome:/path/to/profile"
youtube download --id VIDEO_ID --cookies ~/cookies.txt
youtube download --id VIDEO_ID --no-cookies
youtube download --id VIDEO_ID -f "bestvideo+bestaudio"
How it works: yt-dlp reads cookies directly from Chrome's cookie database on disk.
You must be logged into YouTube in Chrome. No browser window is opened — it reads the stored cookies programmatically.
For private videos, the Chrome session must be logged into the account that owns the video.
Transcribe Videos
Fetches existing YouTube captions/subtitles — no AI or OAuth needed.
For private/unplayable videos, automatically downloads via yt-dlp (with Chrome cookies) and transcribes locally with Whisper.
youtube transcribe "https://youtu.be/VIDEO_ID"
youtube transcribe VIDEO_ID
youtube transcribe "https://youtu.be/VIDEO_ID" --seconds
youtube transcribe video.mp4
youtube transcribe "https://youtu.be/PRIVATE_VIDEO_ID"
youtube transcribe "https://youtu.be/VIDEO_ID" > transcript.txt
Post a Comment
Posts a top-level comment on a video as the authenticated channel. Uses commentThreads.insert with the youtube.force-ssl scope (already included in the OAuth token).
youtube comment --id VIDEO_ID --text "Your comment text here"
Prints the Thread ID, Comment ID, and a Studio deep link for pinning.
Pinning is NOT available via the API — it's a Studio-UI-only action. Use the Chrome automation playbook below after posting.
Pin a Comment via Chrome Automation
The YouTube Data API exposes no pin endpoint, so pinning requires driving Studio's UI. This playbook is verified end-to-end — follow it to avoid fishing for selectors.
Prerequisites: claude-in-chrome MCP connected and logged into the target YouTube channel in Chrome.
Steps:
- Navigate to
https://studio.youtube.com/video/<VIDEO_ID>/comments in a fresh tab (create one with tabs_create_mcp — never clobber an existing tab).
- Clear the "Response status: Unresponded" filter chip. Studio hides the channel owner's own comments under this filter by default, so your just-posted comment will NOT appear until you clear it.
find query: "Response status filter chip with X to clear" — click the returned ref for the Remove (X) sub-element, not the chip itself.
- Screenshot to confirm your comment from
@<your-handle> is now visible (labeled e.g. "1 minute ago").
- Open the kebab (three-dot) menu on YOUR comment row.
find query: "three-dot kebab action menu button on the <your-handle> comment row".
- Click "Pin" from the dropdown.
find query: "Pin menu item in the action menu dropdown".
- ⚠️ Known quirk: the
find-based click on the Pin menu item sometimes re-opens the dropdown instead of activating the item. If the confirmation dialog doesn't appear, fall back to a coordinate click on the visible "Pin" text — take a screenshot, read the coords, and computer.left_click there. This has been the consistent failure mode across multiple runs.
- Click "Pin" in the "Pin this comment?" confirmation dialog.
find query: "Pin button in the \"Pin this comment?\" confirmation dialog".
- Verify via screenshot — the comment should move to the top and show "📌 Pinned by @<your-handle>".
Parallelization: multiple subagents can pin comments on different videos in parallel. Each agent must create its own fresh tab (tabs_create_mcp) and only operate on that tabId — agents sharing a tab will thrash. Each video has its own independent pinned slot, so there's no cross-video contention.
Generate Chapters
Uses Google Gemini to generate chapter summaries with timestamps.
youtube chapters "https://youtu.be/VIDEO_ID"
youtube chapters video.mp4
Requires: GEMINI_API_KEY environment variable. Get one at https://aistudio.google.com/apikey
Options Reference
Global Options
| Option | Short | Description |
|---|
--verbose | -v | Show progress and debug info |
Upload Options
| Option | Short | Description |
|---|
--file | -f | Path to video file (required) |
--title | -t | Video title (required) |
--description | -d | Video description |
--tags | | Comma-separated tags |
--category | | YouTube category ID (default: 22) |
--privacy | -p | public, private, unlisted (default: private) |
--publish-at | | ISO 8601 timestamp for scheduling |
Update Options
| Option | Short | Description |
|---|
--id | | Video ID (required) |
--title | -t | New title |
--description | -d | New description |
--tags | | New comma-separated tags (replaces existing) |
--category | | New category ID |
--privacy | -p | New privacy status |
Comment Options
| Option | Short | Description |
|---|
--id | | Video ID (required) |
--text | -t | Comment text (required) |
Download Options
| Option | Short | Description |
|---|
--id | | YouTube video ID |
--url | -u | YouTube video URL |
--output | -o | Output file path |
--cookies | | Path to cookies.txt file |
--cookies-from-browser | | Browser name or path (default: chrome). Examples: chrome, firefox, chrome:/path/to/profile |
--format | -f | yt-dlp format string |
--no-cookies | | Skip automatic cookie extraction |
Environment Variables
| Variable | Description |
|---|
YOUTUBE_CLIENT_ID | OAuth 2.0 client ID |
YOUTUBE_CLIENT_SECRET | OAuth 2.0 client secret |
YOUTUBE_CLIENT_SECRETS_FILE | Path to client secret JSON (default: ~/.youtube_client_secret.json) |
YOUTUBE_TOKEN_FILE | Path to stored OAuth token (default: ~/.youtube_oauth_token.json) |
GEMINI_API_KEY | Google Gemini API key (required only for youtube chapters) |
Requirements
- The
hamel package must be installed: pip install hamel
- For download:
yt-dlp must be installed separately
- For chapters:
GEMINI_API_KEY environment variable must be set
- For local MP4 transcription:
openai-whisper and ffmpeg are needed
Troubleshooting
"No OAuth credentials found": Set YOUTUBE_CLIENT_ID and YOUTUBE_CLIENT_SECRET env vars (or place a client_secret JSON file at ~/.youtube_client_secret.json), then run youtube auth.
"Token refresh failed": Your OAuth token has expired. Run youtube auth again to re-authenticate.
"yt-dlp not found": Install with pip install yt-dlp or brew install yt-dlp.
"Video not found or not accessible": Check the video ID is correct and that your authenticated account has access.
"Could not find browser cookies database": Chrome is not at the default location. Specify the profile path: --cookies-from-browser 'chrome:/path/to/profile', or use Firefox: --cookies-from-browser firefox.
"Authentication required for this video": You need to be logged into YouTube in Chrome. Open Chrome, go to youtube.com, sign in, then retry the download.
Scheduling fails: Only private videos that have never been published can be scheduled. If the video was previously public, scheduling will not work.
Complete Setup Walkthrough
If you're starting from scratch on a new machine:
- Install the package:
pip install hamel
- Install yt-dlp (for downloads):
pip install yt-dlp
- Create OAuth credentials:
- Set environment variables:
export YOUTUBE_CLIENT_ID='your-client-id.apps.googleusercontent.com'
export YOUTUBE_CLIENT_SECRET='your-client-secret'
- Authenticate:
youtube auth (opens browser for one-time Google login)
- Verify:
youtube list (should show your uploads)
- For downloads: Make sure you're logged into YouTube in Chrome, then
youtube download --id VIDEO_ID
- For transcripts:
youtube transcribe "https://youtu.be/VIDEO_ID" (no extra setup needed)
- For chapters: Set
GEMINI_API_KEY env var, then youtube chapters "https://youtu.be/VIDEO_ID"