Giving a Hermes agent real read/write access to an Obsidian vault on another machine (SMB → Linux VM → MCP)
If your Hermes agent runs on a different machine than your Obsidian vault, here’s a pattern that gives the agent full read/write access without sync layers, mirrors, or reconciliation. The vault stays exactly where Obsidian expects it, and Hermes reaches it through Hatchdoor’s embedded MCP server.
TL;DR
Obsidian runs on a desktop (Mac/Windows). A Linux VM mounts the vault over SMB and binds it into a Hatchdoor container as a local source. Hermes connects to Hatchdoor over MCP and gets full search/read/write/move/link/graph access. The one thing that will bite you: SMB change notifications are server‑dependent — macOS does not send them, so freshness comes from a timer.
Tested on macOS; the pattern should carry to Windows, but measure your own change‑notify behavior.
Architecture
Obsidian desktop ──SMB──▶ Linux VM ──bind──▶ Hatchdoor container (vault lives here) /mnt/obsidian-vault /data/smb-vault ▲ MCP :42824/mcp └── Hermes agent
Hatchdoor embeds an MCP server with ~35 tools (search, read, write, move, links, graph). Hermes sees the vault as just another MCP server entry (HTTP transport + bearer token). Writes via MCP appear instantly in Obsidian; deletes land in .hatchdoor-trash/.
Mount recipe (the part that matters)
On the machine holding the vault, export the folder over SMB. On the Linux VM, mount it:
//<your mac or windows machine>/Data /mnt/obsidian-vault cifs \ credentials=/etc/smb-credentials,uid=65532,gid=65532,noperm,\ file_mode=0770,dir_mode=0770,vers=3.0,soft,_netdev,nofail 0 0
Key details:
- credentials= — don’t put passwords on the command line.
- uid=65532,gid=65532,noperm,file_mode=0770 — ensures the container’s non‑root user can write; without noperm, everything shows up as root:root 755 and writes fail.
- soft,_netdev,nofail — if the desktop sleeps, the VM gets errors instead of hanging boot.
Then bind‑mount into the container and register the vault as:
{ type: "local", path: "/data/smb-vault" }
No reconciliation layer — the vault is the file tree.
The gotcha: SMB change notifications
Do not assume the Linux client will receive change events. It depends entirely on the SMB server.
On macOS, the answer is a hard no.
Measured:
- Recursive inotify watch across 253 vault directories
- Round of Obsidian edits
- Zero events
- A stat‑based rescan picked up new file sizes within ~4 seconds
This was cifs against SMB 3.0.
Windows shares do implement change notify, so you may get events there — but test it. Whatever you find, a poll you control is the safe default. I run a systemd timer that hits Hatchdoor’s refresh API every 5 minutes; it takes ~1 second across 708 notes.
Why not a sync‑based source?
I originally used rclone over WebDAV with a mirror and reconciliation. The SMB mount has been strictly simpler, so that path is retired. My Hatchdoor fork carries two fixes that make mounts behave cleanly:
renameat2(RENAME_EXCHANGE)fallback for filesystems that lack it- A slug guard so parallel PARA trees with duplicate basenames don’t abort the index build
Hermes operational notes
Two things worth knowing on the agent side:
- Writes are throttled. Hatchdoor re‑embeds the vault on write, so do writes serially. Never blind‑retry a timed‑out write — you’ll get “embedder not ready” and duplicate notes.
- A weekly cron job (vault‑maintenance skill) reads the graph for broken wikilinks and orphans, repairs only clear‑cut cases, and writes a JSON report another service ingests. That’s how 700+ notes stay honest without manual review.
Tested configuration
- Obsidian vault on a Mac Mini
- macOS SMB server
- Linux VM using cifs
vers=3.0 - Container running as uid 65532
- 708 notes
- Hatchdoor fork + deployment notes: https://github.com/rpmalouin/Hatchdoor (FORK.md and HERMES.md have the operational details)
Hatchdoor on my github, fully updated for doing this if you care to, I share my stuff but I don't maintain it for pull requests, you fork it, you maintain if for you.
https://i.redd.it/4ttgsxfeypph1.png
Source: r/hermesagent · by /u/PoppaBear1950
