# Open Notebook Features: A Privacy-First Multi-Model Research Platform

> Explore Open Notebook, a privacy-first research assistant. Features include AI chat, universal content ingestion, and automated podcast generation on a self-hosted platform.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: deep-dive
- Published: 2026-06-13

---

**Open Notebook is a self-hosted research assistant that combines a Next.js frontend, FastAPI backend, and SurrealDB graph database to deliver universal content ingestion, context-aware AI chat, and automated podcast generation while keeping all data under your control.**

Open Notebook (`lfnovo/open-notebook`) is an open-source research platform designed for privacy-conscious users who need to synthesize information from diverse sources. Unlike cloud-based alternatives, it stores all data in your own SurrealDB instance and supports 18+ AI providers through its modular **ModelManager** architecture. The application leverages **LangGraph** workflows to orchestrate complex multi-step operations like chat reasoning and content transformation.

## Privacy-First Data Architecture

All research data lives in your own **SurrealDB** instance, ensuring that sensitive information never touches external cloud servers unless you explicitly invoke an AI provider. The [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) file registers a `PasswordAuthMiddleware` (line 15) that can lock the entire UI behind a password for public deployments, providing optional but robust access control. Database operations are handled through async helpers in [`open_notebook/database/repository.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/database/repository.py), which manages CRUD operations against your local instance.

## Multi-Model AI Support

The platform supports 18+ AI providers through the **Esperanto** library, managed centrally by the `ModelManager` class in [`open_notebook/ai/models.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/models.py) (line 98). This unified interface handles language models, embedding models, speech-to-text (STT), and text-to-speech (TTS) providers including OpenAI, Anthropic, and Ollama. You can configure different models for different tasks—chat, summarization, or audio generation—without modifying core application code.

## Universal Content Ingestion

Open Notebook ingests PDFs, videos, audio, web pages, and Office documents through a content extraction pipeline defined in [`open_notebook/graphs/source.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/graphs/source.py). The system stores extracted materials as **Source** records linked to **Notebook** entities (defined in [`open_notebook/domain/notebook.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/domain/notebook.py)), creating a graph relationship that enables precise context retrieval. After ingestion, the platform automatically generates vector embeddings via [`open_notebook/utils/embedding.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/embedding.py) to power semantic search.

## Context-Aware Chat and Intelligent Search

The chat system uses a **LangGraph** workflow in [`open_notebook/graphs/chat.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/graphs/chat.py) (line 22) that builds prompts from notebook context before streaming to the selected LLM. **Fine-grained context control** allows you to select specific sources (or excerpts) to include in a query, limiting token usage and protecting sensitive information. The system combines full-text search with vector similarity matching through SurrealDB's native embedding capabilities to retrieve the most relevant materials before generation.

## AI-Assisted Content Transformations

Customizable **transformations** run as LangGraph nodes, enabling pipeline-style processing such as summarization, entity extraction, and citation formatting. These workflows operate on **Source** records and can chain multiple AI operations together, with each step managed through the graph architecture in `open_notebook/graphs/`. The transformation system is extensible—new processing steps can be added by defining additional nodes and edges in the graph structure.

## Professional Podcast Generation

The podcast service ([`api/routers/podcasts.py`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/podcasts.py)) generates multi-speaker audio content from notebook materials. It builds conversational scripts, runs text-to-speech synthesis using configured speaker profiles, and assembles final audio files. The feature supports up to four distinct speaker profiles and integrates directly with the **ModelManager** for TTS provider selection.

## REST API and Extensibility

Every UI action is backed by a FastAPI endpoint exposed in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) (line 89), including `/api/notebooks`, `/api/sources`, and `/api/chat`. The API provides OpenAPI documentation for programmatic use, while the underlying domain models (defined using Pydantic in files like [`open_notebook/domain/notebook.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/domain/notebook.py)) ensure type safety across the Python codebase. Configuration management is centralized in [`open_notebook/config.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/config.py), which handles environment parsing and checkpoint file locations for graph workflows. The front-end is available in multiple languages including English, Portuguese, Chinese, Japanese, Russian, and Bengali.

## Common API Operations

The following Python examples demonstrate how to interact with Open Notebook's REST API at `http://localhost:5055`.

### Create a New Notebook

```python
import requests

resp = requests.post(
    "http://localhost:5055/api/notebooks",
    json={"name": "My Research Notebook"},
)
notebook = resp.json()
print("Notebook ID:", notebook["id"])

```

### Add a PDF Source

```python
files = {"file": open("paper.pdf", "rb")}
data = {"notebook_id": notebook["id"], "title": "Important Paper"}

resp = requests.post(
    "http://localhost:5055/api/sources",
    data=data,
    files=files,
)
source = resp.json()
print("Source ID:", source["id"])

```

### Send a Context-Aware Chat Message

```python
payload = {
    "notebook_id": notebook["id"],
    "messages": [
        {"role": "user", "content": "Summarize the main findings of the PDF."}
    ],
    "model_override": None,  # Uses default chat model

}
resp = requests.post(
    "http://localhost:5055/api/chat",
    json=payload,
)
answer = resp.json()
print("AI:", answer["messages"][-1]["content"])

```

### Rebuild Embeddings After Adding Sources

```python
resp = requests.post(
    "http://localhost:5055/api/embeddings/rebuild",
    json={"notebook_id": notebook["id"]},
)
print("Rebuild status:", resp.json())

```

### Generate a Multi-Speaker Podcast

```python
payload = {
    "notebook_id": notebook["id"],
    "episode_title": "Research Highlights",
    "speaker_profiles": ["speaker1", "speaker2"],
}
resp = requests.post(
    "http://localhost:5055/api/podcasts",
    json=payload,
)
podcast = resp.json()
print("Podcast job ID:", podcast["job_id"])

```

## Summary

- **Complete data privacy** through self-hosted SurrealDB and optional password protection in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py)
- **Multi-model flexibility** via the `ModelManager` class supporting 18+ providers including OpenAI and Anthropic
- **Universal ingestion** of PDFs, audio, video, and web content stored as graph-connected **Source** records
- **Context-aware chat** powered by LangGraph workflows in [`open_notebook/graphs/chat.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/graphs/chat.py) with selectable source context
- **Automated media generation** including multi-speaker podcasts through the `/api/podcasts` endpoint
- **Comprehensive REST API** built on FastAPI with Pydantic domain models and OpenAPI documentation

## Frequently Asked Questions

### Is Open Notebook fully self-hosted?

Yes. According to the `lfnovo/open-notebook` source code, all data resides in your own SurrealDB instance. The API only communicates with external AI providers when explicitly configured, and the `PasswordAuthMiddleware` in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) enables local access control without third-party authentication services.

### Which AI models does Open Notebook support?

The platform supports over 18 providers through the **Esperanto** library, as implemented in [`open_notebook/ai/models.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/models.py). This includes cloud providers like OpenAI and Anthropic, as well as local models via Ollama, with dedicated support for language, embedding, STT, and TTS models.

### How does the podcast generation feature work?

The podcast service uses a LangGraph workflow to script conversations based on notebook content, then synthesizes speech using configured TTS models through the `ModelManager`. The [`api/routers/podcasts.py`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/podcasts.py) endpoint accepts speaker profile IDs and episode titles, returning a job ID for asynchronous audio generation.

### Can I limit which sources the AI accesses during chat?

Yes. Open Notebook provides **fine-grained context control** that allows you to select specific sources or excerpts to include in a chat request. This feature, referenced in the repository documentation, reduces token costs and prevents sensitive materials from being sent to AI providers.