nblm

Query Google NotebookLM notebooks directly from Claude for source-grounded, citation-backed answers. Manages multi-account Google authentication with automatic browser login and persistent session handling Supports 20+ commands across notebook management, source uploads (files, URLs, YouTube, Z-Library, text), and queries with automatic follow-up detection Generates media artifacts including podcasts, briefings, debates, slide decks, and infographics with customizable length, format, and instructions Automatic environment setup with virtual environment creation, dependency installation, and idle daemon management; all data stored locally in ~/.claude/skills/notebooklm/data/

INSTALLATION
npx skills add https://github.com/magicseek/nblm --skill nblm
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

NotebookLM Quick Commands

Query Google NotebookLM for source-grounded, citation-backed answers.

Environment

All dependencies and authentication are handled automatically by run.py:

  • First run creates .venv and installs Python/Node.js dependencies
  • If Google auth is missing or expired, a browser window opens automatically
  • No manual pre-flight steps required

Usage

/nblm <command> [args]

Commands

Notebook Management

Command

Description

login

Authenticate with Google

status

Show auth and library status

accounts

List all Google accounts

accounts add

Add a new Google account

accounts switch <id>

Switch active account (by index or email)

accounts remove <id>

Remove a Google account

accounts use <id>

Set agent-specific active account (OpenClaw isolation)

accounts clear

Clear agent-specific account override

local

List notebooks in local library

remote

List all notebooks from NotebookLM API

create <name>

Create a new notebook

delete [--id ID]

Delete a notebook

rename <name> [--id ID]

Rename a notebook

summary [--id ID]

Get AI-generated summary

describe [--id ID]

Get description and suggested topics

add <url-or-id>

Add notebook to local library (auto-detects URL vs notebook ID)

activate <id>

Set active notebook

Source Management

Command

Description

sources [--id ID]

List sources in notebook

upload <file>

Upload a single file

upload <folder>

Sync a folder of files to NotebookLM

upload-zlib <url>

Download from Z-Library and upload

upload-url <url>

Add URL as source

upload-youtube <url>

Add YouTube video as source

upload-text <title> [--content TEXT]

Add text as source

source-text <source-id>

Get full indexed text

source-guide <source-id>

Get AI summary and keywords

source-rename <source-id> <name>

Rename a source

source-refresh <source-id>

Re-fetch URL content

source-delete <source-id>

Delete a source

Upload options:

  • --use-active - Upload to the currently active notebook
  • --create-new - Create a new notebook named after the file/folder
  • --notebook-id <id> - Upload to a specific notebook
  • --dry-run - Show sync plan without executing (folder sync)
  • --rebuild - Force rebuild tracking file (folder sync)

Important: When user runs upload without specifying a target, ASK them first:

"Would you like to upload to the active notebook, or create a new notebook?"

Then pass the appropriate flag (--use-active or --create-new).

Chat &#x26; Audio/Media

Command

Description

ask <question>

Query NotebookLM

podcast [--instructions TEXT]

Generate audio podcast

podcast-status <task-id>

Check podcast generation status

podcast-download [output-path]

Download latest podcast

briefing [--instructions TEXT]

Generate brief audio summary

debate [--instructions TEXT]

Generate debate-style audio

slides [--instructions TEXT]

Generate slide deck

slides-download [output-path]

Download slide deck as PDF

infographic [--instructions TEXT]

Generate infographic

infographic-download [output-path]

Download infographic

media-list [--type TYPE]

List generated media (audio/video/slides/infographic)

media-delete <id>

Delete a generated media item

Command Routing

Based on $ARGUMENTS, execute the appropriate command:

