# jeremy-oz/notediscovery architecture

> Architecture diagram of the GitHub repository jeremy-oz/notediscovery, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-09). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/jeremy-oz/notediscovery
- Repository: https://github.com/jeremy-oz/notediscovery

## Overview

#### 1. Purpose and execution surfaces
NoteDiscovery is a self-hosted, file-backed Markdown knowledge base. The primary web process is launched through `run.py`, which serves backend APIs plus the browser client. Notes persist as Markdown under a mounted `data/` directory rather than a database. A separate MCP stdio process exposes note operations to AI clients.
Paths: `run.py`, `backend/main.py`, `mcp_server/__main__.py`.

#### 2. HTTP application and API boundary
`backend/main.py` is the central server/application boundary: it handles browser/API requests, serves application assets, and coordinates note operations, authentication, configuration, and feature endpoints. Supporting backend modules separate cross-cutting concerns such as shared links, exports, themes, plugins, and filesystem utilities.
Paths: `backend/main.py`, `backend/utils.py`, `backend/share.py`.

#### 3. Filesystem-backed knowledge model
The filesystem is the authoritative storage boundary: folders organize notes and Markdown content encodes links, tags, headings, templates, and attachments/drawings. Indexing derives searchable/discoverable structures from those files rather than maintaining a separate persistent datastore. This makes mounted `data/` portable but means API/MCP writes directly affect user files.
Paths: `backend/note_index.py`, `backend/export.py`, `documentation/DRAWING.md`.

#### 4. Browser client and offline delivery
The frontend is a static JavaScript application served by the backend. It provides editing, navigation, search/discovery, graph-oriented note exploration, rendering, and session-facing UI. The service worker supports offline-capable browser operation; localized UI strings are loaded from JSON locale resources.
Paths: `frontend/index.html`, `frontend/app.js`, `frontend/sw.js`.

#### 5. Content rendering and presentation extensions
Markdown notes are rendered/exported to browser and standalone HTML representations. Presentation is externally customizable through CSS theme files, while plugins provide server-side extension points; the bundled note-statistics plugin is an example. These are file-distributed deployment inputs and can be overridden through container mounts.
Paths: `backend/export.py`, `backend/plugins.py`, `themes/dark.css`, `plugins/note_stats.py`.

#### 6. Sharing and AI/MCP integration
Sharing is a distinct backend capability that publishes/accesses shared-note representations without changing the underlying note format. The MCP server is a separate client of the HTTP API: it reads its endpoint/configuration, translates MCP tool calls into NoteDiscovery operations, and is intended for Claude, Cursor, and other MCP hosts. Thus MCP access inherits the web server’s network and authentication boundary.
Paths: `backend/share.py`, `mcp_server/server.py`, `mcp_server/tools.py`, `mcp_server/client.py`.

#### 7. Deployment, runtime, and external services
The runtime is Python 3.8+ with dependencies declared in `requirements.txt`/`pyproject.toml`; Docker is the primary distribution model and exposes port 8000 with a persistent `/app/data` mount. Compose supports source development, GHCR images, and an optional local AI stack integrating Ollama and Open WebUI. CI publishes container images to GitHub Container Registry; no cloud database or required external browser CDN is part of normal operation.
Paths: `Dockerfile`, `docker-compose.yml`, `docker-compose.ollama-stack.yml`, `.github/workflows/docker-publish.yml`.

