notebooklm-mcp-cli 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. notebooklm_mcp_cli-0.2.0/.claude_settings.json +34 -0
  2. notebooklm_mcp_cli-0.2.0/.github/workflows/publish.yml +30 -0
  3. notebooklm_mcp_cli-0.2.0/.gitignore +68 -0
  4. notebooklm_mcp_cli-0.2.0/CHANGELOG.md +145 -0
  5. notebooklm_mcp_cli-0.2.0/CLAUDE.md +222 -0
  6. notebooklm_mcp_cli-0.2.0/FILE_UPLOAD_IMPLEMENTATION.md +93 -0
  7. notebooklm_mcp_cli-0.2.0/GEMINI.md +130 -0
  8. notebooklm_mcp_cli-0.2.0/LICENSE +21 -0
  9. notebooklm_mcp_cli-0.2.0/PKG-INFO +558 -0
  10. notebooklm_mcp_cli-0.2.0/README.md +530 -0
  11. notebooklm_mcp_cli-0.2.0/docs/API_REFERENCE.md +1391 -0
  12. notebooklm_mcp_cli-0.2.0/docs/AUTHENTICATION.md +211 -0
  13. notebooklm_mcp_cli-0.2.0/docs/CLI_GUIDE.md +212 -0
  14. notebooklm_mcp_cli-0.2.0/docs/KNOWN_ISSUES.md +144 -0
  15. notebooklm_mcp_cli-0.2.0/docs/MCP_GUIDE.md +231 -0
  16. notebooklm_mcp_cli-0.2.0/docs/MCP_TEST_PLAN.md +841 -0
  17. notebooklm_mcp_cli-0.2.0/docs/MULTI_USER_ANALYSIS.md +701 -0
  18. notebooklm_mcp_cli-0.2.0/docs/QUICK_REFERENCE.md +94 -0
  19. notebooklm_mcp_cli-0.2.0/docs/media/header.jpeg +0 -0
  20. notebooklm_mcp_cli-0.2.0/docs/plans/2026-01-27-client-refactoring.md +1222 -0
  21. notebooklm_mcp_cli-0.2.0/docs/plans/2026-01-27-flashcards-quiz-downloads.md +962 -0
  22. notebooklm_mcp_cli-0.2.0/docs/plans/2026-01-27-sharing-api.md +104 -0
  23. notebooklm_mcp_cli-0.2.0/docs/plans/2026-01-28-notes-api.md +609 -0
  24. notebooklm_mcp_cli-0.2.0/pyproject.toml +80 -0
  25. notebooklm_mcp_cli-0.2.0/scripts/inject_cookies_and_inspect.py +168 -0
  26. notebooklm_mcp_cli-0.2.0/scripts/inspect_upload_dom.py +112 -0
  27. notebooklm_mcp_cli-0.2.0/src/notebooklm_mcp/__init__.py +10 -0
  28. notebooklm_mcp_cli-0.2.0/src/notebooklm_mcp/api_client.py +3000 -0
  29. notebooklm_mcp_cli-0.2.0/src/notebooklm_mcp/auth.py +212 -0
  30. notebooklm_mcp_cli-0.2.0/src/notebooklm_mcp/auth_cli.py +838 -0
  31. notebooklm_mcp_cli-0.2.0/src/notebooklm_mcp/constants.py +310 -0
  32. notebooklm_mcp_cli-0.2.0/src/notebooklm_mcp/server.py +2067 -0
  33. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/__init__.py +7 -0
  34. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/__init__.py +1 -0
  35. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/ai_docs.py +788 -0
  36. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/__init__.py +1 -0
  37. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/alias.py +104 -0
  38. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/auth.py +114 -0
  39. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/chat.py +122 -0
  40. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/config.py +129 -0
  41. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/download.py +299 -0
  42. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/export.py +168 -0
  43. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/note.py +171 -0
  44. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/notebook.py +235 -0
  45. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/repl.py +204 -0
  46. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/research.py +344 -0
  47. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/share.py +161 -0
  48. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/source.py +335 -0
  49. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/studio.py +576 -0
  50. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/commands/verbs.py +675 -0
  51. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/formatters.py +422 -0
  52. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/main.py +296 -0
  53. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/cli/utils.py +60 -0
  54. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/__init__.py +6 -0
  55. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/alias.py +141 -0
  56. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/auth.py +460 -0
  57. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/auth_cli.py +844 -0
  58. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/base.py +697 -0
  59. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/client.py +255 -0
  60. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/constants.py +342 -0
  61. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/conversation.py +353 -0
  62. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/data_types.py +70 -0
  63. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/download.py +1217 -0
  64. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/errors.py +96 -0
  65. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/exceptions.py +145 -0
  66. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/exports.py +151 -0
  67. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/models.py +125 -0
  68. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/notebooks.py +263 -0
  69. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/notes.py +220 -0
  70. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/research.py +351 -0
  71. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/sharing.py +152 -0
  72. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/sources.py +733 -0
  73. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/studio.py +963 -0
  74. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/core/utils.py +131 -0
  75. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/__init__.py +1 -0
  76. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/server.py +193 -0
  77. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/__init__.py +83 -0
  78. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/_utils.py +149 -0
  79. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/auth.py +141 -0
  80. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/chat.py +104 -0
  81. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/downloads.py +128 -0
  82. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/exports.py +58 -0
  83. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/notebooks.py +196 -0
  84. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/notes.py +123 -0
  85. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/research.py +182 -0
  86. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/sharing.py +106 -0
  87. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/sources.py +296 -0
  88. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/mcp/tools/studio.py +416 -0
  89. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/utils/__init__.py +1 -0
  90. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/utils/browser.py +102 -0
  91. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/utils/cdp.py +490 -0
  92. notebooklm_mcp_cli-0.2.0/src/notebooklm_tools/utils/config.py +316 -0
  93. notebooklm_mcp_cli-0.2.0/tests/core/test_base.py +154 -0
  94. notebooklm_mcp_cli-0.2.0/tests/core/test_conversation.py +100 -0
  95. notebooklm_mcp_cli-0.2.0/tests/core/test_data_types.py +22 -0
  96. notebooklm_mcp_cli-0.2.0/tests/core/test_download.py +118 -0
  97. notebooklm_mcp_cli-0.2.0/tests/core/test_errors.py +66 -0
  98. notebooklm_mcp_cli-0.2.0/tests/core/test_notebooks.py +100 -0
  99. notebooklm_mcp_cli-0.2.0/tests/core/test_notes.py +153 -0
  100. notebooklm_mcp_cli-0.2.0/tests/core/test_research.py +80 -0
  101. notebooklm_mcp_cli-0.2.0/tests/core/test_sharing.py +81 -0
  102. notebooklm_mcp_cli-0.2.0/tests/core/test_sources.py +101 -0
  103. notebooklm_mcp_cli-0.2.0/tests/core/test_studio.py +75 -0
  104. notebooklm_mcp_cli-0.2.0/tests/core/test_utils.py +19 -0
  105. notebooklm_mcp_cli-0.2.0/tests/test_api_client.py +232 -0
  106. notebooklm_mcp_cli-0.2.0/tests/test_download_integration.py +186 -0
  107. notebooklm_mcp_cli-0.2.0/tests/test_e2e.py +222 -0
  108. notebooklm_mcp_cli-0.2.0/tests/test_file_upload.py +327 -0
  109. notebooklm_mcp_cli-0.2.0/tests/test_mcp_e2e.py +312 -0
  110. notebooklm_mcp_cli-0.2.0/tests/test_mcp_file_upload.py +67 -0
  111. notebooklm_mcp_cli-0.2.0/tests/test_research_polling.py +69 -0
  112. notebooklm_mcp_cli-0.2.0/uv.lock +1660 -0
