yt-video-info

Limecooler/yt-video-info

3.2

If you are the rightful owner of yt-video-info and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

A lightweight MCP server that extracts YouTube video metadata and transcripts through web scraping, featuring robust error handling, caching, and retry logic without requiring API keys or external dependencies.

YouTube Info MCP Server

npm version License: MIT Node.js Version npm downloads

A lightweight MCP server that extracts YouTube video metadata and transcripts through web scraping, featuring robust error handling, caching, and retry logic without requiring API keys or external dependencies.

Table of Contents

🚀 Quick Start

npx @limecooler/yt-info-mcp

That's it! No installation required.

Prerequisites

  • Node.js: Version 18.0.0 or higher
  • npm: Version 9.0.0 or higher (for global installation)
  • Operating System: Windows, macOS, or Linux

Features

  • Fetches video metadata (title, author, duration, views, description)
  • Downloads available transcripts/captions
  • No API key required
  • No external dependencies (like yt-dlp)
  • Fast startup time for Claude Desktop integration
  • Comprehensive error handling with specific error codes
  • Input validation using Zod schemas
  • Retry logic with exponential backoff for network resilience
  • In-memory caching for improved performance
  • Debug logging support (set MCP_DEBUG=true)
  • TypeScript with full type safety

How It Works

This MCP server uses YouTube's InnerTube API (the same API used by YouTube's mobile apps) to reliably fetch video data:

  1. Page Fetch: Retrieves the YouTube video page HTML
  2. API Key Extraction: Extracts the INNERTUBE_API_KEY from the page source
  3. InnerTube Request: Makes an authenticated POST request to /youtubei/v1/player
  4. Android Context: Uses Android client context (clientName: "ANDROID") for better transcript access
  5. Fallback Strategy: Falls back to HTML scraping if InnerTube fails

This approach is more reliable than direct caption URL fetching because it mimics how YouTube's official apps retrieve data.

Comparison with Alternatives

Featureyt-info-mcpyt-dlpyoutube-dlYouTube API
No API Key Required
Transcript Support
Lightweight (<10MB)
MCP Protocol
No Python Required
TypeScript/JavaScript
Caching Built-in

Installation

Note: Installation is not necessary if you're using this with Claude Desktop or Claude Code. See Claude Desktop Configuration or Claude Code Configuration below.

Option 1: Direct Usage with npx (Recommended)

No installation needed! You can run the server directly using npx:

npx @limecooler/yt-info-mcp

Option 2: Install from npm

npm install -g @limecooler/yt-info-mcp

Option 3: Local Installation

  1. Clone this repository:
git clone https://github.com/Limecooler/yt-video-info.git
cd yt-video-info
  1. Install dependencies:
npm install
  1. Build the TypeScript code:
npm run build

Claude Desktop Configuration

Add the following to your Claude Desktop configuration file:

Configuration File Locations

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

Option 1: Using npx (Recommended - No Installation Required)

{
  "mcpServers": {
    "youtube-info": {
      "command": "npx",
      "args": ["-y", "@limecooler/yt-info-mcp@latest"]
    }
  }
}

Option 2: Local Installation

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

Claude Code Configuration

To use this MCP server with Claude Code:

Option 1: Quick Setup Using CLI (Recommended)

Simply run this command in your terminal:

claude mcp add yt-info-mcp -s user -- npx -y @limecooler/yt-info-mcp@latest

This automatically adds the YouTube Info MCP server to your global Claude Code configuration.

Option 2: Manual Global Configuration

Add to your global Claude Code configuration file:

Configuration File Locations:

  • macOS/Linux: ~/.claude/config.json
  • Windows: %USERPROFILE%\.claude\config.json
{
  "mcpServers": {
    "youtube-info": {
      "command": "npx",
      "args": ["-y", "@limecooler/yt-info-mcp@latest"]
    }
  }
}

This makes the YouTube Info MCP server available in all your Claude Code sessions.

Option 3: Project-Specific Configuration

Add to your Claude Code project configuration (.claude/project.json):

{
  "mcpServers": {
    "youtube-info": {
      "command": "npx",
      "args": ["-y", "@limecooler/yt-info-mcp@latest"]
    }
  }
}

Option 4: Local Installation

If you've cloned the repository locally:

{
  "mcpServers": {
    "youtube-info": {
      "command": "node",
      "args": ["./path/to/yt-video-info/dist/index.js"]
    }
  }
}

