Skip to main content
Glama

YouTube MCP Server

A Model Context Protocol (MCP) server that exposes YouTube channel intelligence, video analysis, niche discovery, and content strategy tools to AI assistants such as Cursor, Claude Desktop, and other MCP-compatible clients.

Built for creator workflows: audit channels, benchmark videos, discover niches, score titles, and analyze transcripts — all through structured, agent-friendly JSON responses.

Version: 0.1.0 · Node.js: >= 20 · Transport: stdio


Table of Contents


Related MCP server: YouTube MCP Server

Why This Exists

YouTube creator research usually means juggling the Data API, spreadsheets, and ad-hoc scripts. This server wraps that work into a consistent MCP tool surface so an AI agent can:

  • Resolve messy inputs (@handle, video URLs, channel IDs) into canonical records

  • Fetch channel and video metadata with quota-aware caching

  • Run opinionated analysis (channel audits, niche scoring, title packaging)

  • Return predictable JSON envelopes that agents can reason over reliably

Every tool response includes data, summary, sources, and warnings so downstream workflows stay auditable.


Features

Category

Capabilities

Operations

Health checks, auth status, quota tracking, cache statistics

Channels

Resolve identifiers, fetch profiles, list recent uploads

Videos

Details, batch lookup, search, performance snapshots, thumbnails

Strategy

Full channel audits, niche opportunity ranking

Content

Transcript analysis (user-provided text), title scoring

v0.1 Tool Inventory (17 tools)

Tool

Description

youtube.healthcheck

Server readiness, API reachability, schema version

youtube.auth.status

API key and OAuth configuration status

youtube.quota.status

Daily quota usage by endpoint

youtube.cache.status

Cache size, hit rate, stale entries

Tool

Description

youtube.channel.resolve

Resolve URL, handle, ID, or video URL → channel

youtube.channel.get_profile

Title, stats, thumbnails, branding metadata

youtube.channel.get_uploads

Recent upload IDs via uploads playlist

youtube.video.get_details

Metadata, stats, duration, thumbnails

youtube.video.batch_get_details

Batch lookup (up to 50 videos)

youtube.video.search

Keyword search with filters

youtube.video.performance_snapshot

Views/day, engagement rate, packaging metrics

youtube.thumbnail.get

All thumbnail variants and dimensions

Tool

Description

youtube.strategy.channel_audit

Upload cadence, outliers, title patterns

youtube.niche.find

Rank niche opportunities from seed topics

youtube.transcript.get

Transcript retrieval (provided text mode)

youtube.transcript.analyze

Hook, structure, CTA, repurpose signals

youtube.packaging.analyze_title

Title clarity, curiosity, length scoring


Architecture

flowchart TB
    subgraph Client["MCP Client"]
        Cursor["Cursor / Claude / Inspector"]
    end

    subgraph Server["youtube-mcp-server"]
        MCP["MCP Server (stdio)"]
        Registry["Tool Registry"]
        Analyzer["Channel Analyzer"]
        MCP --> Registry
        Registry --> Analyzer
    end

    subgraph Services["YouTube Layer"]
        ChannelSvc["Channel Service"]
        VideoSvc["Video Service"]
        Client_YT["YouTube Client"]
        Registry --> ChannelSvc
        Registry --> VideoSvc
        ChannelSvc --> Client_YT
        VideoSvc --> Client_YT
        Analyzer --> ChannelSvc
        Analyzer --> VideoSvc
    end

    subgraph Storage["Persistence"]
        Cache["SQLite API Cache"]
        Quota["SQLite Quota Tracker"]
        Client_YT --> Cache
        Client_YT --> Quota
    end

    subgraph External["External"]
        API["YouTube Data API v3"]
        Client_YT --> API
    end

    Cursor <-->|stdio| MCP

Design principles

  • Stdio transport — runs as a subprocess; no HTTP server to deploy

  • Zod validation — strict input schemas on every tool call

  • SQLite persistence — response cache and quota ledger share one database file

  • Quota guardrails — pre-flight checks before each API call; configurable daily budget

  • Structured envelopes — uniform { data, summary, sources, warnings } responses


Prerequisites

  1. Node.js 20+nodejs.org

  2. YouTube Data API v3 key — from Google Cloud Console

