yt-mcp
A YouTube research MCP server that resolves channels, browses and searches their videos, and extracts transcripts, descriptions, links and engagement stats for citation.
find_channel— resolve a handle (@mkbhd), channel URL,UC...id or name into a channel with its title, URL, description, video count and subscriber count.search_channel_videos— keyword-search within a single channel, with ordering (relevance, date, views, rating, title), result limits (1–50) and publish-date filters; costs 100 quota units per 50 results.list_channel_videos— list a channel's uploads newest first (1–200), optionally narrowed by relative (7d,6m,1y), absolute (2025-01-31) or RFC 3339 dates; much cheaper than searching.get_video_transcript— pull a timestamped transcript where each line starts with a Markdown link that seeks to that moment, so quotes stay clickable and traceable; supports language selection, cue merging (chunk_seconds), start/end windows, and costs no API quota.get_video_details— fetch a video's full description, the unique http(s) links the creator cited, tags, plus view/like/comment counts and caption availability.Flexible references — videos accepted as ids or watch/
youtu.be/shorts URLs; channel lookups memoised for the process lifetime.
Provides tools for searching YouTube channels, listing videos, fetching transcripts with timestamps, and retrieving video details with citations.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@yt-mcpsearch MKBHD channel for the latest iphone review"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
working code - the server writes last usage date to usage.json itself, on its first tool call of each day. A stale commit log here means the code is finished, not abandoned. See Usage signal.
Setup
Reads
YOUTUBE_API_KEYfrom.envat the project root;.env.exampleis the template.The key is a Google Cloud API key with "YouTube Data API v3" enabled.
uv syncinstalls.uv run yt-mcpserves MCP over stdio.claude mcp add yt -- uv run --directory "$PWD" yt-mcp, run from the repo root, registers it with Claude Code.
Related MCP server: YouTube MCP
Deployment
designed to by deployed on Prefect Horizon but YouTube api blocks servers IPs for the transcript fetch.
personally running locally to avoid setting up proxy.
Tools
search_channel_videossearches one channel's videos by keyword - search MKBHD channel for the latest iphone review.list_channel_videoslists a channel's videos newest first, filtered by date - everything from the last year.get_video_transcriptextracts a video's transcript with timestamps.get_video_detailsreturns a video's description, with the external links the creator cited pulled out for citation.find_channelresolves a channel and returns its stats.
References
Channels are given as
@mkbhd, a channel URL, aUC...id, or a channel name.Videos are given as an id or any watch /
youtu.be/ shorts URL.Date filters take relative offsets (
7d,6m,1y), dates (2025-01-31), or RFC 3339 timestamps; months and years are 30 and 365 days.
Transcripts
Lines are formatted
[[MM:SS]](watch url with &t=seconds) text, gaining an hour component past an hour -[[03:15]](https://www.youtube.com/watch?v=ID&t=195) the battery is 17% larger than previous year.The timestamp is a Markdown link that seeks to that moment, so a quoted line carries its own clickable citation; the link points at the start of the merged window, not the last cue in it.
chunk_secondsmerges caption cues into windows of that length;0keeps YouTube's raw cues.start_secondsandend_secondsnarrow a long video to one stretch.languagespicks the track by language code; with none given the video's original spoken language is used.Transcripts come from public caption tracks rather than the Data API, so they need no key and cost no quota.
Caption IP blocks
Caption tracks are served to the player rather than to the Data API, so YouTube judges the request by IP instead of by key: it blocks cloud provider ranges outright, and rate limits any single address that pulls transcripts in bulk. Both surface as
TranscriptBlockedError, and both are about the caller, not the video.
Usage signal
This is a signalling device. Not a feature of the server. If you are running yt-mcp for yourself, delete it - see "Removing it" below.
The problem it solves is a presentation one: a repository whose last commit is months old reads as abandoned, whether or not it is.
The middleware notes the UTC date of each tool call and, on the first call of a new date, commits
usage.jsonto this repository through the GitHub contents API. The README badge renders that file.One write per UTC day, not one per call.
records one field:
{"last_used": "2026-08-10"}. A UTC date.
Turning it on
Unset
USAGE_BADGE_TOKENis the default and the recommended state. With no token the middleware is never registered, so nothing inusage.pyruns and a tool call costs exactly what it costs without the feature.With a token set, the signal is on.
USAGE_BADGE_TOKENdeliberately is not namedGITHUB_TOKEN: GitHub Actions injects that name automatically, which would switch the signal on inside CI.The token is a fine-grained personal access token with Contents: read and write on this repository and nothing else. Set it as a host secret next to
YOUTUBE_API_KEY- it never belongs in the repository, and.envis gitignored.REPOSITORYinsrc/yt_mcp/usage.pynames the target. A fork that keeps this module writes to the upstream repository and is refused, which is a reason to delete rather than reconfigure.
Removing it
Five deletions, in any order. Nothing else references any of it.
Delete | |
| the mechanism |
| its tests |
the import and | unregisters it |
| removes the published date and its docs |
| removes the last trace |
httpx in pyproject.toml is there for this feature alone, though it arrives as a fastmcp dependency regardless.
nnel lookups are memoised for the life of the process.
Available Tools
5 toolsfind_channelA
Resolve a channel handle, URL, id or name to a channel with its stats.
Useful on its own to confirm which channel a name refers to before searching.
| Name | Required | Description | Default |
|---|---|---|---|
| channel | Yes | Channel handle (@mkbhd), channel URL, channel id (UC...), or channel name |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Channel id (UC...) |
| url | Yes | Canonical channel URL |
| title | Yes | Channel display name |
| handle | No | Channel handle, e.g. @mkbhd |
| description | No | Channel description |
| video_count | No | Public video count |
| subscriber_count | No | Subscribers, or null when the channel hides the count |
| uploads_playlist_id | No | Playlist holding every public upload, used for listing |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the full burden. It discloses that it returns 'stats' and helps confirm identity, but it does not mention potential side effects, permission requirements, or failure behaviors. This is a reasonable but minimal baseline for a read-style lookup.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences, with the main function front-loaded and a brief usage tip following. Every word earns its place; no fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity, one parameter, and presence of an output schema, the description is sufficient. It explains the input varieties and a practical use case, though it does not mention edge cases like ambiguous names or not-found behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the parameter description already lists handle, URL, id, and name. The tool description repeats this information without adding new semantic detail, so it meets the baseline but adds no extra value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Resolve a channel handle, URL, id or name to a channel with its stats.' This clearly distinguishes it from sibling tools that focus on videos (e.g., search_channel_videos, list_channel_videos).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The second sentence provides context: 'Useful on its own to confirm which channel a name refers to before searching.' This implies when to use it, but it does not explicitly name alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_video_detailsA
Get a video's full description, extracted links, tags and engagement counts.
The links list is what the creator cited in the description — sources, products, sponsors and their own other videos.
| Name | Required | Description | Default |
|---|---|---|---|
| video | Yes | Video id, or a watch / youtu.be / shorts URL |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Video id |
| url | Yes | Canonical watch URL |
| tags | No | Creator-supplied tags |
| links | No | Unique http(s) links found in the description, in order |
| title | Yes | Video title |
| duration | No | Duration as MM:SS or H:MM:SS |
| channel_id | Yes | Owning channel id |
| like_count | No | Likes, when public |
| view_count | No | Lifetime views |
| description | No | Full description text |
| has_captions | No | Whether YouTube reports captions for this video |
| published_at | No | Publish instant |
| channel_title | Yes | Owning channel name |
| comment_count | No | Comments, when public |
| is_short_form | No | Heuristic: duration is 60 seconds or less, i.e. likely a Short |
| duration_seconds | No | Duration in seconds |
| description_excerpt | No | First few lines of the description; use get_video_details for all |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It explains the output contents, including the nature of the links list, but does not disclose any limitations, error conditions, or permission requirements. This is a read-only informational tool, so moderate transparency is acceptable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core purpose, and every sentence adds value. The clarification about the links list is useful and concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simple nature and the presence of an output schema, the description is sufficient. It communicates the key output types and clarifies a potentially ambiguous field (links). It does not detail 'engagement counts' but that is minor and likely covered by the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides a clear description for the single 'video' parameter (ID or URL). The description does not add further parameter-level details, but with 100% schema coverage, the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves a video's full description, extracted links, tags, and engagement counts. This specific verb+resource+details structure distinguishes it from sibling tools like get_video_transcript.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for retrieving video metadata but does not explicitly state when to use this over alternatives or mention exclusions. The context is clear but lacks direct guidance on choosing among related tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_video_transcriptA
Get a video's transcript as timestamped lines you can quote and cite.
Every line starts with a Markdown link that seeks to that moment, so quoting a timestamp back keeps claims traceable and clickable — e.g. "at [03:15] he says the battery is 17% larger than last year". Reproduce those links verbatim rather than rewriting them as plain text. Narrow long videos with start_seconds and end_seconds. Reads public caption tracks, so it costs no API quota.
| Name | Required | Description | Default |
|---|---|---|---|
| video | Yes | Video id, or a watch / youtu.be / shorts URL | |
| languages | No | Preferred language codes in priority order, e.g. ['en', 'en-US']; defaults to the video's original spoken language | |
| end_seconds | No | Only return the transcript up to this offset | |
| chunk_seconds | No | Merge caption cues into windows of about this many seconds; 0 keeps raw cues | |
| start_seconds | No | Only return the transcript from this offset onward |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | Yes | Canonical watch URL |
| text | Yes | Transcript as '[[MM:SS]](watch url with &t=seconds) text' lines, one per merged segment; each timestamp is a Markdown link that seeks to that moment, so quoting a line carries its own citation |
| language | Yes | Transcript language name |
| video_id | Yes | Video id |
| end_seconds | Yes | End offset of the last returned line |
| is_generated | Yes | True when auto-generated by YouTube rather than creator-supplied |
| language_code | Yes | Transcript language code, e.g. en |
| segment_count | Yes | Number of timestamped lines returned |
| start_seconds | Yes | Offset of the first returned line |
| available_languages | No | Language codes with a transcript for this video |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does it well: it discloses the output format (timestamped Markdown links), instructs the agent to preserve links verbatim, and states it reads public caption tracks with zero API quota. It doesn't mention failure cases such as missing captions, but core behavioral traits are transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the primary purpose and output format, and each sentence adds value: linking behavior, verbatim requirement, range parameters, and cost. The example link is useful though slightly long; overall it is well-structured without bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists and all five parameters are documented, the description is nearly complete: it explains output semantics, parameter usage, cost impact, and limitations to public tracks. It omits only edge-case behavior such as missing or auto-generated captions, which is a minor gap for this complexity level.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers 100% of parameters with descriptions, so the baseline is 3. The description adds usage context for start_seconds/end_seconds but doesn't materially elaborate on languages or chunk_seconds beyond the schema, so no higher score is warranted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses a specific verb+resource ('Get a video's transcript') and immediately characterizes the output as timestamped, quotable lines with clickable Markdown links. This clearly differentiates it from siblings like get_video_details, which retrieves metadata, and the channel-list tools, since the purpose is uniquely transcript retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear operational context: narrow long videos with start_seconds/end_seconds, reproduce links verbatim, and reads public caption tracks at no API quota. It doesn't explicitly name sibling alternatives or say when not to use it, but the use case is unmistakable and siblings are unlikely to be confused with it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_channel_videosA
List a channel's uploads newest first, optionally within a date range.
Example: everything MKBHD posted in the last year, via published_after='1y'.
| Name | Required | Description | Default |
|---|---|---|---|
| channel | Yes | Channel handle (@mkbhd), channel URL, channel id (UC...), or channel name | |
| max_results | No | How many videos to return (1-200) | |
| published_after | No | Only videos published at or after this point: 7d, 6m, 1y, 2025-01-31, or RFC 3339 | |
| published_before | No | Only videos published at or before this point, same formats as published_after |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | Number of videos in this response |
| query | No | Search terms, when searching |
| videos | Yes | Videos, newest first unless reordered |
| channel | Yes | The channel the videos belong to |
| truncated | No | True when more videos matched than max_results allowed |
| published_after | No | Lower bound applied to publish dates |
| published_before | No | Upper bound applied to publish dates |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of disclosing behavior. It mentions ordering (newest first) and date-range filtering, which are useful. However, it does not address safety, auth, or error handling, though the read-only nature is implied by 'List'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: a clear purpose statement and a helpful example. No wasted words, and the example is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a list tool with 4 parameters and an output schema, the description is fairly complete. It covers purpose, ordering, and filtering. It does not discuss pagination, but max_results is in the schema, and the output schema covers return format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description adds a concrete example using published_after='1y', which reinforces the schema but does not add substantial new meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists a channel's uploads newest first, with optional date filtering. The verb 'List' is specific, and the resource is 'a channel's uploads', which distinguishes it from search_channel_videos.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this is for retrieving all uploads for a given channel, with an example showing usage. It does not explicitly name alternatives or exclusions, but the context is clear enough to select this over a search tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_channel_videosA
Search one channel's videos by keyword, e.g. the latest iPhone review on MKBHD.
Costs 100 YouTube quota units per 50 results. When you want recent uploads and have no keyword, use list_channel_videos instead — it is 100x cheaper.
| Name | Required | Description | Default |
|---|---|---|---|
| order | No | Result ordering; 'relevance' matches the query best, 'date' is newest first | relevance |
| query | Yes | What to search for within the channel's videos | |
| channel | Yes | Channel handle (@mkbhd), channel URL, channel id (UC...), or channel name | |
| max_results | No | How many videos to return (1-50) | |
| published_after | No | Only videos published at or after this point: 7d, 6m, 1y, 2025-01-31, or RFC 3339 | |
| published_before | No | Only videos published at or before this point, same formats as published_after |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | Number of videos in this response |
| query | No | Search terms, when searching |
| videos | Yes | Videos, newest first unless reordered |
| channel | Yes | The channel the videos belong to |
| truncated | No | True when more videos matched than max_results allowed |
| published_after | No | Lower bound applied to publish dates |
| published_before | No | Upper bound applied to publish dates |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the transparency burden. It discloses the cost: 'Costs 100 YouTube quota units per 50 results,' which is a behavioral trait not visible in the schema. However, it does not mention return format, error handling, or read-only nature beyond the implication of 'search,' so it is not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core purpose, and each sentence earns its place: one for what it does, one for cost and alternative. No fluff or repetition of schema-contained information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 params, output schema present, no annotations), the description covers purpose, cost, and an alternative, and the schema handles parameter semantics. It lacks only minor operational context such as error conditions, but the combination of schema and description is sufficient for selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage with descriptions for all 6 parameters, so the baseline is 3. The description adds only a usage example, not extra parameter-level detail, so it neither improves nor harms parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Search one channel's videos by keyword,' which is a specific verb+resource+scope statement. It distinguishes from the sibling tool list_channel_videos by explicitly noting the alternative for keywordless recent uploads, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when NOT to use this tool: 'When you want recent uploads and have no keyword, use list_channel_videos instead — it is 100x cheaper.' It gives a concrete use-case example (latest iPhone review on MKBHD) and compares cost to the alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.1.1- Changed
get_video_transcript1 field changed- changed
Output schema / properties / text / descriptionPrevious value: -"Transcript as '[MM:SS] text' lines, one per merged segment"New value: +"Transcript as '[[MM:SS]](watch url with &t=seconds) text' lines, one per merged segment; each timestamp is a Markdown link that seeks to that moment, so quoting a line carries its own citation"
5 tool updates
v0.1.0- First observed
find_channel - First observed
get_video_details - First observed
get_video_transcript - First observed
list_channel_videos - First observed
search_channel_videos
TDQS
Scored across 5 tools
Each tool targets a distinct action: channel resolution, keyword search, recent listing, transcript retrieval, and metadata/details. The only potential confusion is between search_channel_videos and list_channel_videos, but their descriptions clearly separate keyword-based search from recent-upload listing.
All five tools follow a consistent verb_noun pattern with snake_case: find_channel, search_channel_videos, list_channel_videos, get_video_transcript, get_video_details. The verbs are appropriate and predictable for their functions.
Five tools is a well-scoped surface for a YouTube research/retrieval server. Each tool covers a distinct part of the workflow without excessive overlap or unnecessary additions.
The core read-oriented workflow is covered: resolve a channel, find/list videos, fetch transcripts, and get detailed metadata. Minor gaps exist, such as no direct cross-YouTube search or playlist support, but common video research tasks are fully supported.
Maintenance
Related MCP Connectors
YouTube transcripts, search, channel browsing, and playlists for AI agents via MCP.
An MCP server that gives any LLM or agent clean YouTube transcripts on demand: a single video, a whole channel, or a playlist, plus AI cleanup of auto-generated captions. API-key auth, credit-based, same backend as the public v1 API. Get a free API key with 25 free credits at youtubetranscriptdownload.com/account.
MCP server for RiverScript, an AI transcription platform - fetches transcripts shared via a link.
YouTube transcripts, search, channel/playlist listings and upload tracking for AI agents.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that enables interaction with the YouTube Data API, allowing users to search videos, get video and channel details, analyze trends, and fetch video transcripts.-
- AlicenseAqualityDmaintenanceAn MCP server that enables users to retrieve YouTube transcripts and perform video or channel searches without requiring Google API keys. It supports transcript chunking and provides tools for detailed video content analysis and channel metadata extraction.530 npm4MIT
- AlicenseAqualityCmaintenanceAn MCP server that enables the extraction of transcripts and detailed metadata from YouTube videos. It allows users to retrieve video information like titles and descriptions, as well as transcripts with optional timestamps and language selection.2MIT
- AlicenseAqualityAmaintenanceMCP server that provides YouTube video data to AI agents, supporting search, metadata, comments, and transcripts without an API key.6111 npmISC