$npx -y skills add tuan3w/obsidian-vault-agent --skill youtubeAnalyze a YouTube video and create a vault note from its transcript. Use this skill whenever a YouTube URL is pasted — even with casual commentary like "check this out" or "interesting talk." Also triggers on "youtube", "take notes from this video", "summarize this video", or any
| 1 | <Purpose> |
| 2 | Extract transcript and metadata from a YouTube video, then synthesize it into |
| 3 | a vault-formatted post note. Uses youtube-transcript-api for transcript and |
| 4 | yt-dlp for rich metadata (with oEmbed fallback). |
| 5 | </Purpose> |
| 6 | |
| 7 | <Use_When> |
| 8 | - User shares a YouTube URL and wants notes taken |
| 9 | - User says "take notes from this video" |
| 10 | - User pastes a YouTube link with /youtube |
| 11 | - User wants to add a video's insights to the vault |
| 12 | </Use_When> |
| 13 | |
| 14 | <Do_Not_Use_When> |
| 15 | - User wants to watch or download the video itself |
| 16 | - User has a local video file (not YouTube) |
| 17 | - Video has no transcript/captions at all |
| 18 | - User wants to process an existing vault note (use /process) |
| 19 | </Do_Not_Use_When> |
| 20 | |
| 21 | <Execution_Policy> |
| 22 | - Extract first, synthesize second, integrate third |
| 23 | - Always check vault for existing notes on the same video before creating |
| 24 | - Create note as type: post with processing_status: inbox |
| 25 | - The note is a starting point — user can /process it later for deeper engagement |
| 26 | </Execution_Policy> |
| 27 | |
| 28 | <Steps> |
| 29 | |
| 30 | ## Stage 1: EXTRACT |
| 31 | |
| 32 | Parse the YouTube URL/ID from $ARGUMENTS. If no URL provided, ask the user. |
| 33 | |
| 34 | Run the extraction script. Redirect stdout to a temp file (stderr has progress messages that break piping): |
| 35 | |
| 36 | ```bash |
| 37 | SKILL_DIR="${CLAUDE_SKILL_DIR}" |
| 38 | YT_OUTPUT="$SKILL_DIR/_output.json" |
| 39 | uv run "$SKILL_DIR/scripts/fetch_youtube.py" "VIDEO_URL" --lang en > "$YT_OUTPUT" |
| 40 | ``` |
| 41 | |
| 42 | Then read `$YT_OUTPUT` with the Read tool to get the JSON. Clean up the file after use. |
| 43 | |
| 44 | The JSON contains: |
| 45 | - `title`, `channel`, `duration`, `upload_date`, `description`, `chapters` |
| 46 | - `transcript.full_text`, `transcript.segments`, `transcript.language` |
| 47 | - `transcript.error` (null if success) |
| 48 | |
| 49 | **If transcript.error is not null:** inform the user and stop. No note without content. |
| 50 | |
| 51 | **If transcript is very long (>50,000 chars):** warn the user this is a long video. |
| 52 | Chunk the transcript for the agent if needed — send first 40,000 chars with a note |
| 53 | about total length. For very long videos (>2hrs), consider suggesting the user |
| 54 | watch key sections instead. |
| 55 | |
| 56 | ## Stage 2: SYNTHESIZE |
| 57 | |
| 58 | Read the agent definition: |
| 59 | ``` |
| 60 | Read("${CLAUDE_SKILL_DIR}/agents/video-noter.md") |
| 61 | ``` |
| 62 | |
| 63 | Search the vault for existing notes related to the video's topics using the MCP tool: |
| 64 | ``` |
| 65 | search_notes(query="KEYWORD", limit=20) |
| 66 | ``` |
| 67 | Or fall back to Grep if MCP is unavailable: |
| 68 | ``` |
| 69 | Grep(pattern="KEYWORD", path="notes/", glob="*.md", head_limit=20) |
| 70 | ``` |
| 71 | |
| 72 | Launch the video-noter agent: |
| 73 | |
| 74 | ``` |
| 75 | Agent( |
| 76 | subagent_type="general-purpose", |
| 77 | model="sonnet", |
| 78 | run_in_background=false, |
| 79 | prompt="You are Video Noter. Follow these instructions exactly: |
| 80 | |
| 81 | [INSERT FULL CONTENT OF agents/video-noter.md HERE] |
| 82 | |
| 83 | VIDEO METADATA: |
| 84 | - Title: [title] |
| 85 | - Channel: [channel] |
| 86 | - Duration: [duration] |
| 87 | - Upload date: [upload_date] |
| 88 | - Chapters: [chapters if any] |
| 89 | - Description: [first 500 chars of description] |
| 90 | |
| 91 | EXISTING VAULT NOTES ON RELATED TOPICS: |
| 92 | [List any matching notes found in grep] |
| 93 | |
| 94 | TRANSCRIPT: |
| 95 | [full_text or chunked text] |
| 96 | |
| 97 | Produce the note body following the Output Format. Do NOT include frontmatter — |
| 98 | only the body starting from the # title line." |
| 99 | ) |
| 100 | ``` |
| 101 | |
| 102 | ## Stage 3: INTEGRATE |
| 103 | |
| 104 | 1. Generate timestamp ID: |
| 105 | ```bash |
| 106 | date +%Y%m%d%H%M%S |
| 107 | ``` |
| 108 | |
| 109 | 2. Format the upload_date for frontmatter (YYYYMMDD → YYYY-MM-DD) |
| 110 | |
| 111 | 3. Check for duplicate notes: |
| 112 | ```bash |
| 113 | grep -rl "VIDEO_TITLE" notes/ --include="*.md" | head -5 |
| 114 | ``` |
| 115 | |
| 116 | 4. Create the note file with frontmatter + agent output: |
| 117 | |
| 118 | ```markdown |
| 119 | --- |
| 120 | id: YYYYMMDDHHMMSS |
| 121 | type: post |
| 122 | processing_status: inbox |
| 123 | author: Channel Name |
| 124 | link: "https://www.youtube.com/watch?v=VIDEO_ID" |
| 125 | created_date: YYYY-MM-DD |
| 126 | updated_date: YYYY-MM-DD |
| 127 | --- |
| 128 | |
| 129 | [AGENT OUTPUT HERE — starts with # title and 🏷️Tags line] |
| 130 | ``` |
| 131 | |
| 132 | Place the note in `notes/` under the most appropriate topic subfolder: |
| 133 | - ML/AI content → `notes/ml/` |
| 134 | - Startup/business → `notes/startup/` |
| 135 | - Finance → `notes/finance/` |
| 136 | - Design → `notes/design/` |
| 137 | - Psychology → `notes/psychology/` |
| 138 | - General/unclear → `notes/` |
| 139 | |
| 140 | 5. Report to user: |
| 141 | - Note path and title |
| 142 | - Number of concepts suggested for extraction |
| 143 | - Any related vault notes found |
| 144 | - Remind: "Run /process on this note when you're ready to deepen it" |
| 145 | |
| 146 | </Steps> |
| 147 | |
| 148 | <Tool_Usage> |
| 149 | - **Bash**: Run fetch_youtube.py script (via uv run), generate timestamps, search vault |
| 150 | - **Read**: Read agent definition, read existing vault notes for context |
| 151 | - **Write**: Create the post note in vault |
| 152 | - **Agent**: Delegate synthesis to video-noter agent (sonnet) |
| 153 | - **Grep/Glob**: Search vault for duplicates and related notes |
| 154 | - **TodoWrite**: Track progre |