$IF($ARGUMENTS,

Parse the command from: "$ARGUMENTS"

loginpython scripts/run.py auth_manager.py setup --service google

accountspython scripts/run.py auth_manager.py accounts list

accounts addpython scripts/run.py auth_manager.py accounts add

accounts switch python scripts/run.py auth_manager.py accounts switch "<id>"

accounts remove python scripts/run.py auth_manager.py accounts remove "<id>"

accounts use python scripts/run.py auth_manager.py accounts use "<id>"

accounts clearpython scripts/run.py auth_manager.py accounts clear

status → Run both:

  • python scripts/run.py auth_manager.py status
  • python scripts/run.py notebook_manager.py list

localpython scripts/run.py notebook_manager.py list

remotepython scripts/run.py nblm_cli.py notebooks

create python scripts/run.py nblm_cli.py create "<name>"

delete [--id ID]python scripts/run.py nblm_cli.py delete <args>

rename [--id ID]python scripts/run.py nblm_cli.py rename "<name>" <args>

summary [--id ID]python scripts/run.py nblm_cli.py summary <args>

describe [--id ID]python scripts/run.py nblm_cli.py describe <args>

add → Smart add workflow (auto-detects URL vs notebook ID)

activate python scripts/run.py notebook_manager.py activate --id "<id>"

sources [--id ID]python scripts/run.py nblm_cli.py sources <args>

upload → First ASK user: "Upload to active notebook or create new?" Then:

  • Active: python scripts/run.py source_manager.py add --file "<file>" --use-active
  • New: python scripts/run.py source_manager.py add --file "<file>" --create-new

upload → Sync a folder:

  • First ASK user: "Sync to active notebook, create new, or specify notebook?"
  • Active: python scripts/run.py source_manager.py sync "<folder>" --use-active
  • New: python scripts/run.py source_manager.py sync "<folder>" --create-new
  • Specific: python scripts/run.py source_manager.py sync "<folder>" --notebook-id ID
  • Dry-run: python scripts/run.py source_manager.py sync "<folder>" --dry-run
  • Rebuild: python scripts/run.py source_manager.py sync "<folder>" --rebuild

upload-zlib → First ASK user: "Upload to active notebook or create new?" Then:

  • Active: python scripts/run.py source_manager.py add --url "<url>" --use-active
  • New: python scripts/run.py source_manager.py add --url "<url>" --create-new

upload-url python scripts/run.py nblm_cli.py upload-url "<url>"

upload-youtube python scripts/run.py nblm_cli.py upload-youtube "<url>"

upload-text python scripts/run.py nblm_cli.py upload-text "<title>" <args>

source-text python scripts/run.py nblm_cli.py source-text "<id>"

source-guide python scripts/run.py nblm_cli.py source-guide "<id>"

source-rename python scripts/run.py nblm_cli.py source-rename "<id>" "<name>"

source-refresh python scripts/run.py nblm_cli.py source-refresh "<id>"

source-delete python scripts/run.py nblm_cli.py source-delete "<id>"

ask python scripts/run.py nblm_cli.py ask "<question>"

podcastpython scripts/run.py artifact_manager.py generate --format DEEP_DIVE <args>

podcast-status python scripts/run.py artifact_manager.py status --task-id "<task-id>"

podcast-download [output-path]python scripts/run.py artifact_manager.py download "<output-path>"

briefingpython scripts/run.py artifact_manager.py generate --format BRIEF <args>

debatepython scripts/run.py artifact_manager.py generate --format DEBATE <args>

slidespython scripts/run.py artifact_manager.py generate-slides <args>

slides-download [output-path]python scripts/run.py artifact_manager.py download "<output-path>" --type slide-deck

infographicpython scripts/run.py artifact_manager.py generate-infographic <args>

infographic-download [output-path]python scripts/run.py artifact_manager.py download "<output-path>" --type infographic

media-list [--type TYPE]python scripts/run.py artifact_manager.py list <args>

media-delete python scripts/run.py artifact_manager.py delete "<id>"

If command not recognized, show usage help.,

Show available commands with /nblm (no arguments)

)

Podcast Options

/nblm podcast --length DEFAULT --wait --output ./podcast.mp3

/nblm podcast --instructions "Focus on the key findings"

/nblm briefing --wait --output ./summary.mp3

/nblm debate --instructions "Compare the two approaches"

Option

Values

--length

SHORT, DEFAULT, LONG

--instructions

Custom instructions for the content

--wait

Wait for generation to complete

--output

Download path (requires --wait)

Slide Deck Options

/nblm slides --format DETAILED_DECK --wait --output ./presentation.pdf

/nblm slides --instructions "Focus on key diagrams" --format PRESENTER_SLIDES

Option

Values

--format

DETAILED_DECK, PRESENTER_SLIDES

--length

SHORT, DEFAULT

--instructions

Custom instructions for the content

--wait

Wait for generation to complete

--output

Download path (requires --wait)

Infographic Options

/nblm infographic --orientation LANDSCAPE --wait --output ./visual.png

/nblm infographic --instructions "Highlight comparison" --detail-level DETAILED

Option

Values

--orientation

LANDSCAPE, PORTRAIT, SQUARE

--detail-level

CONCISE, STANDARD, DETAILED

--instructions

