Skip to main content

YouTube downloader for AI assistants (MCP) and humans (TUI). Subtitles + search + persistent history. Minimal CLI core; TUI and MCP are optional extras.

Project description

yoink - MCP YouTube downloader for AI assistants

yoink

MCP server that lets AI assistants download YouTube videos.
Give Claude, Cursor, or any MCP-compatible AI the ability to download YouTube videos, playlists, and audio through natural language. Also ships with a terminal UI for humans.

MCP Enabled PyPI Python 3.10+ MIT License

pip install yoink-yt  ·  MCP Setup  ·  Terminal UI  ·  API Reference



What is yoink?

yoink is an MCP (Model Context Protocol) server that gives AI assistants like Claude Desktop, Cursor, Windsurf, and other MCP-compatible tools the ability to download YouTube videos on your behalf.

It also ships with a standalone terminal UI (TUI) for when you want to download videos yourself.

The problem

Every YouTube downloader makes you do the work — find the URL, open a tool, pick a format, wait for it, rename the file, repeat.

The yoink way

Just tell your AI assistant what you want:

"Download the latest 3Blue1Brown video in 720p"

"Grab that playlist as audio-only MP3s"

"Download this lecture with subtitles to my Desktop"

Your AI handles the entire workflow — resolves the URL, picks the format, starts the download, tracks progress. No copy-pasting. No menus. Just ask.


⚡ Quick Start

Pick your install — yoink ships a tiny CLI core, with TUI and MCP as optional extras:

pip install yoink-yt              # plain CLI only (just yt-dlp)
pip install 'yoink-yt[tui]'       # + Terminal UI (textual)
pip install 'yoink-yt[mcp]'       # + MCP server for AI assistants
pip install 'yoink-yt[all]'       # everything

[!IMPORTANT] Upgrading from 0.1.x? As of 0.3.0 the TUI and MCP server are optional extras and download history is persisted to ~/.yoink/state.db. If yoink or yoink-mcp errors after upgrading, reinstall with the extra you need: pip install --upgrade 'yoink-yt[all]'.

For AI assistants (MCP server)

pip install 'yoink-yt[mcp]'
yoink-mcp

Add to Claude Desktop, Cursor, or any MCP client — your AI gets 7 YouTube tools instantly.

For humans (terminal UI)

pip install 'yoink-yt[tui]'
yoink

A full terminal UI with progress bars, quality picker, playlist support, and keyboard shortcuts.

Just want to grab a video from your shell? No extras needed:

pip install yoink-yt
yoink-cli "https://youtu.be/..." -q 720

[!TIP] Install ffmpeg for best results — needed to merge video+audio streams and convert to MP3.

brew install ffmpeg          # macOS
sudo apt install ffmpeg      # Ubuntu/Debian

🤖 MCP Setup for AI Assistants

yoink exposes 7 tools via the Model Context Protocol over STDIO, giving any MCP-compatible AI assistant full YouTube download capabilities.

Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "yoink": {
      "command": "yoink-mcp"
    }
  }
}

Restart Claude Desktop. Done — Claude can now download YouTube videos.

Claude Code

Add to your .mcp.json:

{
  "mcpServers": {
    "yoink": {
      "command": "yoink-mcp",
      "type": "stdio"
    }
  }
}

Cursor / Windsurf / Other MCP Clients

Any MCP client that supports STDIO transport works. Point it at yoink-mcp as the command.

Using uv (from source instead of pip)
{
  "mcpServers": {
    "yoink": {
      "command": "uv",
      "args": ["--directory", "/path/to/yoink", "run", "yoink-mcp"]
    }
  }
}

Example prompts for your AI

What you say What yoink does
"Find me the latest 3Blue1Brown video and summarize it" search_youtubeget_subtitles → AI summarizes from transcript
"Summarize this video: [url]" get_subtitles → AI works from the transcript text directly
"Download this video: [url]" Downloads in best quality to ~/Downloads
"Get the 720p version of [url]" Fetches formats, picks 720p, downloads
"Download this playlist as audio" Gets playlist info, downloads each as audio
"What formats are available for [url]?" Lists all quality options with file sizes
"Show me what I downloaded last week" list_downloads reads persisted history
"Cancel the download" Stops an in-progress download
"What's the progress?" Shows status of all active downloads
"Download [url] and let me know when it's done" download_and_wait streams progress until finished
"Convert [url] to MP3" Downloads audio and converts to MP3

