NotebookLM Skill
Provides agent access to Google's NotebookLM through the notebooklm tool.
Prerequisites
Install the upstream CLI:
uv tool install "notebooklm-py[browser]"See notebooklm-py docs for pipx/venv alternatives.
Authenticate in a terminal (one-time):
notebooklm login # auto-installs Chromium on first run notebooklm auth check --test --jsonIf
playwright install chromiumfails during login, run it manually:uv tool run --from 'notebooklm-py[browser]' playwright install chromium
Tool usage
Single notebooklm tool with argument array:
notebooklm args=["list", "--json"]
notebooklm args=["auth", "check", "--test", "--json"]
notebooklm args=["create", "Research Notebook", "--json"]
notebooklm args=["source", "add", "https://...", "-n", "<notebook-id>", "--json"]
notebooklm args=["source", "add", "Inline text content...", "-n", "<notebook-id>", "--json"]
notebooklm args=["ask", "Summarize findings", "-n", "<notebook-id>", "--json"]
notebooklm args=["generate", "audio", "-n", "<notebook-id>"]
notebooklm args=["artifact", "wait", "<task-id>", "-n", "<notebook-id>", "--json"]
notebooklm args=["download", "audio", "-a", "<artifact-id>", "output.mp3"]
Command map (v0.7.3)
| Category | Commands |
|---|---|
| Auth/health | auth check --test --json, doctor --json, status (top-level; auth status is invalid), use <id|partial> (partial prefix matches, e.g. use eadca411 → eadca411-33e4-…), clear (requires confirm: true, no -y) |
| Notebooks | list --json, create <title> --json, rename -n <id> "New Title", delete -n <id> -y (with confirm: true), summary -n <id>, metadata -n <id> --json |
| Sources | source add <content> -n <id> --json (auto-detects url/file/youtube/text), source add-drive <file-id> <title> -n <id>, source add-research "<query>" -n <id> --mode deep --no-wait, source list -n <id> --json, source wait <src-id> -n <id> --json, source get <src-id>, source fulltext <src-id>, source guide <src-id>, source refresh <src-id>, source stale <src-id>, source rename <src-id> "New Title", source delete -y <src-id>, source delete-by-title <title> -n <id> -y, source clean -n <id> (auto-remove duplicate/error/blocked sources) |
| Grounded chat | ask <question> -n <id> --json (returns citations via references[]), ask --new -y <question> -n <id> --json (new conversation, requires confirm: true + -y), ask -c <conv-id> "follow up", configure -n <id> --persona <text>, history -n <id> --json |
| Research | research status -n <id> --json, research wait -n <id> --json, source add-research "<query>" -n <id> --mode deep --no-wait |
| Studio generation | generate audio -n <id>, generate video -n <id>, generate slide-deck -n <id>, generate report -n <id>, generate infographic -n <id>, generate quiz -n <id>, generate flashcards -n <id>, generate mind-map -n <id>, generate data-table -n <id>, generate cinematic-video -n <id>, generate revise-slide (edit one slide in an existing deck) |
| Artifacts | artifact list -n <id> --json, artifact get <art-id>, artifact poll <task-id> -n <id> --json, artifact wait <task-id> -n <id> --json, artifact retry <task-id>, artifact suggestions -n <id> (AI-suggested report topics), artifact rename <art-id> "New Name", artifact delete -y <art-id>, artifact export <art-id> --title "..." --type [docs|sheets] |
| Downloads | download audio [output-path] -a <artifact-id>, download video [output-path] -a <artifact-id>, download slide-deck [output-path] -a <artifact-id> (also: --all, --latest, --name <title>, --dry-run) |
| Notes | note list -n <id> --json, note get <note-id>, note create <content> -n <id> -t "Title", note rename <note-id> "New Title", note save <note-id> --title "..." --content "...", note delete -y <note-id> |
| Sharing | share status -n <id> --json, share public --enable|--disable, share add <email> --permission viewer|editor, share remove <email>, share update <email> --permission <level>, share view-level full|chat |
| Organization | language set <code>, language get, language list, profile list --json, profile switch <name>, profile create <name>, profile rename <name> "New Name", profile delete -y <name> |
| Agent & skills | agent show {codex|claude} (print agent integration instructions), skill install|show|status|uninstall (manage the NotebookLM→agent skill bridge; install --force overwrites — requires confirm: true) |
Rules
- Navigation: always key on full IDs. The
created_atfield returned bylist/metadata/use/statusis not the real creation time — it mutates nearly every call (tracks "last touched"), andstatuseven returns a date-only value. Do not sort, order, or dedup bycreated_at. Thelistorder and theindexfield are unstable too (order swaps between calls), so never reference a notebook/source/artifact byindex— always use the fullid. Partial-prefix IDs also work foruseand source/artifact IDs (e.g.use eadca411resolves toeadca411-…). Root cause is upstream (notebooklm-py); see "Known upstream limitations" below. - Use full notebook IDs and explicit
-nin parallel agent workflows. Sharednotebooklm usecontext can race across calls. - Wait for sources before chat or generation:
source wait <src-id> -n <id> --jsonor check withsource list -n <id> --json. - Async generation: call
generate <type> -n <id>→ get task ID → poll withartifact poll <task-id> -n <id> --jsonor block withartifact wait. - Destructive operations (delete, clean, remove, logout, clear, conversation reset) require
confirm: true. Most also need-y/--yesin args to avoid a hanging prompt (auth logout,clear,skill uninstall, andhistory --clearare exceptions — CLI v0.7.3 does not support -y/--yes for those). - Start a new conversation:
ask --newis destructive (discards server-side conversation). Requiresconfirm: trueand-y/--yes. - File overwrites:
download,source fulltext -o <path>, orskill installwith--forceoverwrites workspace files — requiresconfirm: true. - Authentication stays in NotebookLM CLI's own storage. Never pass cookies through Pi.
JSON output
Add --json for machine-readable output. Key shapes:
ask --json:{"answer": "...", "references": [{"source_id": "...", "cited_text": "...", "citation_number": 1}], "conversation_id": "...", "turn_number": 1}list --json:{"notebooks": [...], "count": N}auth check --test --json:{"status": "ok", "checks": {...}}source list --json:{"sources": [...], "count": N}source wait --json:{"source_id": "...", "status": "ready", "status_code": 2}
Error routing
| Symptom | Likely cause | Action |
|---|---|---|
exit 1 + auth error |
Expired session | Run notebooklm auth check --test --json, re-login if needed |
exit 1 + rate limit |
Quota exceeded | Wait and retry; generation is quota-limited |
exit 1 + source error |
Source not ready | Wait with source wait before chat/generation |
exit 1 + generation fail |
Content policy or invalid params | Adjust query or source content |
exit 2 |
Timeout or CLI error | Increase timeout_ms or check args |
| CLI not found | Missing install | uv tool install "notebooklm-py[browser]" |
BrowserType.launch_persistent_context |
Missing Playwright browser | Auto-installed on first notebooklm login; if fails, run uv tool run --from 'notebooklm-py[browser]' playwright install chromium |
Known upstream limitations
created_atandlistordering are unstable in notebooklm-py (upstream). Thecreated_atvalue changes acrosslist/metadata/use/statuscalls for the same notebook, andlistindex order shifts between calls. Key on full IDs only — never sort, dedup, or reference byindex/created_at. See "Navigation: always key on full IDs" in Rules.