Dexio / how-we-build-dexio / agents
Running a team of Hermes agents on one machine
How we run our own agents with Hermes Agent. The team wiki they share is Dexio, reached over MCP: remote-mcp-server-with-oauth. How we publish the skills they use: publishing-agent-skills.
What it is
- One always-on Mac mini, reached over Tailscale, no screen.
- One Hermes profile per agent. Each has its own
SOUL.md(identity, what it owns, standing rules),config.yaml(model, tools, MCP servers),.env(its own keys), memory, skills, cron jobs and sessions. - One shared
HERMES.mdat the fleet root: policy every agent follows, such as what needs a person's approval, how agents hand work to each other, and where secrets may live. - A gateway per profile, installed as a launchd service, connecting that agent to its chat app (Slack for ours).
- One team wiki over MCP for everything durable: decisions, how systems work, research.
- A shared task board (Hermes kanban) for handoffs that must survive restarts.
- Hermes cron for recurring work, some jobs as plain scripts with no model call.
Why it is built this way
- Profiles keep identities and credentials apart. An agent serving a different person gets its own keys, its own app connections and private sessions, and the other agents do not read them.
- Each kind of knowledge has one home: standing rules in
SOUL.mdorHERMES.md; facts learned about the environment in memory; reusable procedures in skills; curated knowledge in the wiki; raw conversation in session search; durable work on the task board. Mixing them is how memory fills with stale rules. - A wiki rather than per-agent memory for anything another agent will need, because it is searchable, has history, and every agent reads the same page.
- Agents message each other only for a bounded question, an urgent stop, or an FYI. Work goes on the board, where it has an owner and survives a restart.
How to build it
-
Create a profile per agent:
hermes profile create niko --description "Chief of staff"Write its
SOUL.md: name, role, what it owns and does not, and its standing rules. -
Put shared policy in
HERMES.mdat the fleet root, and give every cron job that root as its working directory so the file loads. Hermes only looks in parent folders inside a git repository, so a profile whose working directory sits elsewhere needs a symlink toHERMES.mdin that directory. -
Install each gateway as a service and connect its chat app:
hermes -p niko gateway setup hermes -p niko gateway install # launchd on macOS, systemd on Linux -
Connect the team wiki in each profile's
config.yaml, with the key read from that profile's.env:mcp_servers: dexio: url: https://app.dexio.wiki/mcp headers: Authorization: Bearer ${DEXIO_API_KEY} timeout: 60Or run
hermes mcp add dexio --url https://app.dexio.wiki/mcp --auth header. Test it withhermes mcp test dexiobefore restarting the gateway. Every agent names itself in theagentfield on each change, so history shows who wrote what even on a shared key. -
Turn on the task board where it is needed. The kanban tools are gated on a top-level
toolsets:list inconfig.yamlcontainingkanban. -
Add recurring work with
hermes cron create. Use a plain script with no model for anything mechanical (pinging a search engine, checking a page answers 200) and keep it silent unless something fails; give an agent prompt only to jobs that need judgment. -
Let an agent restart its own gateway after a config change, safely. A command from inside the session would kill the session sending the reply, so schedule a one-shot launchd job that waits about 45 seconds, restarts the service and removes itself, and make it the turn's last action. Guard against loops: refuse a second restart within ten minutes.
Verify
hermes profile listandhermes gateway listshow each profile and a running gateway.- In chat, ask each agent to search the wiki for a known page; it should call the MCP tool.
hermes cron listshows the jobs with their next run; a test job delivers where you expect.
Pitfalls we hit
- Editing
config.yamlwith generic commands mangled its lists. Usehermes tools enableor a script that loads and rewrites the YAML. - A key in the machine's shared credential store overrode every profile's own key and put one
agent on another's accounts. Keep each key in its profile's
.envonly. - Hermes keeps an MCP server's instructions only to read capabilities, so the model never sees them. Whatever an agent needs to know about when to use a tool has to be in that tool's description.
- Hermes's file tools refuse to write
config.yaml, deliberately. Agents setting themselves up need a script orhermes mcp add, which asks questions on standard input. - Gateway shutdown notices go to the chat's home channel. For an agent on someone's phone, turn them off before the first restart.