Install
openclaw skills install @jwestburg/youtube-transcript-native-nodeExtract a clean plain-text transcript from existing YouTube captions - native Node.js, zero npm dependencies. Use when the user asks to summarize, quote, or extract captions/transcript text from a YouTube URL. Wraps the yt-dlp binary on PATH; writes subtitles to a temp dir, parses .vtt captions, strips timestamps/HTML tags, and prints clean text or JSON. No API keys required.
openclaw skills install @jwestburg/youtube-transcript-native-nodeVersion: 1.1.27 / YouTube caption utility with external binary and YouTube access.
Minimal YouTube caption extractor. Native Node.js, zero npm dependencies, wraps the external yt-dlp binary.
Risk class: external binary wrapper / YouTube network access / third-party content.
Use deliberately. This skill does not call a web API directly, but yt-dlp talks to YouTube and the local environment owns the trusted yt-dlp PATH/binary supply-chain boundary.
Required:
url: full single-video YouTube URL from the user. Supported shapes are youtube.com/watch?v=..., /shorts/..., /live/..., /embed/..., and youtu.be/...; playlists, channels, search, and redirect pages are rejected.goal: raw transcript, summary input, quote extraction, timestamped notes, or JSON handoff.privacy_sensitivity: normal, private/client, or unknown.language: default en unless another language is requested.Optional:
timestamps: needed or not.json: needed for downstream tool use.dedup_preference: default auto-caption rolling-window dedup, or --no-dedup to preserve rolling-window/repeated-phrase artifacts as much as possible. Exact consecutive duplicate cue text may still be collapsed during VTT parsing.output_destination: chat summary, explicitly approved saved file path, downstream summarizer, etc.Stop or ask before use if the video/context is private or client-sensitive and sending access to YouTube via yt-dlp is not appropriate.
Return compactly:
youtube.com, www.youtube.com, m.youtube.com, or youtu.be; playlist/channel/search/redirect pages and URL credentials are rejected, and invalid-URL errors redact credential, query, and fragment material before printing user-provided URL context.--lang as a bounded BCP-47-style subtitle language tag such as en, es, or en-US; wildcard/bulk values such as all are rejected before invoking yt-dlp.yt-dlp with an argv array and no shell; it does not execute user-provided commands.yt-dlp stdout/stderr before parsing so a noisy or compromised child process cannot grow diagnostic/output buffers without limit.yt-dlp with a minimal child environment allowlist instead of ambient process.env, and blanks common home/profile/config/cache path variables for the child. Self-test mode can lower test-only size/timeout limits for offline regression coverage, but production execution never replaces yt-dlp with an arbitrary script path from YOUTUBE_TRANSCRIPT_TEST_*; offline tests use an explicit internal self-test fixture argument instead of ambient command redirection. Do not set self-test hooks for normal transcript extraction.--ignore-config, --no-cache-dir, and --no-plugin-dirs so yt-dlp config/cache behavior and default or added plugin-directory discovery do not silently alter wrapper behavior or load additional local plugin code for this invocation.child_process warnings are expected because this skill intentionally wraps trusted yt-dlp.Use this when:
Do not use this when:
yt-dlp is not installed/on PATH and installing it has not been approved.Script: scripts/fetch.mjs
node "<skill-dir>\scripts\fetch.mjs" --url "https://www.youtube.com/watch?v=VIDEO_ID"
node "<skill-dir>\scripts\fetch.mjs" --url "https://www.youtube.com/watch?v=VIDEO_ID" --lang es
node "<skill-dir>\scripts\fetch.mjs" --url "https://www.youtube.com/watch?v=VIDEO_ID" --timestamps
node "<skill-dir>\scripts\fetch.mjs" --url "https://www.youtube.com/watch?v=VIDEO_ID" --json
node "<skill-dir>\scripts\fetch.mjs" --help
POSIX shell examples:
node "<skill-dir>/scripts/fetch.mjs" --url "https://www.youtube.com/watch?v=VIDEO_ID"
node "<skill-dir>/scripts/fetch.mjs" --url "https://www.youtube.com/watch?v=VIDEO_ID" --json
For all flags, dedup details, output formats, dependency notes, and troubleshooting, load references/youtube-transcript-contract.md.
--lang en unless another language is clear.--json as the default structured handoff for research triage, summarization, and downstream tooling.--timestamps only when timestamped notes, quote traceability, or debugging are needed; it is an advanced/evidence mode, not the recommended default for reading.--json --timestamps only for machine traceability workflows that need timestamp anchors inside JSON; it is not intended as a human-readable inspection format.Minimum no-video/no-network checks:
node "<skill-dir>\scripts\fetch.mjs" --help
node --check "<skill-dir>\scripts\fetch.mjs"
node "<skill-dir>\scripts\self-test.mjs"
node "<skill-dir>\scripts\fetch.mjs" --url "https://example.com/watch?v=not-youtube" --json
The invalid-host smoke should fail before invoking yt-dlp. These checks verify local behavior only; they do not publish, upload, update a registry, or prove live YouTube availability.
Optional environment check:
yt-dlp --version
Do not install/update yt-dlp as part of this skill without explicit approval.
If an older yt-dlp build does not recognize --no-plugin-dirs, verify the installed version and escalate for an explicitly approved yt-dlp update path; do not self-update or install from this skill.
If this skill is packaged or shared, its public docs should clearly disclose:
yt-dlp dependency, trusted PATH/binary boundary, and disabled config/cache/plugin discovery;yt-dlp;child_process static-analysis warning;yt-dlp stderr; unrelated absolute paths emitted by yt-dlp itself may remain;--lang accepts bounded language tags only and rejects wildcard/bulk caption extraction values such as all.Respect copyright and platform terms in examples, docs, and outputs: prefer summaries and brief quotes; do not publish long/full third-party transcripts unless rights or permission are clear.
Do not include private/internal/client strategy or full third-party transcript samples in shared examples or docs.
1.1.27: Restrict accepted YouTube URLs to single-video shapes and guard local-path scrubbing against root-directory needles that would over-redact diagnostics in minimal/root container environments.1.1.26: Tighten public-package polish by removing operator-release-process wording from source docs, standardizing local check examples on <skill-dir>, rejecting wildcard/bulk --lang all-style values, and pointing older compact changelog history to the reference contract.1.1.25: Remove ambient arbitrary-script self-test redirection from the production fetch.mjs path, normalize child PATH handling on Windows, and gate persistent transcript-save guidance behind explicit approved destinations plus safe overwrite behavior.1.1.24: Fail-closed malformed credential-like URL redaction for multiple-@ leading-authority shapes, with regression coverage.1.1.23: Broaden invalid-URL redaction for malformed credential-like URL prefixes, including no-scheme and schemeless authority shapes, with regression coverage.1.1.22: Harden invalid-URL redaction for long malformed query/fragment inputs by splitting at ?/# before truncation, with long-canary regression coverage.1.1.21: Redact invalid-URL query and fragment material in CLI error output, with regression coverage for secret-like URL parameters.1.1.20: Soften missing-dependency help/troubleshooting wording so install/update guidance consistently routes through explicit approval.1.1.19: Clarify that --no-plugin-dirs disables default and added plugin-directory discovery, not only user-level plugin paths.1.1.18: Tighten oversized child-output handling by scheduling SIGKILL shortly after capture bounds are exceeded if yt-dlp ignores SIGTERM.1.1.17: Add bounded yt-dlp stdout/stderr capture and troubleshooting guidance for older yt-dlp builds that may not support --no-plugin-dirs.1.1.16: Suppress yt-dlp plugin discovery with --no-plugin-dirs, document the executable-code boundary, and add regression coverage for the plugin-loading guard.1.1.15: Final public-readiness wording polish: simplify legacy changelog wording for public release.1.1.14: Final public-readiness wording polish: simplify recent changelog text for public release.1.1.13: Public-readiness wording polish: simplify recent changelog text.1.1.12: Public-readiness wording polish: simplify recent changelog terms.1.1.11: Public-readiness wording polish: add approval caution to CLI help and use neutral changelog wording.1.1.10: Public-readiness wording polish: mirror approval/install cautions in the reference contract and simplify recent changelog entries.1.1.9: Public-release polish: make owner-approval authority explicit in source-level publish/update guidance and simplify historical wording.1.1.8: Fix final redaction edge case: malformed credential-like URL parse failures now receive bounded credential redaction before error output, with regression coverage.1.1.7: Credential-redaction polish: redact credentials from invalid-URL errors, assert XDG config/cache blanking in self-test, and clean the inert-hook temp PATH fixture.1.1.6: Public-readiness hardening: sanitize the yt-dlp child environment, pass --no-cache-dir, reject URL credentials/non-HTTPS YouTube URLs, add offline argv/env assertions, and document transcript/title content as untrusted third-party data for downstream agents.1.1.5: Input/docs polish: require --lang to begin with an alphanumeric, add POSIX command examples, sync reference changelog, and simplify wording. No categories, topics, topic tags, tags, keywords, or ClawHub catalog metadata added to source.1.1.4: Version refresh; no runtime behavior change.1.1.3: Add stubbed offline yt-dlp fixture tests for dependency-missing, nonzero-exit-with-VTT, 429 hint, temp/home path scrubbing, output-size guard, timeout, and output modes; gate self-test hooks behind YOUTUBE_TRANSCRIPT_SELFTEST=1; continue when usable VTT subtitles are produced despite nonzero yt-dlp exit; kill active yt-dlp child on SIGINT/SIGTERM; broaden local-path scrubbing and scrub unexpected/read-error paths.1.1.2: Add offline self-test fixtures, export parser/allowlist helpers for tests, pass --ignore-config, remove subtitle conversion postprocessor to avoid ffmpeg ambiguity, scrub temp path from yt-dlp error tails, and surface 429 retry guidance.1.1.1: Docs cleanup: normalized input/output packet wording, structured handoff wording, and changelog language; no runtime behavior change.Older changelog entries live in references/youtube-transcript-contract.md.