yt-cc
Skill0 starsChanged 49 days agoMITView on GitHub
Pull a video's captions, description and metadata to local markdown in one command, then read it; a channel or playlist URL pulls every video on it. Use when the user pastes a video or channel link, asks what a video says, or wants quotes or a claim checked against it. Also serves a local board of every transcript grabbed. Not for what is shown on screen rather than spoken (code, a diagram, a UI, a slide read silently).
- Installs packages
In this repository17 other files it gives its agents.
- AGENTS.mdAGENTS.md
- skills/humanizer/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- cherrypickerSkill
- copyable-markdownSkill
- deltamaxxSkill
- docs-mirrorSkill
- ffmpegSkill
- humanizerSkill
- prompt-packSkill
- socials-mirrorSkill
- spamcheckSkill
- tool-call-repairSkill
- writing-beatsSkill
- writing-for-agentsSkill
- writing-fragmentsSkill
- writing-shapeSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 14
Read the file it prints. That is the whole flow.
- Distinctive: line 102
Say which caption source you used: when you quote or make a claim from the text, because auto captions mishear names.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
yt-cc
One command, one file, stdlib only. It prints the transcript path to stdout.
python3 scripts/ytcc.py "<url>"Read the file it prints. That is the whole flow. Everything else on this page is for when the first line does not do what you need.
Paste the link as you got it. A youtu.be/ID?si=… share link, a /shorts/ or
/live/ link, m.youtube.com, a bare 11-character video id, or a bare
@handle all resolve to the same canonical URL, and share and tracking
parameters (si=, feature=, utm_*, fbclid) are stripped before the URL
is used or written to meta.json. The cleaned URL is echoed to stderr when it
differs from what was pasted.
What comes back
A directory per video under the store, named by video ID:
| File | What it is |
transcript.md | H1, a channel/duration/published/URL line, a source line, ## Description (the creator's own text: links, tools, corrections), ## Chapters when the video has them, then ## Transcript with **[MM:SS]** marks about once a minute |
transcript.json | the same cues as {"t": seconds, "text": "..."}, for programmatic use |
meta.json | title, channel, duration, url, upload_date, view_count, like_count, tags, description, chapters, cue count, caption source |
thumb.jpg | poster frame, when the extractor supplies one |
video.mp4 | only with --video |
The Source: line in transcript.md says manual captions, auto
captions, or no captions. Manual means a human wrote them and the text is
worth quoting verbatim. Auto means machine captions: usable for meaning, weak on
proper nouns and punctuation. Say which one you used when you quote it.
A whole channel or playlist
python3 scripts/ytcc.py "https://www.youtube.com/@handle" -n 25A /@handle, /channel/, /c/, /user/, /playlist or list= URL is
taken as a collection without a flag. It lists the videos in one request
(newest first), skips any already in the store, grabs the rest 1.5 s apart,
prints a summary to stderr and the store path to stdout. Re-running next week
costs one listing plus whatever is new. Use -n the first time on an
unfamiliar channel: find out it has 3,000 videos before fetching 3,000.
Flags
| Flag | Use |
-n N (--limit) | newest N only, in collection mode |
--channel (--all) | force collection mode for a watch?v=...&list=... link |
--delay S | seconds between videos in collection mode. Default 1.5; raise it if YouTube starts rate-limiting |
--video (-v, +video) | also download the mp4. Slow, large, and only needed when the answer is visual |
-d DIR (--dir, --store) | write to DIR instead of the default store |
serve | run the web board instead of grabbing |
--selftest | check the URL cleaner against known link forms, no network |
--help | usage |
Environment
| Variable | Default | Why you would set it |
YTCC_STORE | $XDG_DATA_HOME/yt-cc, else ~/.local/share/yt-cc | keep transcripts with a project instead of in the home store |
YTCC_COOKIES_BROWSER | unset | chrome, safari, or brave. Fixes HTTP 403 on video download by borrowing browser cookies |
YTCC_HOST / YTCC_PORT | 127.0.0.1 / 8091 | where the board listens |
The board
python3 scripts/ytcc.py serveServes every grabbed video as a card at http://127.0.0.1:8091, newest first,
with search. It binds loopback. To reach it from a phone or tablet, front it
with tailscale serve rather than binding it to all interfaces.
Requirements
python3 and yt-dlp. The script finds yt-dlp on PATH, or falls back to
python3 -m yt_dlp, and tells you how to install it if neither works
(brew install yt-dlp on macOS, pipx install yt-dlp on Debian or WSL).
Rules
- The saved file is the evidence. Answer a video question from
transcript.md(its description and its captions), not from a fetch of the video page, the title, or a search result. - A video with no English captions still gets its description and metadata
saved. The
Source:line saysno captionsand there is no## Transcriptsection. Say so; answer from the description if it answers the question.--videosaves the file so a different tool can work on it. The description is often the easy win: links, the tool list, the pinned correction. Read it before the transcript. - Say which caption source you used when you quote or make a claim from the text, because auto captions mishear names.
- Re-running a URL is cheap. The store is keyed by video ID and existing files are reused. Run it again rather than assuming a transcript is stale.
- Content shown on screen is unrecoverable from any transcript. Code on a slide, a diagram, a UI being demoed, a prompt read silently. If that is the question, this is the wrong tool and no amount of retrying changes it.
Why this exists
Watching costs an hour per hour. Feeding video frames to a model costs real money per minute. A caption track is text the publisher already produced and already serves, and pulling it is one HTTP request. Measured on a 256-video corpus: 7,399 minutes of talk, 8.3 MB of markdown, no API spend.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

