
Notebooklm
Automate Google NotebookLM sessions—library sync, notebook queries, and source-grounded research—from Claude Code or Cursor without re-authenticating every run.
Install
npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill notebooklmWhat is this skill?
- Hybrid Playwright auth: persistent browser profile plus manual session-cookie injection from state.json to work around s
- Local data/ workspace for auth_info, notebooks.json, and library.json so personal notebooks never land in git
- Headless or headed browser flows for NotebookLM library and notebook interactions
- Explicit .gitignore patterns for .env, cookies, and browser_state to reduce accidental secret commits
- Python scripts under a venv-oriented layout with standard virtualenv exclusions
Adoption & trust: 622 installs on skills.sh; 40.1k GitHub stars; 1/3 security scanners passed (skills.sh audits).
Recommended Skills
Journey fit
NotebookLM’s core job is synthesizing uploaded sources into answers and briefs, which maps first to the Idea phase when solo builders are still researching markets, competitors, and technical options before they commit to a build. Research is the canonical shelf because the skill is optimized around notebooks, libraries, and Q&A over documents—not shipping code, launch SEO, or production ops.
Common Questions / FAQ
Is Notebooklm safe to install?
skills.sh reports 1 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Notebooklm
# Virtual Environment .venv/ venv/ env/ *.venv # Skill Data (NEVER commit - contains auth and personal notebooks!) data/ data/* data/**/* # Claude-specific .claude/ *.claude # Python __pycache__/ *.py[cod] *$py.class *.so .Python scripts/__pycache__/ scripts/*.pyc # Environment .env *.env .env.* # Browser/Auth state (if accidentally placed outside data/) browser_state/ auth/ auth_info.json library.json notebooks.json state.json cookies.json # IDE .vscode/ .idea/ *.swp *.swo *~ # OS .DS_Store .DS_Store? ._* Thumbs.db desktop.ini ehthumbs.db # Logs *.log logs/ *.debug # Backups *.backup *.bak *.tmp *.temp # Test artifacts .coverage htmlcov/ .pytest_cache/ .tox/ # Package artifacts dist/ build/ *.egg-info/ # Authentication Architecture ## Overview This skill uses a **hybrid authentication approach** that combines the best of both worlds: 1. **Persistent Browser Profile** (`user_data_dir`) for consistent browser fingerprinting 2. **Manual Cookie Injection** from `state.json` for reliable session cookie persistence ## Why This Approach? ### The Problem Playwright/Patchright has a known bug ([#36139](https://github.com/microsoft/playwright/issues/36139)) where **session cookies** (cookies without an `Expires` attribute) do not persist correctly when using `launch_persistent_context()` with `user_data_dir`. **What happens:** - ✅ Persistent cookies (with `Expires` date) → Saved correctly to browser profile - ❌ Session cookies (without `Expires`) → **Lost after browser restarts** **Impact:** - Some Google auth cookies are session cookies - Users experience random authentication failures - "Works on my machine" syndrome (depends on which cookies Google uses) ### TypeScript vs Python The **MCP Server** (TypeScript) can work around this by passing `storage_state` as a parameter: ```typescript // TypeScript - works! const context = await chromium.launchPersistentContext(userDataDir, { storageState: "state.json", // ← Loads cookies including session cookies channel: "chrome" }); ``` But **Python's Playwright API doesn't support this** ([#14949](https://github.com/microsoft/playwright/issues/14949)): ```python # Python - NOT SUPPORTED! context = playwright.chromium.launch_persistent_context( user_data_dir=profile_dir, storage_state="state.json", # ← Parameter not available in Python! channel="chrome" ) ``` ## Our Solution: Hybrid Approach We use a **two-phase authentication system**: ### Phase 1: Setup (`auth_manager.py setup`) 1. Launch persistent context with `user_data_dir` 2. User logs in manually 3. **Save state to TWO places:** - Browser profile directory (automatic, for fingerprint + persistent cookies) - `state.json` file (explicit save, for session cookies) ```python context = playwright.chromium.launch_persistent_context( user_data_dir="browser_profile/", channel="chrome" ) # User logs in... context.storage_state(path="state.json") # Save all cookies ``` ### Phase 2: Runtime (`ask_question.py`) 1. Launch persistent context with `user_data_dir` (loads fingerprint + persistent cookies) 2. **Manually inject cookies** from `state.json` (adds session cookies) ```python # Step 1: Launch with browser profile context = playwright.chromium.launch_persistent_context( user_data_dir="browser_profile/", channel="chrome" ) # Step 2: Manually inject cookies from state.json with open("state.json", 'r') as f: state = json.load(f) context.add_cookies(state['cookies']) # ← Workaround for session cookies! ``` ## Benefits | Feature | Our Approach | Pure `user_data_dir` | Pure `storage_state` | |---------|--------------|----------------------|----------------------| | **Browser Fingerprint Consistency** | ✅ Same across restarts | ✅ Same | ❌ Changes each time | | **Session Cookie Persistence** | ✅ Manual injection | ❌ Lost (bug) | ✅ Native support | | **Persistent Cookie Persistence** | ✅ Automatic | ✅ Automatic | ✅ Native support | | **Google Trust** | ✅ High (same bro