Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help


Migrate from OpenClaw

hermes claw migrate imports your OpenClaw (or legacy Clawdbot/Moldbot) setup into Hermes. This guide covers exactly what gets migrated, the config key mappings, and what to verify after migration.

Quick start

# Preview then migrate (always shows a preview first, then asks to confirm)
hermes claw migrate

# Preview only, no changes
hermes claw migrate --dry-run

# Full migration including API keys, skip confirmation
hermes claw migrate --preset full --yes

The migration always shows a full preview of what will be imported before making any changes. Review the list, then confirm to proceed.

Reads from ~/.openclaw/ by default. Legacy ~/.clawdbot/ or ~/.moltbot/ directories are detected automatically. Same for legacy config filenames (clawdbot.json, moltbot.json).

Options

OptionDescription
--dry-runPreview only — stop after showing what would be migrated.
--preset <name>full (default, includes secrets) or user-data (excludes API keys).
--overwriteOverwrite existing Hermes files on conflicts (default: skip).
--migrate-secretsInclude API keys (on by default with --preset full).
--source <path>Custom OpenClaw directory.
--workspace-target <path>Where to place AGENTS.md.
--skill-conflict <mode>skip (default), overwrite, or rename.
--yesSkip the confirmation prompt after preview.

What gets migrated

Persona, memory, and instructions

