YouTube Fetcher to Markdown
Turn any YouTube video into an Obsidian-ready archival note with full metadata, linked timestamps, and language control — no API key required.
Least privilege is strong: only YouTube captions/oEmbed are contacted; the yt-dlp subprocess disables user config, caching, and playlists with bounded timeouts (test-verified); writes are atomic with overwrite and symlink refusal. Deductions: --force is a destructive, irreversible replacement with no undo — rollback rests solely on the safe default; LICENSE copyright reads 'GimySadek' while the repo is 'JimmySadek'; dependencies are loose version ranges with no integrity/audit notes.
Tests and README claims align closely (language selection, file protection, exit codes, timeouts all have contract tests); failure messages are verified actionable and do not leak sensitive details. Deduction: availability against YouTube's undocumented interface cannot be statically guaranteed, and the README itself concedes offline tests do not ensure access.
Serves Obsidian users, CLI users, and multiple agents; broad URL-shape coverage with tests; capability boundaries (no video download, no Whisper, no speaker ID) are explicit; multi-OS CI and venv guidance are complete. Deduction: SKILL.md itself is not in evidence, so trigger precision is only indirectly supported by bundle tests.
Clear information architecture, three-platform install notes, rich examples, troubleshooting and exit-code tables, candid limitations. Deductions: no in-repo CHANGELOG (only external release links); the retained legacy master branch creates dual-branch confusion; LICENSE copyright name mismatches the repo owner; maintainer identity is unverified and the documented release process cannot be statically confirmed as followed.
High output usability: YAML frontmatter, Dataview compatibility, multi-format exports, timestamp links are all test-backed; cost is minimal (no API key, local, optional deps). Deduction: many transcript tools exist; marginal value lies mainly in metadata integration and overwrite safety — an increment, not a unique capability.
Many README claims are directly corroborated by test files (exit code 3, atomic writes, language fallback, translation labeling); referenced specs/ verification records are not in evidence and cannot be checked; facts are separated from snapshot data and machine translation is explicitly labeled non-human. Deduction: the verification documents themselves are unreviewable here, and some claims (Windows behavior, CI status) rest on assertion alone.
- --force fully replaces the destination (including user annotations) with no undo; back up before using it. The default (exit code 3) preserves existing files.
- LICENSE copyright holder 'GimySadek' mismatches repo owner 'JimmySadek', and the publisher is unverified — confirm provenance and commit history before trusting.
- Dependencies are not hash-locked (no lockfile); review requirements.txt and install in an isolated environment.
- Relies on YouTube's undocumented caption interface and may break or be blocked at any time; the script offers no bypass — do not add cookies or proxies yourself.
- main is canonical; master is only a legacy mirror — do not develop on or cite master.
What does this agent do, and when should you use it?
YouTube Fetcher to Markdown (JimmySadek/youtube-fetcher-to-markdown) is a portable AI-agent skill whose core is a Python script, scripts/fetch_transcript.py, that converts a YouTube link into a structured archival Markdown note. Each capture includes the full transcript, title, channel, duration, upload date, description, chapters, the actual caption language, and provenance, written to a single file with YAML frontmatter that is queryable in Obsidian via Dataview and portable to Logseq or plain-text workflows. Data comes from YouTube's undocumented caption interface (via youtube-transcript-api) and oEmbed, with yt-dlp as an optional dependency for richer metadata. It supports manual and auto-generated captions, ordered language preferences, strict language matching, explicit labeled YouTube machine translation, and exports to txt, JSON, SRT, and WebVTT. Installation follows the portable SKILL.md format, so the same command works with Codex, Claude Code, Cursor, Windsurf, Gemini CLI, and other compatible agents, while manual users can run the Python script directly. The project is MIT-licensed with no API keys and no hosted service.
Running python3 scripts/fetch_transcript.py "https://youtu.be/VIDEO_ID" performs the following: 1) Parses many YouTube input formats (standard watch URLs, youtu.be short links, /embed/, /shorts/, /live/, legacy /v/, mobile and YouTube Music URLs, youtube-nocookie embeds, raw 11-character video IDs), rejecting lookalike hosts. 2) Fetches manual or auto-generated captions through youtube-transcript-api's undocumented caption interface, selecting tracks via --lang preferences (e.g. --lang fr,de) or --lang auto, with --strict-lang disabling English fallback and --translate en triggering explicit labeled YouTube machine translation. 3) Gathers title, channel, duration, upload date, description, and chapters via optional yt-dlp or oEmbed; --no-metadata skips both providers. 4) Produces a Markdown file such as ~/yt_transcripts/2026-03-04_title_[videoID].md containing YAML frontmatter (title, channel, url, video_id, fetched, language, caption_type, duration, upload_date, tags, etc.), a metadata table, the video description, and the full transcript. 5) --timestamps adds clickable timestamp links; --format switches to txt//srt/vtt exports; --stdout prints the result without writing a file. Writes go through a temporary sibling file with hard-link or exclusive-creation semantics; an existing destination is preserved with exit code 3 unless --force is given. Output location priority is --output, --output-dir, YOUTUBE_FETCHER_DIR, then the default ~/yt_transcripts/.
- Obsidian users building a video knowledge base: archive course and lecture transcripts with metadata into a vault, queryable by channel, date, and language via Dataview.
- Content researchers collecting material: capture descriptions, chapters, and transcripts of competitor or topic videos, exporting SRT/VTT for later editing or analysis.
- Multilingual learners: force Japanese captions with
--lang ja --strict-lang, or obtain an English version labeled as machine translation via--translate en. - AI agent users (Claude Code, Codex, Cursor, etc.): after installing the skill, paste a YouTube link in conversation and the agent produces a note file automatically.
- Podcast/livestream archivists: batch-archive accessible captions from /live/ or YouTube Music links while keeping an auditable record of source URLs and capture dates.
What are this agent's strengths and limitations?
- Archival completeness: goes beyond raw caption text to include source URL, creator, capture date, actual language, description, chapters, and a predictable filename — all in one local file.
- Careful language handling: ordered language preferences, regional variants (es can match es-MX), strict matching mode, and explicitly labeled machine translation, with selection results recorded in frontmatter.
- Rigorous file safety: every format preserves existing files by default (exit code 3), writes use a temporary file with hard-link/exclusive creation, symbolic-link replacement is refused, and safe in-place refreshes are supported.
- Strong portability: follows the SKILL.md format, so one install command covers Codex, Claude Code, Cursor, Windsurf, and Gemini CLI; it also runs standalone without any agent.
- Relies on YouTube's undocumented caption interface, so YouTube changes or network blocking can break capture; passing offline tests does not guarantee access.
- Private, restricted, or caption-disabled videos cannot be processed, and the script never fabricates or summarizes a missing transcript.
- The optional yt-dlp metadata dependency requires extra installation and PATH setup; without it, only limited title/channel data is available via oEmbed.
- No speech recognition (Whisper), speaker identification, or visual analysis; caption recognition errors are preserved as-is.
How do you install or deploy this agent?
1) Install the skill: npx skills add JimmySadek/youtube-fetcher-to-markdown, or clone the repository: git clone https://github.com/JimmySadek/youtube-fetcher-to-markdown.git. 2) Create an isolated Python environment in the skill directory (Python 3.8–3.14 supported, 3.10+ recommended): python3 -m venv .venv, then .venv/bin/python -m pip install -r requirements.txt, then verify with .venv/bin/python scripts/fetch_transcript.py --check-deps. On Windows PowerShell, use py -m venv .venv and .venv\Scripts\python.exe .... 3) Optionally install yt-dlp for descriptions, chapters, duration, and upload dates: .venv/bin/python -m pip install yt-dlp, and put its executable on PATH by activating the environment. No API keys are needed.
How do you use this agent?
Basic usage: python3 scripts/fetch_transcript.py "https://youtu.be/VIDEO_ID" (activate .venv first or use the full interpreter path). Common examples: save into an Obsidian vault: python3 scripts/fetch_transcript.py URL --output-dir ~/Notes/MyVault; set a persistent directory: export YOUTUBE_FETCHER_DIR=~/Notes/MyVault; language preferences: python3 scripts/fetch_transcript.py --lang fr,de -- URL; strict Japanese captions: --lang ja --strict-lang -- URL; machine translation: --lang auto --translate en -- URL; list available caption languages: --list -- URL; other exports: --format srt URL, --format --output captions. URL, --stdout --timestamps -- URL. Output location follows the priority --output > --output-dir > YOUTUBE_FETCHER_DIR > ~/yt_transcripts/. Agents should resolve the script relative to the installed SKILL.md and use the isolated environment's interpreter.