Obtaining a YouTube API Key

  1. Create or select a Google Cloud project

  2. Enable YouTube Data API v3 under APIs & Services → Library

  3. Go to APIs & Services → Credentials → Create Credentials → API Key

  4. Restrict the key to YouTube Data API v3 (recommended for production)

  5. Copy the key into your environment (see Configuration)

Note: Default Google Cloud quota is 10,000 units/day. This server defaults to a 9,000 unit soft limit to leave headroom.


Quick Start

# Clone and install
git clone <your-repo-url> youtube-mcp-server
cd youtube-mcp-server
npm install

# Configure credentials
cp .env.example .env
# Edit .env and set YOUTUBE_API_KEY=your-key-here

# Build and verify
npm run build
npm test

Verify the server with the MCP Inspector:

npx @modelcontextprotocol/inspector node dist/index.js

Then invoke youtube.healthcheck and youtube.channel.resolve with:

{ "input": "@mkbhd" }

MCP Client Setup

The server communicates over stdio. Point your MCP client at the built entry point (dist/index.js) or the dev runner (tsx src/index.ts).

Cursor

Add to ~/.cursor/mcp.json (Windows: %USERPROFILE%\.cursor\mcp.json):

Production (compiled)

{
  "mcpServers": {
    "youtube": {
      "command": "node",
      "args": ["/absolute/path/to/youtube-mcp-server/dist/index.js"],
      "env": {
        "YOUTUBE_API_KEY": "your-api-key-here"
      }
    }
  }
}

Development (hot reload via tsx)

{
  "mcpServers": {
    "youtube": {
      "command": "npx",
      "args": ["tsx", "/absolute/path/to/youtube-mcp-server/src/index.ts"],
      "env": {
        "YOUTUBE_API_KEY": "your-api-key-here"
      }
    }
  }
}

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent path on your OS:

{
  "mcpServers": {
    "youtube": {
      "command": "node",
      "args": ["/absolute/path/to/youtube-mcp-server/dist/index.js"],
      "env": {
        "YOUTUBE_API_KEY": "your-api-key-here"
      }
    }
  }
}

Using a .env file

The server auto-loads .env from the project root when present. If your MCP config launches the server from the project directory, you can omit inline env keys and rely on the file instead:

YOUTUBE_API_KEY=your-api-key-here
CACHE_DB_PATH=./data/cache.db

Environment variables set in the MCP client config take precedence over .env values already in process.env; unset keys fall through to .env.


Configuration

Variable

Required

Default

Description

YOUTUBE_API_KEY

Yes

YouTube Data API v3 key

CACHE_DB_PATH

No

./data/cache.db

SQLite database for cache + quota

MAX_DAILY_QUOTA_UNITS

No

9000

Soft daily quota budget

CACHE_TTL_CHANNEL_HOURS

No

24

TTL for channel/profile cache

CACHE_TTL_VIDEO_HOURS

No

12

TTL for video detail cache

CACHE_TTL_SEARCH_HOURS

No

6

TTL for search result cache

TRANSCRIPT_MODE

No

provided_text

Comma-separated transcript modes

PUBLIC_TRANSCRIPT_ADAPTER_ENABLED

No

false

Enable public transcript adapter

GOOGLE_CLIENT_ID

No

OAuth client ID (future caption support)

GOOGLE_CLIENT_SECRET

No

OAuth client secret

GOOGLE_REDIRECT_URI

No

OAuth redirect URI

Copy .env.example as a starting point:

cp .env.example .env

Tool Reference

All tools accept JSON arguments and return a structured response. Use forceRefresh: true to bypass cache when you need live data (consumes quota).

Operational

// youtube.healthcheck
{}

// youtube.quota.status
{}

Channel resolution & profiles

// youtube.channel.resolve
{ "input": "@mkbhd" }
{ "input": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }

// youtube.channel.get_profile
{ "channel": "@mkbhd", "forceRefresh": false }

// youtube.channel.get_uploads
{ "channel": "UC...", "maxResults": 25, "pageToken": null }

Accepted channel identifiers: @handle, channel URL, UC... channel ID, custom URL, or a video URL (resolved to its channel).

// youtube.video.get_details
{ "video": "dQw4w9WgXcQ", "includeTags": true }

