Hermes
- Source: https://github.com/NousResearch/hermes-agent
- License: MIT
AI agent gateway with an OpenAI-compatible API and a live dashboard.
Recommended Workflow
| Tool | Use for |
|---|---|
| Hermes dashboard | Sessions, skills, and agent configuration |
| Open WebUI | Day-to-day conversations |
| decree routines | Work with nobody present — agent-task files the answer into workspace/ai/ |
Every surface points at the gateway (https://hermes-agent.<domain>/v1, HERMES_API_KEY as the
API key), so they share the same models, skills and memory.
Don't point a coding agent at the gateway to work on this repo. Hermes is itself an agent running
its own tool loop, and opencode's streaming parser rejects hermes' custom
event: hermes.tool.progress frames outright — see
Why not OpenCode. Edit the stack with a dedicated coding
agent on the host, against a frontier model. Hermes' agent work belongs where it works: in a
container, on workspace/.
Services
| Container | Purpose | Port |
|---|---|---|
| hermes-agent | Gateway API + dashboard | 8642 (API), 9119 (dashboard) — not published to the host; reach them through Caddy |
Architecture
hermes-agent is the long-running gateway. It exposes an OpenAI-compatible HTTP API on :8642 and a dashboard on :9119. Open WebUI connects to it over the internal exist network.
volumes/hermes_agent_data is bind-mounted at /opt/data for agent config, sessions, skills, and memory.
Profiles
With GATEWAY_MULTIPLEX_PROFILES=1 the gateway serves more than one agent from the same
container. The default profile answers at /v1; every other profile lives at /p/<name>/v1
with its own HERMES_HOME under /opt/data/profiles/<name>/, and therefore its own toolsets,
MCP servers and skills.
That separation is what makes routing affordable. A profile's system prompt carries a schema for every tool it owns — roughly 2.4 KB each — so the default profile's 21 tools cost about 17,000 tokens on every single call. A router that only has to pick a department needs no tools at all, so it runs at about 650 tokens: a 64x reduction on a decision made for every incoming message.
Each profile needs its own API_SERVER_KEY — one profile's key will not authenticate against
another, and an unknown profile name returns 404. ai/hermes/entrypoint.sh creates one profile
per directory in ai/hermes/profiles/ on every boot, reading each department's declared
description, toolsets and MCP servers out of its profile.yml. It is idempotent, so a restart
only fills in what is missing.
See Routing to Departments for how a message reaches the right one.
Model configuration
The model: block in config.yaml is kept in step with .env.shared — change EXIST_MODEL_CHAT
or the chat endpoint and the next ./existential.sh moves hermes with the rest of the stack.
That only applies while the block still points at a local model server (provider: custom and a
:11434 endpoint). Point it at Anthropic, OpenRouter or anything else and it becomes yours: every
line is left alone from then on, except context_length, which is a fact about how the model was
built rather than a preference.
Triggering automation
Hermes has no mount into automation/ and shouldn't be given one — decree's
routine scripts are read-only from inside the daemon on purpose. If a task
calls for running a decree routine (now, or as a scheduled follow-up), the
supported path is workspace/outbox/, which Hermes already has file access
to: see Triggering decree from workspace/.
agent-task, which is what answers most Hermes-routed work, already tells the
model this in its system prompt.
Authentication
HERMES_API_KEY in ai/hermes/.env.exist is the shared secret for the gateway. It is the gateway's API_SERVER_KEY; Open WebUI sends it as OPENAI_API_KEY.
Upgrading
docker compose pull && docker compose up -d
hermes_agent_data (mounted at /opt/data) is a host bind mount, not a Docker-managed
volume — there's nothing to docker volume rm. The entrypoint's provisioning is idempotent
and re-runs on every start, so a fresh image is picked up on the next restart with no manual
cache-clearing step.
Debugging
docker compose logs hermes-agent