OpenClaw + Hermes: Multi-Agent Infrastructure

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

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.

What You’ll Learn

  • 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

Why Multi-Agent?

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.

AgentScopeTools
OpenClaw (Clawdia)General tasks, user interactionWeb search, Discord, skills
HermesInfrastructure, GitOpsTerminal, 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.

The Architecture

┌─────────────────┐         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.

Prerequisites

  • 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)

Step 1: Configure Hermes API Server

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

1.1 Configure Environment

Add to ~/.hermes/.env:

# 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.

1.2 Start the Server

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:

hermes gateway

1.3 Verify

curl http://127.0.0.1:8642/health

Expected: {"status": "ok"}

Step 2: Install the OpenClaw Skill

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

2.1 Set API Key

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

2.2 Skill Structure

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

2.3 Restart OpenClaw

openclaw gateway restart

Step 3: Test the Integration

Example: Check Docker Status

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

Available Tools

Hermes exposes these capabilities through the API:

CategoryToolsUse Case
Infrastructureterminal, process, file_read, file_writeRun commands, manage files
DockerVia terminalContainer lifecycle
GitOpsdelegate_task, skill_viewDeploy stacks, manage repos
Observabilityweb_search, web_extractDebug issues
Statememory, todoTrack tasks

Common Usage Patterns

Pattern 1: One-Shot Infrastructure Query

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

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")

Pattern 3: Stream Long Operations

async for chunk in hermes.chat_stream("Deploy nextcloud stack"):
    print(chunk, end="")  # Live progress updates

API Reference

HermesClient

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)

Error Handling

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}")

Security Best Practices

Authentication

  • Store API_SERVER_KEY in 1Password or similar—never in code
  • Use environment variable injection, not hardcoded strings
  • Rotate keys periodically

Network Security

  • 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

Scope of Access

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

Troubleshooting

IssueCauseSolution
Connection refusedHermes API not runningStart with hermes gateway
401 UnauthorizedInvalid API keyVerify HERMES_API_KEY is set and matches Hermes config
Timeout errorsLong-running commandIncrease timeout parameter in HermesClient (default 300s)
Import errorsMissing dependenciesInstall httpx: pip install httpx

Known Issue: Import Variable Not Defined

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

Real-World Examples

Deploy a Stack via Komodo

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."
)

Check Kubernetes Pod Status

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."
)

File Operations with Safety

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."
)

Next Steps

  • 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

Resources


Last updated: April 14, 2026

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