Source: ai-research/agentwikis-hermes-profiles-2026-06-12.md — compiled by Agent Wikis from official Hermes docs (install-and-setup.md + release-v0.6.0.md); sourced 2026-06-12. Feature introduced in v0.6.0. Open-vs-closed-profiles design pattern from raw/x-bookmarks-recent-digest-2026-06-17.md.

A profile is a fully isolated HERMES_HOME directory — its own config.yaml, .env, memories, sessions, skills, logs, cron jobs, and subprocess $HOME. Profiles let one machine run multiple Hermes “personas” in parallel without any shared state. The default profile is an alias for ~/.hermes/ itself; all existing installations already are a profile.

Key Takeaways

  • Full isolation — each profile gets its own memory, sessions, skills, cron jobs, and subprocess home directory; no state bleeds between profiles
  • Two concurrent gateways require two profiles — two gateways pointed at the same HERMES_HOME corrupt the SQLite database; this is what profiles solve
  • --clone vs --clone-all — clone copies config/keys/identity only; skills and sessions must be re-installed or copied separately; --clone-all copies everything
  • Wrapper scriptshermes profile create coder --clone writes ~/.local/bin/coder so you type coder chat instead of hermes -p coder chat
  • OpenClaw migrants — the profile model echoes OpenClaw’s named-account workflow; muscle memory carries over

Profile Structure

Each profile lives at ~/.hermes/profiles/<name>/ and contains the full Hermes home tree:

~/.hermes/profiles/<name>/
  config.yaml      # provider, model, backend, agent settings
  .env             # API keys, allowlists
  memories/        # MEMORY.md + USER.md + memory provider state
  sessions/        # SQLite + FTS5 session search index
  skills/          # installed skills
  skins/           # CLI skin overrides
  logs/            # gateway + agent logs
  cron/            # jobs.json + per-job output
  workspace/       # default working directory
  home/            # per-profile $HOME for subprocesses (npm, git, pip, etc.)

Profile name rules: ^[a-z0-9][a-z0-9_-]{0,63}$

Commands

CommandEffect
hermes profile listList all profiles; marks active
hermes profile create <name> [--clone|--clone-all] [--clone-from SRC] [--no-alias]Create profile + optional wrapper
hermes profile use <name>Set the permanent active profile
hermes profile show [<name>]Print profile metadata
hermes profile delete <name>Remove profile and wrapper
hermes profile rename <old> <new>Rename profile + wrapper
hermes profile export <name> archive.tar.gzArchive entire profile dir
hermes profile import archive.tar.gzRestore from archive

Ad-hoc per-command: hermes -p coder chat or hermes --profile=research gateway run

Clone Modes

ModeWhat’s Copied
No flagEmpty profile — runs hermes setup from scratch
--cloneconfig.yaml, .env, SOUL.md, MEMORY.md, USER.md from source profile (default = default)
--clone-allEntire profile tree (includes sessions, skills, cron, logs)
--clone-from SRCSame as --clone but from a named source other than default

When to Use

  • Different models per work streamcoder profile on a strong code model, assistant on a cheap chat model, research on a long-context model; each optimized separately
  • Per-client isolation — freelancers keeping each client’s allowlists, memory, and skills in a sealed home
  • Safe config experimentation — clone, edit, test; delete on failure without touching the working profile
  • Multiple gateways on one machine — each profile’s gateway is independent; coder can serve Slack while assistant serves Telegram simultaneously
  • Backup snapshotshermes profile export produces a tar.gz of an entire working configuration for offsite storage

Open vs Closed Profiles

A design-pattern framing from @shannholmberg (2026-06) for deciding how to scope a profile:

  • Open profile — an exploratory research agent with a broad toolset (web search, scrapers, transcription, doc parsing) and flexible output. Fast and serendipitous but token-hungry; best for one-off work.
  • Closed profile — one narrow job run repeatedly on a schedule and a normal budget, given the same scaffolding a human jobholder would get: context/data, a clear definition of “good”, allowed-vs-forbidden tools, a check at each step with human sign-off before shipping, and memory so each run sharpens the next. It compounds because the exact setup is saved and re-run rather than rebuilt each time.

Pitfalls

  • PATH name collision — if a binary with the profile name already exists in PATH, wrapper creation fails silently; use --no-alias and call via hermes -p <name>
  • default is special — it points at ~/.hermes/ itself, not ~/.hermes/profiles/default/; cannot be deleted or renamed
  • --clone is config-only — skills and sessions are NOT copied; re-install or use --clone-all if you need them
  • Two gateways, one HERMES_HOME — always use different profiles; shared SQLite will corrupt under concurrent writes
  • Cron jobs are per-profile — a job created in default won’t fire when only the coder gateway is running
  • Per-profile $HOME — useful for isolation but first-run tool downloads (npm, pip, etc.) per new profile may be slow
  • Export/import skips OS keychain credentials — portable secrets belong in .env, not the keychain

Try It

# Create a coding-focused profile cloning current config
hermes profile create coder --clone
# Now "coder" is a shortcut: coder chat, coder gateway run, etc.
 
# Create a fresh research profile on a different model
hermes profile create research
# Then hermes setup to configure provider + model for this profile
 
# Run two gateways simultaneously
hermes gateway run &           # default profile → Telegram
hermes -p coder gateway run &  # coder profile → Slack
 
# Export a profile before destructive changes
hermes profile export default ~/backups/hermes-default-$(date +%Y%m%d).tar.gz

Field report — a real multi-profile deployment

[Reddit signal — r/hermesagent 2026-06-18] Source: raw/reddit-1u9fa2w.md (u/riceinmybelly, 165 score / 58 comments). An involved single-operator Hermes deployment on an Apple Silicon Mac (Docker) running four active profiles — local-admin (orchestrator: Telegram, crons, dispatch), coder, planner, qa-tester — plus a shared repository profile that is just a skills directory. Non-obvious patterns worth stealing:

  • Dual bind-mount of profiles/. Because HERMES_HOME=/opt/data/.hermes but the shared-skill symlinks hardcode /opt/data/profiles, the host profiles/ dir is bind-mounted twice (once via the .hermes mount, once directly at /opt/data/profiles) so the ~40-50 per-profile skill symlinks resolve. Without the second mount every shared-skill symlink breaks.
  • Shared skill repository + whitelist. Each profile’s skills/ holds symlinks into a shared repository/skills/; a patched skill_utils.py adds a skills: include: [...] whitelist so a profile loads only the listed skills instead of all of them (otherwise the system prompt bloats badly). This shares skills across profiles without duplicating them — a complement to the per-profile isolation above.
  • Custom dispatcher hook. The built-in dispatcher is disabled (max_spawn: 0) and replaced by a 60-second asyncio handler.py under hooks/per-profile-dispatcher/ that promotes tasks, reaps stalled workers (heartbeat-stale 15 min, max runtime 4 h), dispatches one task per idle profile, and diffs state so Telegram only pings on a real change.
  • Patch overlay for upstream bugs. Eight Python files in patches/ are bind-mounted read-only over /opt/hermes/ to fix v0.15.1 issues at scale (e.g. a virtiofs-on-macOS lock-file unlink breaking get_running_pid() on restart, a WAL/SHM crash on startup, plus the skills whitelist above).

Single-operator field report — treat as one validated configuration, not official guidance. ^[extracted]