Skip to main content
Glama

YouTube Channel MCP

npm CI OpenSSF Scorecard License: MIT Node

Run your whole YouTube channel from Claude, Hermes, Cursor, Codex, Windsurf or any MCP client. Upload and schedule videos, write titles and chapters from the transcript, fix metadata across the back catalogue, answer and moderate comments, refresh the channel profile and banner, organise playlists and captions, and ask how the channel is doing.

“Upload ~/Videos/ep12.mp4 with chapters from the transcript, add it to the Podcast playlist and schedule it for Friday 6 pm.” “Which videos brought in the most subscribers this month, and where did the views come from?” “Show me comments held for review and reply to the questions.”

It runs on your own computer, talks only to the official YouTube Data API v3 and YouTube Analytics API, and keeps your Google sign-in in your OS keychain. No browser automation, no cookies, no third-party server.

npx @joinhackyard/youtube-channel-mcp setup

Setup takes about five minutes: it walks you through creating your Google credentials, connects your channel, and adds itself to the AI apps it finds on your machine.

What it covers

Area

Publishing

Upload local files or public URLs with resumable 16 MB chunks, checkpointed to disk: a dropped connection or closed app resumes from the last byte YouTube confirmed. Private, unlisted, public or scheduled (publish_at). Thumbnail, playlists and captions in the same call.

Videos

List everything on the channel (including private and scheduled), edit title, description, tags, category, languages, audience and AI-content disclosure, translate titles and descriptions, publish, unlist, schedule, delete.

Metadata

generate_metadata hands your AI the transcript with timestamps plus YouTube's rules; it writes the copy. preview_metadata checks limits and chapter rules before anything is sent. Templates add your standard footer, links, tags and naming.

Channel

Profile and stats, description, keywords, country, language, trailer for non-subscribers, translations, banner, video watermark.

Comments

Read comments per video or across the channel, including held for review and likely spam; reply as the channel; publish, hold or remove; ban authors; delete your own comments.

Analytics

Overview, daily trend, top videos, traffic sources, YouTube search terms, geography, devices, age and gender, audience retention for a video, subscribed vs not, or any custom metrics and dimensions.

Playlists

List, create, edit, delete, add, remove, reorder. Name a playlist and it is found (or created).

Captions

Upload .srt / .vtt, replace, download, delete; optional transcription of local videos with any OpenAI-compatible speech-to-text API (OpenAI, Azure OpenAI, Groq, local Whisper).

Several channels

Connect any number of channels, including brand accounts; pick a default or name one per call.

Quota-aware

Tracks the daily budget, stops on quotaExceeded instead of hammering the API, and resumes stopped uploads after the midnight Pacific reset.

Related MCP server: youtube-mcp

Install

Requirements: Node.js 22.13+. Optional: ffmpeg, only for transcription.

npx @joinhackyard/youtube-channel-mcp setup

Setup does four things:

  1. Google credentials (one time). YouTube only allows this through an OAuth client you own, so setup opens the right Google Cloud pages and you click through:

    1. Create a project.

    2. Enable the YouTube Data API v3 and the YouTube Analytics API.

    3. Configure the OAuth consent screen: External, then under Audience either add your Google account as a test user, or click Publish app so sign-ins don't expire every 7 days (Google shows an “unverified app” notice you can click through for your own app).

    4. Create an OAuth client of type Desktop app and download the JSON.

    Then drag that JSON file into the terminal. The client ID and secret go into your keychain.

  2. Connect a channel. Your browser opens Google sign-in; choose the account and the channel.

  3. Transcription (optional).

  4. Add to your AI apps. It detects and configures Claude Desktop, Claude Code, Cursor, Windsurf, Codex and Hermes Agent. Your original config is kept as *.before-youtube-channel-mcp.bak, and an existing server named youtube is never touched. Restart the app afterwards.

Prefer a global install? npm i -g @joinhackyard/youtube-channel-mcp && youtube-channel-mcp setup.

