Search YouTube in bulk, grab transcripts, get embed snippets — for the photo-keywords-to-blog-post workflow.
A trimmed read-only YouTube Data API v3 CLI built for local research workflows. Bulk search from stdin, transcript fetching via timedtext (no OAuth needed), embed snippet generation, and a heuristic-based videos related that still works despite the 2023 deprecation.
Learn more at YouTube Data API v3.
Sample use case: justinwfu/pictovideo — photo-keywords → candidate-video → embedded blog draft pipeline using this CLI.
Created by @justinwfu (Justin).
The recommended path installs both the youtube-pp-cli binary and the pp-youtube agent skill (Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, and other agents supported by the upstream skills CLI) in one shot:
npx -y @mvanhorn/printing-press-library install youtubeFor CLI only (no skill):
npx -y @mvanhorn/printing-press-library install youtube --cli-onlyFor skill only — installs the skill into the same agents as the default command above, but skips the CLI binary (use this to update or reinstall just the skill):
npx -y @mvanhorn/printing-press-library install youtube --skill-onlyTo constrain the skill install to one or more specific agents (repeatable — agent names match the skills CLI):
npx -y @mvanhorn/printing-press-library install youtube --agent claude-code
npx -y @mvanhorn/printing-press-library install youtube --agent claude-code --agent codexIf npx isn't available (no Node, offline), install the CLI directly via Go (requires Go 1.26.4 or newer):
go install github.com/mvanhorn/printing-press-library/library/media-and-entertainment/youtube/cmd/youtube-pp-cli@latestThis installs the CLI only — no skill.
Download a pre-built binary for your platform from the latest release. On macOS, clear the Gatekeeper quarantine: xattr -d com.apple.quarantine <binary>. On Unix, mark it executable: chmod +x <binary>.
Install the CLI binary first. The installer writes binaries to a per-user managed bin directory by default: $HOME/.local/bin on macOS/Linux and %LOCALAPPDATA%\Programs\PrintingPress\bin on Windows.
npx -y @mvanhorn/printing-press-library install youtube --cli-onlyThen install the focused Hermes skill.
From the Hermes CLI:
hermes skills install mvanhorn/printing-press-library/cli-skills/pp-youtube --forceInside a Hermes chat session:
/skills install mvanhorn/printing-press-library/cli-skills/pp-youtube --forceRestart the Hermes session or gateway if the newly installed skill is not visible immediately.
Install both the CLI binary and the focused OpenClaw skill. The installer defaults binaries to a per-user bin directory ($HOME/.local/bin on macOS/Linux, %LOCALAPPDATA%\Programs\PrintingPress\bin on Windows):
npx -y @mvanhorn/printing-press-library install youtube --agent openclawRestart the OpenClaw session or gateway if the newly installed skill is not visible immediately.
This CLI ships an MCPB bundle — Claude Desktop's standard format for one-click MCP extension installs (no JSON config required).
To install:
- Download the
.mcpbfor your platform from the latest release. - Double-click the
.mcpbfile. Claude Desktop opens and walks you through the install. - Fill in
YOUTUBE_API_KEYwhen Claude Desktop prompts you.
Requires Claude Desktop 1.0.0 or later. Pre-built bundles ship for macOS Apple Silicon (darwin-arm64) and Windows (amd64, arm64); for other platforms, use the manual config below.
Manual JSON config (advanced)
If you can't use the MCPB bundle (older Claude Desktop, unsupported platform), install the MCP binary and configure it manually.
Install the MCP binary from this CLI's published public-library entry or pre-built release.
Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"youtube": {
"command": "youtube-pp-mcp",
"env": {
"YOUTUBE_API_KEY": "<your-key>"
}
}
}
}API-key only — set YOUTUBE_API_KEY and you're done. Read-only public-data operations only (10,000 quota units/day default). Write operations are not configured; this CLI is for discovery and research, not channel management.
# Verify the API key and reachability.
youtube-pp-cli doctor
# Single-term search.
youtube-pp-cli youtube search-list --q "sourdough scoring" --max-results 5 --json
# Bulk search from positional args — the photo-keywords -> videos shape (use --stdin to read from a file/pipe instead).
youtube-pp-cli youtube search-bulk "sourdough scoring" "latte art" --top 3 --json
# Fetch the transcript to verify topic relevance before picking the video.
youtube-pp-cli youtube videos-transcript dQw4w9WgXcQ --lang en
# Get a markdown embed snippet for the blog draft.
youtube-pp-cli youtube videos-embed dQw4w9WgXcQ --format markdown
# Find more candidates similar to a video you've already picked.
youtube-pp-cli youtube videos-related dQw4w9WgXcQ --limit 5
- Enum flag values aren't validated client-side. Flags like
--order,--safe-search,--video-duration, and similar carry a "one of:" hint in--help, but the CLI passes whatever string you supply straight to the API. An invalid value comes back as an HTTP 400 from YouTube rather than a local "unknown value" error. Use the documented values from--helpto avoid the round-trip.
These capabilities aren't available in any other tool for this API.
-
youtube search-bulk— Take a list of search terms from stdin or args, return top-N YouTube videos per term in one JSON document with titles, channels, embed URLs, and thumbnails.When you have N search terms from an upstream pipeline (image labels, photo tags, scraped keywords), reach for this instead of looping single searches.
youtube-pp-cli youtube search-bulk "sourdough scoring" "latte art" --top 3
-
youtube videos-transcript— Fetch the spoken-content transcript of a YouTube video using the timedtext endpoint. Works for auto-generated and manual captions on any public video. Caches into the local store.Read the transcript before deciding whether a candidate video actually fits the topic of the blog post or photo.
youtube-pp-cli youtube videos-transcript dQw4w9WgXcQ --lang en --json
-
youtube videos-embed— Print embed HTML, iframe, or markdown-style embed for a video ID. Direct copy-paste into a blog draft.Once you've picked a video for the blog, get the embed snippet without remembering the exact iframe URL pattern.
youtube-pp-cli youtube videos-embed dQw4w9WgXcQ --format markdown
-
youtube videos-related— Find videos related to a target video using topicDetails + same-channel + tag overlap from the local store. Best-effort replacement for the deprecated relatedToVideoId parameter.When one candidate video is on-topic but you want more like it, this is the working stand-in for the deprecated parameter.
youtube-pp-cli youtube videos-related dQw4w9WgXcQ --limit 10 --json
-
youtube videos-comments— Fetch top comments on a video, ranked locally by likeCount. Pulls up to 5 pages from commentThreads.list and sorts so most-liked floats regardless of API order.Use to gauge whether a video is actually well-received before embedding, or to surface viewer-supplied context the description doesn't mention.
youtube-pp-cli youtube videos-comments dQw4w9WgXcQ --top 10
-
youtube channel-uploads— List a channel's most recent uploads in one call. Resolves @handle or channelId, walks the auto-generated uploads playlist, returns video IDs + titles + publish times.Replaces the manual two-step lookup. Pairs naturally with --for-handle workflows.
youtube-pp-cli youtube channel-uploads @veritasium --top 10
Run youtube-pp-cli --help for the full command reference and flag list.
youtube-pp-cli youtube channels-list- List channels by--id,--for-handle,--for-username,--mine, or--managed-by-me.youtube-pp-cli youtube comment-threads-list- List top-level comment threads, filterable by video, channel, or thread id.youtube-pp-cli youtube playlist-items-list- List items in a playlist by--playlist-idor--id.youtube-pp-cli youtube playlists-list- List playlists by--channel-id,--id, or--mine.youtube-pp-cli youtube search-list- Search videos, channels, and playlists with full filter support (--q,--order,--type, etc.).youtube-pp-cli youtube videos-list- List videos by--id,--chart, or--my-rating.
youtube-pp-cli youtube search-bulk- Search multiple terms in one call; top-N per term.youtube-pp-cli youtube videos-transcript- Fetch a video's transcript via timedtext (no OAuth).youtube-pp-cli youtube videos-embed- Print HTML, iframe, or markdown embed snippet for a video.youtube-pp-cli youtube videos-related- Find related videos via topic + channel + tag overlap (replaces deprecatedrelatedToVideoId).youtube-pp-cli youtube videos-comments- Top comments on a video, ranked locally by likeCount.youtube-pp-cli youtube channel-uploads- List a channel's most recent uploads in one call (resolves@handle→ uploads playlist).
# Human-readable table (default in terminal, JSON when piped)
youtube-pp-cli youtube channels-list
# JSON for scripting and agents
youtube-pp-cli youtube channels-list --json
# Filter to specific fields
youtube-pp-cli youtube channels-list --json --select id,name,status
# Dry run — show the request without sending
youtube-pp-cli youtube channels-list --dry-run
# Agent mode — JSON + compact + no prompts in one flag
youtube-pp-cli youtube channels-list --agentThis CLI is designed for AI agent consumption:
- Non-interactive - never prompts, every input is a flag
- Pipeable -
--jsonoutput to stdout, errors to stderr - Filterable -
--select id,namereturns only fields you need - Previewable -
--dry-runshows the request without sending - Read-only by default - this CLI does not create, update, delete, publish, send, or mutate remote resources
- Offline-friendly - sync/search commands can use the local SQLite store when available
- Agent-safe by default - no colors or formatting unless
--human-friendlyis set
Exit codes: 0 success, 2 usage error, 3 not found, 4 auth error, 5 API error, 7 rate limited, 10 config error.
youtube-pp-cli doctorVerifies configuration, credentials, and connectivity to the API.
Config file: ~/.config/youtube-pp-cli/config.toml
Static request headers can be configured under headers; per-command header overrides take precedence.
Environment variables:
| Name | Kind | Required | Description |
|---|---|---|---|
YOUTUBE_API_KEY |
per_call | Yes | Set to your API credential. |
Authentication errors (exit code 4)
- Run
youtube-pp-cli doctorto check credentials - Verify the environment variable is set:
echo $YOUTUBE_API_KEYNot found errors (exit code 3) - Check the resource ID is correct
- Run the
listcommand to see available items
videos transcriptreturns RequestBlocked — Run from a residential IP (your laptop). YouTube blocks AWS/GCP/Azure IPs from the timedtext endpoint.videos relatedreturns no results for a fresh video ID — Runyoutube-pp-cli youtube videos-list --id <id> --parts topicDetails,snippetfirst to populate topic/tag data in the local store, then retry.searchreturns HTTP 403 quotaExceeded — Daily quota (10,000 units) is exhausted. search.list costs 100 units per call, videos.list costs 1. Switch to cached results viayoutube-pp-cli sql \"SELECT * FROM search_results WHERE query='...'\".
This CLI was built by studying these projects and resources:
- Bin-Huang/youtube-data-cli — JavaScript
- pauling-ai/youtube-mcp-server — Python
- jdepoix/youtube-transcript-api — Python
- djthorpe/ytapi — Go
Generated by CLI Printing Press