// youtube.video.batch_get_details
{ "videos": ["id1", "id2", "https://youtu.be/id3"], "includeTags": false }

// youtube.video.search
{
  "query": "home gym setup",
  "maxResults": 10,
  "order": "viewCount",
  "type": "video",
  "regionCode": "US",
  "videoDuration": "medium",
  "recency": "pastMonth"
}

// youtube.video.performance_snapshot
{ "video": "dQw4w9WgXcQ" }

// youtube.thumbnail.get
{ "video": "dQw4w9WgXcQ" }

Search order values: relevance, date, viewCount, rating

Search recency values: any, pastHour, pastDay, pastWeek, pastMonth, pastQuarter, pastYear

Strategy & content analysis

// youtube.strategy.channel_audit
{ "channel": "@mkbhd", "maxVideos": 25 }

// youtube.niche.find
{
  "seedTopics": ["minimalist desk setup", "standing desk review"],
  "regionCode": "US",
  "maxResults": 10
}

// youtube.transcript.get (provided text)
{
  "mode": "provided_text",
  "transcriptText": "Welcome back to the channel...",
  "language": "en"
}

// youtube.transcript.analyze
{
  "transcriptText": "In this video we cover...",
  "analysisTypes": ["hook", "structure", "cta", "repurpose"]
}

// youtube.packaging.analyze_title
{ "title": "I Tried Every Standing Desk Under $300" }

Channel audit output highlights

youtube.strategy.channel_audit returns:

  • Upload cadence — videos/week, consistency score, average gap between uploads

  • Performance — median views, average views/day, engagement rate, outlier count

  • Top videos — highest-performing uploads with engagement metrics

  • Outlier videos — uploads exceeding 2× channel median views

  • Title patterns — average length, common words, detected formulas

  • Thumbnail availability — coverage across analyzed uploads

Niche scoring

youtube.niche.find searches each seed topic, samples top results, and scores opportunities using demand and competition proxies. Results are ranked by overallScore.


Response Format

Successful tool calls return JSON text with this envelope:

{
  "data": { },
  "summary": "Human-readable one-liner for the agent",
  "sources": [
    {
      "type": "youtube_api",
      "endpoint": "channels.list",
      "url": "https://www.youtube.com/@mkbhd",
      "timestamp": "2026-07-07T12:00:00.000Z"
    }
  ],
  "warnings": []
}

Errors return a separate JSON object with isError: true:

{
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Daily quota limit reached (9000/9000 units used)",
    "retryable": true
  }
}

Error codes

Code

Retryable

Meaning

QUOTA_EXCEEDED

Yes

Daily soft limit or Google quota hit

TRANSCRIPT_UNAVAILABLE

No

Requested transcript mode not available

UNKNOWN_TOOL

No

Tool name not registered

INTERNAL_ERROR

No

Unexpected server error


Quota & Caching

Quota costs (estimated units per call)

Endpoint

Cost

channels.list

1

videos.list

1

playlistItems.list

1

playlists.list

1

search.list

100

captions.list

50

commentThreads.list

1

The quota tracker records usage in SQLite and enforces MAX_DAILY_QUOTA_UNITS before each request. Check status anytime:

// youtube.quota.status →
{
  "dailyLimit": 9000,
  "usedToday": 342,
  "remaining": 8658,
  "byEndpoint": { "search.list": 300, "videos.list": 42 },
  "date": "2026-07-07"
}

Caching behavior

  • Responses are keyed by endpoint + normalized request parameters (SHA-256 hash)

  • TTLs are configurable per resource type (channel, video, search)

  • Stale entries are returned as cache misses and refreshed on next call

  • forceRefresh: true skips cache reads (still records quota on API hit)

Tips for quota efficiency

  1. Prefer youtube.video.batch_get_details over repeated get_details calls

  2. Use youtube.channel.get_profile before re-fetching the same channel

  3. Treat youtube.video.search as expensive (~100 units each)

  4. Run youtube.niche.find with fewer seed topics during development

  5. Monitor with youtube.quota.status and youtube.cache.status


Transcript Modes

Official YouTube caption download requires OAuth and (for most captions) video owner permissions. v0.1 supports:

Mode

Status

Description

provided_text

Supported

User pastes transcript text for analysis

owner_oauth

Planned

OAuth-based owner caption access

public_adapter

Disabled