Manual configuration

npx @joinhackyard/youtube-channel-mcp config prints snippets for your machine. The general shape:

{
  "mcpServers": {
    "youtube-channel": {
      "command": "npx",
      "args": ["-y", "@joinhackyard/youtube-channel-mcp@latest"]
    }
  }
}

Hermes Agent (~/.hermes/config.yaml), where tools appear as mcp_youtube_channel_*:

mcp_servers:
  youtube-channel:
    command: "npx"
    args: ["-y", "@joinhackyard/youtube-channel-mcp@latest"]
    timeout: 180

Claude Code: claude mcp add youtube-channel --scope user -- npx -y @joinhackyard/youtube-channel-mcp@latest

Try it

  • “Check my YouTube connection.”

  • “Upload ~/Videos/launch.mp4 as private with the title ‘We shipped v2’, then show me the upload status.”

  • “Transcribe ~/Videos/episode-12.mp4, write three title options, a description with chapters and tags using my podcast template, and schedule it for Friday 18:00 IST with ~/Videos/ep12.jpg as the thumbnail.”

  • “How did the channel do in the last 28 days compared with the month before? Which five videos drove it?”

  • “What are people searching on YouTube to find us?”

  • “List comments held for review, publish the genuine ones and remove the spam.”

  • “Reply to the unanswered questions on my latest video.”

  • “Rewrite the channel description and keywords around hackathons and founders.”

  • “Add Hindi titles and descriptions to my five most viewed videos.”

  • “Make every video in the ‘Drafts’ playlist unlisted.”

Tools

Tool

What it does

auth_status · connect_channel · list_channels · set_default_channel · disconnect_channel

Connection, sign-in health, quota, known limits

upload_video · get_upload_status · list_uploads · cancel_upload · resume_upload

Background uploads from a file or URL, with progress and resume

list_my_videos · get_video · update_video · set_visibility · set_thumbnail · set_video_localizations · delete_video · list_categories

Videos

get_channel · update_channel · set_channel_banner · set_watermark

Channel profile and branding

list_comments · reply_to_comment · moderate_comments · delete_comment

Comments and moderation

get_analytics

YouTube Analytics reports for the channel or a video

list_playlists · create_playlist · update_playlist · delete_playlist · add_to_playlist · remove_from_playlist · move_in_playlist · list_playlist_items

Playlists

list_captions · upload_captions · download_captions · delete_captions · transcribe_video

Captions and transcripts

generate_metadata · preview_metadata · list_templates · save_template · delete_template

Writing metadata and channel templates

quota_status

Today's quota estimate

There is also a publish_video prompt for clients that support MCP prompts.

Approvals

Reading is free. Private uploads and private edits go straight through. Anything other people will see or that cannot be undone needs your approval: public, unlisted or scheduled uploads and visibility changes, public replies and comments, channel profile and banner changes, removing comments or banning authors, and deleting videos, playlists, captions or channels.

  • In clients that support MCP elicitation, you get a confirm dialog.

  • Otherwise the tool returns CONFIRMATION REQUIRED with a summary and a single-use token tied to those exact arguments. The AI is instructed to show you the summary and call again with the token only after you agree; if the arguments change, the token is rejected. This fallback relies on the AI following instructions, so prefer clients with elicitation, or YT_CONFIRM=always, when the AI reads untrusted text such as comments.

Set YT_CONFIRM=always to confirm every write, or never for unattended pipelines.

Templates

Templates are JSON files in ~/.youtube-channel-mcp/templates/ (or ask your AI to call save_template):

{
  "name": "podcast",
  "description": "Weekly episode",
  "title_format": "{title} | My Podcast",
  "description_footer": "Listen everywhere: https://example.com/podcast",
  "hashtags": ["#Podcast"],
  "tags": ["podcast", "interview"],
  "category_id": "22",
  "playlists": ["Podcast episodes"],
  "guidance": "Lead with the guest's name and the one idea listeners take away."
}

