MCP Servers

A collection of Model Context Protocol servers, templates, tools and more.

I
Ironbeard MCP Youtube

MCP server for pulling YouTube video transcripts. Single Rust binary. No Python, Node, or yt-dlp needed.

Created 2/18/2026
Updated about 21 hours ago
Repository documentation and setup instructions

ironbeard-mcp-youtube

MCP server for pulling YouTube video transcripts. Single Rust binary. No Python, Node, or yt-dlp needed.

Features

  • Grabs transcripts from any YouTube video that has captions
  • Four output formats: plain text, timestamped, SRT subtitles, JSON
  • Language resolution with prefix matching and automatic fallback
  • File-based caching with 7-day TTL (SHA-256 hashed keys)
  • Retries with exponential backoff on network errors
  • Saves transcripts as markdown with YAML frontmatter
  • Works on Linux, macOS, and Windows
  • Plugs into Claude Desktop, Cursor, or any MCP client

Installation

git clone https://github.com/Alatar86/ironbeard-mcp-youtube.git
cd ironbeard-mcp-youtube
cargo build --release

Binary lands at target/release/ironbeard-mcp-youtube.

Usage

MCP Server Setup

The server runs over stdio. Point your MCP client at the binary.

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "youtube-transcript": {
      "command": "/path/to/ironbeard-mcp-youtube"
    }
  }
}

Cursor (.cursor/mcp.json in workspace root):

{
  "mcpServers": {
    "youtube-transcript": {
      "command": "/path/to/ironbeard-mcp-youtube"
    }
  }
}

Tool: get_youtube_transcript

| Parameter | Type | Required | Description | |------------|----------|----------|-------------| | url | string | Yes | YouTube video URL or 11-character video ID | | language | string | No | BCP-47 language code (e.g., en, es, ja). Defaults to the video's primary language. | | format | string | No | Output format: plain (default), timestamped, srt, json |

Accepted URL formats:

  • https://www.youtube.com/watch?v=VIDEO_ID
  • https://youtu.be/VIDEO_ID
  • https://youtube.com/embed/VIDEO_ID
  • Raw 11-character video ID (e.g., dQw4w9WgXcQ)

Command-Line Options

| Flag | Description | Default | |------|-------------|---------| | --transcript-dir <PATH> | Where to save transcript .md files | ~/Documents/youtube-transcripts | | --cache-dir <PATH> | Where to store cached transcript JSON | Platform cache directory (see below) |

As a Rust Library

use ironbeard_mcp_youtube::{TranscriptService, OutputFormat, SaveOutcome};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let service = TranscriptService::new()?;

    let result = service
        .get_transcript("dQw4w9WgXcQ", Some("en"), OutputFormat::Plain)
        .await?;

    println!("{}", result.formatted_text);
    match &result.save_outcome {
        SaveOutcome::Saved(path) => println!("Saved to: {}", path.display()),
        SaveOutcome::Failed(err) => eprintln!("Save failed: {}", err),
        SaveOutcome::NotAttempted => {}
    }
    Ok(())
}

Output Formats

Plain

All caption text joined with spaces:

We're no strangers to love You know the rules and so do I...

Timestamped

Each segment prefixed with [HH:MM:SS]:

[00:00:18] We're no strangers to love
[00:00:22] You know the rules and so do I

SRT

Standard SubRip subtitle format:

1
00:00:18,000 --> 00:00:22,000
We're no strangers to love

2
00:00:22,000 --> 00:00:27,000
You know the rules and so do I

JSON

Structured array:

[
  {"start": 18.0, "duration": 4.0, "text": "We're no strangers to love"},
  {"start": 22.0, "duration": 5.0, "text": "You know the rules and so do I"}
]

Saved Transcripts

Every transcript gets saved as a markdown file named {title} - {author}.md with YAML frontmatter:

---
title: "Never Gonna Give You Up"
author: "Rick Astley"
video_id: "dQw4w9WgXcQ"
url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
language: "en"
duration: "00:03:33"
duration_seconds: 213
date_saved: "2026-02-17"
---

# Never Gonna Give You Up

We're no strangers to love You know the rules and so do I...

Configuration