WhatOpenClaw sourceHermes destinationNotes
Personaworkspace/SOUL.md~/.hermes/SOUL.mdDirect copy
Workspace instructionsworkspace/AGENTS.mdAGENTS.md in --workspace-targetRequires --workspace-target flag
Long-term memoryworkspace/MEMORY.md~/.hermes/memories/MEMORY.mdParsed into entries, merged with existing, deduped. Uses § delimiter.
User profileworkspace/USER.md~/.hermes/memories/USER.mdSame entry-merge logic as memory.
Daily memory filesworkspace/memory/*.md~/.hermes/memories/MEMORY.mdAll daily files merged into main memory.

Workspace files are also checked at workspace.default/ and workspace-main/ as fallback paths (OpenClaw renamed workspace/ to workspace-main/ in recent versions, and uses workspace-{agentId} for multi-agent setups).

Skills (4 sources)

SourceOpenClaw locationHermes destination
Workspace skillsworkspace/skills/~/.hermes/skills/openclaw-imports/
Managed/shared skills~/.openclaw/skills/~/.hermes/skills/openclaw-imports/
Personal cross-project~/.agents/skills/~/.hermes/skills/openclaw-imports/
Project-level sharedworkspace/.agents/skills/~/.hermes/skills/openclaw-imports/

Skill conflicts are handled by --skill-conflict: skip leaves the existing Hermes skill, overwrite replaces it, rename creates a -imported copy.

Model and provider configuration

WhatOpenClaw config pathHermes destinationNotes
Default modelagents.defaults.modelconfig.yamlmodelCan be a string or {primary, fallbacks} object
Custom providersmodels.providers.*config.yamlcustom_providersMaps baseUrl, apiType/api — handles both short (“openai”, “anthropic”) and hyphenated (“openai-completions”, “anthropic-messages”, “google-generative-ai”) values
Provider API keysmodels.providers.*.apiKey~/.hermes/.envRequires --migrate-secrets. See API key resolution below.

Agent behavior

WhatOpenClaw config pathHermes config pathMapping
Max turnsagents.defaults.timeoutSecondsagent.max_turnstimeoutSeconds / 10, capped at 200
Verbose modeagents.defaults.verboseDefaultagent.verbose“off” / “on” / “full”
Reasoning effortagents.defaults.thinkingDefaultagent.reasoning_effort“always”/“high”/“xhigh” → “high”, “auto”/“medium”/“adaptive” → “medium”, “off”/“low”/“none”/“minimal” → “low”
Compressionagents.defaults.compaction.modecompression.enabled“off” → false, anything else → true
Compression modelagents.defaults.compaction.modelcompression.summary_modelDirect string copy
Human delayagents.defaults.humanDelay.modehuman_delay.mode“natural” / “custom” / “off”
Human delay timingagents.defaults.humanDelay.minMs / .maxMshuman_delay.min_ms / .max_msDirect copy
Timezoneagents.defaults.userTimezonetimezoneDirect string copy
Exec timeouttools.exec.timeoutSecterminal.timeoutDirect copy (field is timeoutSec, not timeout)
Docker sandboxagents.defaults.sandbox.backendterminal.backend“docker” → “docker”
Docker imageagents.defaults.sandbox.docker.imageterminal.docker_imageDirect copy

Session reset policies

OpenClaw config pathHermes config pathNotes
session.reset.modesession_reset.mode“daily”, “idle”, or both
session.reset.atHoursession_reset.at_hourHour (0–23) for daily reset
session.reset.idleMinutessession_reset.idle_minutesMinutes of inactivity

Note: OpenClaw also has session.resetTriggers (a simple string array like ["daily", "idle"]). If the structured session.reset isn’t present, the migration falls back to inferring from resetTriggers.

MCP servers

OpenClaw fieldHermes fieldNotes
mcp.servers.*.commandmcp_servers.*.commandStdio transport
mcp.servers.*.argsmcp_servers.*.args
mcp.servers.*.envmcp_servers.*.env
mcp.servers.*.cwdmcp_servers.*.cwd
mcp.servers.*.urlmcp_servers.*.urlHTTP/SSE transport
mcp.servers.*.tools.includemcp_servers.*.tools.includeTool filtering
mcp.servers.*.tools.excludemcp_servers.*.tools.exclude

TTS (text-to-speech)

TTS settings are read from two OpenClaw config locations with this priority:

  1. messages.tts.providers.{provider}.* (canonical location)
  2. Top-level talk.providers.{provider}.* (fallback)
  3. Legacy flat keys messages.tts.{provider}.* (oldest format)
WhatHermes destination
Provider nameconfig.yamltts.provider
ElevenLabs voice IDconfig.yamltts.elevenlabs.voice_id
ElevenLabs model IDconfig.yamltts.elevenlabs.model_id
OpenAI modelconfig.yamltts.openai.model
OpenAI voiceconfig.yamltts.openai.voice
Edge TTS voiceconfig.yamltts.edge.voice (OpenClaw renamed “edge” to “microsoft” — both are recognized)
TTS assets~/.hermes/tts/ (file copy)

Messaging platforms

PlatformOpenClaw config pathHermes .env variableNotes
Telegramchannels.telegram.botToken or .accounts.default.botTokenTELEGRAM_BOT_TOKENToken can be string or SecretRef. Both flat and accounts layout supported.
Telegramcredentials/telegram-default-allowFrom.jsonTELEGRAM_ALLOWED_USERSComma-joined from allowFrom[] array
Discordchannels.discord.token or .accounts.default.tokenDISCORD_BOT_TOKEN
Discordchannels.discord.allowFrom or .accounts.default.allowFromDISCORD_ALLOWED_USERS
Slackchannels.slack.botToken or .accounts.default.botTokenSLACK_BOT_TOKEN
Slackchannels.slack.appToken or .accounts.default.appTokenSLACK_APP_TOKEN
Slackchannels.slack.allowFrom or .accounts.default.allowFromSLACK_ALLOWED_USERS
WhatsAppchannels.whatsapp.allowFrom or .accounts.default.allowFromWHATSAPP_ALLOWED_USERSAuth via Baileys QR pairing — requires re-pairing after migration
Signalchannels.signal.account or .accounts.default.accountSIGNAL_ACCOUNT
Signalchannels.signal.httpUrl or .accounts.default.httpUrlSIGNAL_HTTP_URL
Signalchannels.signal.allowFrom or .accounts.default.allowFromSIGNAL_ALLOWED_USERS
Matrixchannels.matrix.accessToken or .accounts.default.accessTokenMATRIX_ACCESS_TOKENUses accessToken (not botToken)
Mattermostchannels.mattermost.botToken or .accounts.default.botTokenMATTERMOST_BOT_TOKEN

Other config

WhatOpenClaw pathHermes pathNotes
Approval modeapprovals.exec.modeconfig.yamlapprovals.mode“auto”→“off”, “always”→“manual”, “smart”→“smart”
Command allowlistexec-approvals.jsonconfig.yamlcommand_allowlistPatterns merged and deduped
Browser CDP URLbrowser.cdpUrlconfig.yamlbrowser.cdp_url
Browser headlessbrowser.headlessconfig.yamlbrowser.headless
Brave search keytools.web.search.brave.apiKey.envBRAVE_API_KEYRequires --migrate-secrets
Gateway auth tokengateway.auth.token.envHERMES_GATEWAY_TOKENRequires --migrate-secrets
Working directoryagents.defaults.workspace.envMESSAGING_CWD

Archived (no direct Hermes equivalent)

These are saved to ~/.hermes/migration/openclaw/<timestamp>/archive/ for manual review:

WhatArchive fileHow to recreate in Hermes
IDENTITY.mdarchive/workspace/IDENTITY.mdMerge into SOUL.md
TOOLS.mdarchive/workspace/TOOLS.mdHermes has built-in tool instructions
HEARTBEAT.mdarchive/workspace/HEARTBEAT.mdUse cron jobs for periodic tasks
BOOTSTRAP.mdarchive/workspace/BOOTSTRAP.mdUse context files or skills
Cron jobsarchive/cron-config.jsonRecreate with hermes cron create
Pluginsarchive/plugins-config.jsonSee plugins guide
Hooks/webhooksarchive/hooks-config.jsonUse hermes webhook or gateway hooks
Memory backendarchive/memory-backend-config.jsonConfigure via hermes honcho
Skills registryarchive/skills-registry-config.jsonUse hermes skills config
UI/identityarchive/ui-identity-config.jsonUse /skin command
Loggingarchive/logging-diagnostics-config.jsonSet in config.yaml logging section
Multi-agent listarchive/agents-list.jsonUse Hermes profiles
Channel bindingsarchive/bindings.jsonManual setup per platform
Complex channelsarchive/channels-deep-config.jsonManual platform config

API key resolution

When --migrate-secrets is enabled, API keys are collected from four sources in priority order:

  1. Config valuesmodels.providers.*.apiKey and TTS provider keys in openclaw.json
  2. Environment file~/.openclaw/.env (keys like OPENROUTER_API_KEY, ANTHROPIC_API_KEY, etc.)
  3. Config env sub-objectopenclaw.json"env" or "env"."vars" (some setups store keys here instead of a separate .env file)
  4. Auth profiles~/.openclaw/agents/main/agent/auth-profiles.json (per-agent credentials)

Config values take priority. Each subsequent source fills any remaining gaps.

Supported key targets

OPENROUTER_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY, DEEPSEEK_API_KEY, GEMINI_API_KEY, ZAI_API_KEY, MINIMAX_API_KEY, ELEVENLABS_API_KEY, TELEGRAM_BOT_TOKEN, VOICE_TOOLS_OPENAI_KEY

Keys not in this allowlist are never copied.

SecretRef handling

OpenClaw config values for tokens and API keys can be in three formats:

// Plain string
"channels": { "telegram": { "botToken": "123456:ABC-DEF..." } }

// Environment template
"channels": { "telegram": { "botToken": "${TELEGRAM_BOT_TOKEN}" } }

// SecretRef object
"channels": { "telegram": { "botToken": { "source": "env", "id": "TELEGRAM_BOT_TOKEN" } } }

The migration resolves all three formats. For env templates and SecretRef objects with source: "env", it looks up the value in ~/.openclaw/.env and the openclaw.json env sub-object. SecretRef objects with source: "file" or source: "exec" can’t be resolved automatically — the migration warns about these, and those values must be added to Hermes manually via hermes config set.

After migration

  1. Check the migration report — printed on completion with counts of migrated, skipped, and conflicting items.

  2. Review archived files — anything in ~/.hermes/migration/openclaw/<timestamp>/archive/ needs manual attention.

  3. Start a new session — imported skills and memory entries take effect in new sessions, not the current one.

  4. Verify API keys — run hermes status to check provider authentication.

  5. Test messaging — if you migrated platform tokens, restart the gateway: systemctl --user restart hermes-gateway

  6. Check session policies — verify hermes config get session_reset matches your expectations.

  7. Re-pair WhatsApp — WhatsApp uses QR code pairing (Baileys), not token migration. Run hermes whatsapp to pair.

  8. Archive cleanup — after confirming everything works, run hermes claw cleanup to rename leftover OpenClaw directories to .pre-migration/ (prevents state confusion).

Troubleshooting

“OpenClaw directory not found”

The migration checks ~/.openclaw/, then ~/.clawdbot/, then ~/.moltbot/. If your installation is elsewhere, use --source /path/to/your/openclaw.

“No provider API keys found”

Keys might be stored in several places depending on your OpenClaw version: inline in openclaw.json under models.providers.*.apiKey, in ~/.openclaw/.env, in the openclaw.json "env" sub-object, or in agents/main/agent/auth-profiles.json. The migration checks all four. If keys use source: "file" or source: "exec" SecretRefs, they can’t be resolved automatically — add them via hermes config set.

Skills not appearing after migration

Imported skills land in ~/.hermes/skills/openclaw-imports/. Start a new session for them to take effect, or run /skills to verify they’re loaded.

TTS voice not migrated

OpenClaw stores TTS settings in two places: messages.tts.providers.* and the top-level talk config. The migration checks both. If your voice ID was set via the OpenClaw UI (stored in a different path), you may need to set it manually: hermes config set tts.elevenlabs.voice_id YOUR_VOICE_ID.