Cited memory for research agents, on unofficial Google APIs. Prototypes only.
notebooklm-py 0.8.5 keyless gate, re-run and reproduced: 18,960 upstream unit tests passed, 0 pip-audit findings across 21 packages. Unofficial Google APIs, prototypes only.
By David Discua
Measured in the lab
- 18960
- upstream tests passed
- 78
- skipped
- 0
- audit findings
- 0.8.5
- pin
From reports/gate.json · run on October 13, 2026. Upstream pytest tests/unit at teng-lin/notebooklm-py v0.8.5 (50493ddf), light markers, keyless, -n auto: 18,957 passed / 78 skipped / 3 pytest-timeout; the 3 timeouts re-run serially (-n 0, same 180 s budget) all passed in 311 s → 18,960 passed, 0 failed. Minilab wrapper 4 passed. pip-audit 0 findings across 21 packages. 932.6 s on an i7-9750H.
Where it sits
01/01Your agent calls notebooklm-py, which calls NotebookLM unofficially, and a cited answer comes back.
We pinned teng-lin/notebooklm-py at 0.8.5, vendored its agent skill under .claude/skills/notebooklm/, and re-ran the keyless gate on 2026-10-13 (run on October 13, 2026): 18,960 upstream unit tests passed, 0 failed, 0 pip-audit findings across 21 packages. notebooklm-py is a Python API, a CLI and an agent skill that drive NotebookLM and hand a research agent answers with their sources attached. The catch is that it talks to unofficial, undocumented Google APIs, so it is for prototypes only; the upstream README says so, and so do we.
Our lab never calls Google. Everything below is upstream's own unit suite running offline.
The catch
Unofficial endpoints change without notice, and nobody owes you a migration guide when they do. Live NotebookLM auth is a browser cookie jar under ~/.notebooklm/, which means storage_state.json, master_token.json and cookie exports must never land in a repo or a chat window. That is why the ship gate runs keyless tests/unit only. tests/e2e is never run, in CI or on our machine.
There is a second, smaller catch that the first version of this drop got wrong. An earlier report quoted "18,955 unit tests passed" with five failures waved through. We rebuilt the report script so the number means one thing, and we can say exactly what it counts.
What we ran (keyless)
uv sync --extra dev
uv run python scripts/report.py # wrapper tests + layout + pip-audit + upstream light gate
scripts/report.py clones teng-lin/notebooklm-py at tag v0.8.5 (50493ddf), runs upstream uv sync, then upstream pytest tests/unit with the light marker filter (not requires_playwright and not requires_chromium and not reality and not refactor_qualification), excluding one CI-matrix file and one snapshot that expect a full maintainer checkout. Numbers from reports/gate.json:
| Metric | Value |
|---|---|
Upstream unit tests passed under xdist (-n auto) | 18,957 |
| Skipped (marker/platform) | 78 |
| Failed under xdist | 3, all pytest-timeout (180 s) |
| Those 3 re-run serially, same 180 s budget | 3 passed in 311 s |
| Upstream unit tests passed, total | 18,960 (0 failed) |
| Minilab wrapper tests (pin, import, skill file) | 4 passed |
| pip-audit findings | 0 across 21 packages |
| Pin | notebooklm-py==0.8.5 |
| Wall time | 932.6 s on a 6-core i7-9750H |
The headline figure counts upstream's tests. The 18,960 cases come from teng-lin's own tests/unit tree at the pinned tag, run with no Google credentials. The three timeouts are CPU-bound audits that walk the whole test tree with ast (test_auth_lifecycle_cleanup_policy, test_auth_patch_survivor_policy). Scheduled last on twelve xdist workers of a six-core laptop they blow the 180 s budget, and run alone they pass inside it. The report records both runs separately and never rewrites the xdist counts. Our four minilab tests only prove that the pin matches the script, the client imports, and the skill file is where Claude Code expects it.
Why this matters
The wiring is short. Your agent loads the notebooklm skill, the skill calls notebooklm-py, notebooklm-py calls NotebookLM over the undocumented API, and the answer comes back with its sources attached. The control point is notebooklm-py, which is why it is the only thing we pin and the only thing we test. Everything to its right is Google's, unofficial and unversioned.
Treat it as a research-prototype harness. Use it to give a research agent cited recall over your own notebooks on your own machine. Do not put it in a customer path, do not put the cookie jar in CI, and re-run scripts/report.py after every upstream bump. The whole gate took 932.6 s on our laptop, so running it after every bump costs little.
Minilab (open source)
Upstream: teng-lin/notebooklm-py (MIT, Python, 19,713 stars on October 13, 2026)
Run it yourself
SkilledDragonCorp/minilab-notebooklm-py-skill
Clone, install and run the report with no API keys. The numbers above are what that run writes.
uv sync --extra dev && uv run python scripts/report.pySkilledDragon is not affiliated with Google or with teng-lin/notebooklm-py. notebooklm-py uses unofficial, undocumented Google APIs, prototypes only; our lab never calls them. Test counts are upstream's own keyless unit suite at pin 0.8.5, run on our machine; re-run the gate before relying on them. Marks belong to their owners.
All labs