Skip to main content

YouTube channel video/Shorts downloader - CLI and lightweight web UI, with a .txt info file of metrics per video.

Project description

ycdl

CI 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

Clone the repository and install from source:

git clone https://github.com/tolgahanuzun/ycdl.git
cd ycdl
pip install .

For development (editable install with dev tools):

pip install -e ".[dev]"

Not yet published to PyPI; install from source for now.

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 (from source) and run it:

pip install -e ".[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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ycdl-0.1.0.tar.gz (25.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ycdl-0.1.0-py3-none-any.whl (32.8 kB view details)

Uploaded Python 3

File details

Details for the file ycdl-0.1.0.tar.gz.

File metadata

  • Download URL: ycdl-0.1.0.tar.gz
  • Upload date:
  • Size: 25.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for ycdl-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5c9b4a480ed5f0c76200964f7b1bb11982b3bff9590933e4fb0e3fd98e5ad1c5
MD5 ceba6f6e0451092756402bed830f6359
BLAKE2b-256 164c0201b7fe951403701fae41f9afbf662d43067dfbd8531cd65c8f33e79974

See more details on using hashes here.

File details

Details for the file ycdl-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ycdl-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 32.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for ycdl-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 aa1e73c57c8a34ac1256d406a5a30281eb3698a4d00f4593a1e2a1ba7605c721
MD5 e0ac09ee810f787b21b7dcfcde475bf4
BLAKE2b-256 90c9f94119c3f39dc9fd52d2eaf4af03e4b0a95e2ea4a9775a93f8f913e451ef

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page