Design & media

youtube-summary

Convert YouTube URLs into inline chaptered summaries, timestamped transcripts, or transcript JSON.

What it does

Turn one or more YouTube URLs into inline summaries or transcripts using a locally installed, pinned youtube2md CLI. Full mode returns the tool’s Markdown verbatim with a short Summary and detailed Chapters; simple mode summarizes a timestamped caption transcript, while transcript mode returns text or JSON. Caption language can be pinned and verified to avoid selecting translated tracks.

When to use it

  • Chaptered notes from a long YouTube video
  • Timestamped transcript extraction
  • JSON transcript output for downstream processing
  • Sequential summaries of multiple videos

The skill document

YouTube Summary (youtube2md)

Use the official youtube2md CLI behavior from the package/repository (pinned youtube2md@1.2.0).

Runtime + security prerequisites

  • Require Node.js 20.18.1+.
  • Require preinstalled youtube2md on PATH.
    • Recommended pinned install: npm i -g youtube2md@1.2.0
  • Default runner uses the local youtube2md executable only.
  • Runtime npm execution (npx) is intentionally not supported by this skill runner.
  • The YOUTUBE2MD_BIN environment variable override is rejected by the runner.
  • Full mode needs a summarization provider; with --provider auto, youtube2md tries:
    1. Codex SDK with ChatGPT login — requires both the optional @openai/codex-sdk peer (npm i -g @openai/codex-sdk) and a ChatGPT-authenticated Codex session. A logged-in codex CLI without the SDK is not enough. OPENAI_API_KEY is not passed to Codex.
    2. OpenAI API — used when Codex is unavailable or fails and OPENAI_API_KEY is set.
  • The runner asks the installed youtube2md for its own Codex verdict (detectCodexChatGptLogin) rather than guessing, so its pre-check cannot disagree with the tool. When Codex is unavailable it logs the upstream reason, and in auto mode with OPENAI_API_KEY set it logs that the run will use the billed API path instead of the ChatGPT session.
    • If npm i -g @openai/codex-sdk fails with EACCES on a root-owned node_modules/@openai, it needs sudo (the user must run it; the skill never escalates privileges).
  • Either provider sends transcript-derived content to OpenAI systems; for sensitive content, use simple or transcript mode when captions are available.
  • Model default: the runner passes --model only when the fifth runner argument or YOUTUBE2MD_DEFAULT_MODEL is set; otherwise the upstream default (gpt-5.6-luna for both providers) and the per-provider CODEX_MODEL / OPENAI_MODEL env vars apply.
  • Extract mode passes --captions-only by default: audio is never sent to Whisper in simple/transcript mode. Set YOUTUBE2MD_CAPTIONS_ONLY=0 to allow Whisper STT for captionless videos (requires OPENAI_API_KEY).
  • Full mode keeps the Whisper fallback available: a captionless video may have its audio uploaded to OpenAI when OPENAI_API_KEY is set. Set YOUTUBE2MD_CAPTIONS_ONLY=1 to forbid that in full mode too (captionless videos then fail instead).
  • YOUTUBE_COOKIES_PATH or YOUTUBE_COOKIE_HEADER can be used when YouTube blocks anonymous caption/audio access.
  • In sensitive environments, audit upstream youtube2md@1.2.0 and dependencies before installation or future version bumps.

See references/security.md before first-time install/enable.

