# 🧠 NotebookLM MCP Server ### Bridge the Gap Between Google NotebookLM and Your AI Workspace [![NPM Version](https://img.shields.io/npm/v/@m4ykeldev/notebooklm-mcp)](https://www.npmjs.com/package/@m4ykeldev/notebooklm-mcp) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Build Status](https://github.com/m4yk3ldev/notebooklm-mcp/actions/workflows/publish.yml/badge.svg)](https://github.com/m4yk3ldev/notebooklm-mcp/actions) Stop jumping between browser tabs. **NotebookLM MCP** brings the full analytical power of [Google NotebookLM](https://notebook.google.com) directly into your local terminal, IDE, and AI assistants like Claude, Cursor, and VS Code. Manage notebooks, ingest diverse sources, trigger deep research, and generate studio-quality contentβ€”all via a single, standardized Model Context Protocol (MCP) interface. > **New to MCP?** The [Model Context Protocol](https://modelcontextprotocol.io) is a standard for connecting LLMs to external data sources and tools. This package speaks MCP over stdio β€” your AI client (Claude Desktop, Cursor, VS Code, etc.) spawns `notebooklm-mcp serve` as a subprocess and the two communicate over JSON-RPC. The 27 tools below become callable functions in the model's tool list. --- ## πŸ”₯ Key Capabilities - ⚑ **Seamless Authentication**: Log in once with `notebooklm-mcp auth`. Our automated CDP-based flow handles secure cookie extraction so you can focus on your data. - πŸ”„ **Resilient Connectivity**: Built-in background session restoration. If your session expires, the server transparently reconnects without breaking your workflow. - πŸ“‚ **Universal Ingestion**: Instantly add URLs, YouTube transcripts, Google Drive files, or raw text snippets to any notebook. - πŸ•΅οΈ **Autonomous Research**: Harness Google's Deep Research engine. Start a task, poll its progress, and import structured insights directly into your project. - 🎭 **Creative Studio**: Programmatically generate Audio Overviews (podcasts), Briefing Docs, Infographics, Slide Decks, and Quizzes from your sources. --- ## πŸš€ Quick Start ### 1. Installation Requires **Node.js β‰₯ 20** and Google Chrome or Chromium (for `auth`). Run it instantly with `npx`: ```bash npx -y @m4ykeldev/notebooklm-mcp serve ``` Or install globally for better performance: ```bash npm install -g @m4ykeldev/notebooklm-mcp ``` > Developers who want to hack on the source: this repo uses **pnpm** > (pinned via `packageManager` in `package.json`). After cloning, run > `corepack enable && pnpm install`. See [CONTRIBUTING.md on GitHub](https://github.com/m4yk3ldev/notebooklm-mcp/blob/main/CONTRIBUTING.md) > for the full dev / release flow. ### 2. The "One-Click" Login Say goodbye to manual cookie hunting. Our smart auth flow does the heavy lifting for you. ```bash notebooklm-mcp auth ``` _A secure Chrome window will open. Simply log into your Google account, and we'll handle the rest. Your session is stored locally and securely._ **Auth fallbacks** if automated Chrome can't run: ```bash notebooklm-mcp auth --manual # interactive copy/paste from your browser notebooklm-mcp auth --file tokens.json # import a previously exported bundle notebooklm-mcp auth --show-tokens # verify the cached session ``` For headless / CI environments, set `NOTEBOOKLM_COOKIES` (and optionally `NOTEBOOKLM_CSRF_TOKEN`, `NOTEBOOKLM_SESSION_ID`) instead of running the auth flow. Token resolution order: env var β†’ `~/.notebooklm-mcp/auth.json` β†’ error. --- ## πŸ€– AI Assistant Integration Pick your client below β€” every section shows the **config file path per OS**, a **minimal copy-paste block**, and the **advanced variant** with `--query-timeout` and `NOTEBOOKLM_COOKIES` env override. | Client | Config file | Format | |---|---|---| | [Claude Desktop](#claude-desktop) | `claude_desktop_config.json` | JSON | | [Claude Code (CLI)](#claude-code-cli) | `~/.claude.json` or `claude mcp add` | JSON / CLI | | [Codex CLI](#codex-cli) | `~/.codex/config.toml` | TOML | | [OpenAI Agents SDK (Python)](#openai-agents-sdk--python) | in-code | Python | | [OpenAI Agents SDK (TypeScript)](#openai-agents-sdk--typescript) | in-code | TypeScript | | [Gemini CLI](#gemini-cli) | `~/.gemini/settings.json` | JSON | | [Cursor](#cursor) | `~/.cursor/mcp.json` | JSON | | [VS Code (Copilot Chat agent mode)](#vs-code-copilot-chat-agent-mode) | `.vscode/mcp.json` | JSON | | [Windsurf](#windsurf) | `~/.codeium/windsurf/mcp_config.json` | JSON | | [JetBrains AI Assistant / Junie](#jetbrains-ai-assistant--junie) | `~/.junie/mcp/mcp.json` | JSON | | [Zed](#zed) | `~/.config/zed/settings.json` | JSON | | [OpenCode (sst)](#opencode-sst) | `opencode.jsonc` | JSONC | | [Cline (VS Code extension)](#cline-vs-code-extension) | extension settings UI | JSON | | [Goose (Block)](#goose-block) | `~/.config/goose/config.yaml` | YAML | | [5ire](#5ire) | in-app settings | GUI | | [Aider](#aider) | not yet supported | β€” | | [Generic stdio caller](#generic-stdio-caller) | yours | β€” | --- ### Claude Desktop - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json` - Linux: `~/.config/Claude/claude_desktop_config.json` - Windows: `%APPDATA%\Claude\claude_desktop_config.json` ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"] } } } ```
With timeout + env override ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve", "--query-timeout", "180000", "--debug"], "env": { "NOTEBOOKLM_COOKIES": "SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..." } } } } ``` **Verify:** restart Claude Desktop, click the hammer icon at the bottom-right of the input. **Gotchas:** absolute paths only; relative paths fail silently on startup.
--- ### Claude Code (CLI) Recommended path is the `claude mcp add` CLI (writes the JSON for you): ```bash claude mcp add --transport stdio notebooklm -- npx -y @m4ykeldev/notebooklm-mcp serve ```
Equivalent JSON (project scope, ./.mcp.json) ```json { "mcpServers": { "notebooklm": { "type": "stdio", "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"] } } } ```
With timeout + env override (CLI) ```bash claude mcp add --transport stdio \ --env NOTEBOOKLM_COOKIES="SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..." \ notebooklm -- npx -y @m4ykeldev/notebooklm-mcp serve --query-timeout 180000 ``` **Verify:** `claude mcp list && claude mcp get notebooklm`, or `/mcp` inside a session. **Gotchas:** all options before the server name; use `--` to separate options from the command. Project-scoped `.mcp.json` needs interactive approval on first sight.
--- ### Codex CLI - macOS: `~/.codex/config.toml` - Linux: `~/.config/codex/config.toml` - Windows: `%APPDATA%\codex\config.toml` ```toml [mcp_servers.notebooklm] command = "npx" args = ["-y", "@m4ykeldev/notebooklm-mcp", "serve"] ```
With timeout + env override ```toml [mcp_servers.notebooklm] command = "npx" args = ["-y", "@m4ykeldev/notebooklm-mcp", "serve", "--query-timeout", "180000"] env = { NOTEBOOKLM_COOKIES = "SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..." } ``` **Verify:** `codex --list-tools` should list the NotebookLM tools. **Gotchas:** Codex CLI's MCP schema is still being formalized β€” double-check against the latest `openai/codex` README.
--- ### OpenAI Agents SDK β€” Python Wire it in code (no config file): ```python from agents.mcp import MCPServerStdio async with MCPServerStdio( name="NotebookLM", params={ "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"], }, ) as server: tools = await server.list_tools() print([t.name for t in tools]) # 27 tools ```
With timeout + env override ```python async with MCPServerStdio( name="NotebookLM", params={ "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve", "--query-timeout", "180000"], "env": {"NOTEBOOKLM_COOKIES": "SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..."}, }, ) as server: ... ```
--- ### OpenAI Agents SDK β€” TypeScript ```typescript import { MCPServerStdio } from "@openai/agents"; const server = new MCPServerStdio({ command: "npx", args: ["-y", "@m4ykeldev/notebooklm-mcp", "serve"], }); await server.connect(); const tools = await server.listTools(); console.log(tools.map((t) => t.name)); // 27 tools ```
With timeout + env override ```typescript const server = new MCPServerStdio({ command: "npx", args: ["-y", "@m4ykeldev/notebooklm-mcp", "serve", "--query-timeout", "180000"], env: { NOTEBOOKLM_COOKIES: "SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..." }, }); ```
--- ### Gemini CLI `~/.gemini/settings.json` (user-global) or `.gemini/settings.json` (per-project). ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"] } } } ```
With timeout + env override (Gemini supports $VAR expansion) ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"], "timeout": 180000, "env": { "NOTEBOOKLM_COOKIES": "$NOTEBOOKLM_COOKIES" } } } } ``` **Verify:** `gemini mcp list`, or `/mcp` in a session. **Gotchas:** undefined `$VAR` resolves to empty string β€” pre-export them in your shell.
--- ### Cursor - macOS / Linux: `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (per-project) - Windows: `%APPDATA%\Cursor\mcp.json` ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"] } } } ```
With timeout + env override ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve", "--query-timeout", "180000"], "env": { "NOTEBOOKLM_COOKIES": "SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..." } } } } ``` **Verify:** `Cursor Settings β†’ MCP` should show `notebooklm` in green, or `MCP: View Server Status` in the Command Palette. **Gotchas:** Cursor only loads MCP servers at startup β€” fully quit and relaunch after edits. Soft ~40-tool ceiling across all enabled servers combined.
--- ### VS Code (Copilot Chat agent mode) `.vscode/mcp.json` (per-project). Top-level key is **`servers`** (not `mcpServers` β€” Microsoft renamed this). ```json { "servers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"] } } } ```
With timeout + env override ```json { "servers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve", "--query-timeout", "180000"], "env": { "NOTEBOOKLM_COOKIES": "SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..." } } } } ``` **Verify:** Command Palette β†’ `MCP: Open User Configuration`. Ask Copilot Chat in **agent mode** to list NotebookLM notebooks.
--- ### Windsurf - macOS / Linux: `~/.codeium/windsurf/mcp_config.json` - Windows: `%APPDATA%\Codeium\Windsurf\mcp_config.json` ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"] } } } ```
With timeout + env override (uses Windsurf's ${env:VAR} interpolation) ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve", "--query-timeout", "180000"], "env": { "NOTEBOOKLM_COOKIES": "${env:NOTEBOOKLM_COOKIES}" } } } } ``` **Verify:** open the Cascade sidebar β†’ MCP settings β†’ confirm `notebooklm` is active. **Gotchas:** prefer `${env:VAR}` / `${file:/path}` interpolation over inlining cookies; Windsurf substitutes at server-launch time so secrets stay out of the config file.
--- ### JetBrains AI Assistant / Junie - macOS / Linux: `~/.junie/mcp/mcp.json` (user-global) or `.junie/mcp/mcp.json` (per-project) - Windows: `%APPDATA%\JetBrains\Junie\mcp.json` ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"] } } } ```
With timeout + env override ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve", "--query-timeout", "180000"], "env": { "NOTEBOOKLM_COOKIES": "SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..." } } } } ``` **Verify:** `Settings (Ctrl+Alt+S) β†’ Tools β†’ Junie β†’ MCP Settings` β€” `notebooklm` should appear in the discovered list.
--- ### Zed `~/.config/zed/settings.json` β€” the relevant key is **`context_servers`** (Zed's MCP equivalent). ```json { "context_servers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"] } } } ```
With timeout + env override ```json { "context_servers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve", "--query-timeout", "180000"], "env": { "NOTEBOOKLM_COOKIES": "SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..." } } } } ``` **Verify:** Zed's AI Agent Panel lists `notebooklm` as an available context source.
--- ### OpenCode (sst) `opencode.jsonc` (project root) or `~/.config/opencode/config.json`. ```jsonc { "mcp": { "servers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"] } } } } ```
With timeout + env override ```jsonc { "mcp": { "servers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve", "--query-timeout", "180000"], "env": { "NOTEBOOKLM_COOKIES": "SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..." } } } } } ``` **Verify:** start OpenCode and ask *"List my NotebookLM notebooks."* β€” the model should call `notebook_list`. **Gotchas:** OpenCode's MCP schema is still evolving; confirm against the [OpenCode docs](https://opencode.ai/docs) if startup fails.
--- ### Cline (VS Code extension) Managed via Cline's MCP settings UI inside VS Code. Underlying file (don't edit by hand): `~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json`. 1. Open the Cline panel β†’ click the MCP icon β†’ `Configure MCP Servers`. 2. Paste: ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve"] } } } ``` 3. Save. Cline restarts the server automatically.
With timeout + env override ```json { "mcpServers": { "notebooklm": { "command": "npx", "args": ["-y", "@m4ykeldev/notebooklm-mcp", "serve", "--query-timeout", "180000"], "env": { "NOTEBOOKLM_COOKIES": "SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..." } } } } ``` **Verify:** ask Cline *"List my NotebookLM notebooks."* β€” the tool-call panel shows `notebook_list`.
--- ### Goose (Block) `~/.config/goose/config.yaml` (or via `goose configure`). Goose calls MCP servers "extensions". ```yaml extensions: notebooklm: type: stdio command: npx args: - "-y" - "@m4ykeldev/notebooklm-mcp" - serve ```
With timeout + env override ```yaml extensions: notebooklm: type: stdio command: npx args: - "-y" - "@m4ykeldev/notebooklm-mcp" - serve - "--query-timeout" - "180000" env: NOTEBOOKLM_COOKIES: "SID=...; HSID=...; SSID=...; APISID=...; SAPISID=..." ``` **Verify:** `goose configure` β†’ confirm the extension is enabled, then `goose session` and ask *"List my NotebookLM notebooks."*
--- ### 5ire GUI app (no user-editable config file): 1. Open 5ire β†’ `Settings` (`Mod+K` β†’ `Providers`). 2. Click **Add MCP Server**. 3. Name: `notebooklm` 4. Type: `Stdio` 5. Command: `npx` 6. Args: `-y @m4ykeldev/notebooklm-mcp serve` (add `--query-timeout 180000` if needed) 7. Env vars (optional): `NOTEBOOKLM_COOKIES=SID=...; HSID=...; SSID=...; APISID=...; SAPISID=...` 8. Save and restart. **Verify:** ask in chat *"List my NotebookLM notebooks."* β€” tool-call panel shows `notebook_list`. --- ### Aider Aider does not yet have first-class MCP-server client integration. Workarounds: run `notebooklm-mcp serve` separately and pipe responses, or use the [generic stdio caller](#generic-stdio-caller) inside a small wrapper script. Track upstream support via the [Aider Discord](https://discord.gg/Y7X7bhMQFV). --- ### Generic stdio caller If your client speaks the [MCP protocol](https://modelcontextprotocol.io/specification) over stdio but isn't listed above, every config above reduces to the same primitive: ``` spawn: npx -y @m4ykeldev/notebooklm-mcp serve stdio: parent <- stdout (JSON-RPC responses) | parent -> stdin (JSON-RPC requests) env: (optional) NOTEBOOKLM_COOKIES=... # skip the auth flow in CI NOTEBOOKLM_CSRF_TOKEN=... NOTEBOOKLM_SESSION_ID=... flags: (optional) --query-timeout # per-RPC timeout, default 120000 --debug # verbose stderr logging ``` On connection the server advertises 27 tools β€” see the [Complete Tool Reference](#-complete-tool-reference-27) below. --- ### Verify any wiring After restarting your client, ask: > *"List my NotebookLM notebooks."* If the model invokes `notebook_list` and returns a table of titles, you're connected. --- ## 🧩 Agent Skill [`skills/notebooklm/SKILL.md`](skills/notebooklm/SKILL.md) teaches an agent when and how to use these tools (setup, query β†’ studio β†’ research workflows, confirmation rules, failure handling). Copy the `skills/notebooklm/` folder into your agent's skills directory (for Claude Code: `~/.claude/skills/`). --- ## πŸ’¬ Example Prompts Once wired up, your AI can drive NotebookLM end-to-end with natural language. The model picks the right tool from the 27 below. | Goal | Sample prompt | Tools the model will call | |---|---|---| | Inventory | _"Show me every NotebookLM project I own"_ | `notebook_list` | | Start a project | _"Create a notebook called 'Q3 Earnings' and add the AAPL 10-Q PDF at https://…"_ | `notebook_create`, `source_add_url` | | Grounded Q&A | _"From the AAPL notebook, what is the year-over-year services revenue change?"_ | `notebook_query` | | Multi-source brief | _"In my 'Climate Policy' notebook, generate a one-page briefing doc focused on IRA tax credits"_ | `report_create`, `studio_status` | | Studio podcast | _"Make a 10-min audio overview of my 'AI Safety Reading' notebook"_ | `audio_overview_create`, `studio_status` | | Deep Research β†’ import | _"Run deep research on 'kelp aquaculture in Maine' and import the findings into my 'Climate' notebook"_ | `research_start`, `research_status`, `research_import` | | Cleanup | _"Delete the 'Old Drafts' notebook I no longer need"_ | `notebook_list`, `notebook_delete` | ## πŸ›  Complete Tool Reference (27) Every tool carries a title, a description of what it returns, and MCP annotations (read-only, destructive, idempotent), so clients can tell safe lookups from changes. Since v0.5.0 each tool also publishes an `outputSchema` and returns its result as `structuredContent` (typed fields) alongside the usual JSON text. The server also sends usage instructions at initialization. > **Renamed in v0.4.0.** Tool names now follow one `resource_action` scheme. If your client allow-lists tools by name (e.g. `mcp__notebooklm__notebook_add_url` in Claude Code permissions), update it: > > | Before | Now | > | :-- | :-- | > | `notebook_add_url` / `notebook_add_text` / `notebook_add_drive` | `source_add_url` / `source_add_text` / `source_add_drive` | > | `source_describe` | `source_get` | > | `notebook_describe` | `notebook_summarize` | > | `refresh_auth` / `save_auth_tokens` | `auth_refresh` / `auth_save_tokens` | ### πŸ“” Notebook Management | Tool | Description | | :------------------ | :---------------------------------------------------------------------------------------------- | | `notebook_list` | Get an overview of your notebooks (titles, sources, ownership), up to `max_results` (default 100). | | `notebook_create` | Create a new NotebookLM project instantly from your terminal or AI assistant. | | `notebook_get` | Retrieve deep metadata and a full list of sources for a specific notebook. | | `notebook_summarize` | Get an AI-generated summary of the notebook plus the questions NotebookLM suggests asking. | | `notebook_rename` | Update the title of an existing notebook. | | `notebook_delete` | Permanently remove a notebook (requires explicit confirmation). | ### πŸ“„ Source Ingestion & Management | Tool | Description | | :------------------- | :------------------------------------------------------------------------------------- | | `source_add_url` | Add any public website or YouTube video as a source. Returns the new source's ID. | | `source_add_text` | Ingest raw text snippets or local file contents. Returns the new source's ID. | | `source_add_drive` | Import a Google Drive file by its file ID. Returns the new source's ID. | | `source_get` | Get a source's title, type and extracted-text length (the text itself: next tool). | | `source_get_content` | Extract the full underlying text of a source for processing by other AI tools. | | `source_sync_drive` | Sync selected Google Drive sources to pull the latest changes into NotebookLM. | | `source_delete` | Remove a specific source from your notebook. | ### πŸ”¬ Research & Deep Analysis | Tool | Description | | :---------------- | :------------------------------------------------------------------------------------ | | `research_start` | Launch an autonomous research task using Google's engine (Web or Drive sources). | | `research_status` | Track the progress of active research tasks and view discovered insights. | | `research_import` | Instantly import the findings of a research task as new sources in your notebook. | | `notebook_query` | Ask questions answered only from your sources, with follow-ups in the same conversation. | ### 🎬 Studio (AI Content Generation) | Tool | Description | | :---------------------- | :--------------------------------------------------------------------------------------- | | `audio_overview_create` | Transform your notebook's sources into a professional, podcast-style audio discussion. | | `video_overview_create` | Generate a structured video explainer based on your project data. | | `report_create` | Create professional Briefing Docs, Study Guides, or Blog Posts tailored to your sources. | | `slide_deck_create` | Turn your research into a presenter-ready slide deck automatically. | | `infographic_create` | Visualize complex data and relationships with an AI-generated infographic. | | `flashcards_create` | Generate interactive study flashcards to master your notebook's content. | | `quiz_create` | Create a comprehensive quiz to test knowledge grounded in your provided sources. | | `studio_status` | Check the generation status of your Studio artifacts and get download links. | ### πŸ”‘ Authentication Helpers | Tool | Description | | :----------------- | :--------------------------------------------------------------------- | | `auth_refresh` | Manually trigger a session refresh if you encounter connection issues. | | `auth_save_tokens` | Manually save cookie data (legacy fallback method). | --- ## πŸŽ› CLI Reference ```bash notebooklm-mcp serve [--query-timeout ] [--debug] notebooklm-mcp auth [--manual] [--file ] [--show-tokens] notebooklm-mcp --version ``` | Flag | Default | Description | |---|---|---| | `serve --query-timeout` | `120000` | Per-RPC timeout in ms. Bump for large studio jobs or slow research. | | `serve --debug` | off | Verbose stderr logging of every RPC + retry. | | `auth --manual` | off | Skip Chrome automation; paste cookies yourself. | | `auth --file ` | β€” | Import a previously exported tokens JSON. | | `auth --show-tokens` | β€” | Print the cached session's metadata (cookie names, age, CSRF/SID presence β€” never the secret values). | --- ## 🩹 Troubleshooting | Symptom | Likely cause | Fix | |---|---|---| | _"Could not find Google Chrome or Chromium"_ | No Chrome/Chromium on PATH | Install Chrome or run `notebooklm-mcp auth --manual` | | _"Authentication expired"_ inside the AI session | Cookies stale | The server auto-refreshes once; if it can't, re-run `notebooklm-mcp auth` | | _"NotebookLM redirected to … (Google sign-in)"_ or _"page has no CSRF token"_ | Google session signed out | Re-run `notebooklm-mcp auth`. The server does not open a browser on its own for this | | HTTP 401 with valid cookies (`v0.3.1` and older) | NotebookLM moved to `notebook.google.com` | Upgrade to the latest version | | `research_import` says _"Imported X of Y"_ with X < Y | NotebookLM could not fetch some URLs | Retry, or pick other results. Drive results are skipped; only web results import | | Tool calls hang past 2 min | Big studio job over default timeout | Restart server with `--query-timeout 300000` | | _"file_path … outside the allowed roots"_ | `source_add_text` got a path outside cwd / tmp | Copy the file into your working directory or pass `content` inline | | MCP client reports server crashed on startup | `dist/cli.js` missing (dev clone) | `pnpm install && pnpm run build` | | Multiple Chrome windows pop up on concurrent failures | Older version without single-flight mutex | Upgrade to β‰₯ `v0.2.5` | --- ## πŸ’‘ Pro Tips - **Custom Timeouts**: Working with massive sources? Increase the timeout: `notebooklm-mcp serve --query-timeout 180000` - **Check Connections**: Use `notebooklm-mcp auth --show-tokens` to verify your session validity without exposing the secrets. - **CI / headless**: Set `NOTEBOOKLM_COOKIES` (plus `NOTEBOOKLM_CSRF_TOKEN`, `NOTEBOOKLM_SESSION_ID`) to skip the browser flow entirely. --- ## πŸ›‘ Security & Privacy - **Local Storage** with hardened perms. Tokens live at `~/.notebooklm-mcp/auth.json` (mode `0600`) inside `~/.notebooklm-mcp/` (mode `0700`). Nothing leaves your machine except calls to Google. - **Path-traversal guard**. `source_add_text` rejects `file_path` arguments outside the working directory or the OS temp directory β€” a hostile MCP prompt cannot ask the server to read your `~/.ssh/id_rsa`. - **Loopback-only Chrome DevTools**. The automated auth flow launches Chrome with an OS-assigned ephemeral port bound to `127.0.0.1` β€” no fixed-port squatting, no LAN exposure. - **Single-flight auth refresh**. Concurrent requests that hit an expired session share one refresh promise instead of each spawning their own Chrome. - **Supply-chain gated releases**. Every publish runs gitleaks β†’ osv-scanner β†’ `pnpm audit` (high+) β†’ `npm audit signatures` (Sigstore) β†’ lockfile registry pinning β†’ publish-manifest preview before `pnpm publish` ships via OIDC trusted publishers. See [CONTRIBUTING.md β†’ Releasing on GitHub](https://github.com/m4yk3ldev/notebooklm-mcp/blob/main/CONTRIBUTING.md#releasing). - **Test coverage**: 100% statements / branches / functions / lines, enforced by CI. - **Unofficial Tool**: This project is an independent community effort and is not affiliated with Google. It interfaces with internal endpoints and may be affected by changes to the NotebookLM web platform. ## πŸ“„ License Open-source and available under the [MIT License](LICENSE). --- Crafted with precision for the AI-first developer. Part of the [Model Context Protocol](https://modelcontextprotocol.io) ecosystem.