| Environment Variable | Description | Default | |---------------------|-------------|---------| | TRANSCRIPT_DIR | Where .md transcript files get saved | ~/Documents/youtube-transcripts |

You can set this in your MCP client config:

{
  "mcpServers": {
    "youtube-transcript": {
      "command": "/path/to/ironbeard-mcp-youtube",
      "env": {
        "TRANSCRIPT_DIR": "/path/to/my/transcripts"
      }
    }
  }
}

The --transcript-dir CLI flag takes precedence over the environment variable.

Cache

Transcripts are cached as JSON files in the platform cache directory:

| Platform | Directory | |----------|-----------| | Linux | ~/.cache/ironbeard-mcp-youtube/ | | macOS | ~/Library/Caches/ironbeard-mcp-youtube/ | | Windows | %LOCALAPPDATA%\ironbeard-mcp-youtube\ |

Cache keys are SHA-256 hashes of video_id + language. Entries expire after 7 days and get cleaned up on access.

How It Works

  1. Parse the video ID from the URL or raw ID
  2. Check the file cache for a valid entry
  3. On miss, hit YouTube's innertube /player API for metadata and caption track URLs
  4. Fetch the timedtext XML from the resolved caption track
  5. Parse the XML into transcript lines, decode HTML entities
  6. Cache the result as JSON
  7. Save transcript as markdown with YAML frontmatter
  8. Format and return the transcript in the requested output format

Language resolution tries exact match first, then prefix match (en matches en-US), then falls back to the first available track. Network requests retry up to 3 times with exponential backoff (1s, 2s, 4s).

Architecture

src/
  main.rs           - Entry point, CLI args, starts MCP server on stdio
  lib.rs            - Public API exports
  server.rs         - MCP server (rmcp 0.15), tool definitions
  service.rs        - TranscriptService: fetch, cache, format, save
  config.rs         - Configuration (directories, env vars, defaults)
  youtube/
    mod.rs          - Video ID parsing, module exports
    api.rs          - Transcript fetching with retry logic
    client.rs       - HTTP client with cookie/consent handling
    parser.rs       - Player API JSON, timedtext XML, and json3 parsing
    proto.rs        - Manual protobuf encoding for innertube params
    types.rs        - Data structures (TranscriptLine, VideoMetadata, etc.)
    error.rs        - Error types (VideoNotFound, NoCaptions, RateLimited, etc.)
  processing/
    mod.rs          - Output formatters (plain, timestamped, SRT, JSON)
  cache/
    mod.rs          - File-based transcript cache with SHA-256 keys and TTL
tests/
  integration_test.rs - End-to-end tests against live YouTube

Dependencies

| Crate | Purpose | |-------|---------| | rmcp | MCP server framework (stdio transport) | | tokio | Async runtime | | reqwest | HTTP client with cookie support | | serde / serde_json | Serialization | | schemars | JSON Schema generation for MCP tool input | | regex | URL parsing, XML extraction | | sha2 | Cache key hashing | | dirs | Platform-specific directory resolution | | clap | CLI argument parsing | | chrono | Date formatting for frontmatter | | anyhow | Application error handling | | thiserror | Error type derivation | | tracing / tracing-subscriber | Structured logging | | base64 / urlencoding | Protobuf param encoding for innertube API | | slug | Filename slugification for non-Latin titles | | lazy_static | Static regex compilation |

Development

# Unit tests (offline)
cargo test --lib

# All tests including integration (hits YouTube)
cargo test

# Check formatting
cargo fmt --check

# Lint
cargo clippy

# Build release
cargo build --release

Limitations

  • Video needs captions (human or auto-generated)
  • Video must be public
  • Language availability depends on what YouTube has
  • Rapid requests can get rate-limited (server retries automatically)

License

MIT

Contact

Bug reports: GitHub Issues or Ironbeardai@gmail.com

Quick Setup
Installation guide for this server

Installation Command (package not published)

git clone https://github.com/Alatar86/ironbeard-mcp-youtube
Manual Installation: Please check the README for detailed setup instructions and any additional dependencies required.

Cursor configuration (mcp.json)

{ "mcpServers": { "alatar86-ironbeard-mcp-youtube": { "command": "git", "args": [ "clone", "https://github.com/Alatar86/ironbeard-mcp-youtube" ] } } }