🔌 MCP Tools API Reference

These are the 10 tools your AI assistant gets access to when yoink is configured as an MCP server:

Tool Description Key Parameters
search_youtube NEW in 0.3.0. Search YouTube and return matching videos. Lets the AI find URLs without leaving the conversation. query, limit
get_subtitles NEW in 0.3.0. Fetch a video's transcript as plain text (manual subs preferred, auto-captions fallback). The single biggest enabler for "summarize this video" / Q&A workflows. url, lang
get_video_info Fetch video metadata (title, duration, uploader, available formats) url
get_playlist_info List all videos in a YouTube playlist url
get_formats List available download qualities with file sizes url
start_download Start downloading a video, returns a tracking ID. Now supports idempotency_key for safe retry. url, format_string, output_dir, idempotency_key
download_and_wait NEW in 0.3.0. Download a video and stream progress notifications until it finishes. Best when the AI needs the file before the next step. url, format_string, output_dir
list_downloads List recent downloads (active + persisted history). Survives MCP server restarts. limit
get_download_progress Check status of a specific download by ID download_id
cancel_download Cancel an active download download_id

[!NOTE] Idempotency & dedup. Pass idempotency_key to start_download to make retries safe across restarts — a second call with the same key returns the existing download_id. Active-URL dedup is also built in: a duplicate URL while one is in flight returns error_code: duplicate_active.

[!NOTE] Structured errors. Every error response includes an error_code field (bot_check, rate_limited, age_restricted, ffmpeg_missing, ...) so the AI can branch on the failure mode instead of regex-matching messages.

[!NOTE] Persistent history. Download state is mirrored to ~/.yoink/state.db (SQLite) so list_downloads returns history across MCP server restarts. Delete the file to reset.


🎬 Terminal UI for Humans

For when you want to download videos yourself. A full-featured TUI powered by Textual.

yoink              # default: 3 concurrent downloads
yoink -j 5         # up to 10

Keyboard shortcuts

Key Action
/ Focus URL input
d Start download
r Retry last failed
a Select all (playlist)
n Select none (playlist)
q Quit

Features

Feature Details
Quality picker 1080p down to audio-only
Playlists Search, filter, batch download
Audio-only One-click, or convert to MP3
Subtitles Auto-generated + manual subs
Speed limit e.g. 5M for 5 MB/s cap
Output dir Editable save path
Retry One click on failed downloads
Open folder One click on finished

🛠 Architecture

src/yoink/
├── __main__.py        # python -m yoink → CLI
├── cli.py             # Plain argparse CLI (no optional deps)
├── core/              # Shared engine (used by CLI, MCP, TUI)
│   ├── models.py      # Stdlib dataclasses — no pydantic
│   ├── errors.py      # ErrorCode enum + classify_error pattern matcher
│   ├── extractor.py   # YouTube metadata, search, subtitle extraction
│   ├── engine.py      # Single download executor with progress hooks
│   ├── state.py       # SQLite-backed download history (~/.yoink/state.db)
│   └── manager.py     # Concurrent orchestration + dedup + idempotency
├── mcp_server/        # [mcp] extra — MCP interface for AI assistants
│   └── server.py      # FastMCP server with 10 tools over STDIO
└── tui/               # [tui] extra — Terminal UI for humans
    ├── app.py         # Lazy-loading entry point
    ├── _impl.py       # Textual application (only imported when [tui] installed)
    ├── screens/       # Main screen, format picker modal
    ├── widgets/       # URL bar, video panel, playlist panel, download queue
    └── styles/        # Textual CSS styling

The CLI, MCP server, and TUI are thin wrappers around the same core engine. The core handles all yt-dlp interaction, threading, progress tracking, and error handling — and depends only on yt-dlp plus the Python stdlib.

