Skip to main content
Glama
youtube-studio-mcp

youtube-studio-mcp

by jaimebg

YouTube Studio MCP

YouTubeチャンネルの発見可能性を監査・改善するためのMCPサーバーです。

MCP対応のAIエージェントを、あなた自身のチャンネルのデータ(カタログ、Analytics APIのメトリクス、リテンションカーブ、流入検索語、そしてStudioのCSVエクスポートでのみ取得できるインプレッション数とクリック率)に接続します。そして、クリック率ではなく回復可能な視聴回数で修正すべき項目をランク付けします — アンダーパフォーマーのランク付け方法を参照してください。

8つのツール: auth_status、list_videos、get_video、query_analytics、get_search_terms、get_retention_curve、import_studio_data、find_underperformers。

すべて読み取り専用かつローカルで完結します。SQLiteキャッシュ、OAuthトークン、Studioのエクスポートデータは、あなたのマシンから外部に出ることはありません。

要件

  • Node.js ≥ 22

  • YouTubeチャンネルを所有するGoogleアカウント

Related MCP server: MCP YouTube Intelligence

セットアップ

1. Google Cloudプロジェクトを作成し、APIを有効化する

  1. https://console.cloud.google.com/ にアクセスし、プロジェクトを作成します。

  2. YouTube Data API v3 と YouTube Analytics API を有効にします。 (両方とも実際に使用します。Data APIはカタログ同期と list_videos/get_video を支え、Analytics APIは query_analytics、get_search_terms、get_retention_curve を支えます。Google Cloud Consoleでは、有効にしたAPIに対してのみ同意画面のスコープを追加できるため、次のステップの前に両方を有効にしてください。)

2. OAuth同意画面を設定する

  1. APIとサービス → OAuth同意画面 に移動します。

  2. 外部 を選択し、必須項目を入力します。

  3. 以下のスコープを追加します:

    • https://www.googleapis.com/auth/yt-analytics.readonly

    • https://www.googleapis.com/auth/youtube.readonly

    • https://www.googleapis.com/auth/youtube.force-ssl

重要 — アプリを本番環境に公開してください。 アプリがテストモードの間、Googleはリフレッシュトークンを7日間で失効させます。 そのため、毎週再認証が必要になります。アプリを公開 をクリックしてください。 アプリは未確認のままですが、問題ありません。あなたが唯一のユーザーであり、 自分のデータにアクセスするだけだからです。「未確認のアプリ」という警告が一度表示されます — 詳細 → (アプリ名)に移動 を選択してください。

3. OAuthクライアントを作成する

  1. APIとサービス → 認証情報 → 認証情報を作成 → OAuthクライアントID。

  2. アプリケーションの種類: デスクトップ アプリ。

  3. JSONをダウンロードします。

4. インストールと認証

npm install
npm run build

ダウンロードしたOAuthクライアントJSONを、サーバーの設定ディレクトリに credentials.json として保存します(ディレクトリが存在しない場合は先に作成してください):

# Linux/macOS — adjust the source filename to match what Google actually
# named your download (it starts with "client_secret_")
mkdir -p ~/.config/youtube-studio-mcp
mv ~/Downloads/client_secret_*.json ~/.config/youtube-studio-mcp/credentials.json
# Windows (PowerShell) — same caveat about the source filename
New-Item -ItemType Directory -Force "$env:USERPROFILE\.config\youtube-studio-mcp" | Out-Null
Move-Item "$env:USERPROFILE\Downloads\client_secret_*.json" "$env:USERPROFILE\.config\youtube-studio-mcp\credentials.json"

次に、以下を実行します:

node dist/index.js auth

これによりブラウザが自動的に開きます。そこで認証すると、トークンは <config dir>/tokens.json に保存されます。Linux/macOSでは、ファイルは所有者のみがアクセスできる権限(chmod 600)で書き込まれます。Windowsには同等のファイル権限ビットがないため、その手順はWindowsでは何も行いません — 通常のユーザーアカウントのファイル保護に依存してください。

ブラウザが開かない場合、コマンドは認証リンクを <config dir>/authorize-url.txt にも書き込みます — そのファイルを開いてリンクをクリックしてください。ターミナルからURLを手動でコピーしないでください。URLは約520文字で、複数行に折り返されます。途中で切れたコピーは、Googleで誤解を招くエラー Required parameter is missing: response_type とともに失敗します(欠落したパラメータは、私たちが構築したリクエストではなく、切り取られた部分にあります)。

