Skip to content

tolgahanuzun/ycdl

Repository files navigation

ycdl

CI PyPI Python License: MIT Powered by yt-dlp

A tool to list and download the latest N videos or Shorts from YouTube channels. It ships both a fast CLI (ycdl) and a lightweight web UI (FastAPI + plain HTML/CSS/JS, no build step). For every downloaded video it writes a .txt info file containing metrics such as views / likes / comments.

Note

This tool only uses yt-dlp; no API key is required.

Features

  • Search by channel URL, @handle or name
  • Shorts, regular videos or both (filterable)
  • Web UI with a thumbnail grid, multi-select and live progress (SSE)
  • Bulk download from the CLI without the UI
  • A <id>-<title>.txt info file per video (+ optional .info.json)
  • Persistent search history (shared by CLI and UI) you can re-run with one click
  • Quality selection, audio-only (mp3), concurrent downloads
  • MCP server so AI tools (Cursor, Claude, ...) can list/download for you
  • Installable via pip, exposes ycdl / ycdownload commands

Requirements

  • Python 3.10+
  • ffmpeg (recommended for merging video+audio and mp3 conversion)
    • macOS: brew install ffmpeg
    • Ubuntu/Debian: sudo apt install ffmpeg
    • Windows: ffmpeg.org

Installation

pip install ycdl

Optional extras:

pip install "ycdl[mcp]"    # MCP server (Cursor, Claude, etc.)

Install from source (development):

git clone https://github.com/tolgahanuzun/ycdl.git
cd ycdl
pip install -e ".[dev]"

Quick start

Web UI (recommended)

ycdl serve --open

Opens http://127.0.0.1:8888 in the browser. Enter a channel, list, select and download.

CLI

# List (without downloading)
ycdl list @MrBeast --last 20 --type shorts

# Download the latest 20 Shorts from a channel
ycdl download @MrBeast --last 20 --type shorts -o ./downloads

# Regular videos only, 720p, 4 concurrent
ycdl download @MrBeast -n 10 --type videos -q 720 --concurrency 4

# Download a single video
ycdl download "https://www.youtube.com/watch?v=VIDEO_ID"

# Show the metrics of a single video
ycdl info "https://www.youtube.com/shorts/VIDEO_ID"

python -m ycdl ... works the same way.

CLI commands

Command Description
ycdl list <channel> List the channel's latest videos (no download)
ycdl download <channel|url> Download the latest N videos or a single video
ycdl info <url> Show the metrics of a single video
ycdl history Show saved searches (--clear to wipe)
ycdl serve Start the web UI
ycdl mcp Run as an MCP server (for Cursor, Claude, etc.)

Key options

Option Default Description
--last, -n 20 How many recent videos
--type, -t both shorts / videos / both
--output, -o downloads Download directory
--quality, -q best best / 1080 / 720 / 480
--audio-only off Audio only (mp3)
--concurrency, -c 3 Number of concurrent downloads
--no-txt - Do not write the .txt info file
--no-info-json - Do not write .info.json

Output layout

downloads/
└── <Channel Name>/
    ├── <id>-<title>.mp4
    ├── <id>-<title>.txt        # views, likes, comments, duration, date, description...
    └── <id>-<title>.info.json  # compact machine-readable metadata (optional)

Example .txt:

============================================================
Sample Video Title
============================================================

Channel       : Test Channel
Video ID      : abc123
URL           : https://www.youtube.com/watch?v=abc123
Type          : Shorts
Upload date   : 2026-01-01
Duration      : 0:45

--- Metrics ---
Views         : 1,234,567
Likes         : 8,900
Comments      : 120

Environment variables

Variable Description
YCDL_OUTPUT_DIR Default download directory
YCDL_QUALITY Default quality
YCDL_CONCURRENCY Default concurrency
YCDL_HISTORY_FILE Search history file (default ~/.ycdl/history.json)

Development

pip install -e ".[dev]"
ruff check src tests
ruff format src tests
pytest -q

MCP server (Cursor, Claude, etc.)

ycdl can run as an MCP server, so AI tools can list and download videos for you ("download the latest 20 Shorts from @MrBeast").

Install the optional MCP extra and run it:

pip install "ycdl[mcp]"
ycdl mcp            # stdio transport

Exposed tools: list_channel, video_info, download, search_history, clear_history.

Connect from Cursor

Add this to your Cursor MCP config (~/.cursor/mcp.json or the project's .cursor/mcp.json):

{
  "mcpServers": {
    "ycdl": {
      "command": "ycdl",
      "args": ["mcp", "--output", "/absolute/path/to/downloads"]
    }
  }
}

If ycdl is installed in a virtualenv, use that interpreter, e.g. "command": "/path/to/.venv/bin/ycdl". The same config shape works for other MCP-compatible clients (Claude Desktop, etc.).

Architecture

  • core/ — yt-dlp wrappers (channel listing, downloading, metadata, job management). Shared by the CLI and the server.
  • cli.py — Typer-based CLI.
  • server/ — FastAPI API + static web UI (live progress via SSE).
  • mcp_server.py — MCP server exposing the same core as tools.

Disclaimer

This tool is intended for personal use. You are responsible for respecting copyright and the YouTube Terms of Service for any content you download.

License

MIT

About

Lightweight YouTube channel downloader: CLI + web UI + MCP

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages