youtube-search
Search YouTube by keyword and return structured video metadata (title, URL, channel, views, duration, date) via yt-dlp. No API keys. Triggers on: "search youtube", "find youtube videos", "top youtube videos on", "trending videos on", "youtube results for", "yt search", "/yt-search".
How do I install this agent skill?
npx skills add https://github.com/mathews-tom/armory --skill youtube-searchIs this agent skill safe to install?
- Gen Agent Trust Hubpass
This skill provides YouTube search capabilities by wrapping the yt-dlp command-line tool. It is functional for research tasks but carries a low risk of command injection through the dynamic construction of shell commands and potential indirect prompt injection from processing untrusted video metadata.
- Socketpass
No alerts
- Snykwarn
Risk: MEDIUM · 1 issue
What does this agent skill do?
YouTube Search
Search YouTube by keyword and return structured video metadata — title, URL,
channel, views, duration, upload date. Uses yt-dlp for scraping with no API
keys or OAuth required.
Prerequisites
uv tool install yt-dlp
Verify:
yt-dlp --version
Usage
Basic Search
yt-dlp "ytsearch10:claude code skills" --dump-json --flat-playlist --no-warnings 2>/dev/null \
| jq -r '[.title, .url, .channel, .view_count, .duration_string, .upload_date] | @tsv'
ytsearch10:— search YouTube, return 10 results (adjust number as needed)--dump-json— output metadata as JSON--flat-playlist— don't download, just list--no-warnings— suppress non-error output
Structured JSON Output
yt-dlp "ytsearch5:claude code mcp servers" \
--dump-json --flat-playlist --no-warnings 2>/dev/null \
| jq '{
title: .title,
url: .url,
channel: .channel,
views: .view_count,
duration: .duration_string,
upload_date: .upload_date,
description: (.description // "" | .[0:200])
}'
Search with Sorting
yt-dlp does not support server-side sort. To sort by views or date, capture all results and sort client-side:
# Sort by view count (descending)
yt-dlp "ytsearch20:AI agents 2026" \
--dump-json --flat-playlist --no-warnings 2>/dev/null \
| jq -s 'sort_by(-.view_count) | .[:10][] | {title, url, channel, views: .view_count}'
# Sort by upload date (newest first)
yt-dlp "ytsearch20:claude code tutorial" \
--dump-json --flat-playlist --no-warnings 2>/dev/null \
| jq -s 'sort_by(-.upload_date) | .[:10][] | {title, url, channel, upload_date}'
Search Result Count
The number after ytsearch controls how many results to fetch:
| Pattern | Results |
|---|---|
ytsearch5:query | 5 results |
ytsearch10:query | 10 results (default recommendation) |
ytsearch20:query | 20 results |
ytsearch50:query | 50 results (slow, may hit rate limits) |
Recommendation: Fetch 15-20 results, then filter/sort client-side to the top N the user wants. This provides enough data for meaningful sorting without being excessive.
Workflow
User provides search query
|
v
+---------------------+
| Step 0: Deps check |
+----------+----------+
v
+---------------------+
| Step 1: Search |
| (yt-dlp ytsearch) |
+----------+----------+
v
+---------------------+
| Step 2: Parse JSON |
| (jq formatting) |
+----------+----------+
v
+---------------------+
| Step 3: Present |
| results to user |
+---------------------+
Step 1: Execute Search
yt-dlp "ytsearch${COUNT}:${QUERY}" \
--dump-json --flat-playlist --no-warnings 2>/dev/null
Step 2: Parse and Format
Extract relevant fields with jq. The full metadata object from yt-dlp contains
many fields; the useful subset for search results:
| Field | Description |
|---|---|
.title | Video title |
.url | Full YouTube URL |
.channel | Channel name |
.view_count | Total views (integer) |
.duration_string | Duration as H:MM:SS or MM:SS |
.upload_date | Upload date as YYYYMMDD |
.description | Video description (can be long — truncate) |
.like_count | Likes (may be null) |
.comment_count | Comments (may be null) |
Step 3: Present Results
Format as a markdown table for the user:
yt-dlp "ytsearch10:${QUERY}" \
--dump-json --flat-playlist --no-warnings 2>/dev/null \
| jq -s 'sort_by(-.view_count) | .[] | "| \(.title[:60]) | \(.channel) | \(.view_count) | \(.duration_string) | \(.upload_date) |"' -r
Prefix with a header row:
| Title | Channel | Views | Duration | Date |
|-------|---------|-------|----------|------|
Advanced Patterns
Filter by Duration
# Only videos longer than 10 minutes (600 seconds)
yt-dlp "ytsearch20:deep dive AI agents" \
--dump-json --flat-playlist --no-warnings 2>/dev/null \
| jq -s '[.[] | select(.duration >= 600)] | sort_by(-.view_count) | .[:10][]'
Filter by Recency
# Only videos from the last 30 days
CUTOFF=$(date -v-30d +%Y%m%d 2>/dev/null || date -d "30 days ago" +%Y%m%d)
yt-dlp "ytsearch20:claude code" \
--dump-json --flat-playlist --no-warnings 2>/dev/null \
| jq -s --arg cutoff "$CUTOFF" '[.[] | select(.upload_date >= $cutoff)] | sort_by(-.view_count) | .[]'
Channel-Specific Search
# Search within a specific channel
yt-dlp "ytsearch10:skills site:youtube.com/c/ChannelName" \
--dump-json --flat-playlist --no-warnings 2>/dev/null
Or use the channel URL directly:
yt-dlp "https://www.youtube.com/@ChannelName/search?query=skills" \
--dump-json --flat-playlist --no-warnings 2>/dev/null
Extract URLs Only (for Piping)
# Get just URLs for feeding into other tools (youtube-analysis, notebooklm)
yt-dlp "ytsearch10:claude code MCP" \
--dump-json --flat-playlist --no-warnings 2>/dev/null \
| jq -r '.url'
Composability
This skill produces URLs and metadata that feed into other skills:
- youtube-analysis: Pass URLs to extract transcripts and perform concept analysis
- notebooklm: Pass URLs as sources via
notebooklm source add "URL"
Example pipeline (manual steps, not automated):
/yt-search— discover 10 relevant videos- User reviews and selects videos
- Feed selected URLs into
notebooklm source addoryoutube-analysis
Error Handling
| Error | Cause | Resolution |
|---|---|---|
| No results | Query too specific or misspelled | Broaden the search terms |
| Empty JSON | yt-dlp rate limited by YouTube | Wait a few minutes, retry |
yt-dlp: command not found | Not installed | uv tool install yt-dlp |
| Partial results | Some videos geo-blocked or private | Normal behavior; results are best-effort |
| Timeout | Network or YouTube slowness | Reduce result count or retry |
Limitations
- No server-side sorting: YouTube search results come in relevance order. Sorting by views or date requires fetching extra results and sorting client-side.
- Rate limiting: Aggressive scraping (50+ results, rapid repeated searches) may trigger YouTube rate limits. Space requests apart.
- Metadata completeness: Some fields (
.like_count,.comment_count) may be null for certain videos. Always handle nulls in jq filters. - No authentication: Uses public YouTube data only. Age-restricted or private videos are excluded from results.
- Search relevance: YouTube's search algorithm determines initial ordering. Results may not match exact expectations.
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/mathews-tom/armory/youtube-search">View youtube-search on skillZs</a>