Design decisions
  • Threading model: yt-dlp is synchronous, so each download runs in its own thread via ThreadPoolExecutor. A FIFO dispatcher thread ensures downloads start in submission order.
  • Progress reporting: Hooks are rate-limited to 100ms intervals to avoid callback floods in both MCP and TUI contexts.
  • Playlist optimization: Uses extract_flat to avoid fetching full metadata for large playlists upfront.
  • Error handling: Raw yt-dlp errors are pattern-matched against 15 common cases and translated to user-friendly messages.
  • Duplicate detection: The download manager tracks active URLs and rejects duplicates at the engine level, with a force bypass for retries.
  • Cancellation: Uses threading.Event checked in every progress hook callback for responsive cancellation.
  • Minimal core: Data contracts are stdlib @dataclass — no pydantic, no third-party validation library. The CLI install pulls only yt-dlp.
  • Lazy extras: Importing yoink.tui.app or yoink.mcp_server.server succeeds even without the [tui] / [mcp] extras; missing extras surface a friendly install hint when the entry point runs, not at import time.
  • Durable state: ~/.yoink/state.db is a single SQLite file with WAL mode; reads concurrent, writes serialized via lock. Multiple yoink processes share the same history.
  • Subtitle parsing: Pure-stdlib WebVTT parser strips cue headers and YouTube's inline word-level <00:00:01.000> timing tags, deduplicates consecutive identical lines (auto-captions overlap heavily).
  • Search: yt-dlp ytsearchN:query extractor with extract_flat=True — no per-result fetch.

🔧 Development

git clone https://github.com/JayshKhan/yoink.git
cd yoink
pip install -e ".[dev]"    # all extras + pytest
pytest                     # ~130 tests
yoink-cli --help           # plain CLI
yoink                      # TUI
yoink-mcp                  # MCP server

Frequently Asked Questions

What AI assistants work with yoink?

Any AI assistant that supports the Model Context Protocol (MCP) over STDIO transport. This includes Claude Desktop, Claude Code, Cursor, Windsurf, and any custom MCP client.

Does it only work with YouTube?

yoink uses yt-dlp under the hood, which supports thousands of sites. However, yoink is optimized and tested for YouTube. Other sites may work but are not officially supported.

Can I use the MCP server and TUI at the same time?

They are separate processes with separate download managers, so yes. They won't share state or conflict with each other.

Where do downloads go?

By default, ~/Downloads. The MCP start_download tool accepts an output_dir parameter, and the TUI has an editable path below the URL bar.

What if ffmpeg is not installed?

You can still download videos, but some quality options that require merging separate video and audio streams won't work. MP3 conversion also requires ffmpeg.


📄 License

MIT — do whatever you want with it. Yoink responsibly.


Powered by yt-dlp · UI by Textual · AI integration via MCP

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

yoink_yt-0.3.0.tar.gz (471.9 kB view details)

Uploaded Source

Built Distribution

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

yoink_yt-0.3.0-py3-none-any.whl (416.4 kB view details)

Uploaded Python 3

File details

Details for the file yoink_yt-0.3.0.tar.gz.

File metadata

  • Download URL: yoink_yt-0.3.0.tar.gz
  • Upload date:
  • Size: 471.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for yoink_yt-0.3.0.tar.gz
Algorithm Hash digest
SHA256 2417601e41e8151083a921ddfe619bb50c383b83395a682f886cee8b38d795e6
MD5 2360a2ba974f79f4fa12d39b5ca441a5
BLAKE2b-256 75ba1e8b91c189f75f4ebe5e628dbc72d29b0bcff7183b11e5e22c6da68548aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for yoink_yt-0.3.0.tar.gz:

Publisher: publish.yml on JayshKhan/yoink

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yoink_yt-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: yoink_yt-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 416.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for yoink_yt-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 29502a6c15bf89521093f437a909907c91fd7fd89829d9fd0b2f020cc995be19
MD5 cfc44b21d64f00588a3d5d771ea92c60
BLAKE2b-256 0cbcd8911579b8932a8916ae31504b8744c933dd3d6f4ef8dcead890b7699200

See more details on using hashes here.

Provenance

The following attestation bundles were made for yoink_yt-0.3.0-py3-none-any.whl:

Publisher: publish.yml on JayshKhan/yoink

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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