extends inherits another template. Tags and hashtags are combined, the footer is appended, and guidance is passed to your AI when it writes metadata. A built-in shorts template adds #Shorts. See examples/templates.

Things YouTube decides (worth knowing)

  • Unaudited projects upload as private. Google Cloud projects created after July 2020 that haven't passed the YouTube API compliance audit can have every API upload locked to private. The server detects this and tells you; publish those videos in YouTube Studio, or apply for the audit.

  • Testing-mode sign-ins last 7 days. If your consent screen is in Testing, Google expires the sign-in weekly. Reconnect (connect_channel), or publish the consent screen. Stopped uploads resume on their own after you reconnect.

  • Quota. Each Google Cloud project has a daily budget shared by every channel connected through it (by default about 10,000 API units; uploads have their own allowance). quota_status shows this server's estimate; the Cloud Console has the exact numbers.

  • Not available through the API: pinning comments, changing the channel name or handle, community posts, and Shorts-specific editing. Do those in YouTube Studio.

  • Phone verification. Custom thumbnails and videos over 15 minutes need a verified channel.

Configuration

Everything works without these. Environment variables override what setup stored.

Variable

Default

GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET

from keychain

Desktop-app OAuth client

YT_MCP_HOME

~/.youtube-channel-mcp

Data folder (state database, templates, transcripts)

YT_CONFIRM

public

public, always or never

YT_CHUNK_MB

16

Upload chunk size (rounded to 256 KB)

YT_DAILY_UNIT_LIMIT / YT_DAILY_UPLOAD_LIMIT

10000 / 100

Budgets used for the local estimate

YT_MCP_VAULT

auto

Set to file to use the encrypted file instead of the OS keychain

TRANSCRIBE_API_KEY (or OPENAI_API_KEY)

Speech-to-text key

TRANSCRIBE_BASE_URL (or OPENAI_BASE_URL)

https://api.openai.com/v1

Any OpenAI-compatible endpoint, e.g. https://<resource>.cognitiveservices.azure.com/openai/v1

TRANSCRIBE_MODEL

whisper-1

Model or deployment name

Security

  • Google refresh tokens and client secrets are stored in the OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service). On machines without one, they go into an AES-256-GCM encrypted file with a separate 0600 key file.

  • Sign-in uses a one-shot 127.0.0.1 loopback server with PKCE and a random state, as Google recommends for desktop apps.

  • Requested scopes: youtube.upload, youtube, youtube.force-ssl (comments, captions and deletes) and yt-analytics.readonly (reports). No monetary or revenue access.

  • URL downloads refuse private and internal addresses.

  • disconnect_channel revokes the token at Google.

  • An audit log of uploads and changes is kept in the local database.

CLI

youtube-channel-mcp setup              guided setup (safe to re-run)
youtube-channel-mcp connect            connect or reconnect a channel
youtube-channel-mcp status             channels, quota, recent uploads
youtube-channel-mcp doctor             check everything, explain fixes
youtube-channel-mcp install [ids|all]  claude-desktop, claude-code, cursor, windsurf, codex, hermes
youtube-channel-mcp uninstall [ids]
youtube-channel-mcp config             print config snippets

Contributing

Contributions are welcome. Start with CONTRIBUTING.md for setup, layout and guidelines. Please follow the Code of Conduct.

License

MIT. Built and maintained by Hackyard. Not affiliated with, or endorsed by, YouTube or Google. YouTube is a trademark of Google LLC.

Available Tools

46 tools
add_to_playlistAdd a video to a playlistB

Add a video to a playlist by playlist id or exact title. Optionally at a position (0 = first).

Inputs: playlist (required), video_id (required), channel, position, +1 more.

auth_statusConnection statusA
Read-only