Once configured, you can use the tool in Claude Code:

User: Get information about YouTube video dQw4w9WgXcQ

Claude Code: I'll fetch the video information using the YouTube Info MCP server.
[Uses the MCP tool to retrieve video metadata and transcript]

Usage

Using with Claude Desktop

Once configured, you can use the tool in Claude Desktop:

Please get information from YouTube video dQw4w9WgXcQ

Using from npm (Command Line)

If you installed globally via npm:

# Run the MCP server directly
yt-info-mcp

# Or use with a tool that supports MCP
npx @modelcontextprotocol/cli connect yt-info-mcp

Using as a Library

import { fetchVideoInfo, fetchTranscript } from '@limecooler/yt-info-mcp';

// Get video information
const { metadata, captionTracks } = await fetchVideoInfo('dQw4w9WgXcQ');

// Fetch transcript if available
if (captionTracks.length > 0) {
  const transcript = await fetchTranscript(captionTracks[0]);
}

The tool will return:

  • Video metadata (title, author, duration, view count, description)
  • Transcript with timestamps (if available)
  • Error details if the video is unavailable or has no transcript

API Reference

fetchVideoInfo(videoId: string)

Fetches video metadata and available caption tracks.

Parameters:

  • videoId (string): The 11-character YouTube video ID

Returns: Promise<{ metadata: VideoMetadata; captionTracks: CaptionTrack[] }>

  • metadata: Object containing video information
    • title (string): Video title
    • author (string): Channel name
    • lengthSeconds (number): Duration in seconds
    • viewCount (number): View count
    • description (string): Video description
  • captionTracks: Array of available caption tracks
    • baseUrl (string): URL to fetch the transcript
    • languageCode (string): Language code (e.g., "en", "es")

Throws: YouTubeError with specific error codes:

  • INVALID_ID: Invalid video ID format
  • NOT_FOUND: Video doesn't exist
  • PRIVATE: Video is private
  • AGE_RESTRICTED: Age-restricted content
  • REGION_BLOCKED: Region-blocked content

fetchTranscript(captionTrack: CaptionTrack)

Fetches and parses transcript for a given caption track.

Parameters:

  • captionTrack (CaptionTrack): Caption track object from fetchVideoInfo

Returns: Promise<Transcript>

  • text (string): Full transcript text
  • segments (array): Array of transcript segments
    • start (number): Start time in seconds
    • text (string): Segment text

Example with Error Handling:

try {
  const { metadata, captionTracks } = await fetchVideoInfo('dQw4w9WgXcQ');
  
  if (captionTracks.length > 0) {
    const transcript = await fetchTranscript(captionTracks[0]);
    console.log(transcript.text);
  }
} catch (error) {
  if (error.code === 'PRIVATE') {
    console.log('This video is private');
  }
}

Response Format

{
  "metadata": {
    "title": "Video Title",
    "author": "Channel Name",
    "lengthSeconds": 215,
    "viewCount": 1234567,
    "description": "Video description..."
  },
  "transcript": {
    "text": "Full transcript text...",
    "segments": [
      {
        "start": 0.0,
        "text": "First segment"
      },
      {
        "start": 2.5,
        "text": "Second segment"
      }
    ]
  },
  "error": "Error message if transcript unavailable"
}

Error Handling

The server handles various error cases:

  • Invalid video ID format
  • Video not found (404)
  • Private or age-restricted videos
  • Videos without transcripts
  • Network errors

Development

Run in development mode with auto-reload:

npm run dev

Testing

Run comprehensive tests:

npm test

Test MCP protocol communication:

npm run test:mcp

Enable debug logging:

MCP_DEBUG=true npm start

Troubleshooting

Common Issues

"Command not found" after npm install

Solution: Add npm global bin directory to your PATH or use npx:

# Check npm bin location
npm bin -g

# Or just use npx
npx @limecooler/yt-info-mcp
Empty transcript responses

Possible causes:

  • Video doesn't have captions enabled
  • Video is region-restricted in your area
  • YouTube is rate-limiting your requests

Solution: Check if the video has the "CC" button on YouTube's website.

"INVALID_ID" error

Solution: Ensure the video ID is exactly 11 characters. Extract it from the URL:

  • ✅ Correct: dQw4w9WgXcQ
  • ❌ Wrong: https://youtube.com/watch?v=dQw4w9WgXcQ
Connection refused in Claude Desktop