YTMCP_HOME を設定すると、設定ディレクトリを上書きできます(例:2つ目のチャンネルやテスト環境用)。~/.config/youtube-studio-mcp パス全体を置き換えるため、credentials.json、tokens.json、SQLiteキャッシュはすべてそれに合わせて移動します。

5. AIエージェントにサーバーを登録する

サーバーはstdio上で標準のMCPを話すため、MCP対応のクライアントならどれでも実行できます。どの場合でも必要なものは1つだけです:このリポジトリ内の dist/index.js への絶対パス。

ほとんどのクライアントは同じJSON形式を共有しています。ご自身のパスに置き換えてください:

{
  "mcpServers": {
    "youtube-studio": {
      "command": "node",
      "args": ["/absolute/path/to/youtube-studio-mcp/dist/index.js"]
    }
  }
}

Agent

そのJSONの配置場所

Claude Code

claude mcp add youtube-studio -- node /absolute/path/to/dist/index.js

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json (macOS) · %APPDATA%\Claude\claude_desktop_config.json (Windows)

Cursor

全プロジェクト用に ~/.cursor/mcp.json、または単一プロジェクト内の .cursor/mcp.json

Windsurf

~/.codeium/windsurf/mcp_config.json

Cline

拡張機能の cline_mcp_settings.json(MCPサーバー → 設定 経由)

Continue

~/.continue/config.yaml(または config.json)

Gemini CLI

~/.gemini/settings.json

Zed

settings.json の context_servers 配下

2つのクライアントは異なる形式を使用します。

VS Code / GitHub Copilot — .vscode/mcp.json。mcpServers ではなく servers キーを使用します:

{
  "servers": {
    "youtube-studio": {
      "type": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/youtube-studio-mcp/dist/index.js"]
    }
  }
}

OpenAI Codex CLI — ~/.codex/config.toml。JSONではなくTOML形式:

[mcp_servers.youtube-studio]
command = "node"
args = ["/absolute/path/to/youtube-studio-mcp/dist/index.js"]

設定を編集したら、エージェントを再起動します。auth_status を実行するよう依頼してください。チャンネル名と残りクォータが表示されるはずです。Authenticated: NO と報告された場合は、node dist/index.js auth を再実行してください。

お使いのクライアントがリストにない場合は、設定内で「MCP」を探してください — 上記のコマンドと引数があれば、どのクライアントでも動作します。設定パスはリリース間で変更されることがあるため、ここに記載されたパスが存在しない場合は、クライアント自身のドキュメントを確認してください。

エージェントの動作に関する注意

すべてのツールに readOnlyHint: true の注釈が付いているため、そのヒントを表示するエージェントは書き込み確認を求めません。このサーバーはチャンネルを変更するものは何もありません — メタデータの書き戻しは後の段階です。

list_videos は同期を要求されない限りローカルキャッシュから提供され、find_underperformers と import_studio_data はネットワークに一切アクセスしません。明示的な同期とAnalyticsクエリのみがクォータを消費します。これはエージェントが探索的に動作するため重要です:list_videos を20回呼び出してもコストはかかりませんが、カタログ同期を20回行うと1日分の予算を使い果たします。auth_status は残りを報告します。

ツール

Tool

目的

auth_status

接続状態、チャンネルID、残りクォータ、ローカルキャッシュサイズ

list_videos

カタログの一覧表示とフィルタリング。sync: true でAPIから更新

get_video

1本の動画の完全なキャッシュ済みメタデータと統計

query_analytics

Analytics APIへの脱出ハッチ — 任意のメトリクス、ディメンション、フィルタ

get_search_terms

視聴者を引き込んだ検索クエリ。動画のメタデータと照合

get_retention_curve

視聴者がどこで離脱するか。生のポイントではなく注釈付きの離脱ポイントとして表示

import_studio_data

StudioのCSVエクスポートからインプレッション数とCTRをインポート — Analytics APIが公開していない唯一のメトリクス。ローカルファイルを読み取るのみ。認証もクォータも不要

find_underperformers

回復可能な視聴回数でカタログをランク付け — インプレッション数×チャンネルのインプレッション加重CTRベースラインとの差。事前にStudioエクスポートのインポートが必要。ローカルデータのみを読み取る

