Claude
Skills
Sign in
Back

youtube

Included with Lifetime
$97 forever

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.

Image & Video

What this skill does


# 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:

1. **YouTube Data API v3 + OAuth 2.0** — upload, list, update, schedule, thumbnails
2. **yt-dlp + browser cookies** — download your own videos (including private)
3. **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](https://console.cloud.google.com/apis/credentials):

1. Create a project (or use an existing one)
2. Enable the **YouTube Data API v3**
3. Create **OAuth 2.0 Client ID** (type: Desktop app)
4. Download the client secret JSON

Provide credentials via one of:

```bash
# Option A: Place the downloaded JSON file at the default path
cp ~/Downloads/client_secret_*.json ~/.youtube_client_secret.json

# Option B: Set env vars
export YOUTUBE_CLIENT_ID="your_client_id"
export YOUTUBE_CLIENT_SECRET="your_client_secret"

# Option C: Point to your JSON file
export YOUTUBE_CLIENT_SECRETS_FILE="/path/to/client_secret.json"
```

Then authenticate:

```bash
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)

```bash
pip install yt-dlp
# or
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

```bash
# Upload as private (default)
youtube upload --file video.mp4 --title "My Video" --description "Description here"

# Upload with tags and schedule
youtube upload --file video.mp4 --title "My Video" --tags "tag1, tag2" --publish-at 2026-04-10T16:00:00Z

# Upload as public
youtube upload --file video.mp4 --title "My Video" --privacy public -v
```

### List Uploads

```bash
# List recent uploads as a table
youtube list

# List more videos
youtube list -n 50

# Output as JSON
youtube list --json

# Verbose mode (shows tags, category)
youtube list -v
```

### Update Metadata

```bash
# Update title only
youtube update --id VIDEO_ID --title "New Title"

# Update multiple fields
youtube update --id VIDEO_ID --title "New Title" --description "New desc" --tags "a, b, c"

# Change privacy
youtube update --id VIDEO_ID --privacy unlisted

# Change category
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

```bash
# Schedule a private video
youtube schedule --id VIDEO_ID --publish-at 2026-04-10T16:00:00Z

# Unschedule back to private draft
youtube unschedule --id VIDEO_ID

# Reschedule to a new time
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

```bash
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.

```bash
# Download a video (auto-extracts Chrome cookies by default)
youtube download --id VIDEO_ID

# Download by URL
youtube download --url "https://youtu.be/VIDEO_ID"

# Save to specific path
youtube download --id VIDEO_ID -o ~/Downloads/video.mp4

# Use Firefox instead of Chrome
youtube download --id VIDEO_ID --cookies-from-browser firefox

# Specify a custom Chrome profile path
youtube download --id VIDEO_ID --cookies-from-browser "chrome:/path/to/profile"

# Use a cookies.txt file instead
youtube download --id VIDEO_ID --cookies ~/cookies.txt

# Skip cookie extraction (public videos only)
youtube download --id VIDEO_ID --no-cookies

# Choose format
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.

```bash
# Get transcript by URL
youtube transcribe "https://youtu.be/VIDEO_ID"

# Get transcript by video ID
youtube transcribe VIDEO_ID

# Timestamps in seconds format
youtube transcribe "https://youtu.be/VIDEO_ID" --seconds

# Transcribe a local video file (uses Whisper — supports mp4, webm, mkv, etc.)
youtube transcribe video.mp4

# Private videos work too (auto-downloads with Chrome cookies, then transcribes locally)
youtube transcribe "https://youtu.be/PRIVATE_VIDEO_ID"

# Save to file
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).

```bash
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:**

1. **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).
2. **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 

Related in Image & Video