Limecooler/yt-video-info
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
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
- Prerequisites
- Features
- How It Works
- Comparison with Alternatives
- Installation
- Claude Desktop Configuration
- Claude Code Configuration
- Usage
- API Reference
- Response Format
- Error Handling
- Development
- Troubleshooting
- Environment Variables
- Performance
- Security
- Limitations
- Contributing
- Built with Claude Code
- Changelog
- License
🚀 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:
- Page Fetch: Retrieves the YouTube video page HTML
- API Key Extraction: Extracts the
INNERTUBE_API_KEY
from the page source - InnerTube Request: Makes an authenticated POST request to
/youtubei/v1/player
- Android Context: Uses Android client context (
clientName: "ANDROID"
) for better transcript access - 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
Feature | yt-info-mcp | yt-dlp | youtube-dl | YouTube 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
- Clone this repository:
git clone https://github.com/Limecooler/yt-video-info.git
cd yt-video-info
- Install dependencies:
npm install
- 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 informationtitle
(string): Video titleauthor
(string): Channel namelengthSeconds
(number): Duration in secondsviewCount
(number): View countdescription
(string): Video description
captionTracks
: Array of available caption tracksbaseUrl
(string): URL to fetch the transcriptlanguageCode
(string): Language code (e.g., "en", "es")
Throws: YouTubeError
with specific error codes:
INVALID_ID
: Invalid video ID formatNOT_FOUND
: Video doesn't existPRIVATE
: Video is privateAGE_RESTRICTED
: Age-restricted contentREGION_BLOCKED
: Region-blocked content
fetchTranscript(captionTrack: CaptionTrack)
Fetches and parses transcript for a given caption track.
Parameters:
captionTrack
(CaptionTrack): Caption track object fromfetchVideoInfo
Returns: Promise<Transcript>
text
(string): Full transcript textsegments
(array): Array of transcript segmentsstart
(number): Start time in secondstext
(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
Variable | Description | Default | Example |
---|---|---|---|
MCP_DEBUG | Enable debug logging to stderr | false | MCP_DEBUG=true |
DEBUG | Alternative debug flag | false | DEBUG=true |
NODE_ENV | Environment mode | production | NODE_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
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Make your changes
- Run tests (
npm test
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - 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:
-
Install Claude Code (if you haven't already):
npm install -g @anthropic-ai/claude-code
-
Clone and open the repository:
git clone https://github.com/Limecooler/yt-video-info.git cd yt-video-info claude-code
-
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"
-
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