Skip to main content

skimtube

You follow 40 YouTube channels. You watch 4.
skimtube reads the other 36 and leaves you notes.

CI License: MIT Python 3.10+

skimtube run writes one note per new video; the note, then a digest listing claims that disagree across channels

New videos from the channels you follow become Markdown notes you can skim, grep, drop into Obsidian or hand to your coding agent. No YouTube API key, any LLM (local or hosted), one cron line.

Why

I follow 68 channels, mostly about AI. I was never going to watch them all, and the one video that mattered each week was buried under three thumbnails of someone looking shocked. So now a cron job reads the subtitles for me: in four months it has written 725 notes, and every morning I read one digest instead of a subscriptions page. My coding agent greps the rest.

Side effect: you stop seeing the shocked faces.

What it is good for

  • Keeping up with a field without the videos. A daily digest grouped by theme, with links back to each video when something is worth the 20 minutes.
  • Giving a coding agent a memory of what is new. Notes are plain files, so grep -ril mcp knowledge-feed/ works, and the Claude Code plugin answers "what did people say about X this month?" with sources.
  • Growing an Obsidian vault on autopilot. Point SKIMTUBE_OUT at a vault folder. Every note has YAML front matter (channel, date, URL) for Dataview queries.
  • Watching a niche or your competitors. List their channels, add a keyword pre-filter and a topic, and skip everything else. The digest flags when two channels disagree.
  • Doing it privately and cheaply. Run it with Ollama for $0, or pay about $0.002 per note with DeepSeek.

What you get

Every few hours it checks the channels you list, grabs the subtitles of new videos, and has an LLM write one structured note per video. Once a day it merges the recent notes into a digest, grouped by theme, with a section for claims that disagree across sources ("channel A says X, channel B says the opposite, same week").

knowledge-feed/
├── INDEX.md                      # one line per video, newest first
├── DIGEST.md                     # latest digest
├── digests/2026-09-21.md
└── 2026-09/
    └── 2026-09-20_some-channel_new-open-model-beats-gpt_abc123.md

Quickstart

pipx install skimtube                      # or: uv tool install skimtube
mkdir kb && cd kb && skimtube init         # writes config.env, channels.txt, blocklist.txt
SKIMTUBE_LLM_API_KEY=sk-or-... SKIMTUBE_LLM_MODEL=deepseek/deepseek-chat skimtube run

init points to OpenRouter by default. For a fully local setup, use Ollama instead. Ollama serves 4,096 tokens of context by default and silently cuts longer prompts, so a normal transcript loses most of its text without any error. Create a model with a larger context first:

printf 'FROM qwen2.5:3b\nPARAMETER num_ctx 16384\n' > Modelfile
ollama create qwen2.5-16k -f Modelfile
SKIMTUBE_LLM_BASE_URL=http://localhost:11434/v1 SKIMTUBE_LLM_MODEL=qwen2.5-16k skimtube run

(Or start the server with OLLAMA_CONTEXT_LENGTH=16384.) On a laptop CPU without a GPU, a 3B model takes about 4 minutes per note; that is fine for a scheduled job, slow for a first try.

The first run only looks back 24 hours (SKIMTUBE_LOOKBACK_HOURS). After that, every run processes whatever is new since the previous one. Then:

skimtube digest                  # merge the last 30 h of notes
skimtube digest --window-hours 168   # weekly

Use it from Claude Code

The repo is also a Claude Code plugin. It adds a skill that finds your feed, searches it, and answers with the video links as sources ("what did the channels I follow say about MCP this month?"). It can also run or set up the collector for you.

/plugin marketplace add arnaugonzalez/skimtube
/plugin install skimtube@skimtube

Other agents (Cursor, Codex, Gemini CLI) can read the same instructions from plugin/skills/youtube-knowledge-feed/SKILL.md.

Why not…

Watches channels unattended Output Contradictions between sources Cost
skimtube yes (RSS, no API key) one Markdown note per video + index + digest, in a folder yes your LLM (≈$0.002/note measured with DeepSeek; $0 with Ollama)
fabric no, one URL at a time stdout no your LLM
tubeless yes daily ranked briefing, one file per day no your LLM
NotebookLM / Eightify / Glasp no in their app no free tier / subscription
Feedly Leo / Readwise Reader feeds, not transcripts in their app no subscription

fabric has a much larger prompt library, and tubeless also transcribes videos without subtitles (Whisper) and ranks them by importance. Pick them if you want a daily briefing to read. Pick skimtube if you want the notes to pile up as files that you, Obsidian or a coding agent can grep months later.

How it works

