ytbrain
MCP server for turning YouTube channels into a queryable local knowledge base. Enables BM25 search and extractive Q&A over captions with timestamped citations.
README
ytbrain
Turn a YouTube channel into a queryable local knowledge base.
Index every video's captions into a local SQLite/FTS5 brain, then search it with BM25 and ask it questions — answers are sentences quoted from the transcripts, each with a timestamped link that jumps to the exact moment in the video. Works from the CLI and as an MCP server for Claude Desktop, ZCode, Cursor, ...
channel/playlist URL --yt-dlp--> video list --captions--> segments
|
ask "why did they drop postgres?" SQLite + FTS5 (BM25, porter)
\ |
`------> quoted sentences -----+
with [MM:SS] + &t= jump links
Where youtube-transcript-mcp answers "what does this one video say?", ytbrain answers "where across this whole channel was X explained?".
Highlights
- Channel-scale, not per-video: ingest a channel, playlist or single video; resumable — interrupted runs continue where they stopped, re-ingest replaces.
- Caption-first: uses YouTube's own manual/auto captions (json3 preferred, vtt fallback with rolling-window dedup). No audio downloads, no whisper, no GPU.
- Zero API keys, fully local: yt-dlp as a library + httpx + SQLite FTS5. The brain is one file you can drop, copy, or delete.
- BM25 search with porter stemming (
databasesfindsdatabase), phrase queries ("write ahead log"), filters by video or channel. - Extractive Q&A:
askranks passages, quotes the best-matching sentences and cites each with[MM:SS]+ a&t=SECONDSsdeep link. Sentences are extracted, never generated — no LLM, no paraphrasing. - MCP server (5 read-only tools) so any MCP client can query the brain.
- Honest by construction: no-caption videos are reported and skipped, unanswerable questions say so, nothing is invented.
Install
python -m venv .venv # Python 3.10-3.13
.venv/Scripts/activate # Windows; source .venv/bin/activate elsewhere
pip install -e . # or: pip install -e ".[dev]" for pytest
Quickstart
# 1. build a brain (limit optional — omit it for the whole channel)
ytbrain ingest https://www.youtube.com/@Fireship/videos --limit 20
# 2. search it
ytbrain search "open source models"
# 3. ask it
ytbrain ask "what is the problem with robot demos"
# 4. inspect
ytbrain stats
ytbrain videos
ytbrain transcript VIDEO_ID
Verified end-to-end run (3 videos ingested, 567 segments, 0.17 MB database):
$ ytbrain ask "what is the problem with robot demos"
Q: what is the problem with robot demos
A (extractive — sentences quoted from the transcripts):
"When you read the fine print of virtually any robot demo, you'll find that
multi-finger dexterity success rates range anywhere from 0% to 90%, and
that's a big problem because nobody wants to buy a Rosie the Robot maid who"
— I spent 3 days at MIT... the robot hype is worse than you think [02:35]
https://www.youtube.com/watch?v=aB5LGrHISqY&t=155s
$ ytbrain search "open source"
1. [02:08] Meta's new model wants "deep access" to your personal life...
https://www.youtube.com/watch?v=G55HSGpuh1M&t=128s
and abandon >>open<< >>source<< entirely.
MCP server
Build the brain with the CLI, then serve it read-only to MCP clients:
{
"mcpServers": {
"ytbrain": {
"command": "C:\\path\\to\\ytbrain\\.venv\\Scripts\\ytbrain.exe",
"args": ["mcp"],
"env": { "YTBRAIN_DB": "C:\\path\\to\\ytbrain\\data\\ytbrain.sqlite3" }
}
}
}
| Tool | Purpose |
|---|---|
ytbrain_search |
BM25 search; FTS5 syntax ("exact phrase", OR, prefix*), video/channel filters. |
ytbrain_ask |
Extractive Q&A: quoted sentences + timestamped citations. |
ytbrain_get_transcript |
[MM:SS] text lines with offset/limit pagination. |
ytbrain_list_videos |
Indexed videos: id, duration, segments, caption source. |
ytbrain_stats |
Videos, segments, unique terms, channels, talk time, DB size. |
The server is deliberately read-only — ingestion is a CLI concern (long-running, needs progress output), querying is what agents do.
CLI reference
| Command | Purpose |
|---|---|
ytbrain ingest SOURCE [--limit N] [--force] [--languages en de] |
Index a channel/playlist/watch URL. Skips already-indexed videos unless --force. |
ytbrain search QUERY [--limit N] [--video ID] [--channel NAME] |
BM25 hits with snippets and jump links. |
ytbrain ask QUESTION [--sentences N] |
Extractive answer, max N quoted sentences (default 3). |
ytbrain videos [--channel NAME] |
List the index. |
ytbrain stats |
Index statistics. |
ytbrain transcript ID [--offset N] [--limit N] |
Print a transcript with navigation hints. |
ytbrain mcp |
Run the MCP stdio server. |
Configuration
No .env needed; everything defaults sensibly. Environment variables:
| Variable | Default | Notes |
|---|---|---|
YTBRAIN_DB |
./data/ytbrain.sqlite3 |
brain location |
YTBRAIN_LANGUAGES |
en |
comma-separated caption language preference |
YTBRAIN_INGEST_SLEEP |
0.5 |
seconds between per-video fetches (politeness) |
Performance expectations
- Ingest speed is bounded by YouTube: ~2-4 s per video (metadata + captions) plus the politeness delay. 20 videos ≈ one minute; captions-only means no audio downloads, so it stays cheap and throttle-friendly.
- Search and
askare single-digit milliseconds — the whole brain is one SQLite file with an FTS5 index (3 videos / 567 segments = 0.17 MB; extrapolates to roughly ~35 MB per 1000 talking-hours). - Re-runs skip indexed videos instantly (
= cachedlines).
Privacy & security
- Reads public caption tracks via yt-dlp as a library (no shell, no string-built commands); caption files are fetched with httpx and never written to disk.
- Everything stays local: the brain is a SQLite file under
data/(gitignored). - No API keys, no accounts, no cookies, no telemetry.
Testing
pip install -e ".[dev]"
pytest # 46 tests: db/FTS, search, ask, ingest (mocked),
# CLI, MCP tools, json3/vtt parsing
YTBRAIN_DB=data/smoke.sqlite3 python scripts/smoke_mcp.py # real MCP handshake over stdio
Limitations (honest list)
- Captions only. Videos without captions in your languages are counted and skipped — no local transcription here (that's youtube-transcript-mcp's job).
askis extractive, not generative: it quotes, it doesn't compose. If no sentence matches the question terms, it says so instead of guessing.- Sentence boundaries come from caption punctuation — auto-caption sentences can run long or split mid-thought.
- One best passage region per video per question (deduped); multi-hop synthesis across videos is out of scope.
- Auto-caption vtt fallback dedupes rolling windows best-effort; json3 is preferred whenever YouTube offers it.
- Channel enumeration reflects what YouTube lists (uploads order), not a complete historical archive guarantee.
Project layout
src/ytbrain/
config.py env settings, DB path resolution
db.py SQLite schema, FTS5 index, search_segments/stats
youtube.py yt-dlp wrapper, language/track selection, json3/vtt parsing
ingest.py resumable ingest pipeline
search.py BM25 search + extractive ask + formatters
cli.py argparse CLI (7 subcommands)
mcp_server.py FastMCP stdio server (5 tools, read-only)
tests/ 46 unit/integration tests (network mocked)
scripts/ smoke_mcp.py (real stdio handshake)
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。