Files
hermes-agent/website/docs/guides/migrate-from-openclaw.md
Teknium a347921314 docs: comprehensive OpenClaw migration guide (#3900)
New standalone guide at guides/migrate-from-openclaw.md with:
- Complete config key mapping tables for every category
- Agent behavior mappings (thinkingDefault → reasoning_effort, etc.)
- Session reset policy mapping (session.reset vs resetTriggers)
- TTS dual-source explanation (messages.tts.providers + talk config)
- MCP server field-by-field mapping
- Messaging platform table with exact config paths and env vars
- API key resolution: 3 sources, priority order, supported targets
- SecretRef handling: plain strings, env templates, SecretRef objects
- Post-migration checklist (6 steps)
- Troubleshooting section
- Complete archived items table with recreation guidance

CLI commands reference condensed to summary + link to full guide.
Added to sidebar under Guides & Tutorials.
2026-03-29 23:58:12 -07:00

13 KiB
Raw Blame History

sidebar_position, title, description
sidebar_position title description
7 Migrate from OpenClaw Complete guide to migrating your OpenClaw / Clawdbot setup to Hermes Agent — what gets migrated, how config maps, and what to check after.

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 what would happen (no files changed)
hermes claw migrate --dry-run

# Run the migration (secrets excluded by default)
hermes claw migrate

# Full migration including API keys
hermes claw migrate --preset full

The migration reads from ~/.openclaw/ by default. If you still have a legacy ~/.clawdbot/ or ~/.moldbot/ directory, it's detected automatically. Same for legacy config filenames (clawdbot.json, moldbot.json).

Options

Option Description
--dry-run Preview what would be migrated without writing anything.
--preset <name> full (default, includes secrets) or user-data (excludes API keys).
--overwrite Overwrite existing Hermes files on conflicts (default: skip).
--migrate-secrets Include 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.
--yes Skip confirmation prompt.

What gets migrated

Persona, memory, and instructions

What OpenClaw source Hermes destination Notes
Persona workspace/SOUL.md ~/.hermes/SOUL.md Direct copy
Workspace instructions workspace/AGENTS.md AGENTS.md in --workspace-target Requires --workspace-target flag
Long-term memory workspace/MEMORY.md ~/.hermes/memories/MEMORY.md Parsed into entries, merged with existing, deduped. Uses § delimiter.
User profile workspace/USER.md ~/.hermes/memories/USER.md Same entry-merge logic as memory.
Daily memory files workspace/memory/*.md ~/.hermes/memories/MEMORY.md All daily files merged into main memory.

All workspace files also check workspace.default/ as a fallback path.

Skills (4 sources)

Source OpenClaw location Hermes destination
Workspace skills workspace/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 shared workspace/.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

What OpenClaw config path Hermes destination Notes
Default model agents.defaults.model config.yamlmodel Can be a string or {primary, fallbacks} object
Custom providers models.providers.* config.yamlcustom_providers Maps baseUrl, apiType ("openai"→"chat_completions", "anthropic"→"anthropic_messages")
Provider API keys models.providers.*.apiKey ~/.hermes/.env Requires --migrate-secrets. See API key resolution below.

Agent behavior

What OpenClaw config path Hermes config path Mapping
Max turns agents.defaults.timeoutSeconds agent.max_turns timeoutSeconds / 10, capped at 200
Verbose mode agents.defaults.verboseDefault agent.verbose "off" / "on" / "full"
Reasoning effort agents.defaults.thinkingDefault agent.reasoning_effort "always"/"high" → "high", "auto"/"medium" → "medium", "off"/"low"/"none"/"minimal" → "low"
Compression agents.defaults.compaction.mode compression.enabled "off" → false, anything else → true
Compression model agents.defaults.compaction.model compression.summary_model Direct string copy
Human delay agents.defaults.humanDelay.mode human_delay.mode "natural" / "custom" / "off"
Human delay timing agents.defaults.humanDelay.minMs / .maxMs human_delay.min_ms / .max_ms Direct copy
Timezone agents.defaults.userTimezone timezone Direct string copy
Exec timeout tools.exec.timeoutSec terminal.timeout Direct copy (field is timeoutSec, not timeout)
Docker sandbox agents.defaults.sandbox.backend terminal.backend "docker" → "docker"
Docker image agents.defaults.sandbox.docker.image terminal.docker_image Direct copy

Session reset policies

OpenClaw config path Hermes config path Notes
session.reset.mode session_reset.mode "daily", "idle", or both
session.reset.atHour session_reset.at_hour Hour (023) for daily reset
session.reset.idleMinutes session_reset.idle_minutes Minutes 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 field Hermes field Notes
mcp.servers.*.command mcp_servers.*.command Stdio transport
mcp.servers.*.args mcp_servers.*.args
mcp.servers.*.env mcp_servers.*.env
mcp.servers.*.cwd mcp_servers.*.cwd
mcp.servers.*.url mcp_servers.*.url HTTP/SSE transport
mcp.servers.*.tools.include mcp_servers.*.tools.include Tool filtering
mcp.servers.*.tools.exclude mcp_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)
What Hermes destination
Provider name config.yamltts.provider
ElevenLabs voice ID config.yamltts.elevenlabs.voice_id
ElevenLabs model ID config.yamltts.elevenlabs.model_id
OpenAI model config.yamltts.openai.model
OpenAI voice config.yamltts.openai.voice
Edge TTS voice config.yamltts.edge.voice
TTS assets ~/.hermes/tts/ (file copy)

Messaging platforms

Platform OpenClaw config path Hermes .env variable Notes
Telegram channels.telegram.botToken TELEGRAM_BOT_TOKEN Token can be string or SecretRef
Telegram credentials/telegram-default-allowFrom.json TELEGRAM_ALLOWED_USERS Comma-joined from allowFrom[] array
Discord channels.discord.token DISCORD_BOT_TOKEN
Discord channels.discord.allowFrom DISCORD_ALLOWED_USERS
Slack channels.slack.botToken SLACK_BOT_TOKEN
Slack channels.slack.appToken SLACK_APP_TOKEN
Slack channels.slack.allowFrom SLACK_ALLOWED_USERS
WhatsApp channels.whatsapp.allowFrom WHATSAPP_ALLOWED_USERS Auth via Baileys QR pairing (not a token)
Signal channels.signal.account SIGNAL_ACCOUNT
Signal channels.signal.httpUrl SIGNAL_HTTP_URL
Signal channels.signal.allowFrom SIGNAL_ALLOWED_USERS
Matrix channels.matrix.botToken MATRIX_ACCESS_TOKEN Via deep-channels migration
Mattermost channels.mattermost.botToken MATTERMOST_BOT_TOKEN Via deep-channels migration

Other config

What OpenClaw path Hermes path Notes
Approval mode approvals.exec.mode config.yamlapprovals.mode "auto"→"off", "always"→"manual", "smart"→"smart"
Command allowlist exec-approvals.json config.yamlcommand_allowlist Patterns merged and deduped
Browser CDP URL browser.cdpUrl config.yamlbrowser.cdp_url
Browser headless browser.headless config.yamlbrowser.headless
Brave search key tools.web.search.brave.apiKey .envBRAVE_API_KEY Requires --migrate-secrets
Gateway auth token gateway.auth.token .envHERMES_GATEWAY_TOKEN Requires --migrate-secrets
Working directory agents.defaults.workspace .envMESSAGING_CWD

Archived (no direct Hermes equivalent)

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

What Archive file How to recreate in Hermes
IDENTITY.md archive/workspace/IDENTITY.md Merge into SOUL.md
TOOLS.md archive/workspace/TOOLS.md Hermes has built-in tool instructions
HEARTBEAT.md archive/workspace/HEARTBEAT.md Use cron jobs for periodic tasks
BOOTSTRAP.md archive/workspace/BOOTSTRAP.md Use context files or skills
Cron jobs archive/cron-config.json Recreate with hermes cron create
Plugins archive/plugins-config.json See plugins guide
Hooks/webhooks archive/hooks-config.json Use hermes webhook or gateway hooks
Memory backend archive/memory-backend-config.json Configure via hermes honcho
Skills registry archive/skills-registry-config.json Use hermes skills config
UI/identity archive/ui-identity-config.json Use /skin command
Logging archive/logging-diagnostics-config.json Set in config.yaml logging section
Multi-agent list archive/agents-list.json Use Hermes profiles
Channel bindings archive/bindings.json Manual setup per platform
Complex channels archive/channels-deep-config.json Manual platform config

API key resolution

When --migrate-secrets is enabled, API keys are collected from three 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. Auth profiles~/.openclaw/agents/main/agent/auth-profiles.json (per-agent credentials)

Config values take priority. The .env fills any gaps. Auth profiles fill whatever remains.

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. SecretRef objects with source: "file" or source: "exec" can't be resolved automatically — those values must be added to Hermes manually after migration.

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. Verify API keys — run hermes status to check provider authentication.

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

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

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

Troubleshooting

"OpenClaw directory not found"

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

"No provider API keys found"

Keys might be in your .env file instead of openclaw.json. The migration checks both — make sure ~/.openclaw/.env exists and has the keys. If keys use source: "file" or source: "exec" SecretRefs, they can't be resolved automatically.

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.