Workflow

  1. Validate input

    • Accept youtube.com and youtu.be URLs (watch, Shorts, Live, Embed, Music, and youtube-nocookie.com embed shapes are supported; timestamped &t= URLs are accepted but the whole video is processed).
    • Quote URLs containing & when passing them to the shell.
    • If a message contains only YouTube URL(s), treat it as a request to summarize with this skill.
    • If YouTube URL(s) are provided without an explicit task, default to summary output, not transcript-only output.
    • If URLs are missing, ask for one URL per line.
  2. Pin the caption language

    • Always set YOUTUBE2MD_CAPTION_LANG when the video's spoken language is known or inferable (user's request language, channel, title/description). Use en for an English video, ko for a Korean one, and so on.
    • Why: with no preference, every caption track ties in youtube2md's ranking, so the first track YouTube lists wins. Videos with community translations frequently yield a translated track — e.g. a 3blue1brown video returns Arabic (actualLanguage: "ar"), and the whole summary then comes out in Arabic.
    • After any run, verify the transcript/summary language and re-run with the correct YOUTUBE2MD_CAPTION_LANG if a translated track was picked. YOUTUBE2MD_JSON=1 exposes actualLanguage for an exact check; otherwise glance at the transcript text.
    • The runner warns on stderr whenever YOUTUBE2MD_CAPTION_LANG is unset. Treat that warning as a prompt to check the output language, not as noise.
  3. Choose mode

    • Full mode: generates Markdown with youtube2md's summarization pipeline (Codex ChatGPT login first, then OpenAI API).
      • If a provider is available (Codex ChatGPT login or OPENAI_API_KEY) and external API use is acceptable, try full mode first.
      • Detail density is tunable via YOUTUBE2MD_DETAIL=concise|balanced|exhaustive (upstream default: balanced). Use exhaustive when the user asks for the densest possible notes, concise for a quick overview. --detail moves chapter-bullet density only; the ## Summary section stays short at every level.
      • Expect a short ## Summary and detailed ## Chapters (youtube2md 1.2.0 design): the Summary is a few-sentence orientation that states the video's conclusion/verdict, and every supporting fact lives in the chapter bullets. A short Summary is not truncated output — never pad, expand, or rewrite it.
    • Simple mode: uses youtube2md --extract-only --extract-format timestamped-text --captions-only internally to produce a timestamped .txt transcript, then summarizes from that transcript.
      • Use when no provider is available, content is sensitive, external API use is not acceptable, or full mode fails/falls back.
    • Transcript mode: uses the same extract path and returns transcript output without a summary.
      • Use when the user asks for transcript extraction, transcript-only output, raw transcript, or machine-readable transcript JSON (YOUTUBE2MD_EXTRACT_FORMAT=json).
    • Prefer a no-error path: the runner pre-checks provider availability and switches to the extract path automatically when full mode cannot run.
  4. Run converter

    • Preferred runner script:
      • scripts/run_youtube2md.sh full [output_md_path] [language] [model]
        • If no summarization provider is available, runner auto-falls back to the internal extract path; disclose summary output as simple mode.
        • [model] and YOUTUBE2MD_DEFAULT_MODEL are optional; when omitted, upstream defaults apply.
      • scripts/run_youtube2md.sh extract [output_txt_path]
        • extract is the runner/CLI mode name; default artifact is timestamped text (.txt).
        • Disclose it as simple when summarizing from the .txt.
        • Disclose it as transcript when returning transcript-only output.
    • Optional machine-readable CLI output:
      • YOUTUBE2MD_JSON=1 scripts/run_youtube2md.sh full
      • YOUTUBE2MD_JSON=1 scripts/run_youtube2md.sh extract
      • With --json or --stdout active, stdout carries a single data payload; runner status goes to stderr.
    • Optional stdout/no-file mode:
      • YOUTUBE2MD_STDOUT=1 scripts/run_youtube2md.sh extract
    • Optional output directory:
      • YOUTUBE2MD_OUT_DIR=./output scripts/run_youtube2md.sh extract
    • Caption language (set this whenever the language is known — see step 2):
      • YOUTUBE2MD_CAPTION_LANG=ko scripts/run_youtube2md.sh extract
    • Optional full-mode detail density:
      • YOUTUBE2MD_DETAIL=exhaustive scripts/run_youtube2md.sh full
    • Runtime controls:
      • Use only locally installed youtube2md executable.
      • Do not use runtime npm execution (npx) for this skill.
    • Direct CLI equivalent:
      • Full: youtube2md --url [--out ] [--out-dir ] [--lang ] [--model ] [--provider auto|codex|openai] [--detail concise|balanced|exhaustive]
      • Simple/transcript: youtube2md --url --extract-only --extract-format timestamped-text --captions-only [--out ]
      • Add --caption-lang to pin the caption language; omitting it lets YouTube's track order decide (see step 2).
      • Add --captions-only in full mode to forbid the Whisper audio upload.
      • Add --json for a versioned machine-readable result envelope (includes outputPath).
      • Add --stdout to write output to stdout instead of a file.
  5. Verify output

    • Full mode: Markdown file exists and is non-empty unless --stdout is used.
    • Simple mode: timestamped .txt transcript exists and is non-empty when file output is used.
    • Transcript mode: .txt or .json transcript output exists and is non-empty, unless --stdout is used.
    • If using --json, parse the envelope: ok: true/false, outputPath, transcriptSource, actualLanguage, provider, fallbackUsed; handle error code per references/troubleshooting.md.
  6. Respond to the user

    • Follow references/output-format.md for the response shape: full mode is a verbatim pass-through of the package Markdown; simple/transcript modes use the compact authored structure.
    • Follow references/summarization-behavior.md for source policy and chapter/takeaway density.
    • Deliver the summary inline in the reply, in full — never as a file attachment, download link, or a meta-description in place of the content, no matter how long. A 3-hour video with 100+ chapters still gets its complete summary pasted into the response; length is never a reason to attach, truncate, or summarize-the-summary.
    • Send it in one reply even on channels that cap message size (Telegram ~4096 chars, Slack ~4000) — the host splits long text into multiple messages by itself. Do not hand-split into (1/3), (2/3), (3/3) sends: on openclaw the first message tool call ends the turn, so the later parts never get sent. See references/output-format.md.
    • Do not include generated local file path(s) in normal user-facing replies.
    • Share file paths, or produce an export file, only when explicitly requested by the user (e.g., debugging/export workflows).
    • Summary source policy:
      • Full mode succeeded -> the youtube2md Markdown output is the final summary; present it verbatim (append only the mode line). Do not re-summarize, condense, drop chapters/bullets, or reflow it into the compact template — that discards the detail the package produced. This is what makes the skill match the detail of running youtube2md directly.
      • Simple mode -> Claude summarizes from the timestamped .txt transcript using the compact structure in references/output-format.md.
      • Transcript mode -> return transcript content or requested transcript artifact details, not a summary.
    • Always append a final mode line after the user-facing result:
      • Mode: full
      • Mode: simple
      • Mode: simple (fallback from full; no summarization provider available) when full was requested but the runner fell back and a summary was still produced.
      • Mode: transcript when transcript-only output was requested.
    • Keep user-facing flow smooth: if no provider is available, use simple output and summarize from .txt without surfacing avoidable tool-error noise.

