原始内容
name: youtube-summary description: "Summarize YouTube videos with youtube2md, including bare YouTube URLs with no instructions, chaptered notes, timestamp links, transcript extraction, and key takeaways." version: 1.0.13 metadata: openclaw: emoji: "📺" homepage: https://github.com/sunghyo/youtube2md#readme primaryEnv: OPENAI_API_KEY requires: bins: - youtube2md envVars: - name: OPENAI_API_KEY required: false description: Enables the OpenAI API summarization provider and Whisper STT fallback. When set, transcript/audio-derived content may be sent to OpenAI. Omit to use simple or transcript mode when captions are available. - name: YOUTUBE2MD_DEFAULT_MODEL required: false description: Optional runner default model for full mode. When unset, the upstream youtube2md default (gpt-5.6-luna) and per-provider CODEX_MODEL / OPENAI_MODEL env vars apply. - name: OPENAI_MODEL required: false description: Optional youtube2md model for the OpenAI API provider when --model is not passed (default gpt-5.6-luna). Does not affect the Codex provider. - name: CODEX_MODEL required: false description: Optional youtube2md model for the Codex (ChatGPT login) provider when --model is not passed (default gpt-5.6-luna). - name: YOUTUBE2MD_PROVIDER required: false description: Summarization provider for full mode; auto (default), codex, or openai. - name: YOUTUBE2MD_DETAIL required: false description: Full-mode chapter-bullet detail density; concise, balanced (upstream default), or exhaustive. Passed to youtube2md as --detail when set. Does not change the length of the Summary section. - name: YOUTUBE2MD_CAPTION_LANG required: false description: Preferred caption language code (en, ko, pt-BR, ...); youtube2md falls back to another available track when unavailable. Set it whenever the video language is known — when unset, youtube2md has no preference to rank by and takes the first track YouTube lists, which is often a community translation. - name: YOUTUBE2MD_CAPTIONS_ONLY required: false description: Forbids the Whisper audio fallback. Extract mode defaults to 1 (audio never uploaded); full mode keeps Whisper available unless this is explicitly set to 1. - name: YOUTUBE_COOKIES_PATH required: false description: Optional EditThisCookie JSON export for youtube.com; used when captions/audio require signed-in YouTube access. - name: YOUTUBE_COOKIE_HEADER required: false description: Optional raw YouTube Cookie header for authenticated metadata, caption, or audio fallback requests.
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
youtube2mdon PATH.- Recommended pinned install:
npm i -g youtube2md@1.2.0
- Recommended pinned install:
- Default runner uses the local
youtube2mdexecutable only. - Runtime npm execution (
npx) is intentionally not supported by this skill runner. - The
YOUTUBE2MD_BINenvironment variable override is rejected by the runner. - Full mode needs a summarization provider; with
--provider auto, youtube2md tries:- Codex SDK with ChatGPT login — requires both the optional
@openai/codex-sdkpeer (npm i -g @openai/codex-sdk) and a ChatGPT-authenticated Codex session. A logged-incodexCLI without the SDK is not enough.OPENAI_API_KEYis not passed to Codex. - OpenAI API — used when Codex is unavailable or fails and
OPENAI_API_KEYis set.
- Codex SDK with ChatGPT login — requires both the optional
- 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 inautomode withOPENAI_API_KEYset it logs that the run will use the billed API path instead of the ChatGPT session.- If
npm i -g @openai/codex-sdkfails withEACCESon a root-ownednode_modules/@openai, it needssudo(the user must run it; the skill never escalates privileges).
- If
- 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
--modelonly when the fifth runner argument orYOUTUBE2MD_DEFAULT_MODELis set; otherwise the upstream default (gpt-5.6-lunafor both providers) and the per-providerCODEX_MODEL/OPENAI_MODELenv vars apply. - Extract mode passes
--captions-onlyby default: audio is never sent to Whisper in simple/transcript mode. SetYOUTUBE2MD_CAPTIONS_ONLY=0to allow Whisper STT for captionless videos (requiresOPENAI_API_KEY). - Full mode keeps the Whisper fallback available: a captionless video may have its audio uploaded to OpenAI when
OPENAI_API_KEYis set. SetYOUTUBE2MD_CAPTIONS_ONLY=1to forbid that in full mode too (captionless videos then fail instead). YOUTUBE_COOKIES_PATHorYOUTUBE_COOKIE_HEADERcan be used when YouTube blocks anonymous caption/audio access.- In sensitive environments, audit upstream
youtube2md@1.2.0and dependencies before installation or future version bumps.
See references/security.md before first-time install/enable.
Workflow
Validate input
- Accept
youtube.comandyoutu.beURLs (watch, Shorts, Live, Embed, Music, andyoutube-nocookie.comembed 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.
- Accept
Pin the caption language
- Always set
YOUTUBE2MD_CAPTION_LANGwhen the video's spoken language is known or inferable (user's request language, channel, title/description). Useenfor an English video,kofor 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_LANGif a translated track was picked.YOUTUBE2MD_JSON=1exposesactualLanguagefor an exact check; otherwise glance at the transcript text. - The runner warns on stderr whenever
YOUTUBE2MD_CAPTION_LANGis unset. Treat that warning as a prompt to check the output language, not as noise.
- Always set
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). Useexhaustivewhen the user asks for the densest possible notes,concisefor a quick overview.--detailmoves chapter-bullet density only; the## Summarysection stays short at every level. - Expect a short
## Summaryand 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.
- If a provider is available (Codex ChatGPT login or
- Simple mode: uses youtube2md
--extract-only --extract-format timestamped-text --captions-onlyinternally to produce a timestamped.txttranscript, 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).
- Use when the user asks for transcript extraction, transcript-only output, raw transcript, or machine-readable transcript JSON (
- Prefer a no-error path: the runner pre-checks provider availability and switches to the extract path automatically when full mode cannot run.
- Full mode: generates Markdown with youtube2md's summarization pipeline (Codex ChatGPT login first, then OpenAI API).
Run converter
- Preferred runner script:
scripts/run_youtube2md.sh <url> 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]andYOUTUBE2MD_DEFAULT_MODELare optional; when omitted, upstream defaults apply.
scripts/run_youtube2md.sh <url> extract [output_txt_path]extractis the runner/CLI mode name; default artifact is timestamped text (.txt).- Disclose it as
simplewhen summarizing from the.txt. - Disclose it as
transcriptwhen returning transcript-only output.
- Optional machine-readable CLI output:
YOUTUBE2MD_JSON=1 scripts/run_youtube2md.sh <url> fullYOUTUBE2MD_JSON=1 scripts/run_youtube2md.sh <url> extract- With
--jsonor--stdoutactive, stdout carries a single data payload; runner status goes to stderr.
- Optional stdout/no-file mode:
YOUTUBE2MD_STDOUT=1 scripts/run_youtube2md.sh <url> extract
- Optional output directory:
YOUTUBE2MD_OUT_DIR=./output scripts/run_youtube2md.sh <url> extract
- Caption language (set this whenever the language is known — see step 2):
YOUTUBE2MD_CAPTION_LANG=ko scripts/run_youtube2md.sh <url> extract
- Optional full-mode detail density:
YOUTUBE2MD_DETAIL=exhaustive scripts/run_youtube2md.sh <url> full
- Runtime controls:
- Use only locally installed
youtube2mdexecutable. - Do not use runtime npm execution (
npx) for this skill.
- Use only locally installed
- Direct CLI equivalent:
- Full:
youtube2md --url <url> [--out <path>] [--out-dir <dir>] [--lang <language>] [--model <model>] [--provider auto|codex|openai] [--detail concise|balanced|exhaustive] - Simple/transcript:
youtube2md --url <url> --extract-only --extract-format timestamped-text --captions-only [--out <path>] - Add
--caption-lang <code>to pin the caption language; omitting it lets YouTube's track order decide (see step 2). - Add
--captions-onlyin full mode to forbid the Whisper audio upload. - Add
--jsonfor a versioned machine-readable result envelope (includesoutputPath). - Add
--stdoutto write output to stdout instead of a file.
- Full:
- Preferred runner script:
Verify output
- Full mode: Markdown file exists and is non-empty unless
--stdoutis used. - Simple mode: timestamped
.txttranscript exists and is non-empty when file output is used. - Transcript mode:
.txtor.jsontranscript output exists and is non-empty, unless--stdoutis used. - If using
--json, parse the envelope:ok: true/false,outputPath,transcriptSource,actualLanguage,provider,fallbackUsed; handle errorcodeperreferences/troubleshooting.md.
- Full mode: Markdown file exists and is non-empty unless
Respond to the user
- Follow
references/output-format.mdfor 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.mdfor 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 firstmessagetool call ends the turn, so the later parts never get sent. Seereferences/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
youtube2mddirectly. - Simple mode -> Claude summarizes from the timestamped
.txttranscript using the compact structure inreferences/output-format.md. - Transcript mode -> return transcript content or requested transcript artifact details, not a summary.
- 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
- Always append a final mode line after the user-facing result:
Mode: fullMode: simpleMode: simple (fallback from full; no summarization provider available)when full was requested but the runner fell back and a summary was still produced.Mode: transcriptwhen transcript-only output was requested.
- Keep user-facing flow smooth: if no provider is available, use simple output and summarize from
.txtwithout surfacing avoidable tool-error noise.
- Follow
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/<video_id>.md - Simple/transcript modes:
./summaries/<video_id>.txt(timestamped text) or./summaries/<video_id>.json(YOUTUBE2MD_EXTRACT_FORMAT=json)
- Full mode:
- Model defaults: upstream youtube2md defaults to
gpt-5.6-lunafor both providers;CODEX_MODEL/OPENAI_MODELoverride per provider; the fifth runner argument orYOUTUBE2MD_DEFAULT_MODELoverrides 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):
## Summaryis 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.--detaildoes not lengthen it.## Chapterscarries 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;--detailshifts chapter density only for short or sparse sections.
- Chunking thresholds: single-pass at
<= 20000transcript tokens (and whenever the split yields one chunk, up to ~25000); chunk target is20000tokens 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-langprefers an exact match, then the same base language, then another track. youtube-transcriptfallback.- Whisper STT fallback (
whisper-1, audio under 24 MB) whenOPENAI_API_KEYis available; skipped under--captions-only(the runner's extract-mode default) or when no API key is set.
- YouTube captions via watch-page / InnerTube requests, with YouTube cookies when configured;
- 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