Skip to content

OpenClaw + Hermes: Multi-Agent Infrastructure

Connect OpenClaw (Clawdia) to Hermes Agent for delegating infrastructure tasks via HTTP API. This lets you manage Docker, Kubernetes, and GitOps operations through conversational commands.

  • When to use multi-agent architecture for infrastructure tasks
  • How to connect OpenClaw to Hermes via HTTP API
  • Configuring the Hermes integration skill
  • Querying Docker, deploying stacks, and managing GitOps
  • Security considerations for agent-to-agent communication

Running everything in one agent creates a security problem. Infrastructure tasks need terminal and Docker access—capabilities you don’t want tied to your general-purpose assistant.

Agent Scope Tools
OpenClaw (Clawdia) General tasks, user interaction Web search, Discord, skills
Hermes Infrastructure, GitOps Terminal, Docker, kubectl, Komodo API

Splitting these concerns means:

  • Hermes can have elevated host access while staying isolated
  • OpenClaw delegates infrastructure work through a controlled API
  • Each agent does what it’s designed for

Both agents run on the same host (openclaw-node01) and communicate over localhost.

┌─────────────────┐ HTTP API ┌─────────────────┐
│ OpenClaw │ ═══════════════════════► │ Hermes │
│ (Clawdia) │ localhost:8642 │ (SRE Agent) │
│ │ ◄═══════════════════════ │ │
│ - Skills │ JSON responses │ - Terminal │
│ - Memory │ │ - Docker │
│ - Subagents │ │ - Komodo API │
└─────────────────┘ │ - kubectl │
└─────────────────┘

Communication stays on 127.0.0.1:8642—no external exposure needed.

  • OpenClaw running (see Getting Started with OpenClaw)
  • Hermes Agent installed with GitOps configured
  • Python 3.10+ with httpx
  • Hermes API key (stored in 1Password or secrets manager)

Hermes exposes an OpenAI-compatible HTTP API that OpenClaw uses to delegate tasks.

Add to ~/.hermes/.env:

Terminal window
# Enable API server
API_SERVER_ENABLED=true
API_SERVER_KEY=${HSM_HERMES_API_KEY}
# Bind to localhost only
API_SERVER_HOST=127.0.0.1
API_SERVER_PORT=8642

Security: 127.0.0.1 restricts access to the local machine only. Hermes has full terminal access—don’t expose this port externally.

Via Komodo:

services:
hermes-api:
image: hermes-agent:latest
command: hermes gateway
env_file: ~/.hermes/.env
ports:
- "127.0.0.1:8642:8642" # Bind to localhost only
restart: unless-stopped

Or run directly:

Terminal window
hermes gateway
Terminal window
curl http://127.0.0.1:8642/health

Expected: {"status": "ok"}

The Hermes skill lives at ~/.openclaw/skills/hermes/.

Terminal window
# In ~/.openclaw/.env
export HERMES_API_KEY=$(op read op://OpenClaw/hermes-api/key)

The skill provides a Python client (hermes.py) and configuration (SKILL.md). Place the skill files in:

~/.openclaw/skills/hermes/
├── SKILL.md # Skill definition
├── hermes.py # Python client
└── README.md # Usage docs
Terminal window
openclaw gateway restart
from hermes import HermesClient
async def check_containers():
hermes = HermesClient()
result = await hermes.chat(
message="Run 'docker ps' and show running containers",
system_prompt="Execute commands and report results concisely."
)
print(result)
await hermes.close()

What happens:

  1. OpenClaw sends the request to Hermes via HTTP API
  2. Hermes executes docker ps using its terminal tool
  3. Results return formatted through the API

Hermes exposes these capabilities through the API:

Category Tools Use Case
Infrastructure terminal, process, file_read, file_write Run commands, manage files
Docker Via terminal Container lifecycle
GitOps delegate_task, skill_view Deploy stacks, manage repos
Observability web_search, web_extract Debug issues
State memory, todo Track tasks

For quick checks where you just need the answer:

result = await hermes.chat(
message="How much disk space is left on /var/lib/docker?",
system_prompt="Run 'df -h /var/lib/docker' and report the result."
)

Pattern 2: Stateful Multi-Turn Conversation

Section titled “Pattern 2: Stateful Multi-Turn Conversation”

For complex tasks requiring context:

from hermes import HermesSession
session = HermesSession(hermes, "postgres-deploy-001")
# First message establishes context
await session.send("I need to deploy a PostgreSQL database")
# Subsequent messages have full context
await session.send("Use the template from /opt/stacks/templates/postgres")
await session.send("Set the password from my secrets manager")
async for chunk in hermes.chat_stream("Deploy nextcloud stack"):
print(chunk, end="") # Live progress updates
class HermesClient:
def __init__(
self,
base_url: str = "http://127.0.0.1:8642",
api_key: Optional[str] = None,
timeout: float = 300.0 # 5 minutes for long operations
)
async def chat(
self,
message: str,
system_prompt: Optional[str] = None,
stream: bool = False
) -> str
async def chat_stream(
self,
message: str
) -> AsyncGenerator[str, None]
async def close(self)
from httpx import HTTPStatusError, ConnectError
try:
result = await hermes.chat("Deploy stack")
except ConnectError:
print("Hermes API not running. Start with: hermes gateway")
except HTTPStatusError as e:
if e.response.status_code == 401:
print("Invalid API key. Check HERMES_API_KEY")
else:
print(f"API error: {e}")
  • Store API_SERVER_KEY in 1Password or similar—never in code
  • Use environment variable injection, not hardcoded strings
  • Rotate keys periodically
  • Always bind to 127.0.0.1—never 0.0.0.0 or public interfaces
  • Both agents should run on the same trusted host
  • Consider firewall rules to block external access to port 8642

Remember: Hermes has full terminal access to your host. Be intentional about:

  • Which OpenClaw agents can invoke Hermes
  • What commands you’re delegating
  • Using read-only operations when possible for safety
Issue Cause Solution
Connection refused Hermes API not running Start with hermes gateway
401 Unauthorized Invalid API key Verify HERMES_API_KEY is set and matches Hermes config
Timeout errors Long-running command Increase timeout parameter in HermesClient (default 300s)
Import errors Missing dependencies Install httpx: pip install httpx

Error: NameError: name 'HAS_REQUESTS' is not defined

Cause: The client tries multiple HTTP libraries but doesn’t initialize fallback variables properly.

Fix: Initialize all flags before the try blocks:

# In hermes.py
HAS_HTTPX = False
HAS_REQUESTS = False
try:
import httpx
HAS_HTTPX = True
except ImportError:
pass
try:
import requests
HAS_REQUESTS = True
except ImportError:
pass
result = await hermes.chat(
message="Deploy the 'nextcloud' stack using Komodo. Ensure volumes are created first.",
system_prompt="You are a GitOps SRE. Use the Komodo API to deploy Docker Compose stacks."
)
result = await hermes.chat(
message="Check the status of pods in the monitoring namespace",
system_prompt="Use kubectl to get pod status and report any issues."
)
result = await hermes.chat(
message="Show me the last 50 lines of /var/log/syslog",
system_prompt="Read the file and display the content. Do not make changes."
)
  • Add specialized agents for other domains
  • Automate infrastructure checks with cron
  • Set up alerts for Hermes-reported issues
  • Document your own runbooks as delegatable tasks

Last updated: April 14, 2026

Have questions or feedback? Open an issue on the guides repository.