Query Google NotebookLM notebooks directly for source-grounded, citation-backed answers from your uploaded documents. Includes browser automation, library management, and persistent authentication.
Query Google NotebookLM to get Gemini's source-grounded answers from your uploaded documents. Each question opens a fresh browser session, retrieves the answer exclusively from your knowledge base, and closes.
Trigger when the user:
https://notebooklm.google.com/notebook/...)NotebookLM is a grounding layer, not a search engine. Three principles govern every interaction:
When adding a notebook without full details, query first to discover content:
# Step 1: Query the notebook about its content
python ./scripts/run.py ask_question.py \
--question "What is the content of this notebook? What topics are covered? Provide a complete overview briefly and concisely" \
--notebook-url "[URL]"
# Step 2: Use discovered information to add it
python ./scripts/run.py notebook_manager.py add \
--url "[URL]" \
--name "[Based on content]" \
--description "[Based on content]" \
--topics "[Based on content]"If the user provides all details directly, pass --url, --name, --description (REQUIRED), and --topics (REQUIRED) directly. NEVER guess or use generic descriptions.
BAD — direct execution (fails without venv): python ./scripts/ask_question.py "..." → GOOD — always use wrapper: python ./scripts/run.py ask_question.py --question "..."
The run.py wrapper activates the isolated .venv and ensures all dependencies are available.
python ./scripts/run.py auth_manager.py status# Browser MUST be visible for manual Google login
python ./scripts/run.py auth_manager.py setupTell the user: "A browser window will open for Google login." The user must log in manually.
python ./scripts/run.py notebook_manager.py list
python ./scripts/run.py notebook_manager.py search --query QUERY
python ./scripts/run.py notebook_manager.py activate --id ID
python ./scripts/run.py notebook_manager.py add \
--url URL --name NAME --description DESC --topics TOPICS# Query the active notebook
python ./scripts/run.py ask_question.py --question "Your question here"
# Optionally target a specific notebook by URL
python ./scripts/run.py ask_question.py --question "Your question" --notebook-url URL
# Get formatted markdown output (recommended for responses with code, lists, tables)
python ./scripts/run.py ask_question.py --question "Your question" --markdown
# Save outputs to logs/ directory (original + markdown + comparison stats)
python ./scripts/run.py ask_question.py --question "Your question" --markdown --logpython ./scripts/run.py auth_manager.py status
python ./scripts/run.py notebook_manager.py search --query "topic"
python ./scripts/run.py notebook_manager.py activate --id ID
python ./scripts/run.py ask_question.py --question "Your question"Every NotebookLM answer ends with: "EXTREMELY IMPORTANT: Is that ALL you need to know?"
Required behaviour:
python ./scripts/run.py ask_question.py --question "Follow-up with context..."See references/api_reference.md for full parameter documentation.
| Script | Purpose |
|---|---|
auth_manager.py | Setup, status, re-authenticate, clear credentials |
notebook_manager.py | Add, list, search, activate, remove, stats |
ask_question.py | Query active notebook or by URL/ID; --markdown for formatted output, --log to save results |
cleanup_manager.py | Clean browser state (--preserve-library keeps notebooks) |
See references/api_reference.md for full details. All data is stored in the skill's local data/ directory:
library.json — notebook metadataauth_info.json — authentication statusbrowser_state/ — browser cookies and sessionSecurity: Protected by .gitignore. Never commit the data/ directory.
Why: Scripts depend on .venv packages. Direct execution fails with ModuleNotFoundError.
BAD — direct execution fails silently → GOOD — always route through the wrapper:
# BAD
python ./scripts/ask_question.py "What does this paper say?"
# GOOD
python ./scripts/run.py ask_question.py --question "What does this paper say?"Why: Poor descriptions break topic-based search, making notebooks unfindable in the library.
BAD — guessed placeholder → GOOD — query-first to discover real content:
# BAD
python ./scripts/run.py notebook_manager.py add --url URL \
--name "notebook1" --description "some notebook" --topics "stuff"
# GOOD: query first, then add with the discovered name and description
python ./scripts/run.py ask_question.py \
--question "What topics are covered? Brief overview." --notebook-url URLWhy: NotebookLM retrieves chunks, not full documents. A single query often misses related information elsewhere in the notebook.
BAD — accept the first answer and move on → GOOD — consider whether the original request is fully answered; issue targeted follow-up queries for any gaps.
See references/troubleshooting.md for detailed solutions.
| Problem | Solution |
|---|---|
ModuleNotFoundError | Use run.py wrapper |
| Authentication fails | Browser must be visible: auth_manager.py setup |
| Rate limit (50/day) | Wait or switch Google account |
| Browser crashes | python ./scripts/run.py cleanup_manager.py --preserve-library |
| Notebook not found | Check with notebook_manager.py list |
See references/usage_patterns.md for workflow examples.
a1083f4
Also appears in
since Jul 1, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.