@@ -0,0 +1,34 @@
1
+ {
2
+ "sandbox": {
3
+ "enabled": true,
4
+ "autoAllowBashIfSandboxed": true
5
+ },
6
+ "permissions": {
7
+ "defaultMode": "acceptEdits",
8
+ "allow": [
9
+ "Read(./**)",
10
+ "Write(./**)",
11
+ "Edit(./**)",
12
+ "Glob(./**)",
13
+ "Grep(./**)",
14
+ "Read(/Users/jbd/dev_projects/notebooklm-mcp/**)",
15
+ "Write(/Users/jbd/dev_projects/notebooklm-mcp/**)",
16
+ "Edit(/Users/jbd/dev_projects/notebooklm-mcp/**)",
17
+ "Glob(/Users/jbd/dev_projects/notebooklm-mcp/**)",
18
+ "Grep(/Users/jbd/dev_projects/notebooklm-mcp/**)",
19
+ "Read(/Users/jbd/dev_projects/notebooklm-mcp/.auto-claude/ideation/**)",
20
+ "Write(/Users/jbd/dev_projects/notebooklm-mcp/.auto-claude/ideation/**)",
21
+ "Edit(/Users/jbd/dev_projects/notebooklm-mcp/.auto-claude/ideation/**)",
22
+ "Bash(*)",
23
+ "WebFetch(*)",
24
+ "WebSearch(*)",
25
+ "mcp__context7__resolve-library-id(*)",
26
+ "mcp__context7__get-library-docs(*)",
27
+ "mcp__graphiti-memory__search_nodes(*)",
28
+ "mcp__graphiti-memory__search_facts(*)",
29
+ "mcp__graphiti-memory__add_episode(*)",
30
+ "mcp__graphiti-memory__get_episodes(*)",
31
+ "mcp__graphiti-memory__get_entity_edge(*)"
32
+ ]
33
+ }
34
+ }
@@ -0,0 +1,30 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ name: Build and publish to PyPI
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ id-token: write # Required for trusted publishing (OIDC)
13
+
14
+ steps:
15
+ - name: Checkout repository
16
+ uses: actions/checkout@v4
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v4
20
+ with:
21
+ version: "latest"
22
+
23
+ - name: Set up Python
24
+ run: uv python install 3.11
25
+
26
+ - name: Build package
27
+ run: uv build
28
+
29
+ - name: Publish to PyPI
30
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,68 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ .venv/
25
+ venv/
26
+ ENV/
27
+
28
+ # IDE
29
+ .idea/
30
+ .vscode/
31
+ *.swp
32
+ *.swo
33
+
34
+ # Testing
35
+ .pytest_cache/
36
+ .coverage
37
+ htmlcov/
38
+
39
+ # Misc
40
+ .DS_Store
41
+ *.log
42
+
43
+ # Credentials
44
+ cookies.txt
45
+
46
+ # uv
47
+ .uv/
48
+
49
+ # Internal planning docs (do not push)
50
+ Studio_tools_plan.md
51
+
52
+ # Local project memory (personal, not shared)
53
+ CLAUDE.local.md
54
+ PROJECT_RECAP.md
55
+ todo.md
56
+ .notebooklm*/
57
+
58
+
59
+ # Data and Artifacts
60
+ download/
61
+ downloads/
62
+
63
+ # Auto Claude data directory
64
+ .auto-claude/
65
+ .worktrees/
66
+ .claude/
67
+ run*.notebooklm-py-analysis/
68
+ *.code-workspace
@@ -0,0 +1,145 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.14] - 2026-01-17
9
+
10
+ ### Fixed
11
+ - **Critical Research Stability**:
12
+ - `poll_research` now accepts status code `6` (Imported) as success, fixing "hanging" Fast Research.
13
+ - Added `target_task_id` filtering to `poll_research` to ensure the correct research task is returned (essential for Deep Research).
14
+ - Updated `research_status` and `research_import` to use task ID filtering.
15
+ - `research_status` tool now accepts an optional `task_id` parameter.
16
+ - **Missing Source Constants**:
17
+ - Included the code changes for `SOURCE_TYPE_UPLOADED_FILE`, `SOURCE_TYPE_IMAGE`, and `SOURCE_TYPE_WORD_DOC` that were omitted in v0.1.13.
18
+
19
+ ## [0.1.13] - 2026-01-17
20
+
21
+ ### Added
22
+ - **Source type constants** for proper identification of additional source types:
23
+ - `SOURCE_TYPE_UPLOADED_FILE` (11): Direct file uploads (e.g., .docx uploaded directly)
24
+ - `SOURCE_TYPE_IMAGE` (13): Image files (GIF, JPEG, PNG)
25
+ - `SOURCE_TYPE_WORD_DOC` (14): Word documents via Google Drive
26
+ - Updated `SOURCE_TYPES` CodeMapper with `uploaded_file`, `image`, and `word_doc` mappings
27
+
28
+ ## [0.1.12] - 2026-01-16
29
+
30
+ ### Fixed
31
+ - **Standardized source timeouts** (supersedes #9)
32
+ - Renamed `DRIVE_SOURCE_TIMEOUT` to `SOURCE_ADD_TIMEOUT` (120s)
33
+ - Applied to all source additions: Drive, URL (websites/YouTube), and Text
34
+ - Added graceful timeout handling to `add_url_source` and `add_text_source`
35
+ - Prevents timeout errors when importing large websites or documents
36
+
37
+ ## [0.1.11] - 2026-01-16
38
+
39
+ ### Fixed
40
+ - **Close Chrome after interactive authentication** - Chrome is now properly terminated after `notebooklm-mcp-auth` completes, releasing the profile lock and enabling headless auth for automatic token refresh
41
+ - **Improve token reload from disk** - Removed the 5-minute timeout when reloading tokens during auth recovery. Previously, cached tokens older than 5 minutes were ignored even if the user had just run `notebooklm-mcp-auth`
42
+
43
+ These fixes resolve "Authentication expired" errors that occurred even after users re-authenticated.
44
+
45
+ ## [0.1.10] - 2026-01-15
46
+
47
+ ### Fixed
48
+ - **Timeout when adding large Drive sources** (fixes #9)
49
+ - Extended timeout from 30s to 120s for Drive source operations
50
+ - Large Google Slides (100+ slides) now add successfully
51
+ - Returns `status: "timeout"` instead of error when timeout occurs, indicating operation may have succeeded
52
+ - Added `DRIVE_SOURCE_TIMEOUT` constant in `api_client.py`
53
+
54
+ ## [0.1.9] - 2026-01-11
55
+
56
+
57
+ ### Added
58
+ - **Automatic re-authentication** - Server now survives token expirations without restart
59
+ - Three-layer recovery: CSRF refresh → disk reload → headless Chrome auth
60
+ - Works with long-running MCP sessions (e.g., MCP Super Assistant proxy)
61
+ - `refresh_auth` MCP tool for explicit token reload
62
+ - `run_headless_auth()` function for background authentication (if Chrome profile has saved login)
63
+ - `has_chrome_profile()` helper to check if profile exists
64
+
65
+ ### Changed
66
+ - `launch_chrome()` now returns `subprocess.Popen` handle instead of `bool` for cleanup control
67
+ - `_call_rpc()` enhanced with `_deep_retry` parameter for multi-layer auth recovery
68
+
69
+ ## [0.1.8] - 2026-01-10
70
+
71
+ ### Added
72
+ - `constants.py` module as single source of truth for all API code-name mappings
73
+ - `CodeMapper` class with bidirectional lookup (name→code, code→name)
74
+ - Dynamic error messages now show valid options from `CodeMapper`
75
+
76
+ ### Changed
77
+ - **BREAKING:** `quiz_create` now accepts `difficulty: str` ("easy"|"medium"|"hard") instead of `int` (1|2|3)
78
+ - All MCP tools now use `constants.CodeMapper` for input validation
79
+ - All API client output now uses `constants.CodeMapper` for human-readable names
80
+ - Removed ~10 static `_get_*_name` helper methods from `api_client.py`
81
+ - Removed duplicate `*_codes` dictionaries from `server.py` tool functions
82
+
83
+ ### Fixed
84
+ - Removed duplicate code block in research status parsing
85
+
86
+ ## [0.1.7] - 2026-01-10
87
+
88
+ ### Fixed
89
+ - Fixed URL source retrieval by implementing correct metadata parsing in `get_notebook_sources_with_types`
90
+ - Added fallback for finding source type name in `get_notebook_sources_with_types`
91
+
92
+ ## [0.1.6] - 2026-01-10
93
+
94
+ ### Added
95
+ - `studio_status` now includes mind maps alongside audio/video/slides
96
+ - `delete_mind_map()` method with two-step RPC deletion
97
+ - `RPC_DELETE_MIND_MAP` constant for mind map deletion
98
+ - Unit tests for authentication retry logic
99
+
100
+ ### Fixed
101
+ - Mind map deletion now works via `studio_delete` (fixes #7)
102
+ - `notebook_query` now accepts `source_ids` as JSON string for compatibility with some AI clients (fixes #5)
103
+ - Deleted/tombstone mind maps are now filtered from `list_mind_maps` responses
104
+ - Token expiration handling with auto-retry on RPC Error 16 and HTTP 401/403
105
+
106
+ ### Changed
107
+ - Updated `bl` version to `boq_labs-tailwind-frontend_20260108.06_p0`
108
+ - `delete_studio_artifact` now accepts optional `notebook_id` for mind map fallback
109
+
110
+ ## [0.1.5] - 2026-01-09
111
+
112
+ ### Fixed
113
+ - Improved LLM guidance for authentication errors
114
+
115
+ ## [0.1.4] - 2026-01-09
116
+
117
+ ### Added
118
+ - `source_get_content` tool for raw text extraction from sources
119
+
120
+ ## [0.1.3] - 2026-01-08
121
+
122
+ ### Fixed
123
+ - Chrome detection on Linux distros
124
+
125
+ ## [0.1.2] - 2026-01-07
126
+
127
+ ### Fixed
128
+ - YouTube URL handling - use correct array position
129
+
130
+ ## [0.1.1] - 2026-01-06
131
+
132
+ ### Changed
133
+ - Improved research tool descriptions for better AI selection
134
+
135
+ ## [0.1.0] - 2026-01-05
136
+
137
+ ### Added
138
+ - Initial release
139
+ - Full NotebookLM API client with 31 MCP tools
140
+ - Authentication via Chrome DevTools or manual cookie extraction
141
+ - Notebook, source, query, and studio management
142
+ - Research (web/Drive) with source import
143
+ - Audio/Video overview generation
144
+ - Report, flashcard, quiz, infographic, slide deck creation
145
+ - Mind map generation
@@ -0,0 +1,222 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ **NotebookLM MCP Server & CLI** - Provides programmatic access to NotebookLM (notebooklm.google.com) via both a Model Context Protocol server and a comprehensive command-line interface.
8
+
9
+ Tested with personal/free tier accounts. May work with Google Workspace accounts but has not been tested.
10
+
11
+ ## Development Commands
12
+
13
+ ```bash
14
+ # Install dependencies
15
+ uv tool install .
16
+
17
+ # Reinstall after code changes (ALWAYS clean cache first)
18
+ uv cache clean && uv tool install --force .
19
+
20
+ # Run the MCP server (stdio)
21
+ notebooklm-mcp
22
+
23
+ # Run with Debug logging
24
+ notebooklm-mcp --debug
25
+
26
+ # Run as HTTP server
27
+ notebooklm-mcp --transport http --port 8000
28
+
29
+ # Run tests
30
+ uv run pytest
31
+
32
+ # Run a single test
33
+ uv run pytest tests/test_file.py::test_function -v
34
+ ```
35
+
36
+ **Python requirement:** >=3.11
37
+
38
+ ## Authentication (SIMPLIFIED!)
39
+
40
+ **You only need to provide COOKIES!** The CSRF token and session ID are now **automatically extracted** when needed.
41
+
42
+ ### Method 1: Chrome DevTools MCP (Recommended)
43
+
44
+ **Option A - Fast (Recommended):**
45
+ Extract CSRF token and session ID directly from network request - **no page fetch needed!**
46
+
47
+ ```python
48
+ # 1. Navigate to NotebookLM page
49
+ navigate_page(url="https://notebooklm.google.com/")
50
+
51
+ # 2. Get a batchexecute request (any NotebookLM API call)
52
+ get_network_request(reqid=<any_batchexecute_request>)
53
+
54
+ # 3. Save with all three fields from the network request:
55
+ save_auth_tokens(
56
+ cookies=<cookie_header>,
57
+ request_body=<request_body>, # Contains CSRF token
58
+ request_url=<request_url> # Contains session ID
59
+ )
60
+ ```
61
+
62
+ **Option B - Minimal (slower first call):**
63
+ Save only cookies, tokens extracted from page on first API call
64
+
65
+ ```python
66
+ save_auth_tokens(cookies=<cookie_header>)
67
+ ```
68
+
69
+ ### Method 2: Environment Variables
70
+
71
+ | Variable | Required | Description |
72
+ |----------|----------|-------------|
73
+ | `NOTEBOOKLM_COOKIES` | Yes | Full cookie header from Chrome DevTools |
74
+ | `NOTEBOOKLM_CSRF_TOKEN` | No | (DEPRECATED - auto-extracted) |
75
+ | `NOTEBOOKLM_SESSION_ID` | No | (DEPRECATED - auto-extracted) |
76
+
77
+ ### Token Expiration
78
+
79
+ - **Cookies**: Stable for weeks, but some rotate on each request
80
+ - **CSRF token**: Auto-refreshed on each client initialization
81
+ - **Session ID**: Auto-refreshed on each client initialization
82
+
83
+ When API calls fail with auth errors, re-extract fresh cookies from Chrome DevTools.
84
+
85
+ ## Architecture
86
+
87
+ ```
88
+ src/notebooklm_tools/
89
+ ├── __init__.py # Package version
90
+ ├── cli/ # CLI commands and formatting
91
+ ├── mcp/server.py # FastMCP server with tool definitions
92
+ ├── core/client.py # Internal API client
93
+ ├── core/constants.py # Code-name mappings (CodeMapper class)
94
+ ├── core/auth.py # Token caching and validation
95
+ ├── core/auth_cli.py # CLI for Chrome-based auth (notebooklm-mcp-auth)
96
+ └── utils/ # Configuration and browser utilities
97
+ ```
98
+
99
+ **Executables:**
100
+ - `notebooklm-mcp` - The MCP server
101
+ - `notebooklm-mcp-auth` - CLI for extracting tokens (requires closing Chrome)
102
+
103
+ ## MCP Tools Provided
104
+
105
+ | Tool | Purpose |
106
+ |------|---------|
107
+ | `notebook_list` | List all notebooks |
108
+ | `notebook_create` | Create new notebook |
109
+ | `notebook_get` | Get notebook details |
110
+ | `notebook_describe` | Get AI-generated summary of notebook content with keywords |
111
+ | `source_describe` | Get AI-generated summary and keyword chips for a source |
112
+ | `source_get_content` | Get raw text content from a source (no AI processing) |
113
+ | `notebook_rename` | Rename a notebook |
114
+ | `chat_configure` | Configure chat goal/style and response length |
115
+ | `notebook_delete` | Delete a notebook (REQUIRES confirmation) |
116
+ | `source_add` | Add source (url, text, drive, file) |
117
+ | `notebook_query` | Ask questions (AI answers!) |
118
+ | `source_list_drive` | List sources with types, check Drive freshness |
119
+ | `source_sync_drive` | Sync stale Drive sources (REQUIRES confirmation) |
120
+ | `source_delete` | Delete a source from notebook (REQUIRES confirmation) |
121
+ | `research_start` | Start Web or Drive research to discover sources |
122
+ | `research_status` | Check research progress and get results |
123
+ | `research_import` | Import discovered sources into notebook |
124
+ | `studio_create` | Generate unified content (audio, video, infographic, slides, etc.) |
125
+ | `download_artifact` | Download any artifact (audio, video, pdf, markdown, json) |
126
+ | `export_artifact` | Export Data Tables to Google Sheets or Reports to Google Docs |
127
+ | `studio_status` | Check studio artifact generation status |
128
+ | `studio_delete` | Delete studio artifacts (REQUIRES confirmation) |
129
+ | `notebook_share_status` | Get sharing settings and collaborators |
130
+ | `notebook_share_public` | Enable/disable public link access |
131
+ | `notebook_share_invite` | Invite collaborator by email |
132
+ | `save_auth_tokens` | Save tokens extracted via Chrome DevTools MCP |
133
+ | `refresh_auth` | Reload auth tokens or run headless auth |
134
+ | `note_create` | Create a note in a notebook |
135
+ | `note_list` | List all notes in a notebook |
136
+ | `note_update` | Update a note's content or title |
137
+ | `note_delete` | Delete a note (REQUIRES confirmation) |
138
+
139
+ **IMPORTANT - Operations Requiring Confirmation:**
140
+ - `notebook_delete` requires `confirm=True` - deletion is IRREVERSIBLE
141
+ - `source_delete` requires `confirm=True` - deletion is IRREVERSIBLE
142
+ - `source_sync_drive` requires `confirm=True` - always show stale sources first via `source_list_drive`
143
+ - All studio creation tools require `confirm=True` - show settings and get user approval first
144
+ - `studio_delete` requires `confirm=True` - list artifacts first via `studio_status`, deletion is IRREVERSIBLE
145
+ - `note_delete` requires `confirm=True` - deletion is IRREVERSIBLE
146
+
147
+ ## Features NOT Yet Implemented
148
+
149
+ None - all NotebookLM features that can be accessed programmatically are implemented.
150
+
151
+ ## Troubleshooting
152
+
153
+ ### "401 Unauthorized" or "403 Forbidden"
154
+ - Cookies or CSRF token expired
155
+ - Re-extract from Chrome DevTools
156
+
157
+ ### "Invalid CSRF token"
158
+ - The `at=` value expired
159
+ - Must match the current session
160
+
161
+ ### Empty notebook list
162
+ - Session might be for a different Google account
163
+ - Verify you're logged into the correct account
164
+
165
+ ### Rate limit errors
166
+ - Free tier: ~50 queries/day
167
+ - Wait until the next day or upgrade to Plus
168
+
169
+ ## Documentation
170
+
171
+ ### API Reference
172
+
173
+ **For detailed API documentation** (RPC IDs, parameter structures, response formats), see:
174
+
175
+ **[docs/API_REFERENCE.md](./docs/API_REFERENCE.md)**
176
+
177
+ This includes:
178
+ - All discovered RPC endpoints and their parameters
179
+ - Source type structures (URL, text, Drive)
180
+ - Studio content creation (audio, video, reports, etc.)
181
+ - Research workflow details
182
+ - Mind map generation process
183
+ - Source metadata structures
184
+
185
+ Only read API_REFERENCE.md when:
186
+ - Debugging API issues
187
+ - Adding new features
188
+ - Understanding internal API behavior
189
+
190
+ ### MCP Test Plan
191
+
192
+ **For comprehensive MCP tool testing**, see:
193
+
194
+ **[docs/MCP_TEST_PLAN.md](./docs/MCP_TEST_PLAN.md)**
195
+
196
+ This includes:
197
+ - Step-by-step test cases for all 31 MCP tools
198
+ - Authentication and basic operations tests
199
+ - Source management and Drive sync tests
200
+ - Studio content generation tests (audio, video, infographics, etc.)
201
+ - Quick copy-paste test prompts for validation
202
+
203
+ Use this test plan when:
204
+ - Validating MCP server functionality after code changes
205
+ - Testing new tool implementations
206
+ - Debugging MCP tool issues
207
+
208
+ ## Contributing
209
+
210
+ When adding new features:
211
+
212
+ 1. Use Chrome DevTools MCP to capture the network request
213
+ 2. Document the RPC ID in docs/API_REFERENCE.md
214
+ 3. Add the param structure with comments
215
+ 4. Update the api_client.py with the new method
216
+ 5. Add corresponding tool in server.py
217
+ 6. Update the "Features NOT Yet Implemented" checklist
218
+ 7. Add test case to docs/MCP_TEST_PLAN.md
219
+
220
+ ## License
221
+
222
+ MIT License
@@ -0,0 +1,93 @@
1
+ # File Upload Implementation
2
+
3
+ ## Overview
4
+
5
+ File upload uses **HTTP Resumable Upload** – the reliable, headless method.
6
+
7
+ ## HTTP Resumable Upload
8
+
9
+ ### Implementation
10
+
11
+ Uses Google's 3-step resumable upload protocol:
12
+
13
+ 1. **Register source intent** (RPC: `o4cbdc`) → get SOURCE_ID
14
+ 2. **Start upload session** (POST to `/upload/_/`) → get upload URL
15
+ 3. **Stream file content** → upload URL (memory-efficient streaming)
16
+
17
+ ### Code Structure
18
+
19
+ - `SourceMixin._register_file_source()` - Step 1: Register and get SOURCE_ID
20
+ - `SourceMixin._start_resumable_upload()` - Step 2: Get upload URL
21
+ - `SourceMixin._upload_file_streaming()` - Step 3: Stream file content
22
+ - `SourceMixin.add_file()` - Public API that orchestrates all 3 steps
23
+
24
+ ### Usage
25
+
26
+ **Python:**
27
+ ```python
28
+ from notebooklm_tools.core.client import NotebookLMClient
29
+
30
+ with NotebookLMClient() as client:
31
+ result = client.add_file(notebook_id="...", file_path="document.pdf")
32
+ # Returns: {"id": "source-id", "title": "document.pdf"}
33
+ ```
34
+
35
+ **CLI:**
36
+ ```bash
37
+ nlm source add <notebook-id> --file document.pdf
38
+ ```
39
+
40
+ **MCP:**
41
+ ```python
42
+ source_add(notebook_id="...", source_type="file", file_path="/path/to/file.pdf")
43
+ ```
44
+
45
+ ### Supported File Types
46
+
47
+ - PDF (`.pdf`)
48
+ - Text (`.txt`, `.md`)
49
+ - Documents (`.docx`, `.csv`)
50
+ - Audio (`.mp3`)
51
+ - Video (`.mp4`)
52
+ - Images (`.jpg`, `.jpeg`, `.png`)
53
+
54
+ ### Advantages
55
+
56
+ - ✅ No Chrome dependency
57
+ - ✅ Works in headless/server environments
58
+ - ✅ Memory-efficient streaming for large files
59
+ - ✅ Faster and more reliable
60
+ - ✅ No browser fingerprinting issues
61
+
62
+ ## Testing
63
+
64
+ ```bash
65
+ # Create a test file
66
+ echo "Test content" > test.txt
67
+
68
+ # Upload the file
69
+ nlm source add <notebook-id> --file test.txt
70
+
71
+ # Verify it was added
72
+ nlm source list <notebook-id>
73
+ ```
74
+
75
+ ## Troubleshooting
76
+
77
+ ### "File not found"
78
+ - **Cause**: The file path doesn't exist or is inaccessible
79
+ - **Fix**: Check the file path spelling and permissions
80
+
81
+ ### "Unsupported file type"
82
+ - **Cause**: File extension is not in the supported list
83
+ - **Fix**: Convert the file to a supported format
84
+
85
+ ### Upload times out
86
+ - **Cause**: Large file or slow connection
87
+ - **Fix**: The upload may still complete on the backend; check notebook sources before retrying
88
+
89
+ ---
90
+
91
+ ## Historical Note
92
+
93
+ A browser-based upload fallback using Chrome automation was previously available (`--browser` flag) but has been removed. NotebookLM's UI now uses the File System Access API which cannot be automated via CDP. The HTTP method is more reliable anyway.