Custom instructions for the content

--wait

Wait for generation to complete

--output

Download path (requires --wait)

Media Generation

Command

Description

Output

/nblm podcast

Deep-dive audio discussion

MP3

/nblm briefing

Brief audio summary

MP3

/nblm debate

Debate-style audio

MP3

/nblm slides

Slide deck presentation

PDF

/nblm infographic

Visual infographic

PNG

Examples

/nblm podcast --wait --output ./deep-dive.mp3

/nblm briefing --instructions "Focus on chapter 3" --wait

/nblm debate --length LONG --wait --output ./debate.mp3

/nblm slides --instructions "Include key diagrams" --format DETAILED_DECK --wait --output ./presentation.pdf

/nblm infographic --orientation LANDSCAPE --detail-level DETAILED --wait --output ./summary.png

Download &#x26; Manage

/nblm podcast-download ./my-podcast.mp3

/nblm slides-download ./presentation.pdf

/nblm infographic-download ./visual.png

/nblm media-list                     # List all generated media

/nblm media-list --type audio        # List only audio

/nblm media-delete <id>              # Delete a media item

Extended Documentation

When to Use This Skill

Trigger when user:

  • Mentions NotebookLM explicitly
  • Shares NotebookLM URL (https://notebooklm.google.com/notebook/...)
  • Asks to query their notebooks/documentation
  • Wants to add documentation to NotebookLM library
  • Uses phrases like "ask my NotebookLM", "check my docs", "query my notebook"

⚠️ CRITICAL: Add Command - Smart Discovery

The add command now automatically discovers metadata from the notebook:

# Smart Add (auto-discovers name, description, topics)

python scripts/run.py notebook_manager.py add <notebook-id-or-url>

# With optional overrides

python scripts/run.py notebook_manager.py add <id> --name "Custom Name" --topics "custom,topics"

What Smart Add does:

  • Fetches notebook title from NotebookLM API
  • Queries the notebook content to generate description and topics
  • Adds to local library with discovered metadata

Supported input formats:

  • Notebook ID: 5fd9f36b-8000-401d-a7a0-7aa3f7832644
  • Full URL: https://notebooklm.google.com/notebook/5fd9f36b-8000-401d-a7a0-7aa3f7832644

NEVER manually specify --name, --description, or --topics unless the user explicitly provides them.

Critical: Always Use run.py Wrapper

**NEVER call scripts directly. ALWAYS use python scripts/run.py [script]:**

# ✅ CORRECT - Always use run.py:

python scripts/run.py auth_manager.py status

python scripts/run.py notebook_manager.py list

python scripts/run.py ask_question.py --question "..."

# ❌ WRONG - Never call directly:

python scripts/auth_manager.py status  # Fails without venv!

The run.py wrapper automatically:

  • Creates .venv if needed
  • Installs all dependencies
  • Activates environment
  • Executes script properly

Core Workflow

Step 1: Check Authentication Status

python scripts/run.py auth_manager.py status

If not authenticated, proceed to setup.

Step 2: Authenticate (One-Time Setup)

# Browser MUST be visible for manual Google login

python scripts/run.py auth_manager.py setup

Important:

  • Browser is VISIBLE for authentication
  • Browser window opens automatically
  • User must manually log in to Google
  • Tell user: "A browser window will open for Google login"

Step 3: Manage Notebook Library

# List all notebooks

python scripts/run.py notebook_manager.py list

# BEFORE ADDING: Ask user for metadata if unknown!

# "What does this notebook contain?"

# "What topics should I tag it with?"

# Add notebook to library (ALL parameters are REQUIRED!)

python scripts/run.py notebook_manager.py add \

  --url "https://notebooklm.google.com/notebook/..." \

  --name "Descriptive Name" \

  --description "What this notebook contains" \  # REQUIRED - ASK USER IF UNKNOWN!

  --topics "topic1,topic2,topic3"  # REQUIRED - ASK USER IF UNKNOWN!

# Search notebooks by topic

python scripts/run.py notebook_manager.py search --query "keyword"

# Set active notebook

python scripts/run.py notebook_manager.py activate --id notebook-id

# Remove notebook

python scripts/run.py notebook_manager.py remove --id notebook-id

Quick Workflow

  • Check library: python scripts/run.py notebook_manager.py list
  • Ask question: python scripts/run.py ask_question.py --question "..." --notebook-id ID

Step 4: Ask Questions

# Basic query (uses active notebook if set)

python scripts/run.py ask_question.py --question "Your question here"

# Query specific notebook

python scripts/run.py ask_question.py --question "..." --notebook-id notebook-id

# Query with notebook URL directly

python scripts/run.py ask_question.py --question "..." --notebook-url "https://..."

# Show browser for debugging

python scripts/run.py ask_question.py --question "..." --show-browser

Follow-Up Mechanism (CRITICAL)

Every NotebookLM answer ends with: "EXTREMELY IMPORTANT: Is that ALL you need to know?"

Required Claude Behavior:

  • STOP - Do not immediately respond to user
  • ANALYZE - Compare answer to user's original request
  • IDENTIFY GAPS - Determine if more information needed
  • ASK FOLLOW-UP - If gaps exist, immediately ask:
python scripts/run.py ask_question.py --question "Follow-up with context..."
  • REPEAT - Continue until information is complete
  • SYNTHESIZE - Combine all answers before responding to user

Z-Library Integration

Triggers

  • User provides Z-Library URL (zlib.li, z-lib.org, zh.zlib.li)
  • User says "download this book to NotebookLM"
  • User says "add this book from Z-Library"

Setup (One-Time)

# Authenticate with Z-Library

python scripts/run.py auth_manager.py setup --service zlibrary

Commands

# Add book from Z-Library

python scripts/run.py source_manager.py add --url "https://zh.zlib.li/book/..."

# Check Z-Library auth status

python scripts/run.py auth_manager.py status --service zlibrary

Script Reference

Authentication Management ( auth_manager.py )

python scripts/run.py auth_manager.py setup                    # Default: Google

python scripts/run.py auth_manager.py setup --service google

python scripts/run.py auth_manager.py setup --service zlibrary

python scripts/run.py auth_manager.py status                   # Show all services

python scripts/run.py auth_manager.py status --service zlibrary

python scripts/run.py auth_manager.py clear --service zlibrary # Clear auth

# Multi-Account Management (Google)

python scripts/run.py auth_manager.py accounts list             # List all accounts

python scripts/run.py auth_manager.py accounts add              # Add new account

python scripts/run.py auth_manager.py accounts switch 1         # Switch by index

python scripts/run.py auth_manager.py accounts switch user@gmail.com  # Switch by email

python scripts/run.py auth_manager.py accounts remove 2         # Remove account

Notebook Management ( notebook_manager.py )

python scripts/run.py notebook_manager.py add --url URL --name NAME --description DESC --topics TOPICS

# OR use notebook ID directly:

python scripts/run.py notebook_manager.py add --notebook-id ID --name NAME --description DESC --topics TOPICS

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 remove --id ID

python scripts/run.py notebook_manager.py stats

Question Interface ( ask_question.py )

python scripts/run.py ask_question.py --question "..." [--notebook-id ID] [--notebook-url URL] [--show-browser]

Source Manager ( source_manager.py )

# Upload to active notebook

python scripts/run.py source_manager.py add --file "/path/to/book.pdf" --use-active

# Create new notebook for upload

python scripts/run.py source_manager.py add --file "/path/to/book.pdf" --create-new

# Upload to specific notebook

python scripts/run.py source_manager.py add --file "/path/to/book.pdf" --notebook-id NOTEBOOK_ID

# Z-Library download and upload

python scripts/run.py source_manager.py add --url "https://zh.zlib.li/book/..." --use-active

python scripts/run.py source_manager.py add --url "https://zh.zlib.li/book/..." --create-new

# Sync a folder (new!)

python scripts/run.py source_manager.py sync "/path/to/docs" --use-active

python scripts/run.py source_manager.py sync "/path/to/docs" --create-new

python scripts/run.py source_manager.py sync "/path/to/docs" --notebook-id NOTEBOOK_ID

# Sync options (new!)

python scripts/run.py source_manager.py sync "/path/to/docs" --dry-run    # Preview only

python scripts/run.py source_manager.py sync "/path/to/docs" --rebuild   # Force re-hash all files

Folder Sync:

  • Scans folder for supported types: PDF, TXT, MD, DOCX, HTML, EPUB
  • Tracks sync state internally (no per-folder tracking file to manage)
  • Sync strategy: add new, update modified (delete + re-upload), skip unchanged
  • Multi-account aware (tracks which Google account was used)

Note: One of --use-active, --create-new, or --notebook-id is REQUIRED.

Uploads wait for NotebookLM processing and print progress as Ready: N/T. Press Ctrl+C to stop waiting.

Local file uploads use browser automation and require Google authentication.

If browser automation is unavailable, set NOTEBOOKLM_UPLOAD_MODE=text to upload extracted text instead (PDFs require pypdf).

Data Cleanup ( cleanup_manager.py )

python scripts/run.py cleanup_manager.py                    # Preview cleanup

python scripts/run.py cleanup_manager.py --confirm          # Execute cleanup

python scripts/run.py cleanup_manager.py --preserve-library # Keep notebooks

Watchdog Status ( auth_manager.py )

python scripts/run.py auth_manager.py watchdog-status

Environment Management

The virtual environment is automatically managed:

  • First run creates .venv automatically
  • Dependencies install automatically
  • Node.js dependencies install automatically
  • agent-browser daemon starts on demand and keeps browser state in memory
  • daemon stops after 10 minutes of inactivity (any agent-browser command resets the timer)
  • set AGENT_BROWSER_OWNER_PID to auto-stop when the agent process exits
  • scripts/run.py sets AGENT_BROWSER_OWNER_PID to its parent PID by default
  • Everything isolated in skill directory

Manual setup (only if automatic fails):

python -m venv .venv

source .venv/bin/activate  # Linux/Mac

pip install -r requirements.txt

npm install

npm run install-browsers

Data Storage

All data stored in ~/.claude/skills/notebooklm/data/:

  • library.json - Notebook metadata (with account associations)
  • auth/google/ - Multi-account Google auth
  • index.json - Account index (active account, list)
  • <n>-<email>.json - Per-account credentials
  • auth/zlibrary.json - Z-Library auth state
  • agent_browser/session_id - Current daemon session ID
  • agent_browser/last_activity.json - Last activity timestamp for idle shutdown
  • agent_browser/watchdog.pid - Idle watchdog process ID

Security: Protected by .gitignore, never commit to git.

Configuration

Optional .env file in skill directory:

HEADLESS=false           # Browser visibility

SHOW_BROWSER=false       # Default browser display

STEALTH_ENABLED=true     # Human-like behavior

TYPING_WPM_MIN=160       # Typing speed

TYPING_WPM_MAX=240

DEFAULT_NOTEBOOK_ID=     # Default notebook

Decision Flow

User mentions NotebookLM

    ↓

Check auth → python scripts/run.py auth_manager.py status

    ↓

If not authenticated → python scripts/run.py auth_manager.py setup

    ↓

Check/Add notebook → python scripts/run.py notebook_manager.py list/add (with --description)

    ↓

Activate notebook → python scripts/run.py notebook_manager.py activate --id ID

    ↓

Ask question → python scripts/run.py ask_question.py --question "..."

    ↓

See "Is that ALL you need?" → Ask follow-ups until complete

    ↓

Synthesize and respond to user

Troubleshooting

Problem

Solution

ModuleNotFoundError

Use run.py wrapper

Authentication fails

Browser must be visible for setup! --show-browser

DAEMON_UNAVAILABLE

Ensure Node.js/npm installed, run npm install, retry

AUTH_REQUIRED

Run python scripts/run.py auth_manager.py setup

ELEMENT_NOT_FOUND

Verify notebook URL and re-run with fresh page load

Rate limit (50/day)

Wait or add another Google account with accounts add

Browser crashes

python scripts/run.py cleanup_manager.py --preserve-library

Notebook not found

Check with notebook_manager.py list

Best Practices

  • Always use run.py - Handles environment automatically
  • Check auth first - Before any operations
  • Follow-up questions - Don't stop at first answer
  • Browser visible for auth - Required for manual login
  • Include context - Each question is independent
  • Synthesize answers - Combine multiple responses

Limitations

  • No session persistence (each question = new browser)
  • Rate limits on free Google accounts (50 queries/day per account; use multiple accounts to increase)
  • Manual upload required (user must add docs to NotebookLM)
  • Browser overhead (few seconds per question)

Resources (Skill Structure)

Important directories and files:

  • scripts/ - All automation scripts (ask_question.py, notebook_manager.py, etc.)
  • data/ - Local storage for authentication and notebook library
  • references/ - Extended documentation:
  • api_reference.md - Detailed API documentation for all scripts
  • troubleshooting.md - Common issues and solutions
  • usage_patterns.md - Best practices and workflow examples
  • .venv/ - Isolated Python environment (auto-created on first run)
  • .gitignore - Protects sensitive data from being committed
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card