Solution: Make sure the configuration path is absolute, not relative:

{
  "mcpServers": {
    "youtube-info": {
      "command": "node",
      "args": ["/Users/username/yt-video-info/dist/index.js"]  // Full path
    }
  }
}
Rate limiting errors

Solution: Implement delays between requests or use the built-in caching:

// Videos are cached for 1 hour, transcripts for 2 hours
await fetchVideoInfo('video1');
// Second call uses cache
await fetchVideoInfo('video1');

Environment Variables

VariableDescriptionDefaultExample
MCP_DEBUGEnable debug logging to stderrfalseMCP_DEBUG=true
DEBUGAlternative debug flagfalseDEBUG=true
NODE_ENVEnvironment modeproductionNODE_ENV=development

Performance

  • Startup Time: <500ms (measured on M1 MacBook Air)
  • Memory Usage: ~50MB idle, ~100MB during active requests
  • Cache TTL: Video info (1 hour), Transcripts (2 hours)
  • Response Time:
    • Cached: <100ms
    • Fresh fetch: 2-4s (depends on YouTube's response time)
  • Concurrent Requests: Limited by Node.js event loop

Security

Security Considerations

  • No credentials: No API keys or authentication tokens required or stored
  • Read-only: Only performs GET/POST requests to retrieve public data
  • No user data: Doesn't collect or transmit any user information
  • Content filtering: Respects YouTube's age restrictions and privacy settings
  • Safe dependencies: Minimal dependencies, all from trusted sources
  • Input validation: All inputs validated with Zod schemas

Best Practices

  • Run in isolated environment if processing untrusted video IDs
  • Monitor rate limits to avoid IP blocking
  • Use environment variables for configuration, not hardcoded values

Limitations

  • Relies on YouTube's web interface structure, which may change
  • Cannot transcribe audio - only downloads existing captions
  • May be rate-limited by YouTube if used excessively
  • Age-restricted or private videos cannot be accessed

Contributing

We welcome contributions! Here's how you can help:

Getting Started

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run tests (npm test)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

Development Guidelines

  • Follow existing code style and conventions
  • Add tests for new features
  • Update documentation as needed
  • Keep commits focused and descriptive
  • Ensure all tests pass before submitting PR

Reporting Issues

  • Check existing issues before creating new ones
  • Include steps to reproduce bugs
  • Provide system information (Node.js version, OS)
  • Include relevant error messages and logs

Built with Claude Code

This entire project was developed using Claude Code, Anthropic's AI-powered coding assistant. Claude Code enables rapid development with built-in best practices and comprehensive testing.

Making Changes with Claude Code

To contribute or modify this repository using Claude Code:

  1. Install Claude Code (if you haven't already):

    npm install -g @anthropic-ai/claude-code
    
  2. Clone and open the repository:

    git clone https://github.com/Limecooler/yt-video-info.git
    cd yt-video-info
    claude-code
    
  3. Ask Claude Code to make changes:

    • "Add support for playlist extraction"
    • "Improve error handling for rate limiting"
    • "Add unit tests for the scraper module"
    • "Update the InnerTube API implementation"
  4. Claude Code will:

    • Understand the existing codebase structure
    • Follow the established patterns and conventions
    • Run tests to ensure changes don't break functionality
    • Update documentation as needed
    • Commit changes with descriptive messages

Why Claude Code?

  • Context-aware: Understands the entire codebase and maintains consistency
  • Best practices: Automatically follows TypeScript, MCP, and npm conventions
  • Test-driven: Ensures changes are tested and documented
  • Efficient: Reduces development time from hours to minutes

Example Claude Code Session

You: "Add a feature to download video thumbnails"

Claude Code: I'll add thumbnail download functionality to the MCP server.
[Claude Code analyzes the codebase, implements the feature, adds tests, 
updates types, and creates a commit]

You: "Now add documentation for the new feature"

Claude Code: I'll update the README and add inline documentation.
[Updates all relevant documentation files]

Changelog

See Releases for a detailed version history.

Latest Version: v1.1.1

  • 🔧 Fixed executable permissions for npx compatibility
  • 🐛 Resolved Claude Code connection error (MCP error -32000)
  • 📚 Added simple Claude Code CLI setup command

v1.1.0

  • 🐛 Fixed transcript fetching using YouTube's InnerTube API
  • ✨ Added Android client context for better reliability
  • 📚 Improved documentation with badges and better structure

License

MIT