A fast, single-binary publishing server for Obsidian-style vaults, written in Go. Amythest gives you the Quartz experience — wikilinks, backlinks, an interactive spring graph, ⌘K full-text search, a polished reading UI — plus the things a static site generator can't do, at a fraction of the memory.
Born as a replacement for a Node/Quartz setup that peaked at 1.24 GiB RSS on a Raspberry Pi. Amythest serves the same 1,700-note vault in ~50 MB, cold-indexes it in about a second, and never serves a stale build because there is no build.
Same vault, same Raspberry Pi, same day: Quartz (teal) vs Amythest (green) resident memory across the cutover.
Notes: explorer + section nav, rendered note, spring graph, table of contents, and backlinks.
Kanban: markdown-backed boards with card search, creation dates, labels, comments, due dates, blocked flags, and per-card status moves.
- Live server, not a build step. Pages render from an mmap'd SQLite index (FTS5) that reconciles with the vault on a fixed interval — the rescan is the freshness guarantee, so there is no file watcher to die. Full reconcile of ~1,700 notes: ~1.4 s cold, no-op when nothing changed.
- Obsidian-flavored markdown, AST-based (goldmark):
[[wikilinks]]with#headingand|alias, transclusions with cycle guards, callouts (including unknown types),==highlights==,#tags,[Key:: value]inline fields, checkboxes, chroma-highlighted code, lazy-loaded mermaid. Frontmatter parsing never fails the page — malformed legacy YAML is preserved raw instead of crashing the renderer. - Graph view: d3-force on canvas. Local BFS neighbourhood on every page, global graph in a modal, drag/zoom/pan, visited-node tinting.
- Search: server-side SQLite FTS5 with snippet highlighting behind a ⌘K modal — the full corpus never ships to the browser.
- Kanban built in. Boards are markdown files inside the vault — human
readable in Obsidian, canonical on disk — managed by a locked, journaled,
crash-safe store with a stable JSON API and an embedded React board UI at
/kanban. - Tasks: Obsidian Tasks emoji syntax (📅 ⏳ 🔁 ⏫ ✅) indexed vault-wide;
```tasksblocks in notes render live results (filters, relative dates, sort/group/limit);/tasksdashboard;/api/tasks. - Bases:
.baseYAML views over your frontmatter with the Obsidian Bases expression language (note.*,file.*,formula.*,if(), string/number/date/list methods,file.hasTag()…) rendered as table / list / cards / board views at/bases/{name}and inline via```baseblocks. Unsupported expressions degrade to per-cell errors, never broken pages. - Data catalog: import CSVs into a separate SQLite database
(
amythest import csv data.csv), browse and query them read-only at/dborPOST /api/db/query. - Share to notes (
/share): record a voice memo in the browser or drop any file; it lands inAssets/Share/with a wrapping note in_Inbox/. Processor plugins (any executable, declared inshare_plugins:) enrich the note asynchronously — each is probed at startup and activates only when its own configuration is present.examples/plugins/openai-transcribeappends a transcript whenOPENAI_API_KEYis set. The full upload lifecycle and plugin contract are documented ininternal/share/share.go. - MCP endpoint (
/mcp, streamable HTTP, bearer token): agents getsearch_notes,get_note,list_notes,get_graph,query_tasks,query_base,query_sql, and fullkanban_*actions — in-process, same locks as the UI.
Requires Go ≥ 1.24 and Node (dev-time only, for esbuild).
make build
./bin/amythest -vault ~/notes
# open http://127.0.0.1:8639Configuration: amythest.example.yaml (vault, listen address, data dir,
rescan interval). Secrets are env-only:
| Variable | Purpose |
|---|---|
KANBAN_USERNAME / KANBAN_PASSWORD / KANBAN_SESSION_SECRET |
enable the kanban app |
KANBAN_COOKIE_SECURE=true |
secure cookies behind TLS |
AMYTHEST_MCP_TOKEN |
enable the /mcp endpoint |
Amythest binds loopback by default; put Tailscale Serve or any TLS-terminating proxy in front.
Prometheus metrics are exposed at /metrics, including HTTP request counts
and duration histograms, vault note/asset gauges, rescan health, heap usage,
and goroutine count. The HTTP series use only method and status-code labels
to avoid unbounded path cardinality.
internal/vault walker (symlink-safe), slugs, never-fail frontmatter
internal/markdown goldmark pipeline + obsidian extensions
internal/index SQLite: notes, links, tags, tasks, FTS5, render cache
internal/tasks emoji parser + tasks query language
internal/bases expression engine, .base views, CSV catalog
internal/kanban board store (locking/journaling), HTTP API, auth
internal/mcp MCP tools over the same stores
web/ templates, TS islands (graph/search/popover/spa), SCSS
deploy/ systemd unit, staging script, cutover guide
Derived data (-data dir) is disposable: delete it and the next start
reindexes. Schema and renderer changes invalidate it automatically.
make test # unit + golden tests
make compat # boots the server and drives the original kanban.py client
# through the full card lifecycle (wire compatibility gate)
AMYTHEST_SMOKE_VAULT=~/notes go test ./internal/markdown -run Smoke # full-vault renderAmythest is designed for a single user or small trusted group behind a private network (a tailnet, VPN, or reverse proxy with its own auth):
- The server binds loopback by default and refuses nothing at the network layer beyond that — put TLS and network access control in front.
- Reading notes is unauthenticated. Mutations (task toggles, share uploads) require a valid kanban session when kanban auth is configured; without it they are open to whoever can reach the port.
- Kanban mutations always require login + CSRF; sessions are stateless
HMAC-signed cookies (
SameSite=Strict, HttpOnly) with constant-time verification and login rate limiting. /mcprequires a bearer token (constant-time compared) and is disabled unlessAMYTHEST_MCP_TOKENis set.- Catalog SQL runs on a read-only database connection (
query_only), and only single SELECT statements are accepted. - Vault writes are confined: path-traversal guarded, kanban board files excluded from the generic write paths, atomic temp+rename writes.
- Share plugins are arbitrary executables you configure; they run with the server's privileges. Only list plugins you trust.
MIT — see LICENSE. Visual design derived from Quartz v4 (MIT); see NOTICE.