Third-party public transcript adapter

speech_to_text

Planned

Audio → text pipeline

Configure enabled modes via TRANSCRIPT_MODE (comma-separated). Every transcript response includes provenance metadata.

Example workflow

  1. Copy transcript text manually (or from your own pipeline)

  2. Call youtube.transcript.get with mode: "provided_text"

  3. Pass the text to youtube.transcript.analyze for hook/structure/CTA insights


Development

# Run server directly (stdio — intended for MCP clients)
npm run dev

# Type-check
npm run typecheck

# Build for production
npm run build
npm start

NPM scripts

Script

Description

npm run dev

Start via tsx (no build step)

npm run build

Compile TypeScript → dist/

npm start

Run compiled dist/index.js

npm test

Run Vitest unit tests

npm run typecheck

tsc --noEmit

Tech stack

  • Runtime: Node.js 20+, ESM ("type": "module")

  • MCP SDK: @modelcontextprotocol/sdk

  • Validation: Zod

  • Storage: better-sqlite3

  • Testing: Vitest


Testing

npm test

Unit tests cover identifier parsing (@handle, URLs, channel IDs), duration/engagement utilities, title scoring, and transcript analysis heuristics.


Troubleshooting

Symptom

Likely cause

Fix

YOUTUBE_API_KEY is required

Missing API key

Set in .env or MCP env block

QUOTA_EXCEEDED

Daily limit hit

Wait for reset (midnight Pacific) or raise MAX_DAILY_QUOTA_UNITS

YouTube API error (403)

API not enabled or key restricted

Enable YouTube Data API v3; check key restrictions

Server starts but tools fail

Wrong working directory

Use absolute paths in MCP config args

Empty search results

Overly narrow filters

Relax recency, videoDuration, or regionCode

TRANSCRIPT_UNAVAILABLE

Unsupported mode

Use provided_text with transcriptText

Cache shows stale entries

Normal TTL expiry

Stale entries refresh on next miss; or use forceRefresh

Debug with MCP Inspector

npx @modelcontextprotocol/inspector node dist/index.js

Inspect raw tool inputs/outputs, list registered tools, and verify API connectivity without an IDE.


Project Structure

youtube-mcp-server/
├── src/
│   ├── index.ts              # Entry point, .env loader
│   ├── server/
│   │   ├── mcpServer.ts      # MCP server + stdio transport
│   │   ├── toolRegistry.ts   # Tool handlers + definitions
│   │   └── schemas.ts        # Zod input schemas
│   ├── youtube/
│   │   ├── youtubeClient.ts  # API client, cache, quota integration
│   │   ├── channelService.ts # Channel resolve, profile, uploads
│   │   ├── videoService.ts   # Video details, search, snapshots
│   │   └── quotaTracker.ts   # Daily quota ledger
│   ├── analysis/
│   │   └── channelAnalyzer.ts # Audits, niche scoring, title/transcript analysis
│   ├── storage/
│   │   └── cache.ts          # SQLite response cache
│   ├── config/
│   │   ├── env.ts            # Environment validation
│   │   └── defaults.ts       # Quota costs, schema version
│   ├── utils/
│   │   ├── ids.ts            # URL/ID parsing
│   │   ├── duration.ts       # ISO duration, engagement math
│   │   └── response.ts       # Response envelope helpers
│   └── tests/
│       └── unit/             # Vitest unit tests
├── .env.example
├── package.json
├── tsconfig.json
└── vitest.config.ts

Roadmap

v0.1 ships 17 tools. A broader roadmap (53+ tools) is documented separately, including:

  • OAuth-based owner caption download

  • Thumbnail vision analysis

  • Competitor comparison reports

  • Export and reporting utilities

See the parent YouTube MCP Server Build Plan for the full phased rollout.


Security

  • Never commit .env, API keys, or *.db files — they are gitignored

  • Restrict your API key to YouTube Data API v3 and (optionally) specific IPs

  • Prefer MCP env injection or OS-level secrets over hardcoding keys in config files shared via git

  • Quota limits are enforced server-side, but Google Cloud quotas are the ultimate ceiling

  • OAuth credentials (GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET) are optional and only needed for future caption features


Install Server
F
license - not found
A
quality
C
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.

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/CodingWithShahzaib/youtube-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server