# io.github.Pantheon-Security/notebooklm-mcp-secure (npm · @pan-sec/notebooklm-mcp)

Security-hardened NotebookLM MCP with post-quantum encryption

- Trust score: 65/100 (medium)
- Change this week: +41
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- npm · `@pan-sec/notebooklm-mcp`: 65/100 (this document), [markdown](https://verifymcp.io/servers/pantheon-security-notebooklm-mcp-secure/pan-sec-notebooklm-mcp.md), [page](https://verifymcp.io/servers/pantheon-security-notebooklm-mcp-secure/pan-sec-notebooklm-mcp)

## Channel facts

- Registry: `npm`
- Package: `@pan-sec/notebooklm-mcp`
- Version: `2026.1.6`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Supply Chain Security**: 87/100
  - No malware found by supply-chain analysis.
  - Only part of the dependency tree could be resolved (171 of 175), so this covers what we could see, not the whole tree.
  - No install/post-install scripts declared.
  - Only part of the dependency tree could be resolved (171 of 175), so this covers what we could see, not the whole tree.
- **Provenance & Transparency**: 45/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 62 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 54/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (poor).
  - Context-footprint check failed: tool/resource definitions use about 7568 tokens (~172/item across 44 items; 43 tools + 1 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 99% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add pantheon-security-notebooklm-mcp-secure -- npx -y @pan-sec/notebooklm-mcp
```

### Codex

```bash
codex mcp add pantheon-security-notebooklm-mcp-secure -- npx -y @pan-sec/notebooklm-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "pantheon-security-notebooklm-mcp-secure": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@pan-sec/notebooklm-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add pantheon-security-notebooklm-mcp-secure --command npx --arg -y --arg @pan-sec/notebooklm-mcp
```

### Hermes

```yaml
mcp_servers:
  pantheon-security-notebooklm-mcp-secure:
    command: "npx"
    args: ["-y", "@pan-sec/notebooklm-mcp"]
```

### Other

```json
{
  "mcpServers": {
    "pantheon-security-notebooklm-mcp-secure": {
      "command": "npx",
      "args": [
        "-y",
        "@pan-sec/notebooklm-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 65, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-02 (score 64, +24)

- [security regression] Provenance: unverified → fail
- [security improvement] Known CVEs: unverified → partial
- [security improvement] Install scripts: unverified → pass
- [functional improvement] Schema quality: unverified → poor
- [functional improvement] Stability: unverified → 0.23
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] License: unverified → pass
- [functional] Licence: MIT

### 2026-08-01 (score 40, +7)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-31 (score 33, −18)

- [security regression] Malware scan: pass → unverified

### 2026-07-30 (score 51, +27)

- [functional regression] Security disclosure: unverified → fail
- [functional improvement] Schema quality: unverified → 100
- [functional improvement] Tool coverage: unverified → 100
- [functional] First check of Schema quality: unverified
- [functional] First check of Schema quality: fail
- [functional] First check of Tool coverage: 99
- [functional] First check of Schema quality: fail

### 2026-07-28 (score 24, 0)

- [functional regression] Security disclosure: fail → unverified

### 2026-07-27 (score 24)

First indexed and scored.

## MCP tools (43)

### `ask_question` (~336 tokens)

\# Conversational Research Partner (NotebookLM • Gemini 2.5 • Session RAG)

\## No Active Notebook
\- Visit https://notebooklm.google to create a notebook and get a share link
\- Use **add_notebook** to add it to your library (explains how to get the link)
\- Use **list_notebooks** to show available sources
\- Use **select_notebook** to set one active

\> Auth tip: If login is required, use the prompt 'notebooklm.auth-setup' and then verify with the 'get_health' tool. If authentication later fails (e.g., expired cookies), use the prompt 'notebooklm.auth-repair'.

Tip: Tell the user you can manage NotebookLM library and ask which notebook to use for the current task.

Input parameters:

- `browser_options` (object): Optional browser behavior settings. Claude can control everything: visibility, typing speed, stealth mode, timeouts. Useful for debugging or fine-tuning.
- `notebook_id` (string): Optional notebook ID from your library. If omitted, uses the active notebook. Use list_notebooks to see available notebooks.
- `notebook_url` (string): Optional notebook URL (overrides notebook_id). Use this for ad-hoc queries to notebooks not in your library.
- `question` (string, required): The question to ask NotebookLM
- `session_id` (string): Optional session ID for contextual conversations. If omitted, a new session is created.
- `show_browser` (boolean): Show browser window for debugging (simple version). For advanced control (typing speed, stealth, etc.), use browser_options instead.

### `add_notebook` (~468 tokens)

PERMISSION REQUIRED — Only when user explicitly asks to add a notebook.

\## Conversation Workflow (Mandatory)
When the user says: "I have a NotebookLM with X"

1\) Ask URL: "What is the NotebookLM URL?"
2\) Ask content: "What knowledge is inside?" (1–2 sentences)
3\) Ask topics: "Which topics does it cover?" (3–5)
4\) Ask use cases: "When should we consult it?"
5\) Propose metadata and confirm:
   \- Name: [suggested]
   \- Description: [from user]
   \- Topics: [list]
   \- Use cases: [list]
   "Add it to your library now?"
