Metadata-Version: 2.4
Name: notebooklm-mcp-lisa
Version: 0.2.0
Summary: Unofficial NotebookLM MCP server and CLI — drives NotebookLM's internal RPCs through a Playwright session.
Project-URL: Homepage, https://github.com/gracelee087/notebooklm-mcp-lisa
Project-URL: Repository, https://github.com/gracelee087/notebooklm-mcp-lisa
Project-URL: Issues, https://github.com/gracelee087/notebooklm-mcp-lisa/issues
Author-email: Sohee Lee <gracelee.087@gmail.com>
License: MIT
License-File: LICENSE
Keywords: automation,claude,llm,mcp,notebooklm,playwright
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: fastmcp>=0.4.0
Requires-Dist: httpx>=0.27
Requires-Dist: mcp>=1.2.0
Requires-Dist: platformdirs>=4.2
Requires-Dist: playwright>=1.47.0
Requires-Dist: pydantic>=2.6
Requires-Dist: rich>=13.7
Requires-Dist: typer>=0.12
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# notebooklm-mcp

An unofficial NotebookLM MCP server and CLI — inspired by
[`jacob-bd/notebooklm-mcp-cli`](https://github.com/jacob-bd/notebooklm-mcp-cli).

> ⚠️ NotebookLM has no public API. This project talks to NotebookLM's
> internal `batchexecute` / `GenerateFreeFormStreamed` RPCs through a
> Playwright persistent-context session. It is not affiliated with Google.

## What works today

| Tool | Status | Notes |
|---|---|---|
| `notebook_list` | ✅ | Returns "mine" + "shared" notebooks. Pagination for many owned notebooks not yet discovered (shows most-recent owned). |
| `notebook_create` | ✅ | Untitled empty notebook. |
| `notebook_delete` | ✅ | Permanent, no undo. |
| `notebook_query` | ✅ | Streams the answer with inline `[1][2]` citations. |
| `source_add` | ⚠️ | `kind="text"` and `kind="url"` work. `drive` / `file` stubs. |
| `research_start` | ✅ | NotebookLM Discover → returns candidate URLs (does not auto-import). |
| `research_and_ask` | ✅ | One-shot: create → research → import → ask N questions → (optional) delete. |
| `studio_create` | ⚠️ | `artifact="audio"` (podcast) works. video / slides / mindmap / etc. stubs. |
| `download_artifact` | ✅ | Saves completed audio as `.m4a`. |
| `refresh_auth` | ✅ | Checks whether the stored Google session is still live. |

Stubs (raise `NotImplementedError`): `notebook_share_public`,
`notebook_share_invite`, `source_sync_drive`, `source_get_content`,
`studio_revise`, `cross_notebook_query`, `batch`, `pipeline`, `tag`.

## End-to-end workflow this supports

Manual orchestration:

```
notebook_create()              → empty notebook
research_start(nid, topic)     → ~10 candidate URLs
source_add(nid, kind="url")×N  → import the ones you want
notebook_query(nid, question)  → grounded answer with citations
studio_create(nid, "audio")    → start podcast generation (2-5 min)
download_artifact(nid)         → .m4a file on disk
```

Or, in a single call:

```python
research_and_ask(
    topic="history of the Cold War space race",
    questions=["Who reached space first?", "Key consequences?"],
    max_sources=3,
    keep_notebook=False,  # ephemeral — delete after
)
# → { sources_imported: [...], qa: [{question, answer, ...}, ...] }
```

## Install

### Quick start (from PyPI)

```bash
uv tool install notebooklm-mcp-lisa
uvx --from notebooklm-mcp-lisa playwright install chromium
nlm login                       # one-time Google sign-in (opens a browser)
nlm setup add claude-code       # or: claude-desktop
```

The `setup add` command edits the target's config file so the MCP server is
registered — no JSON editing by hand. Restart the client to pick it up.

Verify registration any time:

```bash
nlm setup list
```

### Dev setup (from source)

```bash
git clone https://github.com/gracelee087/notebooklm-mcp-lisa.git
cd notebooklm-mcp
uv sync
uv run playwright install chromium
uv run nlm login
```

## First-time Google login

NotebookLM requires a signed-in Google session. Run once, headed:

```bash
uv run nlm login
```

A Chromium window opens. Complete Google OAuth; the session is saved to
the OS user-data dir (`NLM_PROFILE_DIR` to override). Subsequent runs are
headless.

Verify:

```bash
uv run nlm status
# {'logged_in': True}
```

## Run the MCP server

```bash
uv run notebooklm-mcp
# or
uv run nlm serve
```

### Claude Code (project-scoped, auto-picked-up)

`.mcp.json` in this repo is already configured. When you open the project in
Claude Code it prompts you to trust and loads `notebooklm` automatically.

### Claude Desktop

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "notebooklm": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/this/repo", "run", "notebooklm-mcp"]
    }
  }
}
```

## Repo layout

```
src/notebooklm_mcp/
  server.py          # FastMCP entry
  cli.py             # `nlm` CLI (login/status/serve)
  browser.py         # Playwright persistent context
  config.py          # paths, env
  tools/
    notebook.py source.py studio.py research.py workflow.py auth.py
```

## Status

- [x] Package scaffold, MCP server, CLI
- [x] Playwright session with persistent Google login
- [x] All tools registered (stubs)
- [ ] `notebook_list` DOM scrape
- [ ] `notebook_query` chat flow
- [ ] `source_add` (url/text/drive/file)
- [ ] `studio_create` audio (podcast) + download
- [ ] remaining tools

## License

MIT