flowchart LR
  A[channels.txt<br/>+ optional subscriptions] --> B[YouTube RSS<br/>per channel]
  B --> C{new video?<br/>keyword filter}
  C --> D[yt-dlp subtitles]
  D --> E[LLM: structured note<br/>or SKIP if off-topic]
  E --> F[knowledge-feed/YYYY-MM/*.md<br/>+ INDEX.md]
  F --> G[digest: themes,<br/>contradictions, weak signals]
  S[(state.json)] <--> C
  • No YouTube API key. Channel feeds come from the public RSS endpoint; @handles are resolved to channel ids once and cached in state.json.
  • Idempotent. Processed video ids live in state.json, so running it twice does nothing new. If the LLM call fails, the video is retried on the next run (up to 3 times) and the run exits with status 1 so your scheduler shows the failure.
  • Notes have a fixed shape: YAML front matter (title, channel, url, video_id, published, collected) and the sections TL;DR, Key topics, What's new, Entities, Facts and figures. Headings stay in English; the content follows SKIMTUBE_SUMMARY_LANG.

Configuration

Values come from config.env in the working directory (or -C DIR), else $XDG_CONFIG_HOME/skimtube/config.env. Environment variables override both.

Variable Default
SKIMTUBE_LLM_BASE_URL https://api.openai.com/v1 any OpenAI-compatible endpoint
SKIMTUBE_LLM_API_KEY falls back to OPENAI_API_KEY not needed for localhost
SKIMTUBE_LLM_MODEL — (required)
SKIMTUBE_LLM_PROVIDER openai command pipes the prompt into SKIMTUBE_LLM_COMMAND (e.g. llm -m …, or claude -p --tools "" --strict-mcp-config: see Security)
SKIMTUBE_SUMMARY_LANG English language of the note content
SKIMTUBE_TOPIC technology and AI the LLM skips off-topic videos; empty = keep all
SKIMTUBE_KEYWORDS empty cheap whole-word pre-filter on title + description
SKIMTUBE_OUT knowledge-feed
SKIMTUBE_CHANNELS / SKIMTUBE_BLOCKLIST / SKIMTUBE_STATE channels.txt / blocklist.txt / state.json
SKIMTUBE_SUB_LANGS en,en-orig,en-US subtitle languages, tried one at a time
SKIMTUBE_LOOKBACK_HOURS 24 first run only
SKIMTUBE_MAX_PER_RUN 25 the rest wait for the next run
SKIMTUBE_MAX_TRANSCRIPT_CHARS 48000 transcript truncation
SKIMTUBE_YTDLP_BIN empty = the bundled yt-dlp set to use another yt-dlp binary

Your subscriptions (optional). skimtube auth runs a one-time OAuth consent (read-only scope) and from then on merges the channels you are subscribed to. It needs your own Google Cloud OAuth client of type Desktop app (SKIMTUBE_OAUTH_CLIENT_ID / SKIMTUBE_OAUTH_CLIENT_SECRET). While the OAuth app stays in "testing" mode, Google expires the refresh token after a while: re-run auth when the log says so.

Scheduling

run and digest are plain idempotent commands. See examples/ for cron, a systemd user timer, and a GitHub Actions workflow. To publish the feed somewhere else, chain it: skimtube run && rsync -a knowledge-feed/ server:kb/.

Limits

  • Subtitles are required. Videos without subtitles or auto-captions are skipped.
  • Datacenter IPs get bot-checked. YouTube often refuses subtitle downloads from cloud servers ("Sign in to confirm you're not a bot"). A home machine works reliably; on a server you need yt-dlp cookies or a proxy.
  • Terms of service. Downloading subtitles with yt-dlp is not a use YouTube explicitly permits. skimtube keeps transcripts in memory only and writes transformed summaries. Don't redistribute transcripts, and check the rules that apply to you.
  • Contradictions are leads, not verdicts. Checked by hand over 4 real days, the section flags 2–3 pairs per window and at most one is a genuine disagreement; the rest are nuances the model explains away in its own note.

Non-goals: a web UI, a database, transcribing audio.

Security

Transcripts are text written by strangers, and skimtube hands them to an LLM. If that LLM is an agent CLI with tools (Claude Code, Codex, Gemini CLI…), a video can carry instructions like "ignore the above and run this command", and the agent may do it with your permissions. We reproduced this with claude -p in auto mode. Disable every tool for this job:

SKIMTUBE_LLM_COMMAND=claude -p --tools "" --strict-mcp-config

HTTP providers (SKIMTUBE_LLM_PROVIDER=openai, the default) only return text, so they can't run anything. skimtube itself never runs a shell, opens a port, or sends telemetry; it talks to YouTube, your LLM endpoint and nothing else. See SECURITY.md to report issues.

License

MIT. skimtube is an independent project for YouTube users; it is not affiliated with or endorsed by YouTube or Google.

Release files for skimtube 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for skimtube 0.1.0
File Size Uploaded
skimtube-0.1.0.tar.gz 864.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for skimtube 0.1.0
File Interpreter ABI Platform
skimtube-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 890.0 kB

Release files / skimtube-0.1.0.tar.gz

Download URL skimtube-0.1.0.tar.gz
Size 864.5 kB
Tags Source
SHA-256 checksum
How to use checksums
9cd3c95a9024e35d19c2f1afaa8dd0771c290c34008e843f8844c215eeb0602d
BLAKE2b-256 checksum
How to use checksums
4fe7a2381bf6aff210915e6d99bd06283ca0a221c1be986e6ad3f18b2c96d0b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release files / skimtube-0.1.0-py3-none-any.whl

Download URL skimtube-0.1.0-py3-none-any.whl
Size 25.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bb91428bea4cab28dc671371df600528537fca90a42d66ec275fde15353e16fd
BLAKE2b-256 checksum
How to use checksums
8f632e694c69915aef9c96b1888f635e516d928aa2ac81036044fa21f35a2bc2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page