youtube_searchSearch YouTube and filter the results on view count, how recently they were posted, video length, and the channel's subscriber count. Filters combine: a video about X with over 50,000 views, posted in the last month, from a channel with over 80,000 subscribers. Free, no API key. Returns video ids you can pass to youtube_transcript.Input schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"query": {
"type": "string",
"minLength": 1,
"maxLength": 500,
"description": "What to search for, in plain language."
},
"limit": {
"description": "How many results to return after filtering. Defaults to 10.",
"type": "integer",
"minimum": 1,
"maximum": 30
},
"minViews": {
"description": "Drop videos with fewer views than this.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"maxViews": {
"description": "Drop videos with more views than this. Useful for finding smaller creators.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"publishedWithinDays": {
"description": "Drop videos older than this many days. COARSE: YouTube gives a relative string (\"3 weeks ago\"), not a date, so anything inside the current month reads as weeks. Good for \"the past month\", not for \"since the 14th\".",
"type": "integer",
"minimum": 1,
"maximum": 3650
},
"minSubscribers": {
"description": "Drop videos from channels with fewer subscribers than this. Costs one extra request per distinct channel, so it runs last, after the free filters have cut the set.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"minDurationSeconds": {
"description": "Drop videos shorter than this. 60 excludes most Shorts.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"maxDurationSeconds": {
"description": "Drop videos longer than this.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"maxPages": {
"description": "How many result pages to read before giving up. Defaults to 4. Raise it when a narrow filter returns too few.",
"type": "integer",
"minimum": 1,
"maximum": 10
}
},
"required": [
"query"
],
"additionalProperties": false
}Annotations{
"title": "Search YouTube",
"readOnlyHint": true,
"destructiveHint": false,
"openWorldHint": true
} | — | Read onlyNon-destructiveOpen world | — |
youtube_transcriptGet a YouTube video's transcript. Tries the video's own captions first (free, and most videos have them), then Gemini reading the URL (billed), then yt-dlp if installed. Returns the transcript plus which source produced it, so you can tell a human-written caption track from a machine transcription. Accepts any YouTube URL shape or a bare video id.Input schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"url": {
"type": "string",
"minLength": 1,
"maxLength": 2000,
"description": "A YouTube URL (watch, youtu.be, shorts, embed) or a bare 11-character video id."
},
"languages": {
"description": "Preferred caption languages as BCP-47 codes, most wanted first, e.g. [\"en\",\"fr\"]. Defaults to English.",
"maxItems": 5,
"type": "array",
"items": {
"type": "string",
"minLength": 2,
"maxLength": 10
}
},
"timestamps": {
"description": "Prefix each line with [mm:ss]. Only possible from a caption track; a model transcription has no timings.",
"type": "boolean"
},
"allowPaid": {
"description": "Allow the billed Gemini fallback when captions are missing or unusable. Defaults to true. Set false to get captions or nothing, which is the right choice when cost matters more than coverage.",
"type": "boolean"
}
},
"required": [
"url"
],
"additionalProperties": false
}Annotations{
"title": "YouTube transcript",
"readOnlyHint": false,
"destructiveHint": false,
"openWorldHint": true
} | — | WritesNon-destructiveOpen world | — |
youtube_transcript_doctorCheck what this server can actually do right now: which caption clients answer, whether a transcription key is configured, and whether yt-dlp is installed. Free, and makes one unauthenticated request to YouTube.Input schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {},
"additionalProperties": false
}Annotations{
"title": "Check transcript sources",
"readOnlyHint": true,
"destructiveHint": false,
"openWorldHint": true
} | — | Read onlyNon-destructiveOpen world | — |
youtube_transcriptsGet transcripts for several videos in one call. Each one goes through the same chain as youtube_transcript: captions first, then Gemini, then yt-dlp. Videos are fetched in parallel and a failure on one does not stop the rest. Set allowPaid false to keep the whole batch free.Input schema{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"urls": {
"minItems": 1,
"maxItems": 20,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 2000
},
"description": "YouTube URLs or bare video ids. Capped at 20 per call, because each one can be a billed transcription."
},
"languages": {
"description": "Preferred caption languages, most wanted first.",
"maxItems": 5,
"type": "array",
"items": {
"type": "string",
"minLength": 2,
"maxLength": 10
}
},
"allowPaid": {
"description": "Allow the billed Gemini fallback per video. Defaults to FALSE for a batch, which is the opposite of the single-video tool: twenty videos is twenty bills.",
"type": "boolean"
}
},
"required": [
"urls"
],
"additionalProperties": false
}Annotations{
"title": "YouTube transcripts (batch)",
"readOnlyHint": false,
"destructiveHint": false,
"openWorldHint": true
} | — | WritesNon-destructiveOpen world | — |