The Problem

Google's Notebook LM locks research into a single provider with no API access, limited podcast controls, and no self-hosting option. Teams that need data sovereignty, model flexibility, or automation have no equivalent.

What This Does

open-notebook is a self-hosted, multi-model alternative to Notebook LM. The Python backend (api/, open_notebook/) handles notebooks, sources, embeddings, chat, and podcast generation. The React/Next.js frontend (frontend/) provides the UI. Docker deployment is supported via docker-compose.yml and two Dockerfiles.

The system supports 18+ AI providers, multi-speaker podcasts, full-text and vector search, and a REST API for automation. It's forked from lfnovo/open-notebook (37k+ stars).

How It Is Wired

Execution starts in api/main.py at the lifespan function, which reaches 27 functions. The API layer (api/routers/) exposes endpoints that delegate to service files like api/notebook_service.py and api/chat_service.py. The core domain logic sits in open_notebook/domain/ with notebook.py as the central hub (25 modules import it, 7 import cycles).

The highest-blast-radius functions are repo_query (called from 58 places) and _make_request (53 places). open_notebook/database/repository.py owns database effects; open_notebook/utils/encryption.py handles secrets and file I/O; api/client.py makes outbound network calls. A typical flow: API request → repo_query → database connection, in 2-3 hops.

The module graph shows a cycle involving open_notebook/ai/models.py and open_notebook/domain/credential.py — changing either risks breaking the other. open_notebook/exceptions.py is a stable hub (26 dependents) with zero instability.

How To Use It

Setup: Clone and run with Docker:

git clone https://github.com/moses-y/open-notebook
cd open-notebook
cp .env.example .env
docker compose up -d

Configuration: Set provider API keys in .env (e.g., OPENAI_API_KEY, ANTHROPIC_API_KEY). The .env.example file documents available variables.

Running it: For local dev, the Makefile has targets; the API entry point is api/main.py (FastAPI). Frontend runs via npm from frontend/.

Real-World Use

A research team self-hosts this to process internal PDFs and web pages. They configure Ollama for local embeddings and OpenAI for chat. Analysts upload sources, generate two-speaker podcast summaries, and query via the REST API to automate weekly briefings. All data stays on their infrastructure.

Code Health & Issues

Static analysis found 107 findings (23 high, 84 medium) across 7 categories:

  • High – Deep nesting (33 occurrences) in open_notebook/domain/notebook.py, base.py, credential.py; max indentation depth 9.
  • High – Import cycle members (7) including open_notebook/ai/models.py and domain/credential.py.
  • High – Hub modules (7) with high blast radius: exceptions.py (26 dependents), notebook.py (25).
  • High – Duplicated code: 282 repeated 6-line blocks across 90 files.
  • Medium – Broad exception handling (8), high branching in frontend/src/lib/api/client.ts, oversized files (3).

Security audit: 2 critical findings in .github/workflows/claude-code-review.yml — the workflow checks out untrusted PR code with a privileged token (CLAUDE_CODE_OAUTH_TOKEN) exposed to fork-triggered jobs. 2 high: unpinned GitHub Actions (tag-based, not SHA) and a secret baked into the Dockerfile as ENV. 5 medium: no Dependabot, unpinned base image, no dependency scan, persist-credentials not disabled, no non-root user.

The Bottom Line

Functionally strong: a complete Notebook LM alternative with real model flexibility and a working API. The CI/CD security posture is not production-safe — the PR review workflow is a credential exfiltration risk and must be fixed before public contribution. Worth deploying for internal use after addressing the workflow issues.