Multi-video requests

  • Process URLs sequentially.
  • Return per-video results (omit local file paths unless requested).
  • Include the final mode line for each video result.
  • If any fail, report successful items first, then failures with fixes.

Built-in behavior to trust

  • Default output paths:
    • Full mode: ./summaries/.md
    • Simple/transcript modes: ./summaries/.txt (timestamped text) or ./summaries/.json (YOUTUBE2MD_EXTRACT_FORMAT=json)
  • Model defaults: upstream youtube2md defaults to gpt-5.6-luna for both providers; CODEX_MODEL / OPENAI_MODEL override per provider; the fifth runner argument or YOUTUBE2MD_DEFAULT_MODEL overrides everything via --model.
  • Detail levels (--detail, full mode): chapter-bullet density scales with video length and content density at every level; the flag only shifts where the target sits (concise ≈ one bullet per ~750 transcript tokens, balanced ≈ ~450 (default), exhaustive ≈ ~300, densest notes). Responses that land far below the requested target (under 70%) are re-requested once automatically.
  • Section sizing (full mode):
    • ## Summary is an orientation, not a recap: its sentence budget scales with duration but is hard-capped at 8 sentences (~3 for a 1-hour video) with a matching word ceiling, and it must state the video's actual conclusion/verdict — answering the title outright when the title poses a question. --detail does not lengthen it.
    • ## Chapters carries the detail. Bullets are budgeted as one approximate total per request and spent unevenly, so a dense section gets several times more bullets than a transitional one.
    • Chapter count follows chunk count (CHUNK_CHAPTER_CAP = 9 chapters per full-size chunk) rather than --detail; --detail shifts chapter density only for short or sparse sections.
  • Chunking thresholds: single-pass at <= 20000 transcript tokens (and whenever the split yields one chunk, up to ~25000); chunk target is 20000 tokens with boundaries snapped to native chapter starts or speech pauses, summarized up to 4 chunks in parallel.
  • Transcript strategy:
    • YouTube captions via watch-page / InnerTube requests, with YouTube cookies when configured; --caption-lang prefers an exact match, then the same base language, then another track.
    • youtube-transcript fallback.
    • Whisper STT fallback (whisper-1, audio under 24 MB) when OPENAI_API_KEY is available; skipped under --captions-only (the runner's extract-mode default) or when no API key is set.
  • Timestamps render as [M:SS] / [MM:SS] (and [H:MM:SS] past one hour); chapter display times and ?t= links always agree.

Packaging hygiene

  • Do not publish generated outputs (e.g., summaries/*.md, summaries/*.txt, summaries/*.json) inside the skill folder.
  • Keep only source files (SKILL.md, scripts/, references/) in release artifacts.

Resources

  • CLI runner: scripts/run_youtube2md.sh
  • Output guidance: references/output-format.md
  • Behavior reference: references/summarization-behavior.md
  • Security/install notes: references/security.md
  • Troubleshooting and error codes: references/troubleshooting.md

Questions people ask

What happens if I send only a YouTube URL?
A bare YouTube URL is treated as a summary request. Multiple URLs are processed sequentially, with a separate result and mode line for each video.
Does full summarization require an external provider?
Yes. Full mode uses a ChatGPT-authenticated Codex SDK session first, then the OpenAI API when available; if neither is available, the runner automatically uses the extract path and produces a simple summary from captions.
Can it avoid sending video audio or transcript content to OpenAI?
Simple and transcript modes use captions only by default, so audio is not sent to Whisper. Full mode sends transcript-derived content to OpenAI systems and may upload audio for captionless videos unless captions-only is enabled.

Related skills

Compress documents, transcripts, threads, data, and code changes while preserving claims, caveats, and actions.

239 installs4 stars

Turn video files and links into transcripts, visual descriptions, summaries, and answers.

65 installs5 stars

Create YouTube videos, Shorts, thumbnails, and scripts from structured prompts through CellCog.

102 installs11 stars

Downloads ArXiv artifacts and produces a full-text-based summary.md for each paper.

116 installs1 stars

Create and export videos from scripts, URLs, documents, visuals, ideas, or speech.

100 installs

Research recent discussions across Reddit, X, YouTube, and the web, then synthesize cited findings.

110 installs