youtube-analytics-mcp

youtube-analytics-mcp

Enables an AI assistant to query the full YouTube Analytics, Data v3, and Reporting API surface for one or multiple channels you own, with unrestricted parameters, local OAuth handling, and large-result output to files.

Category
访问服务器

README

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.

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

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选