# How to Customize Open-Notebook: A Complete Guide to Configuration and Extensions

> Easily customize Open-Notebook by editing environment variables, extending Python modules, or modifying React components. Our guide simplifies configuration and extensions for the lfnovo/open-notebook repository.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: how-to-guide
- Published: 2026-06-08

---

**You can customize Open-Notebook by editing environment variables in `.env`, extending Python modules in the `open_notebook/` package, or modifying React components in the `frontend/` directory, with all core configuration centralized in [`open_notebook/config.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/config.py).**

Open-Notebook is a modular, three-tier application (frontend → API → database) designed for extensibility. The repository `lfnovo/open-notebook` provides specific entry points for tailoring AI providers, content processing pipelines, and database schemas without forking the entire codebase.

## Application Settings and Configuration

**Environment variables** drive all tunable settings in Open-Notebook. The [`open_notebook/config.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/config.py) file defines the `Config` class that reads from your `.env` file at runtime, controlling everything from CORS policies to file upload limits.

Copy `.env.example` to `.env` and modify values such as `DEFAULT_MODEL`, `MAX_UPLOAD_SIZE`, or provider-specific API keys. For programmatic defaults, subclass the `Config` class in [`open_notebook/config.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/config.py) before the FastAPI application initializes.

## AI Model Customization

Open-Notebook abstracts model access through a provider pattern that supports OpenAI, Anthropic, and other backends via the `open_notebook/ai/` module.

### Adding New Providers and Models

To support a new provider, implement a wrapper class in [`open_notebook/ai/models.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/models.py) that follows the `BaseModel` interface, then register it in [`open_notebook/ai/model_discovery.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/model_discovery.py). The [`provision.py`](https://github.com/lfnovo/open-notebook/blob/main/provision.py) module automatically detects available providers based on present environment variables (e.g., `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`).

### Runtime Model Selection

Use `provision_langchain_model()` from [`open_notebook/ai/provision.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/provision.py) to dynamically select models at runtime:

```python
from open_notebook.ai.provision import provision_langchain_model

model = provision_langchain_model(
    provider="anthropic",
    model_name="claude-3-5-sonnet-20240620",
    temperature=0.2,
)
response = await model.ainvoke({"input": "Summarise this notebook"})

```

Credentials are stored securely via [`open_notebook/domain/credential.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/domain/credential.py) using SurrealDB records, separating sensitive keys from configuration files.

## Extending LangGraph Workflows

The application uses **LangGraph** for orchestrating complex AI workflows. You can extend or replace the source ingestion, chat, ask, or transformation graphs located in `open_notebook/graphs/` (e.g., [`source.py`](https://github.com/lfnovo/open-notebook/blob/main/source.py), [`chat.py`](https://github.com/lfnovo/open-notebook/blob/main/chat.py), [`ask.py`](https://github.com/lfnovo/open-notebook/blob/main/ask.py), [`transformation.py`](https://github.com/lfnovo/open-notebook/blob/main/transformation.py)).

To customize the ingestion pipeline, copy an existing graph and modify its nodes:

```python

# open_notebook/graphs/custom_source.py

from .source import source_graph
from open_notebook.utils.graph_utils import add_node

custom_graph = source_graph.copy()

@add_node(custom_graph, "my_custom_step")
async def custom_step(state):
    # Custom processing logic here

    return state

custom_graph.add_edge("extract_text", "my_custom_step")
custom_graph.add_edge("my_custom_step", "embed")

```

Invoke custom graphs using `await custom_graph.ainvoke({...})` within your API routes.

## Content Processing and Embeddings

Modify **text chunking** strategies in [`open_notebook/utils/chunking.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/chunking.py) or adjust cleanup pipelines in [`open_notebook/utils/text_utils.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/text_utils.py) to change how documents are split and sanitized before embedding.

For vector storage customization, edit [`open_notebook/utils/embedding.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/embedding.py), which wraps the Esperanto library. Database migration scripts for schema changes reside in `migrations/` and are executed automatically by [`open_notebook/database/async_migrate.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/database/async_migrate.py).

## API and Backend Extensions

Add new REST endpoints by creating router files in `api/routers/` following the pattern of existing modules like [`sources.py`](https://github.com/lfnovo/open-notebook/blob/main/sources.py) or [`settings.py`](https://github.com/lfnovo/open-notebook/blob/main/settings.py):

```python

# api/routers/custom.py

from fastapi import APIRouter
router = APIRouter()

@router.post("/custom/process")
async def process(payload: dict):
    result = await custom_graph.ainvoke(payload)
    return result

```

Register the router in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py):

```python
app.include_router(router, prefix="/custom")

```

Background job queues for podcast generation and other async tasks can be tuned in [`api/podcast_service.py`](https://github.com/lfnovo/open-notebook/blob/main/api/podcast_service.py) and the `commands/` directory.

## Frontend and Database Modifications

The **React/Next.js frontend** lives in `frontend/`, with reusable UI components under `frontend/src/components/`. You can retheme the interface, add new panels, or modify TanStack-Query hooks to connect with custom backend routes.

To extend the **SurrealDB schema**, create new record types by adding SurrealQL migration files in `migrations/` (e.g., `001_add_projects.surql`). The migration runner applies these automatically on the next API startup.

## Summary

- **Configuration**: Edit `.env` variables or subclass `Config` in [`open_notebook/config.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/config.py) to modify application settings.
- **AI Models**: Implement providers in [`open_notebook/ai/models.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/models.py) and use `provision_langchain_model()` for runtime selection.
- **Workflows**: Copy and extend LangGraph definitions in `open_notebook/graphs/` to customize AI pipelines.
- **API**: Add FastAPI routers in `api/routers/` to expose new functionality.
- **Database**: Create SurrealQL files in `migrations/` to add tables or relationships.
- **Frontend**: Modify React components in `frontend/src/components/` to change the user interface.

## Frequently Asked Questions

### How do I change the default AI model in Open-Notebook?

Set the `DEFAULT_MODEL` environment variable in your `.env` file (e.g., `DEFAULT_MODEL=gpt-4o`), or override the value programmatically in [`open_notebook/config.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/config.py) before the FastAPI app initializes. The system uses [`open_notebook/ai/provision.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/provision.py) to resolve the provider based on available API keys.

### Can I add custom file type handlers to the ingestion pipeline?

Yes. Modify [`open_notebook/utils/chunking.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/chunking.py) to adjust chunk sizes for specific file types, or extend the text cleanup logic in [`open_notebook/utils/text_utils.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/text_utils.py). For complex file formats, add a new processing node to the source ingestion graph in [`open_notebook/graphs/source.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/graphs/source.py).

### What is the best way to add new database tables to Open-Notebook?

Create a SurrealQL migration file in the `migrations/` directory (e.g., `002_add_tags.surql`). The [`open_notebook/database/async_migrate.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/database/async_migrate.py) module automatically detects and applies these migrations when the API restarts, ensuring schema consistency across deployments.

### How do I create a custom LangGraph workflow?

Copy an existing graph such as [`open_notebook/graphs/source.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/graphs/source.py), rename it, and use the graph utilities in [`open_notebook/utils/graph_utils.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/graph_utils.py) to add or modify nodes. Expose the new workflow by creating a FastAPI router in `api/routers/` that invokes your custom graph with `await graph.ainvoke({...})`.