NotebookLM包装器
通过MCP(模型上下文协议)为Google NotebookLM提供Python包装。连接到 notebooklm-mcp 服务器,并为所有NotebookLM功能提供干净、类型化的界面。
特性
- 清洁Python API -无子进程或CLI调用
- 全型安全 -所有数据的Pydantic模型
- 同步+异步 -使用任一编程风格
- 28次操作 -笔记本、资源、聊天、研究、工作室、分享等
- 服务器处理的身份验证 -快跑
nlm login一次,然后使用包装器
需求
- Python 3.11+
- notebooklmcp-cli (自动安装)
安装
来自PyPI (一经发布):
pip install notebooklm-wrapper来源 (开发或未发布):
pip install git+https://github.com/ai-chitect/notebooklm-wrapper.git
# or, from a local clone:
pip install -e .发布到PyPI:运行 ./scripts/publish.sh (运行测试、构建,然后发布)。使用 ./scripts/publish.sh --test 用于TestPyPI。需要 孵化 以及PyPI证书。
先决条件:使用NotebookLM进行身份验证(一次性设置):
pip install notebooklm-mcp-cli
nlm login # Opens browser for authentication快速开始
from notebooklm_wrapper import NotebookLMClient
# Initialize client (uses default profile from nlm login)
client = NotebookLMClient()
# List notebooks
notebooks = client.notebook.list()
for nb in notebooks:
print(f"{nb.title} ({nb.id})")
# Create notebook
notebook = client.notebook.create(title="My Research")
# Add sources
client.source.add(
notebook.id,
"url",
url="https://example.com/article",
)
# Ask questions
response = client.chat.ask(notebook.id, "What are the main points?")
print(response.answer)
for citation in response.citations:
print(f" - {citation.source_title}")异步用法
import asyncio
from notebooklm_wrapper import AsyncNotebookLMClient
async def main():
client = AsyncNotebookLMClient()
notebooks = await client.notebook.list()
print(f"Found {len(notebooks)} notebooks")
# Create and query
notebook = await client.notebook.create(title="Async Research")
response = await client.chat.ask(notebook.id, "Summarize the key findings")
print(response.answer)
asyncio.run(main())多配置文件
# Use specific profile (set via NOTEBOOKLM_MCP_PROFILE when spawning server)
client = NotebookLMClient(profile="work")
notebooks = client.notebook.list()
# Async with profile
async_client = AsyncNotebookLMClient(profile="personal")多用户/Web应用程序
对于多租户应用程序(例如在Google Cloud上),其中每个用户都有自己的NotebookLM凭据存储在您的数据库中(加密)并通过OAuth获得,请使用 config_dir 隔离每个用户的凭据。包装器为每个客户端生成一个MCP服务器进程;具有独特 config_dir 对于每个用户,该过程在以下位置使用专用凭据存储 config_dir/.notebooklm-mcp-cli.
- 存储凭据: 在OAuth(或用户提供的cookie)之后,加密cookie字符串并将其存储在由用户id键入的数据库中。
- 每个请求/会话: 创建一个用户特定的目录(或为每个用户使用持久路径),解密数据库中的凭据,然后创建一个客户端并注入令牌:
import os
from notebooklm_wrapper import AsyncNotebookLMClient
async def notebooklm_client_for_user(user_id: str, decrypted_cookies: str):
# Use a dedicated dir per user so the MCP server stores credentials there
config_dir = f"/app/data/users/{user_id}"
os.makedirs(config_dir, exist_ok=True)
client = AsyncNotebookLMClient(
profile=user_id,
config_dir=config_dir,
)
# Inject credentials so the server can use them (first time or refresh)
await client.auth.save_tokens(cookies=decrypted_cookies)
return client
# Then use the client as usual
async def handle_request(user_id: str, ...):
cookies = get_encrypted_cookies_from_db(user_id)
decrypted = decrypt(cookies)
client = await notebooklm_client_for_user(user_id, decrypted)
try:
notebooks = await client.notebook.list()
# ...
finally:
await client.disconnect()看 docs/多用户证书设计.md 了解凭证隔离的工作原理和设计细节。
api参考
| 资源 | 方法 |
|---|---|
client.notebook | list(), get(id), describe(id), create(title), rename(id, title), delete(id, confirm=True) |
client.source | add(notebook_id, type, url=...), list_drive(notebook_id), sync_drive(ids, confirm=True), delete(id, confirm=True), describe(id), get_content(id) |
client.chat | ask(notebook_id, query), configure(notebook_id, goal=..., response_length=...) |
client.research | start(query, source="web", mode="fast"), status(notebook_id), import_sources(notebook_id, task_id) |
client.studio | create(notebook_id, type, confirm=True), status(notebook_id), delete(notebook_id, artifact_id, confirm=True) |
client.share | status(notebook_id), set_public(notebook_id, is_public), invite(notebook_id, email, role="viewer") |
client.download | artifact(notebook_id, type, output_path) |
client.note | create(notebook_id, content, title=...), list(notebook_id), update(notebook_id, note_id, ...), delete(notebook_id, note_id, confirm=True) |
client.auth | refresh(), save_tokens(cookies, ...) |
client.export | to_docs(notebook_id, artifact_id), to_sheets(notebook_id, artifact_id) |
错误处理
所有操作提高 NotebookLMError 故障子类:
from notebooklm_wrapper import (
NotebookLMClient,
AuthenticationError,
NotFoundError,
ValidationError,
RateLimitError,
GenerationError,
)
client = NotebookLMClient()
try:
notebooks = client.notebook.list()
except AuthenticationError:
print("Run 'nlm login' to authenticate")
except NotFoundError as e:
print(f"Not found: {e}")
except RateLimitError as e:
print(f"Rate limited. Retry after: {e.retry_after}s")错误消息包括工具名称,以便更容易调试(例如。 [notebook_list] Please login first).
发展
# Clone the repository
git clone https://github.com/ai-chitect/notebooklm-wrapper.git
cd notebooklm-wrapper
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
# Install in editable mode with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run tests with coverage
pytest --cov=notebooklm_wrapper --cov-report=term-missing
# Lint
ruff check src/ tests/
# Format
black src/ tests/
isort src/ tests/
# Type check
mypy src/
# Publish to PyPI (after tests pass)
./scripts/publish.sh
# Test OAuth + list notebooks (integration-style; opens browser for login)
python scripts/test_oauth_list_notebooks.py
# Reuse credentials in a directory (skip login next time):
python scripts/test_oauth_list_notebooks.py --config-dir ./tmp_oauth_test
python scripts/test_oauth_list_notebooks.py --config-dir ./tmp_oauth_test --skip-login
# Test paste-cookie flow (use a file for long cookie strings):
echo "SID=...; __Secure-1PSID=...; ..." > cookies.txt # paste from browser
python scripts/test_cookie_list_notebooks.py --cookie-file cookies.txt
# Or prompt for short cookie, or stdin:
python scripts/test_cookie_list_notebooks.py
cat cookies.txt | python scripts/test_cookie_list_notebooks.py --stdin致谢
许可证
麻省理工学院