Main entry points: [`backend/main.py`](https://github.com/jeremy-oz/notediscovery/blob/main/backend/main.py) (HTTP application), [`frontend/app.js`](https://github.com/jeremy-oz/notediscovery/blob/main/frontend/app.js) (Static frontend), [`Dockerfile`](https://github.com/jeremy-oz/notediscovery/blob/main/Dockerfile) (Container runtime), [`frontend/index.html`](https://github.com/jeremy-oz/notediscovery/blob/main/frontend/index.html) (HTML shell)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web application"]
  node_browser(("Browser client"))
  node_frontend["Static frontend<br/>JavaScript app<br/>[app.js]"]
  node_service_worker["Offline worker<br/>service worker<br/>[sw.js]"]
  node_web_shell["HTML shell<br/>static entrypoint<br/>[index.html]"]
  node_run["Web launcher<br/>Python entrypoint<br/>[run.py]"]
  node_api["HTTP application<br/>Python server<br/>[main.py]"]
  node_filesystem_utils["Filesystem utilities<br/>backend module<br/>[utils.py]"]
end

subgraph group_content["Content and extensions"]
  node_note_index["Note index<br/>derived indexer<br/>[note_index.py]"]
  node_data[("Mounted notes<br/>Markdown filesystem")]
  node_export["Render and export<br/>backend module<br/>[export.py]"]
  node_sharing["Sharing<br/>backend capability<br/>[share.py]"]
  node_plugins["Plugin host<br/>extension system<br/>[plugins.py]"]
  node_theme["Dark theme<br/>CSS theme<br/>[dark.css]"]
  node_note_stats["Note statistics<br/>plugin<br/>[note_stats.py]"]
end

subgraph group_mcp["MCP integration"]
  node_mcp_host(("MCP host<br/>AI client"))
  node_mcp_entry["MCP stdio process<br/>Python entrypoint<br/>[__main__.py]"]
  node_mcp_tools["MCP tools<br/>tool adapter<br/>[tools.py]"]
  node_mcp_client["HTTP API client<br/>MCP backend client<br/>[client.py]"]
end

subgraph group_deployment["Deployment"]
  node_container{{"Container runtime<br/>Docker image"}}
  node_compose["Compose deployment<br/>deployment orchestration<br/>[docker-compose.yml]"]
  node_ci["Image publishing CI<br/>GitHub Actions workflow<br/>[docker-publish.yml]"]
end

node_browser -->|"loads"| node_web_shell
node_web_shell -->|"starts"| node_frontend
node_frontend -->|"registers"| node_service_worker
node_browser -->|"HTTP requests"| node_api
node_run -->|"launches"| node_api
node_api -->|"serves"| node_frontend
node_api -->|"uses"| node_filesystem_utils
node_api -->|"queries and updates"| node_note_index
node_note_index -->|"derives from"| node_data
node_api -->|"reads and writes"| node_data
node_api -->|"renders through"| node_export
node_export -->|"reads Markdown"| node_data
node_api -->|"provides"| node_sharing
node_api -->|"loads"| node_plugins
node_plugins -->|"hosts"| node_note_stats
node_frontend -->|"applies"| node_theme
node_mcp_host -->|"stdio"| node_mcp_entry
node_mcp_entry -->|"runs"| node_mcp_tools
node_mcp_tools -->|"invokes"| node_mcp_client
node_mcp_client -->|"HTTP API"| node_api
node_container -->|"runs"| node_run
node_container -->|"mounts"| node_data
node_compose -->|"deploys"| node_container
node_ci -->|"publishes"| node_container

click node_frontend "https://github.com/jeremy-oz/notediscovery/blob/main/frontend/app.js"
click node_service_worker "https://github.com/jeremy-oz/notediscovery/blob/main/frontend/sw.js"
click node_web_shell "https://github.com/jeremy-oz/notediscovery/blob/main/frontend/index.html"
click node_run "https://github.com/jeremy-oz/notediscovery/blob/main/run.py"
click node_api "https://github.com/jeremy-oz/notediscovery/blob/main/backend/main.py"
click node_filesystem_utils "https://github.com/jeremy-oz/notediscovery/blob/main/backend/utils.py"
click node_note_index "https://github.com/jeremy-oz/notediscovery/blob/main/backend/note_index.py"
click node_export "https://github.com/jeremy-oz/notediscovery/blob/main/backend/export.py"
click node_sharing "https://github.com/jeremy-oz/notediscovery/blob/main/backend/share.py"
click node_plugins "https://github.com/jeremy-oz/notediscovery/blob/main/backend/plugins.py"
click node_theme "https://github.com/jeremy-oz/notediscovery/blob/main/themes/dark.css"
click node_note_stats "https://github.com/jeremy-oz/notediscovery/blob/main/plugins/note_stats.py"
click node_mcp_entry "https://github.com/jeremy-oz/notediscovery/blob/main/mcp_server/__main__.py"
click node_mcp_tools "https://github.com/jeremy-oz/notediscovery/blob/main/mcp_server/tools.py"
click node_mcp_client "https://github.com/jeremy-oz/notediscovery/blob/main/mcp_server/client.py"
click node_container "https://github.com/jeremy-oz/notediscovery/blob/main/Dockerfile"
click node_compose "https://github.com/jeremy-oz/notediscovery/blob/main/docker-compose.yml"
click node_ci "https://github.com/jeremy-oz/notediscovery/blob/main/.github/workflows/docker-publish.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_browser,node_frontend,node_service_worker,node_web_shell,node_run,node_api,node_filesystem_utils toneBlue
class node_note_index,node_data,node_export,node_sharing,node_plugins,node_theme,node_note_stats toneAmber
class node_mcp_host,node_mcp_entry,node_mcp_tools,node_mcp_client toneMint
class node_container,node_compose,node_ci toneRose
```

## Components

### Web application

- **Browser client**: browser · Editing, navigation, search, graph exploration, and session UI.
- [Static frontend](https://github.com/jeremy-oz/notediscovery/blob/main/frontend/app.js): JavaScript app · `frontend/app.js`
- [Offline worker](https://github.com/jeremy-oz/notediscovery/blob/main/frontend/sw.js): service worker · `frontend/sw.js`
- [HTML shell](https://github.com/jeremy-oz/notediscovery/blob/main/frontend/index.html): static entrypoint · `frontend/index.html`
- [Web launcher](https://github.com/jeremy-oz/notediscovery/blob/main/run.py): Python entrypoint · `run.py`
- [HTTP application](https://github.com/jeremy-oz/notediscovery/blob/main/backend/main.py): Python server · API, assets, authentication, configuration, and feature boundary. · `backend/main.py`
- [Filesystem utilities](https://github.com/jeremy-oz/notediscovery/blob/main/backend/utils.py): backend module · `backend/utils.py`

### Content and extensions

- [Note index](https://github.com/jeremy-oz/notediscovery/blob/main/backend/note_index.py): derived indexer · Builds searchable and discoverable structures from Markdown files. · `backend/note_index.py`
- **Mounted notes**: Markdown filesystem · Authoritative portable note, attachment, and drawing storage.
- [Render and export](https://github.com/jeremy-oz/notediscovery/blob/main/backend/export.py): backend module · Renders Markdown to browser and standalone HTML. · `backend/export.py`
- [Sharing](https://github.com/jeremy-oz/notediscovery/blob/main/backend/share.py): backend capability · Publishes shared-note representations without changing note files. · `backend/share.py`
- [Plugin host](https://github.com/jeremy-oz/notediscovery/blob/main/backend/plugins.py): extension system · `backend/plugins.py`
- [Dark theme](https://github.com/jeremy-oz/notediscovery/blob/main/themes/dark.css): CSS theme · File-distributed presentation override. · `themes/dark.css`
- [Note statistics](https://github.com/jeremy-oz/notediscovery/blob/main/plugins/note_stats.py): plugin · Bundled server-side extension. · `plugins/note_stats.py`

### MCP integration

- **MCP host**: AI client · Claude, Cursor, or another MCP-capable client.
- [MCP stdio process](https://github.com/jeremy-oz/notediscovery/blob/main/mcp_server/__main__.py): Python entrypoint · `mcp_server/__main__.py`
- [MCP tools](https://github.com/jeremy-oz/notediscovery/blob/main/mcp_server/tools.py): tool adapter · Translates MCP calls into NoteDiscovery operations. · `mcp_server/tools.py`
- [HTTP API client](https://github.com/jeremy-oz/notediscovery/blob/main/mcp_server/client.py): MCP backend client · Uses configured endpoint and inherits HTTP authentication boundaries. · `mcp_server/client.py`

### Deployment

- [Container runtime](https://github.com/jeremy-oz/notediscovery/blob/main/Dockerfile): Docker image · Exposes port 8000 and mounts persistent /app/data. · `Dockerfile`
- [Compose deployment](https://github.com/jeremy-oz/notediscovery/blob/main/docker-compose.yml): deployment orchestration · Supports source development and optional local AI stack. · `docker-compose.yml`
- [Image publishing CI](https://github.com/jeremy-oz/notediscovery/blob/main/.github/workflows/docker-publish.yml): GitHub Actions workflow · Publishes container images to GHCR. · `.github/workflows/docker-publish.yml`

## Connections

- Browser client → HTML shell: loads
- HTML shell → Static frontend: starts
- Static frontend → Offline worker: registers
- Browser client → HTTP application: HTTP requests
- Web launcher → HTTP application: launches
- HTTP application → Static frontend: serves
- HTTP application → Filesystem utilities: uses
- HTTP application → Note index: queries and updates
- Note index → Mounted notes: derives from
- HTTP application → Mounted notes: reads and writes
- HTTP application → Render and export: renders through
- Render and export → Mounted notes: reads Markdown
- HTTP application → Sharing: provides
- HTTP application → Plugin host: loads
- Plugin host → Note statistics: hosts
- Static frontend → Dark theme: applies
- MCP host → MCP stdio process: stdio
- MCP stdio process → MCP tools: runs
- MCP tools → HTTP API client: invokes
- HTTP API client → HTTP application: HTTP API
- Container runtime → Web launcher: runs
- Container runtime → Mounted notes: mounts
- Compose deployment → Container runtime: deploys
- Image publishing CI → Container runtime: publishes
