mcpField
Y
youtube-search

youtube-search

github.com/mathews-tomProductivity338122 installsUpdated 1d ago
Repository

About youtube-search

youtube-search is a skill for finding YouTube videos and returning structured metadata such as titles, channels, views, duration, and upload dates. It uses yt-dlp and is intended for users who want to filter, sort, or pass video results to other skills.

Key features

  1. 01YouTube keyword search via yt-dlp
  2. 02Structured video metadata output
  3. 03Client-side sorting by views or date
  4. 04Filtering by duration and upload date
  5. 05Channel-specific search
  6. 06URL extraction for other skills

Use cases

  1. 01Find videos on a topic and compare results
  2. 02Rank search results by views or upload date
  3. 03Locate recent or long-form videos
  4. 04Pass selected video URLs to watch or notebooklm

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/mathews-tom/armory --skill youtube-search

After installing, type/youtube-searchin Claude Code to confirm it loaded.

Bundled filesevals/cases.yaml

Details

From the project README

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:

PatternResults
ytsearch5:query5 results
ytsearch10:query10 results (default recommendation)
ytsearch20:query20 results
ytsearch50:query50 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:

FieldDescription
.titleVideo title
.urlFull YouTube URL
.channelChannel name
.view_countTotal views (integer)
.duration_stringDuration as H:MM:SS or MM:SS
.upload_dateUpload date as YYYYMMDD
.descriptionVideo description (can be long — truncate)
.like_countLikes (may be null)
.comment_countComments (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 (watch, 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:

  • watch: Pass URLs for transcript concepts, timestamped visual evidence, and question-driven video analysis
  • notebooklm: Pass URLs as sources via notebooklm source add "URL"

Example pipeline (manual steps, not automated):

  1. /yt-search — discover 10 relevant videos
  2. User reviews and selects videos
  3. Feed selected URLs into notebooklm source add or watch

Error Handling

ErrorCauseResolution
No resultsQuery too specific or misspelledBroaden the search terms
Empty JSONyt-dlp rate limited by YouTubeWait a few minutes, retry
yt-dlp: command not foundNot installeduv tool install yt-dlp
Partial resultsSome videos geo-blocked or privateNormal behavior; results are best-effort
TimeoutNetwork or YouTube slownessReduce 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.

Comments

Markdown supported