How jeremy-oz/notediscovery works
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: main.py HTTP application · app.js Static frontend · Dockerfile Container runtime · index.html HTML shell
Components 21
Web application
- Browser client · Editing, navigation, search, graph exploration, and session UI.
- Static frontend
frontend/app.js - Offline worker
frontend/sw.js - HTML shell
frontend/index.html - Web launcher
run.py - HTTP application · API, assets, authentication, configuration, and feature boundary.
backend/main.py - Filesystem utilities
backend/utils.py
Content and extensions
- Note index · Builds searchable and discoverable structures from Markdown files.
backend/note_index.py - Mounted notes · Authoritative portable note, attachment, and drawing storage.
- Render and export · Renders Markdown to browser and standalone HTML.
backend/export.py - Sharing · Publishes shared-note representations without changing note files.
backend/share.py - Plugin host
backend/plugins.py - Dark theme · File-distributed presentation override.
themes/dark.css - Note statistics · Bundled server-side extension.
plugins/note_stats.py
MCP integration
- MCP host · Claude, Cursor, or another MCP-capable client.
- MCP stdio process
mcp_server/__main__.py - MCP tools · Translates MCP calls into NoteDiscovery operations.
mcp_server/tools.py - HTTP API client · Uses configured endpoint and inherits HTTP authentication boundaries.
mcp_server/client.py
Deployment
- Container runtime · Exposes port 8000 and mounts persistent /app/data.
Dockerfile - Compose deployment · Supports source development and optional local AI stack.
docker-compose.yml - Image publishing CI · Publishes container images to GHCR.
.github/workflows/docker-publish.yml
Connections 24
- 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