youtube-analytics-mcp
Provides comprehensive access to the YouTube Analytics, Data v3, and Reporting APIs, allowing AI agents to query channel analytics, retrieve video and audience data, run reporting jobs, and manage multiple authorized YouTube channels.
Click on "Install 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-analytics-mcpShow me my top 10 videos from the last 28 days by views"
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-analytics-mcp
An MCP server that gives an AI assistant the whole YouTube Analytics, Data v3 and Reporting API surface for channels you own — including several channels at once.
Most YouTube MCP servers hardcode a handful of metric strings, so the first question
outside their preset list is unanswerable without forking them. This one is built the
other way round: youtube_analytics_query takes every parameter reports.query accepts,
and youtube_data_call / youtube_reporting_call do the same for the other two APIs. The
presets are conveniences on top, never the only route to something.
You bring your own Google Cloud OAuth client. Nothing is shipped with this package, no credentials pass through any third party, and everything runs locally over stdio.
Tools
Tool | What it does |
| List authorized channels, the default, and where config lives |
| Start adding a channel; returns the consent URL at once |
| How the in-flight consent flow ended |
| Abandon an in-flight consent flow |
| Pick which channel unqualified calls use |
| Drop a stored refresh token |
| Exercise every grant and report its age |
| Unrestricted |
| Unrestricted Data API v3 |
| Unrestricted Reporting API |
| One video or stream: summary + traffic-source split |
| One ended stream's concurrent viewers, minute by minute |
| What these APIs can and cannot answer |
Every data tool takes an optional account, so one conversation can compare two channels.
Large results go to a file, not through the model
youtube_analytics_query, youtube_data_call and youtube_reporting_call take
outputPath (and optional format: csv or json, otherwise inferred from the
extension). With it, the full result is written to disk and only a summary — row count,
columns, byte size, first three rows — comes back. Without it, results over 100 rows are
truncated with a pointer to the option, because a thousand-row report returned inline costs
the caller its context window and is unreadable when it arrives.
For genuinely bulk work — every day of every video, months at a time — use the Reporting
API through youtube_reporting_call: it produces downloadable daily CSV reports with
dimension combinations reports.query will not return in a single call.
Related MCP server: YouTube MCP Server
Setup
1. A Google Cloud OAuth client, once
Create or pick a project.
APIs & Services → Library: enable YouTube Analytics API, YouTube Data API v3 and YouTube Reporting API.
OAuth consent screen → Audience: set user type to External (Internal is only offered when a Workspace organisation is attached). On that same Audience page, under Test users, click + Add users and add the Google account of every channel owner — including your own.
Miss this and consent fails with "… has not completed the Google verification process. The app is currently being tested and can only be accessed by developer-approved testers." Being the project owner does not make you a test user; you have to add yourself explicitly.
Set publishing status to In production. This matters more than it looks. Google:
A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days, unless the only OAuth scopes requested are a subset of name, email address, and user profile.
Every YouTube scope is sensitive, so a Testing app makes you re-authorize every week.
Be warned that publishing is not simply a switch for these scopes: the console is likely to require a demo video and put the app through YouTube API verification review before it will let you leave Testing. That is real work for a personal tool, and weekly re-consent is often the better trade. See The 7-day grant limit below for the alternatives.
Credentials → Create credentials → OAuth client ID → Desktop app. Not Web application: this server listens on a random free loopback port each run, and a Web client requires every redirect URI, port included, to be registered in advance.
Download the JSON.
2. Tell the server where the client is
Put it in the config file (see config.example.json):
// %APPDATA%\youtube-analytics-mcp\config.json (Windows)
// ~/Library/Application Support/youtube-analytics-mcp/ (macOS)
// ~/.config/youtube-analytics-mcp/config.json (Linux)
{
"client": { "client_id": "...", "client_secret": "..." }
}Run youtube-analytics-mcp --where to print that directory. Environment variables work
too and take precedence — YTMCP_CLIENT_ID + YTMCP_CLIENT_SECRET, or
YTMCP_CLIENT_FILE pointing at Google's download verbatim (the {"installed": …} wrapper
is unwrapped for you). YTMCP_CONFIG_DIR relocates the whole directory.
3. Authorize each channel
bun run auth # or: youtube-analytics-mcp --authorize
bun run auth -- --alias second # name it yourselfYour browser opens on the consent page automatically; the URL is printed too, for the
cases where it cannot (SSH, containers, CI). Pick the Google account that owns the channel and
approve. Repeat for each channel — choose a different account in the browser each time.
Accounts are named after their @handle unless you pass --alias.
Set YTMCP_NO_BROWSER=1 to never launch a browser, or pass openBrowser: false to the
youtube_authorize tool for a single call.
Refresh tokens are written to accounts.json in the same directory, separate from the
config.json you hand-edit, so the file you might paste into a bug report is never the
file holding tokens. Both are written 0600 where the platform honours it.
Your assistant can also drive this. youtube_authorize returns the consent URL immediately
and keeps listening in the background; youtube_authorize_status reports how it ended. It
does not block, because consent takes as long as a human takes and MCP clients give up on a
tool call long before that. The URL is also written to pending-auth.txt in the config
directory, since most clients discard a server's stderr and a URL nobody can read is no use.
4. Register with your MCP client
Claude Code:
claude mcp add youtube-analytics --scope user -- bunx youtube-analytics-mcpOr by hand, in any client's mcpServers map:
{
"mcpServers": {
"youtube-analytics": { "command": "bunx", "args": ["youtube-analytics-mcp"] }
}
}Read-only by default
Updating a video, posting or moderating comments, and uploading thumbnails are not
reversible on a live channel, so the write scope is not requested and non-GET calls are
refused. To enable them set YTMCP_ALLOW_WRITE=1 and re-authorize — the flag alone
does nothing, because the stored token does not carry the scope.
Concurrent viewers, and the query shape nobody guesses
averageConcurrentViewers and peakConcurrentViewers do work on ended streams, and
they match Studio's own numbers exactly. They are widely believed not to exist because the
API refuses them in every shape but one: the filter must pin a single video and
dimensions must be livestreamPosition.
query | result |
| 400 |
| 500 internal error |
| 400 — the extra filter is rejected |
| one row per minute of the stream |
No error names the missing dimension, and the 500 in particular reads as the metric being
broken rather than the request being wrong. youtube_concurrent_curve assembles it for you
and returns the peak, the mean, and the whole minute-by-minute curve.
What it genuinely cannot give you
youtube_capabilities returns the current list. Both were checked by asking for the metric
and getting Unknown identifier back, which is how the API distinguishes a name it has
never heard of from one it knows but cannot serve here:
Live chat message and reaction totals. Studio-only.
liveChatMessagesreads a chat in real time and cannot recover an ended one.Impressions and impression click-through rate. Studio-only, in the Reach tab.
Two things worth knowing
There is no "since published" window. The Analytics API is purely date-range, so a window covering a stream day returns that stream's live audience by construction. Studio's default per-video window excludes the entire live period, which is an easy and expensive trap when analysing live streams. This API cannot fall into it.
Analytics quota is separate. The Analytics and Reporting APIs meter independently of the Data API v3 daily unit budget, so querying here does not consume the quota that live chat polling competes for. Strong inference from them being distinct APIs with their own console quota pages — not measured.
Development
bun install
bun run dev # start on stdio
bunx tsc --noEmit # typecheck
bun run inspector # MCP InspectorMIT.
The API lags a few days
Finalized Analytics data is not available immediately. Measured on 2026-08-25, day-dimension rows ran through 08-22 and stopped: sessions from the previous three days returned no rows at all, not zero rows. A query for a stream that ended hours ago will look like a channel with no traffic.
Studio's web UI has a realtime path that the API does not expose, so same-day reporting still has to come from Studio. Use this server for everything older than roughly three days, where it is far better than clicking through Studio one video at a time.
The 7-day grant limit, and why no code can work around it
While the Cloud project's publishing status is Testing with an External user type, Google revokes refresh tokens after 7 days unless the only scopes requested are name, email and profile. Every YouTube scope is sensitive, so the exception never applies here.
This cannot be automated away. The 7 days is on the refresh token. Minting a new one requires a human approving a consent screen in a browser — that is what consent means, not a gap to engineer around. Refreshing access tokens more often does not touch it.
What this server does instead:
youtube_accountsreports each grant'sageDaysand warns from day 5.An expired grant fails with a message naming the cause and the fix, not a bare
invalid_grant.youtube_refresh_tokens(or--refreshfrom the CLI) exercises every grant as a health check. It is also a hedge: it is not established whether the 7-day clock is absolute from issuance or slides on use. If it slides, running this daily on a scheduler keeps grants alive indefinitely; if it does not, the call costs almost nothing. Worth running either way.Re-consenting is one call to
youtube_authorize, which opens the browser itself — about fifteen seconds.
The real fixes, in order of cost:
Publishing status → In production. Free, and grants stop expiring. For sensitive YouTube scopes Google may require a demo video and verification review before it will let you publish, which is a real amount of work for a personal tool.
Internal user type. No 7-day limit and no verification, but the option only exists when the project belongs to a Google Workspace organisation — a paid subscription.
Live with weekly re-consent. For a single-user tool this is often the right answer.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables AI assistants to access YouTube organic analytics, including channel stats, video performance, watch time, and audience engagement, via the YouTube Data API v3 and Analytics API v2.621MIT
- FlicenseAqualityCmaintenanceEnables AI assistants to analyze YouTube channels, videos, transcripts, and content strategy through structured tool calls.1733
- AlicenseBqualityCmaintenanceProvides comprehensive access to YouTube Data, Analytics, and Reporting APIs, enabling AI assistants to manage videos, analyze performance, handle comments, and extract transcripts.40MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI-powered automation of YouTube Studio tasks, including retrieving channel stats, fetching unanswered comments, and posting replies, using Google Gemini and MCP over SSE or stdio.
Related MCP Connectors
Provide token-optimized, structured YouTube data to enhance your LLM applications. Access efficien…
YouTube transcripts, search, channels, playlists and bulk transcript jobs for AI agents. 14 tools.
Search YouTube and read video, channel and transcript data as JSON. No Google Cloud project.
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/modbender/youtube-analytics-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server