---
name: youtube-knowledge
description: Extract durable knowledge from YouTube videos, channels, or playlists for Codex by fetching transcripts locally, summarizing reusable knowledge points, and publishing them through a YouTube Knowledge MCP backend backed by Cloudflare AI Search. Use when the user asks Codex to learn from YouTube, ingest a YouTube URL/channel, build a YouTube transcript knowledge base, upload video knowledge to AI Search, or answer questions using previously ingested YouTube knowledge.
---

# YouTube Knowledge

Use this skill to turn YouTube videos or channels into reusable knowledge for later Q&A.

## Boundary

Codex performs local work:

- Resolve video, channel, or playlist URLs.
- Fetch transcripts from the local runtime or a user-approved local tool.
- Summarize transcripts into durable knowledge points.
- Call the MCP tool `upload_youtube_knowledge`.

The MCP Worker performs remote durable work:

- Store uploaded knowledge documents in Cloudflare AI Search.
- Search those documents with `search_youtube_knowledge`.

Do not assume the Worker can fetch YouTube, crawl channels, run Workers AI summaries, or manage D1 jobs.

## Workflow

1. Identify the user intent:
   - Ingest: fetch transcripts, summarize, upload.
   - Search: call `search_youtube_knowledge`.
2. For ingestion, resolve the source:
   - Single video: use that video URL.
   - Channel or playlist: list candidate videos first and process a bounded batch unless the user explicitly asks for a larger run.
3. Fetch transcript text locally.
   - Prefer `youtube-transcript-api` from the local Python runtime.
   - If it is not installed and network access is allowed, install it with `python -m pip install youtube-transcript-api`.
   - On Windows, force UTF-8 output before printing titles or transcript text, for example `$env:PYTHONIOENCODING='utf-8'` in PowerShell.
   - Use `YouTubeTranscriptApi().list(video_id)` to choose English or official captions first, then fall back to English auto-generated captions, then any available timed transcript.
   - Preserve segment `start`, `duration`, and text. Do not collapse timing away before summarization.
   - Never paste the full transcript into the final answer.
4. Extract knowledge points:
   - Prefer durable technical facts, workflows, decisions, definitions, tradeoffs, commands, constraints, and gotchas.
   - Ignore greetings, sponsorships, filler, duplicated wording, and unsupported opinions.
   - Make each point self-contained enough to be useful outside the original video.
5. Upload points through MCP `upload_youtube_knowledge`.
6. Run one lightweight `search_youtube_knowledge` query to verify that uploaded knowledge is searchable.
7. Report only source URL, transcript language or caption source, uploaded count, document keys, notable failures, and any follow-up batch recommendation.

## Local Transcript Fetch

Use a small local Python script when possible, adapting only the `video_id` and language preferences:

```python
import json
import sys
from youtube_transcript_api import YouTubeTranscriptApi

if hasattr(sys.stdout, "reconfigure"):
    sys.stdout.reconfigure(encoding="utf-8")

video_id = "VIDEO_ID"
api = YouTubeTranscriptApi()
transcripts = api.list(video_id)

selected = None
for languages in (["en"], ["en-US", "en-GB"]):
    try:
        selected = transcripts.find_manually_created_transcript(languages)
        break
    except Exception:
        pass

if selected is None:
    try:
        selected = transcripts.find_generated_transcript(["en", "en-US", "en-GB"])
    except Exception:
        selected = next(iter(transcripts))

segments = selected.fetch()
print(json.dumps({
    "language": selected.language_code,
    "generated": selected.is_generated,
    "segments": segments,
}, ensure_ascii=False))
```

Treat official captions as higher confidence than generated captions. If no transcript exists, report that ingestion could not continue for that video and do not invent content.

## Chunking And Extraction

Chunk timed transcript segments before summarizing:

- Build windows of roughly 90-180 seconds, keeping `startSeconds` and `endSeconds` for each window.
- Keep transcript order and avoid splitting in the middle of a coherent explanation when a nearby segment boundary is available.
- Every knowledge point must trace back to one source window.
- Do not summarize every sentence. Extract reusable facts, workflows, constraints, commands, decisions, patterns, and pitfalls.
- Drop verbal filler, jokes, greetings, self-promotion, sponsor copy, repeated phrasing, and claims that are not supported by the transcript.
- Prefer fewer high-signal points over many shallow notes.

## Knowledge Point Shape

Each point must include:

```json
{
  "title": "Short title",
  "summary": "One sentence summary.",
  "content": "Reusable self-contained knowledge.",
  "tags": ["topic", "tool"],
  "startSeconds": 0,
  "endSeconds": 60,
  "confidence": 0.8
}
```

Rules:

- `title`, `summary`, and `content` are required.
- Keep `content` factual and reusable.
- Use `startSeconds` and `endSeconds` when transcript timing is known.
- Use `confidence` from 0 to 1.
- Start `content` with a source range and caption source, so search results remain useful even if metadata is unavailable:

```txt
From 3:05-4:39. Reusable self-contained knowledge. Transcript source: auto-generated captions.
```

- Generate enough points to preserve useful knowledge, not every sentence.
- Match confidence to source quality and clarity: official captions and explicit claims should score higher than auto-generated or ambiguous segments.

## Upload Tool

Call `upload_youtube_knowledge` with source metadata and points:

```json
{
  "sourceType": "video",
  "sourceUrl": "https://www.youtube.com/watch?v=...",
  "sourceTitle": "Video title",
  "videoId": "optional",
  "channelId": "optional",
  "channelName": "optional",
  "publishedAt": "optional ISO timestamp",
  "transcriptLanguage": "en",
  "points": []
}
```

If the backend requires a token, pass `token` only as a tool argument. Do not reveal it in the final answer.

## Upload Diagnostics

If upload fails, narrow the problem before retrying a full batch:

- First upload one minimal point with `title`, `summary`, `content`, `startSeconds`, `endSeconds`, and `confidence`.
- If the error is `invalid_metadata_format`, retry with numeric fields removed from the point and include time range and confidence in `content`.
- If the error is an internal error or timeout, split points into smaller batches and retry.
- After success, report `uploaded` count and document keys. Do not paste transcript text.

## Known Backend Quirks

- Cloudflare AI Search metadata is safest when every metadata value is a string. The Worker should stringify numeric point fields before upload, but if an older backend rejects metadata, remove numeric point fields and preserve those values in `content`.
- AI Search accepts either `query` or `messages` for search, not both. The Worker should use `query` only.

## Search Tool

For Q&A over ingested material, call `search_youtube_knowledge` with:

```json
{
  "query": "question or topic",
  "limit": 8
}
```

Ground answers in returned search results. Say when the knowledge base has no useful match.
After ingestion, use a short query based on the video topic or one uploaded point title to confirm the upload is searchable.
