Skip to main content
Glama
modbender

youtube-analytics-mcp

by modbender

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

youtube_accounts

List authorized channels, the default, and where config lives

youtube_authorize

Start adding a channel; returns the consent URL at once

youtube_authorize_status

How the in-flight consent flow ended

youtube_authorize_cancel

Abandon an in-flight consent flow

youtube_set_default_account

Pick which channel unqualified calls use

youtube_forget_account

Drop a stored refresh token

youtube_refresh_tokens

Exercise every grant and report its age

youtube_analytics_query

Unrestricted reports.query

youtube_data_call

Unrestricted Data API v3

youtube_reporting_call

Unrestricted Reporting API

youtube_session_report

One video or stream: summary + traffic-source split

youtube_concurrent_curve

One ended stream's concurrent viewers, minute by minute

youtube_capabilities

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 screenAudience: 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 yourself

Your 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-mcp

Or 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

metrics=peakConcurrentViewers alone

400 The query is not supported

+ filters=video==ID

500 internal error

+ filters=video==ID;liveOrOnDemand==LIVE

400 — the extra filter is rejected

+ filters=video==ID + dimensions=livestreamPosition

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. liveChatMessages reads 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 Inspector

MIT.

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_accounts reports each grant's ageDays and 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 --refresh from 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:

  1. 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.

  2. 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.

  3. Live with weekly re-consent. For a single-user tool this is often the right answer.

Install Server
A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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