The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Yt Mem AI listing page.
Give Claude, Codex, Cursor, or any MCP host the ability to watch YouTube for you: transcribe videos, remember them, follow your subscriptions, and turn all of it into summaries, timestamped highlights, Q&A, digests, and video reels. Everything runs on your machine — no cloud service, no API key.

One command, two questions — here it's wiring the skills into Codex.
Example — "make a presentation from this video" (Andrej Karpathy: From Vibe Coding to Agentic Engineering, Sequoia, 30 min) → 13 slides, PDF, every quote timestamped from the transcript. Ingest to deck in one request.
An interactive wizard opens. Pick what you want, tick your apps, press enter:
Plugin teaches your assistant to act on plain requests — "summarize this video". MCP gives it a set of tools instead. Not sure? Start with Plugin; you can run the wizard again for the other.
It installs everything it needs, ticks what you already have, and removes anything you untick (it shows a plan and asks first). Then restart the app and try: summarize 'https://youtu.be/…'.
Already know what you want? Skip the questions:
Hosts: --claude-code --claude-desktop --codex --cursor --antigravity
--openclaw --hermes, or --all. Full flag list and uninstall notes:
integrations/README.md. Rather have an agent do it?
Paste integrations/PROMPT.md into any assistant.
No prior install needed: uvx fetches the package the first time the host
launches the server, and keeps it cached afterwards. Drop this into your host's
MCP config:
That's the whole setup — no paths, no env block. Settings live in
~/.yt-mem-ai/config.env and the agent can write them itself with the
config_set tool (or you with yt-ai config set).
| Host | Where that JSON goes |
|---|---|
| Claude Desktop | macOS ~/Library/Application Support/Claude/claude_desktop_config.json · Windows %APPDATA%\Claude\claude_desktop_config.json — restart the app |
| Claude Code | claude mcp add -s user yt-mem-ai -- uvx --from 'yt-mem-ai[mcp]' yt-ai-mcp |
| Cursor | ~/.cursor/mcp.json (reload Cursor) |
| Antigravity | ~/.gemini/config/mcp_config.json (restart) |
| Codex | ~/.codex/config.toml — TOML, see below (or codex mcp add yt-mem-ai -- uvx --from 'yt-mem-ai[mcp]' yt-ai-mcp) |
| OpenClaw | openclaw mcp add yt-mem-ai --command uvx --arg --from --arg 'yt-mem-ai[mcp]' --arg yt-ai-mcp (or ~/.openclaw/openclaw.json → mcp.servers) |
| Hermes | ~/.hermes/config.yaml under mcp_servers: — YAML, see below |
Restart the app and the tools show up — see Usage for what they do.
Nothing appeared, or the host timed out? The first launch downloads dependencies and can outlast the host's startup check. Run
uvx --from 'yt-mem-ai[mcp]' yt-ai-mcp --helponce, then reopen the app. If the host still can't start it, give it absolute paths —uv tool install 'yt-mem-ai[mcp]'and usewhich yt-ai-mcpascommandwith"args": [](GUI apps often don't see~/.local/binon theirPATH).
Desktop stores plugins on your Claude account, not on disk, so nothing can install them for you. It takes a minute in the app:
Customize (left sidebar) → Plugins → Personal plugins → + → Add marketplace → Add from a repository →
https://github.com/dasein108/yt-mem-ai→ Add → Installyt-mem-ai
Then ask: summarize 'https://youtu.be/…'. Uninstall the same way. The same plugin also works on claude.ai and Cowork. Prefer tools over skills? The MCP setup above works for Desktop too — and that one can be scripted.
Each host loads SKILL.md files from a user-scope directory: Codex
~/.codex/skills/ (CLI and IDE share it, v0.117.0+), Cursor ~/.cursor/skills/,
Antigravity ~/.gemini/skills/, OpenClaw ~/.agents/skills/, Hermes
~/.hermes/skills/ (where they become /yt and /yt-agent).
Codex extras: the /yt-* prompts (integrations/codex/prompts/*.md →
~/.codex/prompts/) and integrations/codex/AGENTS.md → ~/.codex/AGENTS.md.
Full guide: skills/README.md.
The skills drive it, but it's a perfectly good standalone tool:
Needs Python 3.11+ and uv; ffmpeg only for
supercut / frame.
The desktop UI lives in a separate repo: yt-mem-ai-desktop — it depends on this package and runs its own local REST API.
Installed and host restarted? You're ready. Just talk to your assistant — the
skills (or MCP prompts + analyze_video) do the ingesting for you:
"Summarize https://youtu.be/dQw4w9WgXcQ" → ingests the video (captions → whisper), then writes an executive summary plus key points, in the video's own language.
"Give me the highlights of that video with timestamps" → 3–8 deep-linked moments (
watch?v=…&t=123s) anchored by semantic search.
"What did I watch about retrieval-augmented generation?" → searches every transcript in your library and quotes the moments.
"Process my subscriptions into today's digest" → discovers new uploads, ingests them, writes
digests/<DATE>.md.
Prefer the terminal? The same first run:
Everything lands in ~/.yt-mem-ai/ (library, logs, downloads).
The first run is slow — that's expected. Installing pulls the ML stack (torch, LanceDB, sentence-transformers ≈ 1 GB on disk), and your first
fetchorsearchdownloads the embedding model on top of that. If a video has no captions, the Whisper model (small, ≈ 460 MB) downloads too — the captions path never needs it. All of it is cached, so it happens once, not per video. On a GUI host the first MCP launch can outlast the app's startup check for the same reason: runuvx --from 'yt-mem-ai[mcp]' yt-ai-mcp --helponce in a terminal to warm the cache, then reopen the app.
Daily routine
then in your assistant: "process subscriptions" → per-video summaries and
digests/<DATE>.md, and optionally
yt-ai compile --out compilations/$(date +%F).md for the day's highlights as
clickable links.
Two skills ship with the plugin. MCP hosts get the same playbooks as prompts
(yt_summarize, yt_highlights, yt_qa, yt_presentation, yt_digest,
yt_review, yt_group), so nothing is lost without skill support.
| Skill | Use it for |
|---|---|
yt | the entry point — any operation and the full pipelines (daily routine, single video); hands analysis to yt-agent |
yt-agent | the scenarios — one video → summary / highlights / Q&A / presentation; subscriptions → daily digest; a cross-video review; a group of videos |
| What you say | What happens | Where it lands |
|---|---|---|
"summarize <url>" | ingest → executive summary + key points | chat, save_summary in the store |
"highlights for <url>" | 3–8 timestamped, deep-linked moments | chat + store |
"Q&A about <url>" | 3–6 grounded question/answer pairs | chat + store |
"make a presentation from <url>" | ----separated slide deck | slides/<id>.md |
| "process subscriptions" | discover → ingest → per-video analysis | digests/<DATE>.md |
| "review what I watched this week" | cross-video themes essay | reviews/<DATE>.md |
"analyze these videos: <ids/urls/channel>" | ingest a set → per-video + synthesis | groups/<label>.md |
Skills never touch the database directly — they call the CLI, so the same
workflow runs on any host. Install or paste them by hand:
skills/README.md.
The yt-ai-mcp server exposes the whole engine as typed tools. analyze_video
is the one-step entry point: it ingests and returns the transcript so the model
can write the summary itself.
| Category | Tool | Description |
|---|---|---|
| Analyze | analyze_video | Ingest a video and return its transcript (+ title, channel, language, existing summary). Call this first for any summarize / highlight / Q&A request. |
| Ingest | fetch | Download + transcribe + embed one video (force, captions_only, prefer_whisper). |
discover | New uploads from your subscription feed (incremental; after, deep, min_duration). | |
fetch_pending | Batch-ingest everything discovered since a date. | |
channel_list | Enumerate a channel's recent uploads (no ingest). | |
| Library | search | Hybrid / vector / FTS search over every chunk, with timestamps. |
show | Metadata + full transcript for one video. | |
list_videos | List stored videos by status / date / channel. | |
status | Counts by lifecycle status. | |
| Summaries | save_summary | Persist a summary + highlights + Q&A so compile and supercut can use them. |
| Taste | like / dislike | Record feedback for one video. |
recommend | Rank unrated videos by similarity to what you liked. | |
| Media | compile | Deep-linked highlights doc, budget-bounded by minutes. |
supercut | Render the highlight selection into one labeled mp4 (needs ffmpeg + network). | |
frame | Grab a still frame at a timestamp. | |
| Config | config_list / config_get | Inspect settings, values, and where each came from (secrets masked). |
config_set / config_unset | Change settings from chat — proxy creds, cookies browser, embedding model. | |
| Maintenance | reembed | Re-embed the whole library after changing the embedding model. |
Server details, prompt list, and raw config: integrations/mcp/README.md.
Case: a full PDF textbook from a 10-part YouTube course.
examples/defi-crypto-options.pdf — a
96-page Russian educational book built from the series «DeFi. Бесплатный
вводный курс по крипто-опционам» (@Menaskop).
Pipeline: identify the 10 series videos → pull ru-orig captions (yt-dlp +
browser cookies; no Whisper needed) → structured per-video digests → one shared
spine (glossary, notation, figure catalog) → 10 rewritten chapters (~28.5k words)
Nothing is required to start — defaults put the store, logs, and downloads
under ~/.yt-mem-ai/ and use a local embedding model. Tune it when you need to:
| Setting | What it does |
|---|---|
YT_STORE_PATH | LanceDB directory |
YT_EMBEDDING_BACKEND | local (sentence-transformers) or openai |
YT_EMBEDDING_MODEL | e.g. paraphrase-multilingual-MiniLM-L12-v2 for non-English libraries |
OPENAI_API_KEY | only for the openai embedding backend |
YT_COOKIES_BROWSER | chrome/firefox/… — fixes YouTube's "confirm you're not a bot" |
YT_CAPTION_LANGS | preferred caption languages (default en, falls back to any track) |
WEBSHARE_PROXY_*, YT_USE_WEBSHARE | optional rotating proxy |
YT_CHUNK_TARGET_S | chunk length for embeddings |
Configure from the CLI or an agent — instead of editing .env by hand, use
yt-ai config (or the MCP config_* tools, so an agent can reconfigure itself
from chat):
set writes the global config file (~/.yt-mem-ai/config.env) by default so the
MCP server picks it up regardless of its working directory; --project writes
./.env. Precedence: process env > project .env > global config file, and
config list shows which one each value comes from.
Everything below is optional reading — internals, tuning, and developer notes.
The CLI does the heavy IO and owns the store; the skills and MCP tools are thin
callers. A video moves through discovered → downloaded → transcribed → summarized; live streams get a terminal stream status and are skipped by batch
ingestion (transcribe one on demand with yt-ai fetch <url>). Storage is an
embedded LanceDB (videos, channels, transcripts, chunks, summaries,
feedback), with per-chunk vectors plus a full-text index — that's what makes
search hybrid.
Rate & recommend — like/dislike videos you've fetched, then yt-ai recommend ranks the rest by similarity to what you liked (minus what you
disliked), using their transcript embeddings. Before you've liked anything it
falls back to most-recently-published.
discover is incremental — it pulls the newest feed entries in one flat
call (capped by YT_DISCOVER_FEED_LIMIT), stamps each with an approximate
timestamp, and keeps only those newer than the last run's high-water mark minus
a 1h overlap (YT_DISCOVER_OVERLAP_S), so hour-rounded dates never miss a
boundary video. Already-processed videos are filtered out. --after YYYY-MM-DD
overrides the cutoff.
compile vs supercut — compile renders the day's highlights as markdown
deep links (watch?v=ID&t=<start>s), newest-video-first and bounded by
--max-minutes (default 20); it's instant and prints to stdout unless you pass
--out. supercut re-downloads each highlight's section at 720p, burns a label
onto it, and concatenates everything into supercuts/<date>.mp4 plus a
.refs.md sidecar listing sources (and any clips skipped after a failure) — much
slower, needs network + ffmpeg, but shareable.
Embeddings: YT_EMBEDDING_BACKEND=local|openai. Local uses
sentence-transformers (YT_EMBEDDING_MODEL, default all-MiniLM-L6-v2) — for
non-English libraries set paraphrase-multilingual-MiniLM-L12-v2 (384-d, 50+
languages) so semantic search works cross-language. openai uses
text-embedding-3-small|large (needs OPENAI_API_KEY). After changing the model,
run yt-ai reembed to migrate the existing library (re-embeds all chunks; no
re-fetch).
Proxy / VLESS: YT_USE_WEBSHARE defaults off. If you already run a
system-level proxy/VPN (VLESS/Xray etc.), leave it off — traffic rides that
tunnel. Stacking the Webshare proxy on top breaks the authenticated
subscription feed (its CONNECT tunnel returns 405). Only set
YT_USE_WEBSHARE=true if you have no other proxy and YouTube rate-limits your
raw IP. Discover tuning: YT_DISCOVER_FEED_LIMIT (newest-N cap, default 60),
YT_DISCOVER_OVERLAP_S (incremental overlap, default 3600), YT_DISCOVER_TIMEOUT_S.
Working from a checkout? uv sync --extra dev, then cp .env.example .env
if you'd rather keep settings project-local than in ~/.yt-mem-ai/config.env.
yt-mem-ai is a normal library — the CLI is a thin Typer shell over run_*
cores you can call directly. Everything is local: no server, no API key (unless
you pick the openai embedding backend).
Other cores, same shape (run_x(cfg, ..., db=db)): run_discover,
run_fetch_pending, run_channel_list, run_recommend, run_feedback,
run_compile, run_supercut, run_frame, run_reembed. Lower-level pieces
are importable too — yt_mem_ai.download.download, yt_mem_ai.transcript.get_transcript,
yt_mem_ai.store.embeddings.build_embedder / chunk_segments,
yt_mem_ai.store.db (LanceDB CRUD + search_chunks).
The store is plain LanceDB, so you can also open it directly:
The CLI writes structured JSON events to logs/common.jsonl (via
obs.log_event/blog) — one object per line, {ts, source, level, event, msg, ...ctx}. Override the path with YT_LOG_FILE; it's gitignored. Inspect with jq:
Version comes from the git tag (hatch-vcs). Tag, build, and publish:
scripts/publish.sh loads UV_PUBLISH_TOKEN from .env (gitignored) on demand,
so you don't export it each time — add UV_PUBLISH_TOKEN=pypi-… to .env once
(see .env.example). Equivalently: set -a; . ./.env; set +a; uv publish dist/*.
Rotate the token on PyPI if it's ever exposed.