6\) Only after explicit "Yes" → call this tool

\## Rules
\- Do not add without user permission
\- Do not guess metadata — ask concisely
\- Confirm summary before calling the tool

\## Example
User: "I have a notebook with n8n docs"
You: Ask URL → content → topics → use cases; propose summary
User: "Yes"
You: Call add_notebook

\## How to Get a NotebookLM Share Link

Visit https://notebooklm.google/ → Login (free: 100 notebooks, 50 sources each, 500k words, 50 daily queries)
1\) Click "+ New" (top right) → Upload sources (docs, knowledge)
2\) Click "Share" (top right) → Select "Anyone with the link"
3\) Click "Copy link" (bottom left) → Give this link to Claude

(Upgraded: Google AI Pro/Ultra gives 5x higher limits)

Input parameters:

- `content_types` (array): Types of content (e.g., ['documentation', 'examples', 'best practices'])
- `description` (string, required): What knowledge/content is in this notebook
- `name` (string, required): Display name for the notebook (e.g., 'n8n Documentation')
- `tags` (array): Optional tags for organization
- `topics` (array, required): Topics covered in this notebook
- `url` (string, required): The NotebookLM notebook URL
- `use_cases` (array): When should Claude use this notebook (e.g., ['Implementing n8n workflows'])

### `list_notebooks` (~41 tokens)

List all library notebooks with metadata (name, topics, use cases, URL). Use this to present options, then ask which notebook to use for the task.

### `get_notebook` (~29 tokens)

Get detailed information about a specific notebook by ID

Input parameters:

- `id` (string, required): The notebook ID

### `select_notebook` (~150 tokens)

Set a notebook as the active default (used when ask_question has no notebook_id).

\## When To Use
\- User switches context: "Let's work on React now"
\- User asks explicitly to activate a notebook
\- Obvious task change requires another notebook

\## Auto-Switching
\- Safe to auto-switch if the context is clear and you announce it:
  "Switching to React notebook for this task..."
\- If ambiguous, ask: "Switch to [notebook] for this task?"

\## Example
User: "Now let's build the React frontend"
You: "Switching to React notebook..." (call select_notebook)

Input parameters:

- `id` (string, required): The notebook ID to activate

### `update_notebook` (~239 tokens)

Update notebook metadata based on user intent.

\## Pattern
1\) Identify target notebook and fields (topics, description, use_cases, tags, url)
2\) Propose the exact change back to the user
3\) After explicit confirmation, call this tool

\## Examples
\- User: "React notebook also covers Next.js 14"
  You: "Add 'Next.js 14' to topics for React?"
  User: "Yes" → call update_notebook

\- User: "Include error handling in n8n description"
  You: "Update the n8n description to mention error handling?"
  User: "Yes" → call update_notebook

Tip: You may update multiple fields at once if requested.

Input parameters:

- `content_types` (array): New content types
- `description` (string): New description
- `id` (string, required): The notebook ID to update
- `name` (string): New display name
- `tags` (array): New tags
- `topics` (array): New topics list
- `url` (string): New notebook URL
- `use_cases` (array): New use cases

### `remove_notebook` (~135 tokens)

Dangerous — requires explicit user confirmation.

\## Confirmation Workflow
1\) User requests removal ("Remove the React notebook")
2\) Look up full name to confirm
3\) Ask: "Remove '[notebook_name]' from your library? (Does not delete the actual NotebookLM notebook)"
4\) Only on explicit "Yes" → call remove_notebook

Never remove without permission or based on assumptions.

Example:
User: "Delete the old React notebook"
You: "Remove 'React Best Practices' from your library?"
User: "Yes" → call remove_notebook

Input parameters:

- `id` (string, required): The notebook ID to remove

### `search_notebooks` (~46 tokens)