Show whether Google OAuth is configured, which YouTube channels are connected (and whether their sign-in is healthy), the default channel, today’s quota use, and known project limitations. Call this first in a new conversation.

Inputs: no named parameters.

cancel_uploadCancel an uploadA

Stop an upload job that has not finished. It can be resumed later with resume_upload.

Inputs: job_id (required).

connect_channelConnect a YouTube channelA

Start Google sign-in to connect (or reconnect) a YouTube channel. Opens the browser on this computer and returns the sign-in link; the user picks the Google account and channel (brand accounts work). Waits up to wait_seconds for them to finish.

Inputs: open_browser, wait_seconds.

create_playlistCreate a playlistC

Create a new playlist on the channel.

Inputs: title (required), channel, privacy, description.

delete_captionsDelete a caption trackA
DestructiveIdempotent

Delete an uploaded caption track (see list_captions for ids). Needs the user’s confirmation.

Inputs: caption_id (required), channel, confirmation_token.

delete_commentDelete the channel’s own commentA
DestructiveIdempotent

Delete a comment or reply that the channel itself wrote (other people’s comments are removed with moderate_comments). Needs the user’s confirmation.

Inputs: comment_id (required), channel, confirmation_token.

delete_playlistDelete a playlistA
DestructiveIdempotent

Delete a playlist (the videos in it are not deleted). Needs the user’s confirmation.

Inputs: playlist (required), channel, confirmation_token.

delete_templateDelete a templateC
DestructiveIdempotent

Delete a saved template file.

Inputs: name (required).

delete_videoDelete a videoA
DestructiveIdempotent

Permanently delete a video from YouTube. Cannot be undone. Always needs the user’s confirmation.

Inputs: video_id (required), channel, confirmation_token.

disconnect_channelDisconnect a channelA
Destructive

Remove a connected channel and revoke this app’s Google access to it. Needs the user’s confirmation.

Inputs: channel, confirmation_token.

download_captionsDownload captionsA
Read-only

Download a caption track of your own video as SRT (prefers uploaded tracks, falls back to auto-generated). Costs 250 quota units.

Inputs: video_id (required), channel, language.

generate_metadataBrief for writing metadataA
Read-only

Collect everything needed to write a strong title, description, chapters and tags: the transcript with timestamps (from text you pass, a .srt/.vtt/.txt file, an uploaded video’s captions, or by transcribing a local file), the chosen template and YouTube’s rules. You then write the metadata and check it with preview_metadata.

Inputs: notes, format, channel, language, +5 more.

get_analyticsChannel and video analyticsA
Read-only

YouTube Analytics for the channel or one video. Reports: overview (views, watch time, average view duration, subscribers gained/lost, likes, comments, shares), daily (trend by day), top_videos (best performers with titles), traffic_sources, search_terms (YouTube search queries), geography, devices, demographics (age/gender), retention (audience retention curve, needs video_id), subscribed_status, or custom (your own metrics/dimensions). Defaults to the last 28 days. Data lags about 2 days.

Inputs: sort, report, channel, filters, +6 more.

get_channelChannel profile and statsC
Read-only

The channel’s title, handle, description, keywords, country, default language, trailer, subscriber/view/video counts, banner and settings.

Inputs: channel.

get_upload_statusUpload and processing statusA
Read-only

Status of an upload job (progress, errors, resulting video) and/or a video’s YouTube processing state (processing, failed, rejected), plus a check for the "locked to private" restriction. Can wait for changes.

Inputs: job_id, channel, video_id, wait_seconds.

get_videoGet video detailsB
Read-only

Full details of one video: metadata, privacy and schedule, processing state, duration, captions flag and statistics.

Inputs: video_id (required), channel.

list_captionsList caption tracksC
Read-only

Caption tracks on a video (language, name, auto-generated or uploaded, draft).

Inputs: video_id (required), channel.

list_categoriesList video categoriesB
Read-only

YouTube video categories you can assign (id and name) for a region.