list_videos は sync: true を渡さない限り、完全にローカルのSQLiteキャッシュから提供されます — 単純な読み取り(Shorts/長尺動画、視聴回数、公開日、タイトルでのフィルタリング、または並べ替え)はクォータを消費しません。まだ何も同期されていない場合は、空のリストを返す代わりに、sync: true を付けて再度呼び出すよう指示します。

get_search_terms と get_retention_curve は、日付ウィンドウごとに結果をキャッシュします(下記のクォータを参照)。query_analytics はキャッシュせず、常にライブ呼び出しを行います。get_search_terms は最大25行を返します — Googleが基盤となるレポートをそこで上限としているため、日付範囲を広げると返ってくる行数ではなく、上位25位に入る検索語が変わります。

クォータ

YouTubeは1日あたり10,000ユニットに加え、別枠で1日あたり100回の search.list 呼び出しを許可しています。サーバーは両方を追跡し、予備(500ユニット、検索呼び出し10回)を確保するため、一括操作によって対話型ツールが使用不能になることはありません。クォータは太平洋標準時で深夜0時にリセットされます。これが auth_status が報告する内容です。

完全なカタログ同期(sync: true を付けた list_videos)は、1回の channels.list 呼び出しを行い、次にアップロードプレイリストをページングし(playlistItems.list、1ページあたり50本)、動画の詳細をバッチで取得します(videos.list、1回の呼び出しあたり50ID)。各呼び出しは1ユニットを消費します。合計は 1 + ceil(videos/50) + ceil(videos/50) ユニット — 100本のチャンネルで約5ユニットです。

YouTube Analytics APIには、Cloud Consoleでプロジェクトごとに独自のクォータがあり、Data APIの10,000ユニットとは別です。Analytics呼び出しはローカル台帳にゼロユニットコストで記録されるため、auth_status にData APIの予算を消費しているとは表示されません。

検索語の結果とリテンションカーブは日付ウィンドウごとにキャッシュされます。基盤となるレポートが日ごとの行ではなく、範囲に対するランク付けされた上位N件を返すためです。同じ日付での再呼び出しはキャッシュから提供されます。再クエリするには refresh: true を渡してください。

インプレッション数とCTRのインポート

impressions と impressionClickThroughRate はYouTube Analytics APIには存在しません — Studio限定です。取得するには:

  1. YouTube Studio → アナリティクス → 詳細モード(右上)

  2. インプレッション数 と インプレッションのクリック率 列が表示されていることを確認します — エクスポートには現在画面に表示されている列のみが含まれます

  3. エクスポート → カンマ区切り値(.csv) — 3つのファイルを含むzipがダウンロードされます

  4. 解凍し、フォルダパスを指定して import_studio_data を実行します

import_studio_data はディスクからファイルを読み取るだけです — YouTube Data APIやAnalytics APIを呼び出すことはないため、認証は不要でAPIクォータも消費しません。

日付ウィンドウはフォルダ名から読み取られます(Studioは Contenido 2010-01-26_2026-08-09 Channel のような名前を付けます)。上書きするには、rangeStart と rangeEnd の両方を(YYYY-MM-DD 形式で)渡してください — 片方だけの指定は、警告なしに誤った日付の下にデータが配置される可能性があるため、フォルダ名のウィンドウに静かにフォールバックするのではなく、検証エラーで拒否されます。両方の日付は実在する暦日である必要があり(2026-13-45 は拒否され、繰り越されません)、rangeStart は rangeEnd より後であってはなりません。

インプレッションとCTRは期間全体の合計値です。 エクスポート内の3つのファイルのうち、動画ごとのテーブル(Datos de la tabla.csv / Table data.csv)だけがインプレッションとCTRを含み、動画ごとに1行で日付範囲全体の合計として報告されます — エクスポートのどこにも日次CTRはありません。日次ファイル(Datos del gráfico.csv / Chart data.csv)とチャンネル合計ファイル(Totales.csv / Totals.csv)はビューのみを含みます。したがって、時系列での比較は、1つのエクスポートを日付で切り分けるのではなく、異なる範囲の複数のエクスポートをインポートすることを意味します。

