YouTube MCP Connector
Provides tools for searching videos, retrieving video details, reading subscriptions and playlists, generating catch-up digests of recent uploads, and managing playlists via the YouTube Data API v3, with write operations gated behind an explicit approval step.
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., "@YouTube MCP Connectorcatch me up on recent uploads from my subscriptions"
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.
YouTube MCP Connector
An MCP server (streamable HTTP) connecting any MCP-compatible client to the YouTube Data API v3: search videos, read subscriptions and playlists, build a "catch me up" digest of recent uploads, and manage playlists — with every write gated behind an explicit approval step.
Works with
This is a standard Model Context Protocol
server — nothing in it is tied to any single assistant. Run it yourself
(below) and point any MCP-compatible client at http://127.0.0.1:8000/mcp:
Meta Muse, Claude / Claude Code (Anthropic), ChatGPT (OpenAI)
Cursor, Windsurf, Cline, and other MCP-capable coding assistants
Any custom agent built on an MCP SDK (Python, TypeScript, …)
Related MCP server: mcp-apps
How it works
Any MCP client connects to this server's streamable-HTTP endpoint (/mcp).
Credentials are never hard-coded: the server reads
YOUTUBE_API_KEY / YOUTUBE_OAUTH_TOKEN from the environment (your local
.env file).
Auth split (mirrors the YouTube API itself):
Tool kind | Credential | Why |
Public reads ( | API key | Public data needs no user identity |
Private reads ( | OAuth 2.0 user token |
|
All writes | OAuth 2.0 user token | Every mutation requires authorization |
Approval gating: write tools (create_playlist, add_to_playlist,
save_for_later, remove_from_playlist) never execute directly. They
return a pending_confirmation payload with a single-use, expiring token
(default 600 s). The agent surfaces the action description to the user; on
approval it calls confirm_action with the token, which executes exactly
once. cancel_action discards a pending action. This maps 1:1 onto the
approval-card UX in MCP clients.
Known API limitation: YouTube's Data API cannot read or modify the
native Watch Later playlist (support removed August 2016; the API returns
watchLaterNotAccessible). save_for_later therefore uses a user-owned
playlist named "Watch Later (via 1xAI)" as the supported replacement,
creating it on first use.
Setup
You need a Google Cloud project. Do not create anything from this repo — these are manual steps in your own Google account:
Go to Google Cloud Console and create (or pick) a project.
APIs & Services → Library → search "YouTube Data API v3" → Enable.
APIs & Services → Credentials → Create Credentials → API key — for public reads. (Optional: restrict the key to the YouTube Data API v3.)
OAuth consent screen → user type External → fill app name, support email, developer contact → add scopes:
https://www.googleapis.com/auth/youtube.readonlyhttps://www.googleapis.com/auth/youtube.force-ssl
Tip: publish the consent screen to Production. Apps left in Testing issue refresh tokens that expire after 7 days.
Create Credentials → OAuth client ID → type Desktop app (personal use) → run Google's OAuth flow once and capture an access token.
Copy
.env.exampleto.envand fill in the values:YOUTUBE_API_KEY— public readsYOUTUBE_OAUTH_TOKEN— private reads + writes (refresh when it expires)YOUTUBE_HOST/YOUTUBE_PORT— bind address (default127.0.0.1:8000)YOUTUBE_APPROVAL_TTL_SECONDS— approval window (default600)YOUTUBE_HTTP_PROXY/YOUTUBE_HTTPS_PROXY— only if your host needs an explicit egress proxy (ambient proxy env vars are intentionally ignored)YOUTUBE_CA_BUNDLE— path to a PEM CA bundle, only if your egress proxy re-signs TLS with a private CA (it extends the default trust store)
No billing account is needed: the API is free within the daily quota below.
Quota budget
Default project quota: 10,000 units/day, resetting at midnight Pacific. Costs are per call (each result page costs the full amount again).
Tool | API call(s) | Units |
|
| 100 |
|
| 1 / page |
|
| 1 / page |
|
| 1 |
|
| ≈ 2 + #channels |
|
| 50 |
|
| 50 |
|
| 50 |
|
| 50 (100 first time) |
Example daily budget: 5 searches (500) + 3 digests over 40 subscriptions
(~126) + 20 detail lookups (20) + 10 playlist writes (500) ≈ 1,150 units —
about 11% of the free quota. Design rule used throughout: never call
search.list when videos.list/playlistItems.list can answer the question.
On quotaExceeded (HTTP 403) every tool returns a structured
quota_exceeded error telling the user when the quota resets.
Run the server
Local Python:
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
cp .env.example .env # then fill in your keys
.venv/bin/python -m youtube_mcp.server
# Point your MCP client at http://127.0.0.1:8000/mcpOr Docker (the image bakes in a /healthz liveness probe):
cp .env.example .env # then fill in your keys
docker build -t youtube-mcp .
docker run --env-file .env -p 8000:8000 youtube-mcpConnect a client
Point any MCP-compatible client at http://127.0.0.1:8000/mcp
(streamable HTTP). Claude Code, Cursor, Windsurf, Cline, and ChatGPT's
developer mode all accept a remote MCP server URL in their MCP/integration
settings — paste the URL there. See the
MCP documentation for your client's exact
config shape.
Run the tests
.venv/bin/python -m pytest -q # unit tests (mocked HTTP): 71 tests
# Integration tests hit the real API (reads only, ~110 units).
# Skipped automatically when credentials are absent.
YOUTUBE_API_KEY=... YOUTUBE_OAUTH_TOKEN=... .venv/bin/python -m pytest -q -m integrationIntegration tests are skipped automatically when credentials are absent.
Write-path tests run against mocks only — real writes are exercised manually
through the propose → approve → confirm_action flow.
Troubleshooting
Learned the hard way while building this:
channelNotFoundonmy_subscriptions/my_playlists/catch_me_up: the Google account that granted OAuth has no YouTube channel. Create one at youtube.com (any name works), then re-run the OAuth flow.quotaExceeded(HTTP 403) immediately: run OAuth against your own Cloud project. Shared/demo projects (e.g. Google's OAuth 2.0 Playground project) can already have their quota exhausted, and there is nothing you can do about it. Your own project gets a fresh 10,000 units/day.Auth errors right after pasting a token: make sure you pasted the full access token — a truncated paste fails every call. You can sanity-check a token's scopes at
https://oauth2.googleapis.com/tokeninfo?access_token=TOKEN.Refresh token stops working after ~7 days: your OAuth consent screen is still in Testing mode. Publish it to Production (step 4 of Setup).
Behind a corporate egress proxy: the server ignores ambient
HTTP_PROXY/HTTPS_PROXYon purpose (they break inside containers). SetYOUTUBE_HTTP_PROXY/YOUTUBE_HTTPS_PROXYexplicitly; if the proxy re-signs TLS with a private CA, pointYOUTUBE_CA_BUNDLEat your PEM bundle.
Project layout
src/youtube_mcp/
config.py # env-var settings (no secrets in code)
errors.py # typed errors: auth, quota, not-found, API
client.py # httpx client: key/OAuth injection, error mapping, pagination
quota.py # quota cost table + daily budget
approvals.py # single-use expiring tokens for write approvals
tools.py # the 11 tool implementations (pure, fully tested)
server.py # FastMCP wiring → streamable HTTP
tests/
test_client.py # auth headers, error mapping, pagination
test_approvals.py # TTL, single-use, cancel
test_tools.py # every tool: happy path, errors, auth/quota, empty, paging
test_integration.py # real API, reads only, skipped without credentialsExample prompts
"Catch me up on my subscriptions from this week — what did I miss?"
"Find me a video under 20 minutes that explains how sourdough starter works."
"Save this video for later: https://www.youtube.com/watch?v=…"
"What are the three most-viewed uploads from Marques Brownlee this month, and how long is each?"
"Make a private playlist called 'Weekend cooking' and add the pasta video you found yesterday."
License
MIT — see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
YouTube MCP — wraps the YouTube Data API v3 (BYO API key)
YouTube transcripts, search, channel browsing, and playlists for AI agents via MCP.
YouTube discovery, transcripts, library search, and monitors with API keys or OAuth.
Hosted MCP for YouTube Studio: uploads, metadata, playlists, comments, analytics, captions.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables YouTube content browsing, video searching, and metadata retrieval via the YouTube Data API v3. It also facilitates fetching video transcripts for summarization and analysis within MCP-compatible AI clients.719 npm1MIT
- AlicenseNot gradedqualityDmaintenanceEnables interacting with YouTube Data API v3 through MCP tools (get-video, get-channel, get-latest-video) and bundled UI apps for video and channel profiles.3 npm4MIT
- FlicenseAqualityDmaintenanceEnables interaction with YouTube's Data API through MCP, providing tools for channel info, videos, playlists, captions, subscriptions, and more.14-
- AlicenseNot gradedqualityAmaintenanceProvides read-only MCP tools to search YouTube, retrieve video metadata, transcripts, comments, channel information, and popular videos.3MIT