Inputs: channel, region_code.

list_channelsList connected channelsB
Read-only

List the YouTube channels connected to this server.

Inputs: no named parameters.

list_commentsList commentsA
Read-only

Comment threads on one video, or across the whole channel (newest first). Filter by moderation state (published, held_for_review, likely_spam) or search text. Includes replies.

Inputs: order, search, status, channel, +3 more.

list_my_videosList channel videosA
Read-only

List videos on the channel, newest first (including private, unlisted and scheduled ones), with privacy, schedule, duration and view counts. Paginate with page_token.

Inputs: query, channel, privacy, page_token, +1 more.

list_playlist_itemsList videos in a playlistD
Read-only

Videos in a playlist, in order.

Inputs: playlist (required), channel, page_token, max_results.

list_playlistsList playlistsB
Read-only

All playlists on the channel with id, title, privacy and video count.

Inputs: channel.

list_templatesList templatesC
Read-only

Metadata templates (title format, description footer, default tags, hashtags, category, playlists, voice guidance) available for uploads.

Inputs: no named parameters.

list_uploadsList upload jobsB
Read-only

Recent upload jobs from this computer, newest first, with progress and results.

Inputs: limit, status.

moderate_commentsModerate commentsA
DestructiveIdempotent

Publish held comments, hold comments for review, or remove (reject) them; optionally ban the author from commenting on the channel. Removing or banning needs the user’s confirmation.

Inputs: action (required), comment_ids (required), channel, ban_author, +1 more.

move_in_playlistReorder a playlistA
Idempotent

Move a video to a new position in a playlist (0 = first). Works for playlists sorted manually.

Inputs: playlist (required), position (required), video_id (required), channel.

preview_metadataPreview final metadataA
Read-only

Show exactly what would be sent to YouTube (title, description, tags, playlists) after applying a template, and check it against YouTube’s limits and chapter rules. No API call, no quota.

Inputs: title (required), tags, license, template, +7 more.

quota_statusQuota statusA
Read-only

Estimated YouTube API quota used today (units and uploads) for this Google Cloud project, and when it resets (midnight Pacific Time).

Inputs: no named parameters.

remove_from_playlistRemove a video from a playlistB
DestructiveIdempotent

Remove a video from a playlist (the video itself is not deleted).

Inputs: playlist (required), video_id (required), channel.

reply_to_commentReply or comment as the channelA

Post a public reply to a comment (comment_id = the top-level comment or thread id) or a new top-level comment on a video (video_id). Posts publicly as the channel, so the user confirms the exact text first.

Inputs: text (required), channel, video_id, comment_id, +1 more.

resume_uploadResume an uploadB

Resume a stopped, failed or cancelled upload from the last byte YouTube confirmed (for example after a quota reset or reconnecting the channel). Network drops and quota resets are also retried automatically.

Inputs: job_id (required), wait_seconds.

save_templateSave a templateB
Idempotent

Create or replace a metadata template, saved as JSON in the templates folder. Use {title} in title_format. extends inherits another template; tags and hashtags combine.

Inputs: name (required), tags, extends, license, +12 more.

set_channel_bannerSet channel bannerA
Idempotent

Upload a channel banner (JPG/PNG, 16:9, at least 2048x1152, ideally 2560x1440, max 6 MB). Public, so the user confirms first.

Inputs: image_path (required), channel, confirmation_token.

set_default_channelSet the default channelA
Idempotent

Choose which connected channel is used when a tool call does not name one.

Inputs: channel (required).

set_thumbnailSet custom thumbnailA
Idempotent

Upload a JPG or PNG (max 2 MB, ideally 1280x720) from this computer as the video’s thumbnail. The channel must be phone-verified.

Inputs: video_id (required), image_path (required), channel.

set_video_localizationsTranslate title and descriptionA
Idempotent

