notebooklm-mcp
Bridges Claude Code/Cowork with Google NotebookLM for AI-powered research, source analysis, chat, and content generation through a structured tool interface.
README
notebooklm-mcp
MCP (Model Context Protocol) server that bridges Claude Code / Claude Cowork with Google NotebookLM — enabling AI-powered research, source analysis, chat, and content generation through a structured tool interface.
Built on
notebooklm-py(v0.4.1) by Teng Lin — a community-maintained Python client and CLI for Google NotebookLM. All API interaction, authentication, and data models are powered bynotebooklm-py. This project wraps it as an MCP server for use with Claude Code and Claude Cowork.
Features
- 24 MCP tools covering notebooks, sources, chat, artifacts, notes, and account management
- Pagination on all list tools (
limit/offsetwith metadata) - Dual output format: JSON (structured) and Markdown (human-readable) on 15 tools
- Service prefix (
notebooklm_*) to prevent collisions with other MCP servers - Keepalive support for long-running Claude Code sessions (token rotation every 10 min)
- Multiple auth methods: env var, profile-based, or inline JSON
Prerequisites
- Python >= 3.11
- A Google account with access to NotebookLM
- Authentication configured via
notebooklm login(see below)
Installation
# Clone the repository
git clone https://github.com/ripafratta/notebooklm-py-mcp.git
cd notebooklm-py-mcp
# Install in editable mode
pip install -e .
This installs the notebooklm-mcp command along with its two core dependencies:
notebooklm-py>= 0.4.1 — Python client/CLI for NotebookLMmcp>= 1.6.0 — Official MCP Python SDK
Authentication
The server uses the notebooklm-py library's auth system. Choose one method:
Method 1: Browser login (recommended)
# Install with cookie support
pip install 'notebooklm-py[cookies]'
# Login via browser
notebooklm login
This opens a Chromium browser, you sign in to Google, and the session is saved to ~/.notebooklm/profiles/default/storage_state.json.
Method 2: Environment variable (CI/headless)
export NOTEBOOKLM_AUTH_JSON='{"cookies":[...],"origins":[...]}'
The JSON format matches Playwright's storage_state.json. You can extract it from a logged-in browser session.
Method 3: Multiple profiles
notebooklm profile create work
notebooklm login -p work
# Use with the server:
NOTEBOOKLM_PROFILE=work notebooklm-mcp
Verify authentication
notebooklm auth check
notebooklm doctor # Full diagnostic
Quick Start
# Start the MCP server (stdio mode)
notebooklm-mcp
# Or use mcp CLI
mcp run notebooklm-mcp
# Development mode with MCP Inspector
mcp dev src/notebooklm_mcp/server.py
Configure Claude Code
Add to .claude/settings.local.json (project-level) or ~/.claude/settings.json (user-level):
{
"mcpServers": {
"notebooklm": {
"command": "notebooklm-mcp"
}
}
}
With a specific profile:
{
"mcpServers": {
"notebooklm": {
"command": "notebooklm-mcp",
"env": {
"NOTEBOOKLM_PROFILE": "work"
}
}
}
}
Restart Claude Code or reload the window — the 20 notebooklm_* tools will appear in the tool list.
Configure Claude Cowork
Claude Cowork discovers MCP servers from the same .claude/settings.json configuration. Once added, the tools are available in cowork sessions automatically.
You can verify the server is registered:
# List available MCP tools from within a cowork session
# Claude will see: notebooklm_list_notebooks, notebooklm_chat_ask, etc.
Tools Reference
Notebooks (5 tools)
| Tool | Description | Read‑only |
|---|---|---|
notebooklm_list_notebooks |
List all notebooks with pagination and markdown table support | ✅ |
notebooklm_create_notebook |
Create a new notebook with a given title | ❌ |
notebooklm_get_notebook |
Get notebook details including all sources | ✅ |
notebooklm_rename_notebook |
Rename an existing notebook | ❌ |
notebooklm_delete_notebook |
⚠️ Permanently delete a notebook and all contents | ❌ |
Sources (8 tools)
| Tool | Description | Read‑only |
|---|---|---|
notebooklm_list_sources |
List sources with type, status, URL, pagination | ✅ |
notebooklm_add_source_url |
Add a web page or YouTube video as a source | ❌ |
notebooklm_add_source_text |
Add pasted text as a source | ❌ |
notebooklm_add_source_file |
Upload a local file (PDF, Markdown, EPUB, Word, text) | ❌ |
notebooklm_rename_source |
Rename a source | ❌ |
notebooklm_get_source_content |
Get full indexed text extracted by NotebookLM | ✅ |
notebooklm_get_source_guide |
Get AI-generated summary and keywords for a source | ✅ |
notebooklm_delete_source |
⚠️ Permanently remove a source and its content | ❌ |
Chat (4 tools)
| Tool | Description | Read‑only |
|---|---|---|
notebooklm_chat_ask |
Ask a question against notebook sources with citations | ✅ |
notebooklm_get_chat_history |
Get recent Q&A history with pagination | ✅ |
notebooklm_configure_chat |
Set chat persona, goal, and response length | ❌ |
notebooklm_set_chat_mode |
Quick preset: default, learning guide, concise, detailed | ❌ |
Artifacts (4 tools)
| Tool | Description | Read‑only |
|---|---|---|
notebooklm_list_artifacts |
List all AI-generated artifacts (Audio, Reports, etc.) | ✅ |
notebooklm_generate_audio |
Generate an Audio Overview (AI podcast) | ❌ |
notebooklm_generate_report |
Generate a report (Briefing Doc, Study Guide, Blog Post, Custom) | ❌ |
notebooklm_delete_artifact |
⚠️ Permanently delete an artifact | ❌ |
Notes (2 tools)
| Tool | Description | Read‑only |
|---|---|---|
notebooklm_list_notes |
List user-created notes in a notebook | ✅ |
notebooklm_create_note |
Create a new note with title and content | ❌ |
Account (1 tool)
| Tool | Description | Read‑only |
|---|---|---|
notebooklm_get_account |
Get account tier, plan name, and limits | ✅ |
API Coverage
The table below shows every method available in notebooklm-py and whether it's exposed as an MCP tool.
Notebooks (5/11 covered)
| notebooklm-py method | MCP tool | Status |
|---|---|---|
list() |
notebooklm_list_notebooks |
✅ |
create(title) |
notebooklm_create_notebook |
✅ |
get(id) |
notebooklm_get_notebook |
✅ |
rename(id, title) |
notebooklm_rename_notebook |
✅ |
delete(id) |
notebooklm_delete_notebook |
✅ |
get_summary(id) |
— | ❌ |
get_description(id) |
— | ❌ |
get_metadata(id) |
— | ❌ |
get_raw(id) |
— | ❌ |
remove_from_recent(id) |
— | ❌ |
share(...) |
— | ❌ |
Sources (8/14 covered)
| notebooklm-py method | MCP tool | Status |
|---|---|---|
list(nb_id) |
notebooklm_list_sources |
✅ |
add_url(nb_id, url) |
notebooklm_add_source_url |
✅ |
add_text(nb_id, title, text) |
notebooklm_add_source_text |
✅ |
add_file(nb_id, path) |
notebooklm_add_source_file |
✅ |
rename(nb_id, src_id, title) |
notebooklm_rename_source |
✅ |
get_guide(nb_id, src_id) |
notebooklm_get_source_guide |
✅ |
get_fulltext(nb_id, src_id) |
notebooklm_get_source_content |
✅ |
delete(nb_id, src_id) |
notebooklm_delete_source |
✅ |
add_drive(nb_id, file_id, ...) |
— | ❌ |
get(nb_id, src_id) |
— | ❌ |
refresh(nb_id, src_id) |
— | ❌ |
check_freshness(nb_id, src_id) |
— | ❌ |
wait_until_ready(...) |
— (used internally) | ⚪ |
wait_for_sources(...) |
— | ❌ |
Chat (4/8 covered)
| notebooklm-py method | MCP tool | Status |
|---|---|---|
ask(nb_id, question, ...) |
notebooklm_chat_ask |
✅ |
get_history(nb_id, limit) |
notebooklm_get_chat_history |
✅ |
configure(nb_id, goal, ...) |
notebooklm_configure_chat |
✅ |
set_mode(nb_id, mode) |
notebooklm_set_chat_mode |
✅ |
get_conversation_turns(...) |
— | ❌ |
get_conversation_id(nb_id) |
— | ❌ |
get_cached_turns(...) |
— | ❌ |
clear_cache(...) |
— | ❌ |
Artifacts (4/38 covered)
| notebooklm-py method | MCP tool | Status |
|---|---|---|
list(nb_id) |
notebooklm_list_artifacts |
✅ |
generate_audio(nb_id, ...) |
notebooklm_generate_audio |
✅ |
generate_report(nb_id, ...) |
notebooklm_generate_report |
✅ |
delete(nb_id, art_id) |
notebooklm_delete_artifact |
✅ |
generate_video(...), generate_quiz(...), generate_flashcards(...), generate_infographic(...), generate_slide_deck(...), generate_mind_map(...), generate_data_table(...), generate_cinematic_video(...), generate_study_guide(...) |
— | ❌ |
All download_* (audio, video, report, quiz, flashcards, infographic, slide_deck, mind_map, data_table) |
— | ❌ |
All export_* (report, data_table, generic) |
— | ❌ |
poll_status(nb_id, task_id) |
— | ❌ |
wait_for_completion(...) |
— | ❌ |
get(nb_id, art_id), rename(...), revise_slide(...), suggest_reports(nb_id) |
— | ❌ |
Notes (2/7 covered)
| notebooklm-py method | MCP tool | Status |
|---|---|---|
list(nb_id) |
notebooklm_list_notes |
✅ |
create(nb_id, title, text) |
notebooklm_create_note |
✅ |
get(nb_id, note_id) |
— | ❌ |
update(nb_id, note_id, ...) |
— | ❌ |
delete(nb_id, note_id) |
— | ❌ |
list_mind_maps(nb_id) |
— | ❌ |
delete_mind_map(nb_id, mm_id) |
— | ❌ |
Research (0/3 covered)
| notebooklm-py method | MCP tool | Status |
|---|---|---|
start(nb_id, query, ...) |
— | ❌ |
poll(nb_id) |
— | ❌ |
import_sources(nb_id, task_id, ...) |
— | ❌ |
Sharing (0/6 covered)
| notebooklm-py method | MCP tool | Status |
|---|---|---|
get_status(nb_id) |
— | ❌ |
set_public(nb_id, bool) |
— | ❌ |
set_view_level(nb_id, level) |
— | ❌ |
add_user(nb_id, email, ...) |
— | ❌ |
update_user(nb_id, email, ...) |
— | ❌ |
remove_user(nb_id, email) |
— | ❌ |
Settings (1/4 covered)
| notebooklm-py method | MCP tool | Status |
|---|---|---|
get_account_limits() |
notebooklm_get_account |
✅ |
get_account_tier() |
notebooklm_get_account |
✅ |
get_output_language() |
— | ❌ |
set_output_language(code) |
— | ❌ |
Summary: 24 MCP tools covering 24 of ~91 methods. The main gaps are artifact download/export (requires file I/O), additional generate types (video, quiz, flashcards, etc.), research (multi-step workflow), sharing, and note CRUD extensions. See Related for using the
notebooklm-pyCLI directly for unsupported features.
Common Workflows
Research a topic
1. notebooklm_list_notebooks → find or create a notebook
2. notebooklm_add_source_url(nb_id, url) → add web articles
3. notebooklm_get_source_guide(nb_id, src_id) → read AI summaries
4. notebooklm_chat_ask(nb_id, "What are...") → ask questions
Upload and analyze local documents
1. notebooklm_list_notebooks
2. notebooklm_add_source_file(nb_id, "~/papers/paper.pdf") → upload PDF
3. notebooklm_add_source_file(nb_id, "~/docs/notes.md") → upload Markdown
4. notebooklm_list_sources(nb_id) → verify all ready
5. notebooklm_chat_ask(nb_id, "Summarize the papers...") → ask questions
Analyze a document set
1. notebooklm_list_sources(nb_id, limit=50)
2. notebooklm_get_source_content(nb_id, src_id) → read full text
3. notebooklm_chat_ask(nb_id, "Compare...") → cross-source analysis
4. notebooklm_generate_report(nb_id, "briefing_doc") → create executive summary
Generate learning materials
1. notebooklm_list_notebooks
2. notebooklm_generate_report(nb_id, "study_guide") → quiz + glossary
3. notebooklm_generate_audio(nb_id, language="en") → podcast overview
4. notebooklm_list_artifacts(nb_id) → check completion
Response Formats
15 tools accept a response_format parameter:
json(default) — Structured data with all fields. Best for programmatic use.markdown— Human-readable tables, headers, and formatted text. Best for reading in chat.
Example:
notebooklm_list_sources(nb_id, response_format="markdown", limit=10)
Returns:
| Title | Type | Status | ID |
|---|---|---|---|
| Climate Report | pdf | ready | abc123... |
| Research Paper | web_page | processing | def456... |
Showing 2 of 24 sources (offset 0)
Pagination
All list tools support pagination:
| Parameter | Default | Range | Description |
|---|---|---|---|
limit |
50 | 1–100 | Max items per page |
offset |
0 | ≥0 | Items to skip |
Each response includes pagination metadata:
{
"items": [...],
"pagination": {
"total": 150,
"count": 20,
"offset": 0,
"has_more": true,
"next_offset": 20
}
}
Use the pattern: fetch page → check has_more → if true, fetch with offset = next_offset.
Architecture
src/notebooklm_mcp/
├── __init__.py # Package metadata
├── client.py # Singleton NotebookLMClient lifecycle + keepalive
├── models.py # Pydantic v2 models: inputs, outputs, pagination, enums
└── server.py # FastMCP app, lifespan, 20 @mcp.tool definitions
client.py— Lazy singleton that initializesNotebookLMClienton first use, caches it across tool calls, and closes it on server shutdown. Keepalive rotates tokens every 10 minutes.models.py— 15 Pydantic v2 models withField(description=...)for auto-generated JSON Schema. IncludesResponseFormatenum,PaginationMeta, and typed list result wrappers.server.py—FastMCP("notebooklm_mcp")with lifespan context manager. All 20 tools follow the same pattern: get client → call API → format response → handle errors.
Design Decisions
| Decision | Choice | Rationale |
|---|---|---|
| Transport | stdio | Local integration with Claude Code |
| Auth priority | env var → profile → default | Flexibility across local/CI/headless |
| Client lifecycle | Singleton, opened on first use | Prevents auth-at-import, enables keepalive |
| Pagination | Virtual (client-side slice) | Underlying API returns all items; dataset is small (typically <100 items) |
| Error handling | Return error strings, not exceptions | MCP best practice: "report errors within result objects" |
| Tool prefix | notebooklm_ |
Prevents collisions with other MCP servers |
| Response format | JSON default, Markdown optional | JSON for Claude's internal processing, Markdown for user display |
Troubleshooting
"Authentication failed"
# Re-authenticate
notebooklm login --fresh
# Or check auth status
notebooklm auth check --json
The server's error messages include actionable guidance — read them carefully.
"Notebook X not found"
Use notebooklm_list_notebooks to get correct IDs. The library supports partial ID matching (prefix), so a short prefix may resolve to the wrong notebook.
Tools not appearing in Claude Code
- Verify the server starts:
notebooklm-mcp(should hang waiting for stdio input — press Ctrl+C) - Check your
.claude/settings.local.jsonsyntax - Restart Claude Code completely
- Check Claude Code logs for MCP connection errors
Rate limiting
NotebookLM enforces rate limits. If you hit them, wait 30-60 seconds and retry. The error message will tell you when this happens.
Empty source guides / summaries
Newly added sources need time for NotebookLM to process and generate AI guides. Use notebooklm_list_sources to check if the status is ready before calling notebooklm_get_source_guide.
Development
# Install dev dependencies
pip install -e .
# Interactive testing with MCP Inspector
mcp dev src/notebooklm_mcp/server.py
# Run tests (requires auth)
python -c "
import asyncio
from notebooklm_mcp.server import notebooklm_get_account
print(asyncio.run(notebooklm_get_account()))
"
Running Evaluations
The evaluation.xml file contains 10 complex, multi-step questions that test the MCP server end-to-end:
# Requires ANTHROPIC_API_KEY
python scripts/evaluation.py \
-t stdio \
-c python \
-a -m \
-a notebooklm_mcp.server \
evaluation.xml
See .claude/skills/mcp-builder/reference/evaluation.md for the full evaluation workflow.
License
MIT — see LICENSE file.
Related
- notebooklm-py — Python client library for NotebookLM
- MCP Python SDK — Official MCP SDK
- MCP Specification — Protocol documentation
- MCP Builder Skill — Skill used to design this server
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.