NOTEDASHBOARD
rstevens70vault-hearth
Local-only, security-first home dashboard for your Obsidian vault — stdlib Python, no outbound network, loopback only.
Vault Hearth
Local-only home dashboard for your Obsidian vault — a FOSS alternative to the community Hearth plugin, without loading untrusted plugin code into Obsidian.
Design goals (security-first)
| Hearth plugin risk | This app |
|---|---|
| Runs inside Obsidian with full plugin API | Separate process; filesystem API only |
| Web iframes / optional trusted sandbox | No iframes |
| Jira PAT, RSS, FX, remote background | No outbound network from server |
> runs any Obsidian command | Command mode disabled |
| DataviewJS / hosted plugin leaves | Not supported |
| Binds wherever Electron does | Hard-locked to 127.0.0.1 |
Requirements
- Python 3.10+ (stdlib only — no pip packages, no build step)
- Read access to an Obsidian vault directory (any local folder of Markdown notes)
Quick start
git clone https://github.com/<you>/vault-hearth.git
cd vault-hearth
# create your local config and point it at your vault
cp config.example.json config.json
${EDITOR:-nano} config.json # set "vault_path"
./scripts/run.sh
# open http://127.0.0.1:8787/
config.json is gitignored, so your real vault path stays on your machine.
On first run, run.sh seeds config.json from the example if it is missing.
Tests (stdlib unittest, no vault required):
python3 tests/test_vault_lib.py
python3 tests/test_daily_lesson.py
Config (config.json)
| Key | Meaning |
|---|---|
vault_path | Absolute path to Obsidian vault root |
host | Must stay loopback (127.0.0.1) |
port | Default 8787 |
allow_writes | true enables create/append note APIs |
search_body | Full-text body search |
exclude_dirs | Skipped while indexing (.git, .obsidian, …) |
lesson_salt | Salt for date-stable Daily Lesson rotation (default hearth) |
lesson_dir | Vault folder for optional saved lessons (default Lessons) |
lesson_auto_save | Reserved; v1 saves only via UI button |
Start from config.example.json (copy it to config.json). Keep host on
loopback and leave allow_writes off unless you want the create/append APIs.
Features (v0.2)
- Fuzzy-ish search (title/path/body,
#tagprefix) - Hub grid from root
Topic.mdnotes → browse folder / shift-click hub note - Browse folders, recent notes, daily notes
- Daily Lesson — one vault-sourced tutorial per calendar day (roll-ups / workflows / playbooks); home card +
#/lesson; optional save toLessons/YYYY-MM-DD.md - Note view with lightweight Markdown (real tables) + clickable
[[wikilinks]] - raw/ inbox listing (a quick-capture drop zone)
- Optional create / append note (path-traversal safe)
- CSP +
X-Frame-Options: DENY+no-store
Layout
vault-hearth/
config.example.json # template — copy to config.json
README.md
AGENTS.md # notes for AI coding agents
LICENSE
scripts/run.sh
server/app.py # HTTP server (loopback only)
server/vault_lib.py # vault IO (path-traversal safe)
server/daily_lesson.py # offline daily tutorial generator
server/md_render.py # markdown → HTML
static/ # UI (HTML/CSS/JS, no build step)
tests/ # stdlib unittest
Security posture
- Binds
127.0.0.1only; refuses to start on a non-loopback host. - No outbound network from the server (no telemetry, no "phone home").
- No arbitrary command execution and no iframe embeds.
- All file access is path-traversal hardened; writes are opt-in via config.
What this is not
- Not an Obsidian plugin (no live preview parity, no canvas/excalidraw embed)
- Not a sync server and not exposed to LAN/WAN
License
MIT — yours to harden and extend.
How to Install
- Download the dashboard markdown file from GitHub
- Drop it into your vault (anywhere)
- Install the Homepage plugin and point it at the file
- Enable any listed CSS snippets for the intended look
Stats
Stars
0
Forks
0
License
MIT
Last updated 1mo ago
Categories