Add or update the title and description shown to viewers in other languages, e.g. {"hi": {"title": "...", "description": "..."}}. Merged with existing translations. The video needs a default_language set (update_video).

Inputs: video_id (required), localizations (required), channel, remove_languages.

set_visibilityPublish, unlist, hide or scheduleA
Idempotent

Change who can see a video: private, unlisted or public, or schedule it with publish_at. Anything other than private needs the user’s confirmation.

Inputs: video_id (required), channel, privacy, publish_at, +1 more.

set_watermarkSet or remove the video watermarkA
Idempotent

Set the subscribe watermark shown on all channel videos (square JPG/PNG, at least 150x150, max 1 MB), or remove it with remove: true.

Inputs: show, remove, channel, image_path, +2 more.

transcribe_videoTranscribe a local videoA

Transcribe a video file on this computer with any OpenAI-compatible speech-to-text API (needs ffmpeg and a configured key). Saves an .srt you can pass to upload_video or upload_captions, and returns a timestamped transcript for writing metadata and chapters.

Inputs: file_path (required), language.

update_channelEdit channel profileA
Idempotent

Change the channel description, keywords, country, default language or the trailer shown to non-subscribers. Only the fields you pass change. These are public, so the user confirms first. (The channel name and handle can only be changed in YouTube Studio.)

Inputs: channel, country, keywords, description, +4 more.

update_playlistEdit a playlistA
Idempotent

Rename a playlist, change its description or privacy. Making it public or unlisted needs the user’s confirmation.

Inputs: playlist (required), title, channel, privacy, +2 more.

update_videoEdit video metadataA
Idempotent

Change a video’s title, description, tags, category, languages, audience and other settings. Only the fields you pass change. Optionally apply a template to the fields you pass (title format; footer and hashtags when you pass description; template tags when you pass tags). Changing visibility to public/unlisted or scheduling needs the user’s confirmation (or use set_visibility).

Inputs: video_id (required), tags, title, channel, +13 more.

upload_captionsUpload captionsB

Add a captions track (.srt, .vtt or other YouTube-supported format) to a video, from a file on this computer or inline content.

Inputs: video_id (required), name, channel, content, +4 more.

upload_videoUpload a videoA

Upload a video file from this computer (file_path) or a public URL to YouTube with a resumable, checkpointed upload that survives network drops and restarts. Optionally schedule it (publish_at), set a thumbnail, add it to playlists and attach captions in the same call. Runs in the background: returns a job_id right away (or the finished video if it completes within wait_seconds). Poll get_upload_status. Private uploads start immediately; public, unlisted and scheduled uploads need the user’s confirmation first. Tip: write metadata first (generate_metadata, then preview_metadata).

Inputs: title (required), url, tags, channel, +21 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.1/5.0

    Scored across 46 tools

    Disambiguation4/5

    Most tools target a clearly distinct resource and action, and descriptions explicitly separate close pairs such as delete_comment vs moderate_comments and upload_video vs resume_upload. The main overlaps are update_video vs set_visibility and generate_metadata vs preview_metadata, but the descriptions clarify when to use each.

    Naming Consistency4/5

    Nearly all tools follow a consistent snake_case verb_noun pattern (list_playlists, create_playlist, update_video, delete_captions). The only deviations are noun-style status tools auth_status and quota_status, plus the slightly unusual list_my_videos, but the convention is still predictable overall.

    Tool Count2/5

    At 46 tools, the surface is very heavy for a single MCP server, even given YouTube's broad domain. Several tools could be consolidated or folded into options on existing tools (e.g. set_visibility into update_video, upload management helpers, template operations), so the set feels over-expanded.

    Completeness4/5

    Coverage is strong across auth, channels, videos, uploads, playlists, captions, comments, templates, analytics, thumbnails, and channel branding. Minor gaps remain, such as no obvious channel-wide video search or bulk operations, but core lifecycle workflows are well covered.

    Related MCP Connectors

    Related MCP Servers