import_studio_data は、エクスポートフォルダまたは特定のCSVパスのどちらかを受け付けます。フォルダを指定すると、テーブルファイルを自動的に見つけます。他の2つのファイルのいずれかを直接指定すると、インポートは即座に拒否されます。CSVのヘッダーは、3つのレポートのどれであるかを明確に示します(reportType は table、chart、totals のいずれかです — src/studio/csvSchemas.ts を参照)。このインポーターが保存できるものを含むのは table だけです。チャートファイルには動画IDがあるため、単純なインポートは黙って成功し、インプレッション/CTRを NULL で上書きし、ビューを期間合計ではなく最終日の値で上書きしてしまいます。合計ファイルには動画IDがまったくありません。どちらも、何も書き込まれる前に拒否され、代わりに指定すべきファイルとして Datos de la tabla.csv / Table data.csv を指名するメッセージが表示されます。

公開されなくなった動画の行は、マッチしないものとして保存・報告されます。これは想定された動作であり、エラーではありません。

Shorts

動画がShortsとしてカウントされるのは、180秒以下 であり、かつ Shortsが開始された日である 2020-09-14 以降に公開された場合のみです。

再生時間だけでは不十分です。もともと短い長尺動画(ミュージックビデオ、編集動画、予告編など)のカタログでは、再生時間のみのルールは全面的に誤分類します。2020年以前の休眠チャンネルに対する実地検証では、カタログの約70%がShortsとしてフラグされ、そのすべてが誤検出でした。そのチャンネルの最新のアップロードはShorts開始の数か月前だったため、どれ1つとして本物のShortsではあり得ませんでした。

find_underperformers は、このフラグを cohort パラメータを通じて読み取ります。cohort: 'short' または cohort: 'long' を渡すと、ベースラインがカタログのその半分に制限されるため、Shortsと長尺はそれぞれ同じ種類どうしでのみ比較されます。デフォルトの cohort: 'all' はそのようなセグメント化を行いません — 両方を1つの混合ベースラインにプールします。すでに1つのコホートだけのカタログ(このユーザーの実際のケースでは、完全に長尺のみ)では、プールは何もしないのと同じですが、混合カタログでは、デフォルトは典型的なCTRが異なる2つの母集団を混ぜ合わせます。セグメント化するには cohort を明示的に渡してください。動画に対する誤ったフラグは、明らかなエラーではなく、もっともらしいナンセンスを生み出すため、公開日ガードが重要なのです。

パフォーマンス不良動画のランク付け方法

find_underperformers は、クリック率ではなく 回復可能なビュー数 でランク付けします:

recoverable views = impressions x (baseline CTR - video CTR) / 100

これは、動画がチャンネル自身のベースラインで獲得したであろうビュー数の推定値です — 対策を講じる価値のある量です。CTRだけでランク付けすると誤解を招きます。具体的には次の3つの理由があります:

  • インプレッションは集中する。 チャンネルのインプレッションの大部分は、ごく一部の動画に集中しています。そのため、「最悪のCTR」と「最大の機会」はほぼ重ならない集合です。最も見苦しい比率の動画は、多くの場合、ほとんど誰にも表示されていない動画です。

  • インプレッション0は、パフォーマンスではなく割り算によってCTR 0%を生み出す。 昇順に並べ替えると、一度も表示されていないすべての動画が「修正すべきもの」リストの先頭に来ますが、これはまったく逆です。

  • チャンネルで最も高いCTRは、通常、分母が極めて小さい — たまたまコンバージョンした一握りのインプレッションです。それは勝利として提示されたノイズです。

したがって、2つのルールが導かれます。インプレッションの下限を下回る動画は データ不足 として報告され、パフォーマンス不良としてランク付けされることは決してありません。また、ベースラインは インプレッション加重 です。なぜなら、非加重の平均は低トラフィックの動画に支配され、チャンネルが実際に得ているトラフィックのほとんどを説明しないからです。

各機会は型付けされています。weak_metadata は、メタデータスコアが十分に低く、最初に修正すべき対象であることを意味します。low_ctr は、メタデータはすでに健全であり、サムネイルまたはタイトルのフレーミングが改善のレバーであることを意味します。

開発

npm test          # unit tests, no network
npm run typecheck
npm run build

npm run typecheck は2つのプロジェクトを実行します:tsconfig.json(src/**、ビルド)と tsconfig.test.json(src/** + test/** + vitest.config.ts、noEmit のみ)。テストプロジェクトだけを実行するには npm run typecheck:test を使用します。Vitest自体はesbuildを介して型を除去するだけで、型チェックは行いません。したがって、テストファイルの型エラーを実際に検出するのは npm run typecheck です。

Related MCP Connectors

Related MCP Servers