A Claude Code skill that extracts clean, structured notes from any web page or YouTube video and saves them to your Obsidian vault.
Just paste a URL into your conversation with Claude. That's it.
Articles & docs — strips ads and clutter from any web page, generates an AI summary, extracts a heading index, and saves a clean Obsidian note with full frontmatter.
YouTube videos — fetches the full transcript with per-sentence timestamps (linked back to the video), pulls chapter markers, generates a summary and description via Gemini, and saves a structured vault note.
Claude Code's built-in WebFetch tool fetches a page and dumps its content directly into Claude's context window — raw HTML, navigation, ads, footers and all. Claude then has to read through it to answer your question, burning tokens on noise.
This skill offloads the heavy lifting to dedicated tools instead:
- Defuddle runs outside Claude's context and strips the page down to just the article content before Claude ever sees it. Less noise, fewer tokens.
- yt-dlp fetches and parses YouTube transcripts entirely in a subprocess. Claude never processes raw VTT.
- The Python script handles all note formatting — frontmatter, tag extraction, timestamp linking, heading index — without Claude having to reason about any of it.
- Gemini handles AI summarisation as a separate API call. Claude doesn't summarise the content itself, so a full transcript never needs to fit in its context window.
Claude's role is minimal: trigger the skill, receive the finished note, write it to disk. The result is a richer, more structured output than Claude could produce on its own — at a fraction of the token cost.
See the /examples folder for real output generated by this skill:
dolphin-progress-report.md— article note from Dolphin Progress Report: Release 2603ps1-game-dev.md— YouTube note from I made a real PS1 game in 1.5 months
| Tool | Purpose | Install |
|---|---|---|
| Claude Code | Runs the skill | See Claude docs |
| defuddle | Extracts clean content from web pages | npm install -g defuddle |
| yt-dlp | Downloads YouTube transcripts | brew install yt-dlp |
| Python 3 | Runs the formatting script | Pre-installed on macOS |
| gemini-cli | AI enrichment (optional) | brew install gemini-cli |
| Obsidian | Your note vault (optional) | See Obsidian site |
Gemini enrichment is optional. Without it, notes are still saved with the full content and transcript — just with placeholder text in the Summary and Description fields instead of AI-generated text However, it can be used with the free tier, so little reason not to use it!
Platform support: macOS and Linux are fully supported. Windows users should run this inside WSL — Claude Code itself works best there too. The brew install commands work on Linux as well, though you can also use pip install yt-dlp and npm install -g gemini-cli if you prefer.
Place this folder at:
~/.claude/skills/defuddle/
So you end up with:
~/.claude/skills/defuddle/
├── SKILL.md
├── defuddle.py
└── README.md
Open SKILL.md and find this line near the bottom:
Write the script output as-is to `~/Documents/Obsidian/Vault/{filename}.md`
Replace ~/Documents/Obsidian/Vault with the path to your own Obsidian vault (or any folder you want notes saved to).
By default, notes are saved directly to the vault root. If you'd prefer a subfolder, just add it to the path — for example:
~/Documents/Obsidian/clips/{filename}.md
Claude will create the folder automatically if it doesn't exist.
PRO TIP: if you have an Obsidian setup with folders for different projects, add some logic to the skill to ask for the project (or detect it automatically) so files will be organised per project!
Add these to your ~/.claude/settings.json under permissions.allow:
"Bash(defuddle **)",
"Bash(yt-dlp *)",
"Bash(python3 ~/.claude/**)"Note:
defuddle **uses a double wildcard because URLs contain/characters which a single*won't match. At least, this seems to help, but permissions tend to be finicky...
Your full settings.json might look like:
{
"permissions": {
"allow": [
"Bash(defuddle **)",
"Bash(yt-dlp *)",
"Bash(python3 ~/.claude/**)",
"Skill(*)"
]
}
}Gemini enrichment provides AI-generated summaries, descriptions, and tags for each saved note. It supports the free tier of the Gemini API, so no billing is required.
- Go to Google AI Studio
- Sign in with your Google account
- Click Create API key
Open ~/.claude/CLAUDE.md (create it if it doesn't exist) and add:
## API Keys
- **Gemini**: `YOUR_GEMINI_API_KEY_HERE`The formatting skill reads the key from this file automatically — you don't need to set any environment variables yourself.
If the key is missing or the Gemini call fails for any reason, the skill falls back gracefully — notes are saved with
[Summary to be added]and[Description to be added]placeholders instead.
By default, defuddle.py uses gemini-3.1-flash-lite-preview, which is compatible with the free tier. If you have a paid plan and want better quality, you can swap it for any other Gemini model by editing this line in defuddle.py:
result = subprocess.run(
['gemini', '-m', 'gemini-3.1-flash-lite-preview', '-p', prompt],Replace gemini-3.1-flash-lite-preview with your preferred model (e.g. gemini-2.5-pro or gemini-2.0-flash). Some of these other models are also available on the free tier. See the API pricing overview for more details.
Just share a URL in your Claude Code conversation:
"Can you read this article for me? https://dolphin-emu.org/blog/2026/03/12/dolphin-progress-report-release-2603/"
"Summarise this page: https://github.com/kepano/defuddle"
Claude will automatically use the defuddle skill. After fetching, it will ask if you'd like to save the note to your vault.
For YouTube links, transcripts with timestamps are always fetched automatically — no extra steps needed.
The skill's description field in SKILL.md tells Claude when to use it:
TRIGGER when: user provides any URL to a webpage, documentation, article, blog post,
or any standard web content.
DO NOT use WebFetch for these — use defuddle.
You can reinforce this in your own ~/.claude/CLAUDE.md by adding:
## Tools
- **Never use WebFetch for standard web pages** — always use the `defuddle` skill instead.- Transcripts — the skill tries manual captions first (better quality), then falls back to auto-generated. Rolling-window caption artefacts (duplicated lines) are detected and removed automatically.
- YouTube chapters — if the video has chapter markers, they're inserted as
###headings into the transcript at the correct timestamps. If not and Gemini is configured, it generates logical chapter breaks from the transcript. Without Gemini, videos with no chapter markers will have no chapter headings. - Tags — hashtags found in YouTube descriptions are extracted and added to frontmatter. Gemini also contributes additional content-based tags.
