yt-studio-mcp
yt-studio-mcp
An MCP (Model Context Protocol) server for managing a YouTube channel through the official Google APIs — videos, comments and moderation, playlists, live broadcasts, captions, analytics — plus an auditable giveaway suite for running comment-entry giveaways with deterministic, independently verifiable winner drawing.
Official APIs only (YouTube Data v3 + YouTube Analytics v2). No scraping.
Every mutating tool accepts
dry_run=trueand returns a preview instead of writing.No secrets in this repo, in logs, or in your MCP client config.
Quick start
1. Create Google credentials (~5 minutes, one time)
Go to console.cloud.google.com, create a project.
APIs & Services → Library: enable YouTube Data API v3 and YouTube Analytics API.
APIs & Services → OAuth consent screen: External, add yourself as a test user.
APIs & Services → Credentials → Create credentials → OAuth client ID → Desktop app; download the JSON as
client_secret.json.
2. Authorize your channel
uvx yt-studio-mcp auth --client-secret /path/to/client_secret.jsonA browser opens — sign in and pick the channel (Brand Accounts appear as separate choices). The refresh token is stored locally (see Secret storage).
3. Connect your MCP client
# Claude Code
claude mcp add yt-studio -s user -- uvx yt-studio-mcpTools
Area | Tools |
Channel/videos |
|
Playlists |
|
Comments |
|
Live |
|
Captions |
|
Analytics |
|
Giveaways |
|
Twitch |
|
Meta |
|
Known API limitations (documented, not bugs): comments cannot be pinned via
the API (post_video_question reminds you to pin manually in Studio), and
Community-tab posts have no public API.
Multistreaming to Twitch
Multistream plugins (Aitum, Restream) mirror the video to Twitch but not the
metadata — Twitch keeps whatever title and category were set last, so a new
stream goes out under the previous stream's name. create_broadcast therefore
sets the Twitch title/category too (twitch=True by default, twitch_game
strongly recommended); pass twitch=False to skip it. A Twitch failure never
fails the YouTube broadcast — it is reported in the result.
One-time setup:
Create an application at https://dev.twitch.tv/console/apps with the OAuth redirect URL set to exactly
http://localhost:8271.Run, as the channel owner:
yt-studio-mcp twitch-auth --client-id <id> --client-secret <secret>On a headless box the local listener cannot catch the redirect -- it goes to the browser's localhost, not the server's. Do this instead:
yt-studio-mcp twitch-auth --client-id <id> --client-secret <secret> --print-url # open that URL anywhere, let the redirect fail, copy ?code=... from the bar yt-studio-mcp twitch-auth --client-id <id> --client-secret <secret> --code <code>Authorization codes expire in minutes -- paste promptly.
This stores twitch_client_id, twitch_client_secret and
twitch_refresh_token in the configured secret backend. The grant needs the
channel:manage:broadcast scope — an app (client-credentials) token cannot
modify a channel. Twitch rotates refresh tokens, and the rotated value is
persisted automatically (except on the read-only env backend).
Running a giveaway
The giveaway suite implements a common official-rules pattern: comment on any video during the entry window; each distinct video counts as one entry, capped per person; winners drawn at random.
1. collect_entries(start="2026-01-01T00:00:00Z", end="2026-01-31T23:59:59Z",
max_entries_per_user=5, exclude_channel_ids=[...])
→ walks every upload's comments, derives entries, writes a snapshot
file and returns its SHA-256 entry hash. Announce the hash if you
want third-party verifiability.
2. draw_winners(snapshot_path, n=5, seed="any-public-string")
→ deterministic: a seeded shuffle over the canonically sorted entries,
first n distinct channels win. Anyone with the snapshot + seed can
re-run the draw and get identical winners. Records an audit file.
Screen-record this step for extra transparency.
3. make_verification_code(audit_path, winner_channel_id)
→ short code you send to the claimed winner over your announced contact
channel.
4. check_verification_reply(audit_path, comment_id, winner_channel_id)
→ confirms the reply was authored by the winning channel and contains
the code — proves account ownership before shipping a prize.
5. post_winner_reply(comment_id, "Congratulations! ...")Entries and audit records live in ~/.config/yt-studio-mcp/giveaways/.
This tool automates entry collection and drawing; giveaway laws vary by jurisdiction and platform policies apply (e.g. YouTube's contest policies). You are responsible for your own official rules and compliance.
Secret storage
Backend | Select with | Stores |
| — |
|
|
| reads |
|
| items in a Vaultwarden vault via a local vaultproxy HTTP API |
Quota
The Data API's default allocation is 10,000 units/day. Most reads cost 1
unit; writes cost ~50; a video upload costs 1,600. quota_status() shows a
session estimate and warns at 80%. collect_entries reports what it spent.
Development
pip install -e '.[dev]'
ruff check src tests && pytestTests are fully offline (mocked Google API). PRs welcome.
License
MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/aaronckj/yt-studio-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server