Search library by query (name, description, topics, tags). Use to propose relevant notebooks for the task and then ask which to use.

Input parameters:

- `query` (string, required): Search query

### `get_library_stats` (~23 tokens)

Get statistics about your notebook library (total notebooks, usage, etc.)

### `create_notebook` (~476 tokens)

Create a new NotebookLM notebook with sources programmatically.

\## What This Tool Does
\- Creates a NEW notebook in your NotebookLM account
\- Uploads sources (URLs, text, files) to the notebook
\- Returns the notebook URL for immediate use
\- Optionally adds to your local library

\## Supported Source Types
\- **url**: Web page URL (documentation, articles, etc.)
\- **text**: Raw text content (code, notes, etc.)
\- **file**: Local file path (PDF, DOCX, TXT)

\## Example Usage

Create a notebook from API documentation:
\```json
{
  "name": "React Docs",
  "sources": [
    { "type": "url", "value": "https://react.dev/reference/react" }
  ]
}
\```

Create a notebook with multiple sources:
\```json
{
  "name": "Security Research",
  "sources": [
    { "type": "url", "value": "https://owasp.org/Top10" },
    { "type": "file", "value": "/path/to/security-report.pdf" },
    { "type": "text", "value": "Custom notes...", "title": "My Notes" }
  ],
  "description": "Security best practices and research",
  "topics": ["security", "owasp", "best-practices"]
}
\```

\## NotebookLM Limits (Free Tier)
\- 100 notebooks maximum
\- 50 sources per notebook
\- 500k words per source
\- 50 queries per day

\## Notes
\- Requires authentication (run setup_auth first)
\- Creates notebook with sharing set to private by default
\- Large files may take longer to process

Input parameters:

- `auto_add_to_library` (boolean): Whether to automatically add the created notebook to your library (default: true)
- `browser_options` (object): Optional browser settings for debugging
- `description` (string): Optional description for the notebook in your library
- `name` (string, required): Display name for the new notebook
- `show_browser` (boolean): Show browser window (shorthand for browser_options.show)
- `sources` (array, required): Array of sources to add to the notebook
- `topics` (array): Optional topics for categorization in your library

### `sync_library` (~248 tokens)

Sync your local library with actual NotebookLM notebooks.

\## What This Tool Does
\- Navigates to NotebookLM and extracts all your notebooks
\- Compares with local library entries
\- Detects stale entries (notebooks deleted or URLs changed)
\- Identifies notebooks not in your library
\- Optionally auto-removes stale entries

\## When To Use
\- Library seems out of sync with NotebookLM
\- After deleting notebooks in NotebookLM
\- To discover new notebooks to add
\- Before setting up automation workflows

\## Output
Returns a sync report with:
\- **matched**: Library entries that match actual notebooks
\- **staleEntries**: Library entries with no matching notebook (candidates for removal)
\- **missingNotebooks**: NotebookLM notebooks not in library (candidates for adding)
\- **suggestions**: Recommended actions

\## Example Usage
\```json
{ "auto_fix": false }
\```

With auto-fix to remove stale entries:
\```json
{ "auto_fix": true }
\```

Input parameters:

- `auto_fix` (boolean): Automatically remove stale library entries (default: false)
- `show_browser` (boolean): Show browser window for debugging

### `list_sources` (~145 tokens)

List all sources in a NotebookLM notebook.

\## Returns
Array of sources with:
\- id: Source identifier (for use with remove_source)
\- title: Source name/title
\- type: url, text, file, drive, or unknown
\- status: ready, processing, or failed

\## Example
\```json
{ "notebook_id": "my-notebook" }
\```

Or with direct URL:
\```json
{ "notebook_url": "https://notebooklm.google.com/notebook/xxx" }
\```

Input parameters:

- `notebook_id` (string): Library notebook ID
- `notebook_url` (string): Direct notebook URL (overrides notebook_id)

### `add_source` (~138 tokens)

Add a source to an existing NotebookLM notebook.

\## Source Types
\- **url**: Web page URL
\- **text**: Text content (paste)
\- **file**: Local file path (PDF, DOCX, TXT)

\## Example
\```json
{
  "notebook_id": "my-notebook",
  "source": {
    "type": "url",
    "value": "https://docs.example.com/api"
  }
}
\```

Input parameters:

- `notebook_id` (string): Library notebook ID
- `notebook_url` (string): Direct notebook URL (overrides notebook_id)
- `source` (object, required)

### `remove_source` (~121 tokens)

Remove a source from a NotebookLM notebook.

\## Usage
1\. First call list_sources to get source IDs
2\. Then call remove_source with the source ID

\## Example
\```json
{
  "notebook_id": "my-notebook",
  "source_id": "source-0"
}
\```

Input parameters:

- `notebook_id` (string): Library notebook ID
- `notebook_url` (string): Direct notebook URL (overrides notebook_id)
- `source_id` (string, required): Source ID from list_sources (e.g., 'source-0')

### `export_library` (~156 tokens)

Export your notebook library to a backup file.

\## Formats
\- **json**: Full backup with all metadata (recommended for restore)
\- **csv**: Simple list for spreadsheets (name, url, topics, last_used)

\## Default Location
If no output_path specified, saves to:
\~/notebooklm-library-backup-{date}.{format}

\## Example Usage
\```json
{ "format": "json" }
\```

Export to specific location:
\```json
{ "format": "csv", "output_path": "/path/to/backup.csv" }
\```

Input parameters:

- `format` (string): Export format (default: json)
- `output_path` (string): Output file path (optional, defaults to home directory)

### `batch_create_notebooks` (~312 tokens)

Create multiple NotebookLM notebooks in one operation.

\## What This Tool Does
\- Creates up to 10 notebooks in a single batch operation
\- Reports progress for each notebook
\- Optionally continues on error or stops on first failure
\- Auto-adds created notebooks to your library

\## Example Usage
\```json
{
  "notebooks": [
    {
      "name": "React Documentation",
      "sources": [
        { "type": "url", "value": "https://react.dev/reference" }
      ],
      "topics": ["react", "frontend"]
    },
    {
      "name": "Node.js API",
      "sources": [
        { "type": "url", "value": "https://nodejs.org/api/" }
      ],
      "topics": ["nodejs", "backend"]
    }
  ],
  "stop_on_error": false
}
\```

\## Limits
\- Maximum 10 notebooks per batch
\- Each notebook follows individual source limits (50-600 based on tier)
\- Delays between notebooks to avoid rate limiting

\## Returns
Summary with:
\- total: Number of notebooks attempted
\- succeeded: Successfully created count
\- failed: Failed count
\- results: Array of individual results

Input parameters:

- `notebooks` (array, required): Array of notebooks to create (max 10)
- `show_browser` (boolean): Show browser window for debugging
- `stop_on_error` (boolean): Stop batch if any notebook fails (default: false)

### `generate_audio_overview` (~148 tokens)

Generate an AI-powered audio overview (podcast-style) for a notebook.

\## What This Tool Does
\- Triggers NotebookLM's audio overview generation
\- Audio overviews are ~5-15 minute podcast-style summaries
\- Generation takes 2-5 minutes typically
\- Returns immediately with status (check with get_audio_status)

\## Requirements
\- Notebook must have at least one source
\- Audio generation may not be available on all notebooks

\## Example
\```json
{ "notebook_id": "my-research" }
\```

Input parameters:

- `notebook_id` (string): Library notebook ID
- `notebook_url` (string): Or direct notebook URL (overrides notebook_id)

### `get_audio_status` (~117 tokens)

Check the audio overview generation status for a notebook.

\## Returns
\- status: "not_started" | "generating" | "ready" | "failed" | "unknown"
\- progress: Generation progress (0-100) if generating
\- duration: Audio duration in seconds if ready

\## Example
\```json
{ "notebook_id": "my-research" }
\```

Input parameters:

- `notebook_id` (string): Library notebook ID
- `notebook_url` (string): Or direct notebook URL (overrides notebook_id)

### `download_audio` (~133 tokens)

Download the generated audio overview file.

\## Requirements
\- Audio must be in "ready" status
\- Use get_audio_status to check before downloading

\## Output
Downloads to specified path or ~/notebooklm-audio-{timestamp}.mp3

\## Example
\```json
{
  "notebook_id": "my-research",
  "output_path": "/path/to/save/podcast.mp3"
}
\```

Input parameters:

- `notebook_id` (string): Library notebook ID
- `notebook_url` (string): Or direct notebook URL (overrides notebook_id)
- `output_path` (string): Optional output file path

### `list_sessions` (~36 tokens)

List all active sessions with stats (age, message count, last activity). Use to continue the most relevant session instead of starting from scratch.

### `close_session` (~40 tokens)

Close a specific session by session ID. Ask before closing if the user might still need it.

Input parameters:

- `session_id` (string, required): The session ID to close

### `reset_session` (~49 tokens)

Reset a session's chat history (keep same session ID). Use for a clean slate when the task changes; ask the user before resetting.

Input parameters:

- `session_id` (string, required): The session ID to reset

### `get_health` (~179 tokens)

Get server health status including authentication state, active sessions, and configuration. Use this to verify the server is ready before starting research workflows.

\**Deep Check Mode (v2026.1.1)**
Set `deep_check: true` to actually verify the NotebookLM chat UI loads. This catches stale sessions where cookies exist but the UI won't load. Returns `chat_ui_accessible: true/false`.

If authenticated=false and having persistent issues:
Consider running cleanup_data(preserve_library=true) + setup_auth for fresh start with clean browser session.

Input parameters:

- `deep_check` (boolean): If true, actually navigates to NotebookLM and verifies the chat UI loads. More reliable but slower (~5s). Use this before important query sessions.
- `notebook_id` (string): Notebook to check (for deep_check). Defaults to active notebook or first available.

### `setup_auth` (~217 tokens)

Google authentication for NotebookLM access - opens a browser window for manual login to your Google account. Returns immediately after opening the browser. You have up to 10 minutes to complete the login. Use 'get_health' tool afterwards to verify authentication was saved successfully. Use this for first-time authentication or when auto-login credentials are not available. For switching accounts or rate-limit workarounds, use 're_auth' tool instead.

TROUBLESHOOTING for persistent auth issues:
If setup_auth fails or you encounter browser/session issues:
1\. Ask user to close ALL Chrome/Chromium instances
2\. Run cleanup_data(confirm=true, preserve_library=true) to clean old data
3\. Run setup_auth again for fresh start
This helps resolve conflicts from old browser sessions and installation data.

Input parameters:

- `browser_options` (object): Optional browser settings. Control visibility, timeouts, and stealth behavior.
- `show_browser` (boolean): Show browser window (simple version). Default: true for setup. For advanced control, use browser_options instead.

### `re_auth` (~244 tokens)

Switch to a different Google account or re-authenticate. Use this when:
\- NotebookLM rate limit is reached (50 queries/day for free accounts)
\- You want to switch to a different Google account
\- Authentication is broken and needs a fresh start

This will:
1\. Close all active browser sessions
2\. Delete all saved authentication data (cookies, Chrome profile)
3\. Open browser for fresh Google login

After completion, use 'get_health' to verify authentication.

TROUBLESHOOTING for persistent auth issues:
If re_auth fails repeatedly:
1\. Ask user to close ALL Chrome/Chromium instances
2\. Run cleanup_data(confirm=false, preserve_library=true) to preview old files
3\. Run cleanup_data(confirm=true, preserve_library=true) to clean everything except library
4\. Run re_auth again for completely fresh start
This removes old installation data and browser sessions that can cause conflicts.

Input parameters:

- `browser_options` (object): Optional browser settings. Control visibility, timeouts, and stealth behavior.
- `show_browser` (boolean): Show browser window (simple version). Default: true for re-auth. For advanced control, use browser_options instead.

### `cleanup_data` (~409 tokens)

ULTRATHINK Deep Cleanup - Scans entire system for ALL NotebookLM MCP data files across 8 categories. Always runs in deep mode, shows categorized preview before deletion.

⚠️ CRITICAL: Close ALL Chrome/Chromium instances BEFORE running this tool! Open browsers can prevent cleanup and cause issues.

Categories scanned:
1\. Legacy Installation (notebooklm-mcp-nodejs) - Old paths with -nodejs suffix
2\. Current Installation (notebooklm-mcp) - Active data, browser profiles, library
3\. NPM/NPX Cache - Cached installations from npx
4\. Claude CLI MCP Logs - MCP server logs from Claude CLI
5\. Temporary Backups - Backup directories in system temp
6\. Claude Projects Cache - Project-specific cache (optional)
7\. Editor Logs (Cursor/VSCode) - MCP logs from code editors (optional)
8\. Trash Files - Deleted notebooklm files in system trash (optional)

Works cross-platform (Linux, Windows, macOS). Safe by design: shows detailed preview before deletion, requires explicit confirmation.

LIBRARY PRESERVATION: Set preserve_library=true to keep your notebook library.json file while cleaning everything else.

RECOMMENDED WORKFLOW for fresh start:
1\. Ask user to close ALL Chrome/Chromium instances
2\. Run cleanup_data(confirm=false, preserve_library=true) to preview
3\. Run cleanup_data(confirm=true, preserve_library=true) to execute
4\. Run setup_auth or re_auth for fresh browser session

Use cases: Clean reinstall, troubleshooting auth issues, removing all traces before uninstall, cleaning old browser sessions and installation data.

Input parameters:

- `confirm` (boolean, required): Confirmation flag. Tool shows preview first, then user confirms deletion. Set to true only after user has reviewed the preview and explicitly confirmed.
- `preserve_library` (boolean): Preserve library.json file during cleanup. Default: false. Set to true to keep your notebook library while deleting everything else (browser data, caches, logs).

### `get_quota` (~221 tokens)

Get current quota status including license tier, usage, and limits.

Returns:
\- tier: 'free', 'pro', 'ultra', or 'unknown'
\- notebooks: used/limit/remaining/percent
\- sources: limit per notebook
\- queries: used/limit/remaining/percent/should_stop/reset_time
\- warnings: array of warning messages

Quota Limits by Tier:
\- Free: 100 notebooks, 50 sources/notebook, 50 queries/day
\- Pro: 500 notebooks, 300 sources/notebook, 500 queries/day
\- Ultra: 500 notebooks, 600 sources/notebook, 5000 queries/day

Use sync=true to fetch actual quota from Google's NotebookLM UI (requires browser). Without sync, returns locally tracked counts which may differ if you used NotebookLM directly in browser. Query counts reset daily at midnight.

Input parameters:

- `sync` (boolean): If true, navigate to NotebookLM and fetch actual quota from Google's UI. More accurate but requires browser automation. Default: false (use local tracking).

### `set_quota_tier` (~117 tokens)

Manually set your NotebookLM license tier.

Use this if:
\- Auto-detection failed (shows 'unknown')
\- You want to override the detected tier
\- You upgraded/downgraded your plan

Tiers:
\- free: 100 notebooks, 50 sources, 50 queries/day
\- pro: 500 notebooks, 300 sources, 500 queries/day
\- ultra: 500 notebooks, 600 sources, 5000 queries/day

Input parameters:

- `tier` (string, required): License tier to set

### `get_project_info` (~113 tokens)

Get current project context and library location.

Detects the project from the current working directory using:
1\. Git repository root (looks for .git directory)
2\. package.json location (for npm projects)
3\. Current directory as fallback

Returns:
\- project: { id, name, path, type } or null if using global library
\- library_path: Path to the active library.json file
\- is_project_library: Whether using per-project or global library

Use this to understand which library context is active.

### `configure_webhook` (~276 tokens)

Add or update a webhook endpoint for event notifications.

\## Supported Formats
\- generic: Standard JSON payload
\- slack: Slack webhook format
\- discord: Discord webhook format
\- teams: Microsoft Teams format

\## Events
Subscribe to specific events or use '*' for all events:
\- question_answered, notebook_created, notebook_deleted
\- source_added, source_removed
\- session_created, session_expired
\- auth_required, rate_limit_hit, security_incident
\- quota_warning, audio_generated, batch_complete

\## Example
\```json
{
  "name": "Slack Notifications",
  "url": "https://hooks.slack.com/...",
  "format": "slack",
  "events": ["notebook_created", "security_incident"]
}
\```

Input parameters:

- `enabled` (boolean): Enable/disable the webhook (default: true)
- `events` (array): Events to subscribe to. Use ["*"] for all events.
- `format` (string): Payload format (default: generic)
- `id` (string): Webhook ID (for updates). Omit to create new.
- `name` (string, required): Display name for the webhook
- `secret` (string): Secret for HMAC signature (X-Webhook-Signature header)
- `url` (string, required): Webhook endpoint URL

### `list_webhooks` (~39 tokens)

List all configured webhooks with their status and statistics.

Returns array of webhooks with: id, name, url, enabled, events, format.

### `test_webhook` (~49 tokens)

Send a test event to a webhook to verify it's working.

Sends a sample 'question_answered' event and returns success/failure.

Input parameters:

- `id` (string, required): Webhook ID to test

### `remove_webhook` (~28 tokens)

Remove a configured webhook by ID.

Input parameters:

- `id` (string, required): Webhook ID to remove

### `deep_research` (~185 tokens)

Perform deep research using Gemini's Deep Research agent.

This runs in the background and can take 1-5 minutes to complete.

\## When to Use
\- You need comprehensive research on a topic
\- No specific NotebookLM notebook is relevant
\- You want web-grounded answers with citations

\## Requirements
\- GEMINI_API_KEY environment variable must be set

\## Notes
\- Deep Research is a premium feature that may incur costs
\- Results are grounded in web sources with citations
\- For notebook-specific queries, use ask_question instead

Input parameters:

- `max_wait_seconds` (number): Maximum wait time in seconds (default 5 min, max 10 min)
- `query` (string, required): The research question or topic to investigate
- `wait_for_completion` (boolean): Wait for research to complete (polls every 10s). Set to false to run in background.

### `gemini_query` (~182 tokens)

Quick query to Gemini model with optional grounding tools.

Faster than deep_research for simpler questions. Supports:
\- Google Search grounding for current information
\- Code execution for calculations
\- URL analysis for web content

\## Requirements
\- GEMINI_API_KEY environment variable must be set

\## When to Use
\- Quick factual questions
\- Current events (with google_search tool)
\- Code calculations (with code_execution tool)
\- Web page analysis (with url_context tool)

Input parameters:

- `model` (string): Model to use (flash is faster, pro is more capable)
- `previous_interaction_id` (string): Continue a previous conversation (for multi-turn)
- `query` (string, required): The question or prompt
- `tools` (array): Built-in tools to enable for grounding
- `urls` (array): URLs to analyze (automatically enables url_context)

### `get_research_status` (~83 tokens)

Check the status of a background deep research task.

Use this when you started deep_research with wait_for_completion=false.

\## Returns
\- status: pending | running | completed | failed
\- answer: The research result (if completed)
\- error: Error message (if failed)

Input parameters:

- `interaction_id` (string, required): The interaction ID returned from deep_research

### `upload_document` (~293 tokens)

Upload a document (PDF, text, etc.) to Gemini for querying.

\## What This Does
\- Uploads a local file to Gemini's Files API
\- File is retained for 48 hours
\- Returns a file ID for use with query_document

\## Auto-Chunking for Large PDFs (v1.10.0)
\- PDFs over 50MB or 1000 pages are automatically split into chunks
\- Each chunk is uploaded separately and tracked
\- Use query_chunked_document or pass all chunk IDs to query_document
\- Returns wasChunked=true and allFileNames array when chunked

\## Supported File Types
\- PDF (any size - auto-chunked if needed)
\- TXT, MD, HTML, CSV, JSON, XML
\- DOCX, DOC
\- Images (PNG, JPG, GIF, WebP)
\- Audio (MP3, WAV)
\- Video (MP4)

\## When to Use
\- You have a local document to analyze
\- You want fast, API-based document queries (no browser needed)
\- For temporary analysis (48h retention)

\## For Permanent Storage
Use create_notebook instead for permanent document storage with NotebookLM.

\## Requirements
\- GEMINI_API_KEY environment variable must be set

Input parameters:

- `display_name` (string): Optional friendly name for the file
- `file_path` (string, required): Absolute path to the file to upload

### `query_document` (~214 tokens)

Ask questions about an uploaded document.

\## What This Does
\- Queries a document previously uploaded with upload_document
\- Uses Gemini's document understanding (text, images, charts, tables)
\- Returns answers grounded in the document content

\## Features
\- Full document understanding (not just text extraction)
\- Can analyze charts, diagrams, and tables in PDFs
\- Multi-document queries (pass additional file IDs)
\- Fast API-based (no browser automation)

\## When to Use
\- Quick document analysis without browser
\- Comparing multiple documents
\- Extracting specific information

\## Requirements
\- GEMINI_API_KEY environment variable must be set
\- Document must be uploaded first with upload_document

Input parameters:

- `additional_files` (array): Additional file IDs to include in the query (for multi-document analysis)
- `file_name` (string, required): File name/ID returned from upload_document
- `model` (string): Model to use (flash is faster, pro is more capable)
- `query` (string, required): Question to ask about the document

### `list_documents` (~105 tokens)

List all documents uploaded to Gemini.

\## What This Does
\- Shows all files currently stored in Gemini Files API
\- Files expire 48 hours after upload
\- Returns file names, sizes, and expiration times

\## Use Cases
\- Check what documents are available for querying
\- Find file IDs for query_document
\- Monitor storage usage

\## Requirements
\- GEMINI_API_KEY environment variable must be set

Input parameters:

- `page_size` (number): Maximum number of files to return

### `delete_document` (~103 tokens)

Delete an uploaded document from Gemini.

\## What This Does
\- Removes a file from Gemini Files API
\- File will no longer be available for queries
\- Frees up storage space

\## Notes
\- Files auto-delete after 48 hours anyway
\- Use this to immediately remove sensitive documents

\## Requirements
\- GEMINI_API_KEY environment variable must be set

Input parameters:

- `file_name` (string, required): File name/ID to delete (from upload_document or list_documents)

### `query_chunked_document` (~271 tokens)

Query a large document that was automatically chunked during upload.

\## What This Does
\- Queries each chunk of a large document
\- Aggregates results into a single coherent answer
\- Handles documents of any size (1000+ pages)

\## When to Use
\- After upload_document returns wasChunked=true
\- When you have multiple chunk file IDs to query together
\- For comprehensive analysis of large PDFs

\## How It Works
1\. Queries each chunk with your question
2\. Collects answers from all chunks
3\. Uses Gemini to synthesize a unified response
4\. Returns aggregated answer with all sources

\## Example
If upload_document returned:
  { wasChunked: true, allFileNames: ["files/a", "files/b", "files/c"] }

Call this tool with:
  { file_names: ["files/a", "files/b", "files/c"], query: "What are the main findings?" }

\## Requirements
\- GEMINI_API_KEY environment variable must be set
\- Document chunks must be uploaded first

Input parameters:

- `file_names` (array, required): Array of chunk file IDs (from upload_document's allFileNames)
- `model` (string): Model to use for querying and aggregation
- `query` (string, required): Question to ask about the document

### `get_query_history` (~158 tokens)

Retrieve past NotebookLM queries and answers for reviewing research sessions.

Use this tool to:
\- Review past research conversations
\- Find specific information from previous queries
\- Track which notebooks and sessions you've used
\- Search through question and answer content

Returns query entries with question, answer, notebook, session, and timing info.

Input parameters:

- `date` (string): Filter queries by date (format: YYYY-MM-DD)
- `limit` (number): Maximum number of entries to return (default: 50, max: 500)
- `notebook_id` (string): Filter queries by notebook ID (from your library)
- `search` (string): Search pattern to find in questions or answers
- `session_id` (string): Filter queries by session ID

### `get_notebook_chat_history` (~434 tokens)

Extract conversation history from a NotebookLM notebook's chat interface.

This tool uses browser automation to navigate to a notebook and extract all Q&A pairs
from the chat UI. This is useful for:
\- Recovering previous research conversations
\- Auditing what queries were made in a notebook
\- Understanding quota usage from direct NotebookLM browser usage
\- Resuming context from previous sessions

\## Context Management
Use `preview_only: true` to get a quick count before extracting full content.
Use `output_file` to export to JSON instead of returning to context.
Use `offset` with `limit` for pagination through large histories.

\## Examples

Quick audit (preview only):
\```json
{ "notebook_id": "my-research", "preview_only": true }
\```

Export to file (avoids context overflow):
\```json
{ "notebook_id": "my-research", "output_file": "/tmp/chat-history.json" }
\```

Paginate through history:
\```json
{ "notebook_id": "my-research", "limit": 20, "offset": 0 }
{ "notebook_id": "my-research", "limit": 20, "offset": 20 }
\```

Input parameters:

- `limit` (number): Maximum number of message pairs to return (default: 50, max: 200).
- `notebook_id` (string): Library notebook ID. Use list_notebooks to see available notebooks.
- `notebook_url` (string): Direct notebook URL (overrides notebook_id). Use for notebooks not in your library.
- `offset` (number): Number of message pairs to skip from the start. Use with limit for pagination. (default: 0)
- `output_file` (string): If provided, exports chat history to this JSON file instead of returning to context. Useful for large histories.
- `preview_only` (boolean): If true, only returns message count and summary without content. Use this to audit before extracting full history. (default: false)
- `show_browser` (boolean): Show browser window for debugging (default: false)

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/pantheon-security-notebooklm-mcp-secure/pan-sec-notebooklm-mcp#diagnostics

## Score history

- 2026-08-03: 65
- 2026-08-02: 64
- 2026-08-01: 40
- 2026-07-31: 33
- 2026-07-30: 51
- 2026-07-28: 24
- 2026-07-27: 24

## Links

- npm package: https://www.npmjs.com/package/@pan-sec/notebooklm-mcp
- Socket report: https://socket.dev/npm/package/@pan-sec/notebooklm-mcp
- Repository: https://github.com/Pantheon-Security/notebooklm-mcp-secure
- Changelog RSS feed: https://verifymcp.io/servers/pantheon-security-notebooklm-mcp-secure/pan-sec-notebooklm-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/pantheon-security-notebooklm-mcp-secure/pan-sec-notebooklm-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/pantheon-security-notebooklm-mcp-secure/pan-sec-notebooklm-mcp
