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.
What You’ll Learn
Section titled “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?
Section titled “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.
| 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.
The Architecture
Section titled “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
Section titled “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
Section titled “Step 1: Configure Hermes API Server”Hermes exposes an OpenAI-compatible HTTP API that OpenClaw uses to delegate tasks.
1.1 Configure Environment
Section titled “1.1 Configure Environment”Add to ~/.hermes/.env:
# Enable API serverAPI_SERVER_ENABLED=trueAPI_SERVER_KEY=${HSM_HERMES_API_KEY}
# Bind to localhost onlyAPI_SERVER_HOST=127.0.0.1API_SERVER_PORT=8642Security:
127.0.0.1restricts access to the local machine only. Hermes has full terminal access—don’t expose this port externally.
1.2 Start the Server
Section titled “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-stoppedOr run directly:
hermes gateway1.3 Verify
Section titled “1.3 Verify”curl http://127.0.0.1:8642/healthExpected: {"status": "ok"}
Step 2: Install the OpenClaw Skill
Section titled “Step 2: Install the OpenClaw Skill”The Hermes skill lives at ~/.openclaw/skills/hermes/.
2.1 Set API Key
Section titled “2.1 Set API Key”# In ~/.openclaw/.envexport HERMES_API_KEY=$(op read op://OpenClaw/hermes-api/key)2.2 Skill Structure
Section titled “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 docs2.3 Restart OpenClaw
Section titled “2.3 Restart OpenClaw”openclaw gateway restartStep 3: Test the Integration
Section titled “Step 3: Test the Integration”Example: Check Docker Status
Section titled “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:
- OpenClaw sends the request to Hermes via HTTP API
- Hermes executes
docker psusing its terminal tool - Results return formatted through the API
Available Tools
Section titled “Available Tools”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 |
Common Usage Patterns
Section titled “Common Usage Patterns”Pattern 1: One-Shot Infrastructure Query
Section titled “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
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 contextawait session.send("I need to deploy a PostgreSQL database")
# Subsequent messages have full contextawait 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
Section titled “Pattern 3: Stream Long Operations”async for chunk in hermes.chat_stream("Deploy nextcloud stack"): print(chunk, end="") # Live progress updatesAPI Reference
Section titled “API Reference”HermesClient
Section titled “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
Section titled “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
Section titled “Security Best Practices”Authentication
Section titled “Authentication”- Store
API_SERVER_KEYin 1Password or similar—never in code - Use environment variable injection, not hardcoded strings
- Rotate keys periodically
Network Security
Section titled “Network Security”- Always bind to
127.0.0.1—never0.0.0.0or public interfaces - Both agents should run on the same trusted host
- Consider firewall rules to block external access to port 8642
Scope of Access
Section titled “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
Section titled “Troubleshooting”| 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 |
Known Issue: Import Variable Not Defined
Section titled “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.pyHAS_HTTPX = FalseHAS_REQUESTS = False
try: import httpx HAS_HTTPX = Trueexcept ImportError: pass
try: import requests HAS_REQUESTS = Trueexcept ImportError: passReal-World Examples
Section titled “Real-World Examples”Deploy a Stack via Komodo
Section titled “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
Section titled “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
Section titled “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
Section titled “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
Section titled “Resources”Last updated: April 14, 2026
Have questions or feedback? Open an issue on the guides repository.