| name | hermes-multi-user |
| description | Set up and manage multiple Hermes Agent instances on a single machine โ separate HERMES_HOME directories, systemd services, WhatsApp/Slack routing, config version control, and a sync script for tracking changes. Use when adding a second user (family member, coworker, etc.) to your Hermes setup. |
| tags | ["hermes","multi-agent","multi-user","config","systemd","whatsapp"] |
Multi-User Hermes Setup
When to Use
- Adding a second (or third) Hermes user on the same machine
- Each user needs their own personality, memory, sessions, and conversation history
- Users connect via different WhatsApp numbers, Slack accounts, or Telegram chats
- You want to version-control configs without leaking secrets or bundled skills
Architecture
Each user gets their own HERMES_HOME directory. All instances share the same hermes-agent codebase but are completely isolated in terms of data:
~/.hermes/ # Primary user (default)
~/.hermes-<name>/ # Additional user
What each instance contains
~/.hermes-<name>/
config.yaml # Agent settings, model, toolsets, platform config
SOUL.md # Personality/persona
.env # API keys (copy from primary)
skills/ # Auto-populated with bundled skills on first run
memory/ # User-specific memory
sessions/ # Conversation history
cron/ # Scheduled jobs
logs/ # Runtime logs
whatsapp/session/ # WhatsApp pairing data (if applicable)
Step-by-Step Setup
1. Create the directory structure
NEW_USER="alice"
HERMES_NEW="$HOME/.hermes-$NEW_USER"
mkdir -p "$HERMES_NEW"/{memory,sessions,logs,cron,skills,whatsapp/session}
2. Copy API keys
cp ~/.hermes/.env "$HERMES_NEW/.env"
3. Create config.yaml
Start from your primary config and adjust:
_config_version: 10
agent:
max_turns: 200
reasoning_effort: medium
model:
default: anthropic/claude-sonnet-4.6
fallback: anthropic/claude-opus-4.6
provider: anthropic
platform_toolsets:
whatsapp:
- browser
- clarify
- code_execution
- cronjob
- delegation
- file
- image_gen
- memory
- session_search
- skills
- terminal
- todo
- tts
- vision
- web
terminal:
backend: docker
docker_image: nikolaik/python-nodejs:python3.11-nodejs20
container_cpu: 1
container_memory: 4096
container_disk: 51200
container_persistent: true
timeout: 180
platforms:
whatsapp:
extra:
bridge_port: 3001
session_path: /home/<your-username>/.hermes-<name>/whatsapp/session
4. Create SOUL.md
Write a personality file tailored to the new user:
You are a friendly, helpful AI assistant. You communicate clearly and warmly.
Keep responses concise since you're on WhatsApp โ no one wants to read
an essay in a chat bubble. Use plain language, avoid jargon unless asked.
5. Migrate or disable WhatsApp on primary (if applicable)
If the new user is taking over WhatsApp from your primary instance:
systemctl --user stop hermes-gateway
cp -r ~/.hermes/whatsapp/session/* "$HERMES_NEW/whatsapp/session/"
WHATSAPP_ENABLED=false
systemctl --user start hermes-gateway
If both users will have their own WhatsApp connections, skip the copy and just pair each one separately (step 8).
6. Create a systemd service
Save to ~/.config/systemd/user/hermes-<name>-gateway.service:
[Unit]
Description=Hermes Agent Gateway - <Name>'s Instance
After=network.target
StartLimitIntervalSec=600
StartLimitBurst=5
[Service]
Type=simple
ExecStart=<HERMES_VENV>/bin/python -m hermes_cli.main gateway run --replace
WorkingDirectory=<HERMES_AGENT_DIR>
Environment="PATH=<HERMES_VENV>/bin:<NODE_BIN>:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Environment="VIRTUAL_ENV=<HERMES_VENV>"
Environment="HERMES_HOME=<HERMES_NEW>"
Restart=on-failure
RestartSec=30
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=60
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=default.target
Replace the placeholders:
<HERMES_VENV> โ e.g. /home/you/.hermes/hermes-agent/venv
<HERMES_AGENT_DIR> โ e.g. /home/you/.hermes/hermes-agent
<NODE_BIN> โ output of dirname $(which node)
<HERMES_NEW> โ e.g. /home/you/.hermes-alice
<Name> โ e.g. Alice
Key point: HERMES_HOME points to the new user's directory, but WorkingDirectory points to the shared hermes-agent install.
7. Enable and start
systemctl --user daemon-reload
systemctl --user enable hermes-<name>-gateway
systemctl --user start hermes-<name>-gateway
8. Pair WhatsApp (if applicable)
systemctl --user stop hermes-<name>-gateway
HERMES_HOME=~/.hermes-<name> hermes whatsapp
Scan the QR code from the new user's phone. After pairing succeeds, start the service:
systemctl --user start hermes-<name>-gateway
The service is enabled, so it will auto-start on boot going forward โ this manual start is only needed after the initial pairing.
Important: WHATSAPP_ALLOWED_USERS in .env must use bare country+number format without a + prefix (e.g. 11234567890, not +11234567890).
CLI Access
The hermes command defaults to ~/.hermes. Override with HERMES_HOME:
HERMES_HOME=~/.hermes-alice hermes chat
alias hermes-alice='HERMES_HOME=~/.hermes-alice hermes'
hermes-alice chat
hermes-alice whatsapp
hermes-alice gateway status
Version Control Strategy
Track configs in git without secrets or bundled data:
What to track
config.yaml โ agent configuration
SOUL.md โ personality
cron/jobs.json โ scheduled jobs (strip runtime state)
- Custom skills only (not bundled ones)
What to exclude (.gitignore)
.env
*.env.*
whatsapp/
memory/
sessions/
logs/
cron/output/
.DS_Store
Detecting custom vs bundled skills
Hermes maintains skills/.bundled_manifest listing every bundled skill with a content hash. Any skill directory NOT in this manifest is custom (user-created):
from pathlib import Path
def get_custom_skills(hermes_home: Path) -> set[str]:
manifest = hermes_home / "skills" / ".bundled_manifest"
bundled = set()
if manifest.exists():
bundled = {l.split(":")[0] for l in manifest.read_text().splitlines() if ":" in l}
all_skills = {p.parent.name for p in (hermes_home / "skills").rglob("SKILL.md")}
return all_skills - bundled
Pitfalls
- WhatsApp port conflicts โ each agent using WhatsApp MUST have a different
bridge_port value, or they'll fail to bind
- Don't copy WhatsApp sessions between agents โ copied sessions go stale quickly. WhatsApp will show the device as "offline" even though the bridge health endpoint reports "connected". Always do a fresh pairing for each agent.
- Don't use
hermes gateway install if you have a custom service โ it creates a new service with a hash suffix that conflicts with your manually created one
- Don't symlink skills/ directories between agents โ skills created by one agent would bleed into the other
- Docker sandboxing recommended for secondary users โ prevents the agent from accessing the primary user's files or other system resources
- Session data is NOT shared โ each agent has completely independent memory, sessions, and conversation history
- API key costs are shared โ all instances use the same API keys from .env, so usage bills to the same account
- Restart after config changes โ
systemctl --user restart hermes-<name>-gateway to pick up config.yaml or .env changes
- Cron jobs for secondary agents โ the
cronjob tool only targets the primary agent. For secondary agents, write jobs directly to ~/.hermes-<name>/cron/jobs.json and restart the gateway
Verification
After setup, confirm everything is working:
systemctl --user status hermes-<name>-gateway
journalctl --user -u hermes-<name>-gateway -f
HERMES_HOME=~/.hermes-<name> hermes chat