--- name: obsidian description: Read, search, and create notes in the Obsidian vault. version: 1.1.0 author: Hermes Agent license: MIT metadata: hermes: tags: [obsidian, vault, markdown, notes, remote-access] related_skills: [llm-wiki] --- # Obsidian Vault ## Vault Location Set via `OBSIDIAN_VAULT_PATH` environment variable (e.g. in `~/.hermes/.env`). If unset, defaults to `~/Documents/Obsidian Vault`. Always quote the path because vault paths often contain spaces. ```bash VAULT="${OBSIDIAN_VAULT_PATH:-$HOME/Documents/Obsidian Vault}" ``` ## Read a Note ```bash VAULT="${OBSIDIAN_VAULT_PATH:-$HOME/Documents/Obsidian Vault}" cat "$VAULT/Note Name.md" ``` ## List Notes ```bash VAULT="${OBSIDIAN_VAULT_PATH:-$HOME/Documents/Obsidian Vault}" find "$VAULT" -name "*.md" -type f ``` ## Search ```bash VAULT="${OBSIDIAN_VAULT_PATH:-$HOME/Documents/Obsidian Vault}" # By filename find "$VAULT" -name "*.md" -iname "*keyword*" # By content grep -rli "keyword" "$VAULT" --include="*.md" ``` ## Create a Note ```bash VAULT="${OBSIDIAN_VAULT_PATH:-$HOME/Documents/Obsidian Vault}" cat > "$VAULT/New Note.md" << 'ENDNOTE' # Title Content here. ENDNOTE ``` ## Append to a Note ```bash VAULT="${OBSIDIAN_VAULT_PATH:-$HOME/Documents/Obsidian Vault}" echo " New content here." >> "$VAULT/Existing Note.md" ``` ## Wikilinks Obsidian links notes with `[[Note Name]]` syntax. When creating notes, use these to link related content. ## Git-Tracked Vaults For multi-machine or agent-assisted workflows, a strong default is to treat the vault as a private git repo. Recommended pattern: - keep the vault in a private repo - pull before automated edits if multiple machines/jobs may write - commit meaningful ingestion batches - optionally combine with Obsidian Git or Obsidian Sync for local devices This works especially well with `llm-wiki` and scheduled Hermes jobs. ## Remote / VPS Access Options If the vault lives on a VPS, there are three main access patterns. ### 1) Recommended: local Obsidian, remote vault sync Best UX and lowest operational risk: - keep the vault on the VPS as plain markdown/git - sync it to your laptop/phone via git or Obsidian Sync - open it in native Obsidian locally Use this when you want the full Obsidian experience without remote desktop complexity. ### 2) Browser-accessible full Obsidian UI If you specifically need the *actual* Obsidian desktop UI at a URL, the practical server pattern is: - Obsidian desktop app running on the VPS - `Xvfb` for a headless X display - `x11vnc` to expose that display on localhost - `noVNC` as the browser client - nginx reverse proxy + auth in front Concrete VPS deployment proven on Alex's box: - internal display: `:88` - internal VNC: `127.0.0.1:5988` - internal noVNC: `127.0.0.1:6088` - public URL: `https://obsidian.apps.poofc.com` - nginx behavior: `/` should redirect to `/vnc.html?autoconnect=1&resize=remote` - systemd user services: - `obsidian-xvfb.service` - `obsidian-openbox.service` - `obsidian-x11vnc.service` - `obsidian-novnc.service` - `obsidian-app.service` - vault root: `/home/avalon/obsidian-vaults/` Useful checks: ```bash systemctl --user status obsidian-xvfb obsidian-openbox obsidian-x11vnc obsidian-novnc obsidian-app curl -I -u admin:*** https://obsidian.apps.poofc.com/ curl -I -u admin:*** https://obsidian.apps.poofc.com/vnc.html curl -I http://127.0.0.1:6088/ curl -I http://127.0.0.1:6088/vnc.html ss -tlnp | grep -E ':5988|:6088' ``` High-level stack: ```text Obsidian AppImage -> Xvfb :99 -> x11vnc or xpra -> noVNC/websockify -> nginx https://notes.example.com ``` This is feasible, but heavier than local sync. Use it only if the user explicitly wants the real Obsidian UI in-browser. ### 3) Published vault, not full Obsidian If the goal is mainly viewing/searching notes from a URL, publish the markdown with a static or lightweight web layer instead of remote-desktoping Obsidian. This is the preferred answer when Alex says the noVNC/desktop route feels clunky or old-school, especially if the desired feature is the graph viewer. Strong default: **Quartz** - Open-source Quartz transforms Obsidian-style Markdown vaults into a browser-native knowledge site. - Supports Obsidian-flavored Markdown, backlinks, search, and graph view. - Good self-hosted replacement for `noVNC -> Linux desktop -> Obsidian` when the route should feel like a web app. - Use Obsidian as the local/editor file format, not as the hosted UI. Alternatives: - Logseq if the user wants a different open-source knowledge product/workflow, but clean self-hosted web deployment can still be awkward. - Foam is more VS Code workflow than clean web UI. - Custom app-specific graph viewer if editing/mobile/Hermes-native features matter more than quick setup. ### Proven Quartz deployment pattern on Alex's VPS Concrete deployment from the Obsidian/noVNC replacement session: - App path: `/home/avalon/apps/obsidian-quartz` - Public URL: `https://obsidian.apps.poofc.com` - Quartz server port: `4022` - Source vaults: `/home/avalon/obsidian-vaults/main`, `astrology-wiki`, `ai-coding-wiki` - PM2 processes: - `obsidian-quartz`: lightweight Node static server serving Quartz `public/` - `obsidian-quartz-sync`: periodic sync/build loop that copies source vaults into Quartz `content/` and rebuilds only when vault source hash changes - Nginx: keep basic auth; proxy `obsidian.apps.poofc.com` to `127.0.0.1:4022`; remove the old `/ -> /vnc.html?autoconnect=1&resize=remote` redirect. Important implementation details: 1. Copy source vaults into Quartz `content/`; do not point Quartz directly at mutable production vaults if you want a safe build boundary. 2. Generate a root `content/index.md` linking vault indexes, e.g. `[[ai-coding-wiki/index|Ai Coding Wiki]]`. 3. Set `quartz.config.ts`: - `pageTitle: "Poof Obsidian Graph"` - `baseUrl: "obsidian.apps.poofc.com"` - `analytics: null` - ignore `.obsidian` and `.git` 4. Remove default Quartz footer links in `quartz.layout.ts` if this should feel like Alex's app, not Quartz docs. 5. Disable `Plugin.CustomOgImages()` on the VPS unless explicitly needed — it made a tiny ~20-note build take ~9 minutes; with it disabled, the build took seconds. 6. Prefer a static server for `public/` over `quartz build --serve --watch` in production. The Quartz dev server can hang curls and spawns websocket/watch behavior that is unnecessary behind nginx. 7. If serving Quartz with a custom/static Node server, support Quartz's extensionless note routes. Quartz emits note pages as `some/path.html`, while internal links and user-facing URLs are often `/some/path`. Resolve `path.html` before falling back to `path/index.html`; otherwise notes exist in `public/` but deep links 404. 8. For multi-vault/wiki indexes, surface newly ingested raw/source records directly in the vault `index.md`, not only via query/entity pages. If the first pass only saved provenance/transcripts and did not synthesize concept/comparison notes, state that explicitly so the hosted vault doesn't look empty or misleading. 9. Use a hash/state file for the vault sync loop so it does not rewrite `content/` every minute; otherwise Quartz watch/dev server can repeatedly rebuild. Verification checklist: ```bash cd /home/avalon/apps/obsidian-quartz ./scripts/sync-vaults.py npx quartz build -d content -o public curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:4022/ curl -s -o /dev/null -w '%{http_code}\n' -u admin:SecurePass123! https://obsidian.apps.poofc.com/ curl -s -o /dev/null -w '%{http_code}\n' https://obsidian.apps.poofc.com/ # should be 401 while basic auth is enabled ``` Reference: `references/alex-quartz-vps.md` captures session-specific deployment details, the direct SNI/socket verification snippet for when public curl hangs, Prettier ignore details for deployment scripts, and the GitHub workflow-token push pitfall. Reference: `references/quartz-static-routing.md` captures the custom static-server pitfall where Quartz-generated `path.html` note pages 404 at extensionless `/path` URLs unless the server tries `${file}.html` before `index.html` fallback. ## Recommendation Order For VPS deployments, prefer: 1. **local Obsidian + sync** for full native editing UX 2. **Quartz / published markdown graph site** for browser-native viewing/searching/graphing 3. **custom graph viewer** if Alex wants mobile-first editing or Hermes-native graph features 4. **noVNC/xpra-hosted Obsidian UI** only as fallback/emergency when the true desktop UI is required ## Common Pitfalls 1. **Treating Obsidian as the database.** The real source of truth is the markdown files. 2. **Hosting the GUI when sync would do.** Remote GUI adds CPU, RAM, auth, and reliability overhead. 3. **Forgetting auth in front of remote UI.** If exposing Obsidian through a browser, always put it behind HTTPS and auth. 4. **Proxying noVNC root directly and expecting the UI.** `http://127.0.0.1:6088/` often returns a directory listing from the web root rather than the actual client. If the public URL shows `Directory Listing for /`, nginx is healthy but the entry route is wrong; add an nginx redirect from `/` to `/vnc.html?autoconnect=1&resize=remote` and verify both `/` and `/vnc.html` with `curl -I`. 5. **Quartz note routes can exist on disk but 404 in the browser.** If `public/foo/bar.html` exists but `/foo/bar` returns 404, the static server is resolving extensionless routes incorrectly. Patch the server to try `${file}.html` before `file/index.html`, restart PM2, and verify several deep note URLs with authenticated public curls. 6. **A populated vault can look empty if raw ingests are only in folders.** After automated ingestion, update the human-facing index with direct links to raw/source records and a note about what has/has not been synthesized. Users judge the hosted vault by navigability, not only by file existence. 7. **Using a vault path with spaces without quoting it.** This breaks shell commands constantly.