Skip to main content

A local-first media workflow toolkit for downloads, playlists, and automation through CLI and MCP interfaces

Project description

VDL

VDL logo

VDL is a local-first media workflow runtime for building apps and workflows around video downloads, playlists, page discovery, link lists, progress events, and structured results.

It is designed around three surfaces:

Surface Default State Best For
Python library Stateless Embedding media download/discovery in apps and tools
Headless CLI Stateless Scripts, one-shot jobs, and automation
Interactive app Stateful Guided terminal UX with history, status, SQLite, and logs

External products own their own persistence and product workflows. VDL provides the media execution capability; it does not try to become a media library app.

flowchart TD
  StandaloneBinary["curl install.sh<br/>Standalone binary"]
  PythonPkg["pip install vdl<br/>Python package"]
  
  StandaloneBinary --> CLI["vdl CLI"]
  StandaloneBinary --> App["Interactive app"]
  StandaloneBinary --> MCP1["vdl-mcp"]
  
  PythonPkg --> Library["Python library<br/>import vdl"]
  PythonPkg --> CLI
  PythonPkg --> App
  PythonPkg --> Tools["vdl.tools"]
  PythonPkg --> MCP2["MCP server<br/>pip install vdl[mcp]"]
  
  style StandaloneBinary fill:#0277bd,color:#fff
  style PythonPkg fill:#7b1fa2,color:#fff
  style MCP2 fill:#e65100,color:#fff

Install vdl Binary

Use the standalone installer when you want the commands without setting up a Python project:

curl -fsSL https://bildcraft.gitlab.io/products/video-downloader/vdl/install.sh | sh

This gives you:

  • vdl
  • vdl-mcp

Interactive Download App

Start the interactive app with:

vdl

It opens an interactive terminal interface:

VDL Interactive App

The app guides you through:

  1. Input — paste a URL, local file path, or .txt link list
  2. Quality — choose preferred resolution (best, 2160p, 1440p, 1080p, 720p, 480p, or audio)
  3. Output — set download directory (default: ~/Downloads/VDL)
  4. Options — save thumbnails and subtitles
  5. Mode — download directly or crawl the page for more links

Perfect for downloading single videos, playlists, or discovering downloadable media on websites.

The interactive app is intentionally stateful: it creates local app directories, SQLite state, and logs so it can provide history/status/session UX.

CLI Commands

Check the installed binary:

vdl --version

Run direct commands:

vdl download https://example.com/video
vdl crawl https://example.com/gallery --first 3
vdl crawl https://example.com/gallery --crawl-pagination --first 3
vdl playlist https://example.com/playlist
vdl resolve https://example.com/playlist
vdl status
vdl doctor

These headless commands are stateless by default. They do not implicitly create the interactive SQLite database or app logs.

Crawl-specific behavior is intentionally different from direct download and playlist flows:

  • vdl crawl ... --first 3 means first 3 successful downloads, not first 3 discovered links
  • crawl applies its own admission policy, including a default 7 MB minimum file size
  • --allow-tiny disables that crawl-only minimum
  • --crawl-pagination follows pagination/navigation pages discovered during crawl
  • direct downloads and playlists are not guarded by the crawl minimum, which keeps audio and other intentional small downloads working normally

When a site needs authentication, the headless commands can take cookies too:

vdl download --cookies cookies.txt https://example.com/video
vdl crawl --cookies-from-browser firefox https://example.com/gallery --first 3

Install as Python Library

Use the Python package when you want to embed VDL in another Python project:

pip install vdl

That gives you:

  • the vdl Python library
  • the vdl CLI
  • the interactive app entrypoint
  • vdl.tools

Use the library directly:

import asyncio

from vdl import CrawlerPolicy, VDLClient


async def main() -> None:
    client = VDLClient()
    result = await client.download("https://example.com/video")
    print(result.status)

    crawl_plan = await client.discover(
        "https://example.com/gallery",
        crawler_policy=CrawlerPolicy(crawl_pagination_pages=True),
    )
    crawl_results = await client.execute_plan(
        crawl_plan,
        crawler_policy=CrawlerPolicy(first_successful=3),
    )
    print(len(crawl_results))


asyncio.run(main())

The library is stateless by default and embeddable. Your application owns any database, history, user library, retries, or product-specific workflow state.

Use the tool surface:

import asyncio

from vdl.tools import download_video


async def main() -> None:
    result = await download_video("https://example.com/video")
    print(result["status"])


asyncio.run(main())

MCP Support

Install the MCP extra when you want vdl-mcp:

pip install "vdl[mcp]"

That adds MCP support on top of the Python package. If you installed the standalone binary, vdl-mcp is already included there too.

Example MCP client config:

{
  "mcpServers": {
    "vdl": {
      "command": "vdl-mcp",
      "args": []
    }
  }
}

Examples

Each demo in demos/ illustrates a single workflow:

Demo Use Case
download_video.py Download a single video
download_playlist.py Download an entire playlist
resolve_playlist.py Inspect playlist items before downloading
download_link_file.py Batch download URLs from a .txt file
crawl_websites.py Discover and download media on a webpage

All demos use placeholder URLs — copy and edit with your own.

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

vdl-1.0.5.tar.gz (1.4 MB view details)

Uploaded Source

Built Distribution

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

vdl-1.0.5-py3-none-any.whl (108.0 kB view details)

Uploaded Python 3

File details

Details for the file vdl-1.0.5.tar.gz.

File metadata

  • Download URL: vdl-1.0.5.tar.gz
  • Upload date:
  • Size: 1.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for vdl-1.0.5.tar.gz
Algorithm Hash digest
SHA256 81375149a4c467b870e27a09c3a644f487068f34832f28ef44f32ae668a11188
MD5 55a9eeba863889ceb98fed2014800dde
BLAKE2b-256 c5f431160b4a63cc2d772f4dd0cb788097c89db5c54120b88b38b4018be765e4

See more details on using hashes here.

File details

Details for the file vdl-1.0.5-py3-none-any.whl.

File metadata

  • Download URL: vdl-1.0.5-py3-none-any.whl
  • Upload date:
  • Size: 108.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for vdl-1.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 f3695c394680b44acbcaf498578e7999591694d3904c3db69869822b98308b3d
MD5 f610e319ed734d87e8eaf37c42f648df
BLAKE2b-256 bf4ff5a663c244fcf3c0849e1a51cdc11334fd2e7e4bd6be9947cf2efdaa73f5

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