> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ankra.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Hermes

> Hermes is Ankra's autonomous infrastructure agent. Give it the Ankra CLI, Ankra AI, skills, and profiles so it can design, draft, and build the tools your app needs -- databases, caches, and full stacks -- with confirmations and a detailed bill of materials at every step.

## Overview

**Hermes** is Ankra's autonomous infrastructure agent. It runs on the open-source
[OpenClaw](https://openclaws.io/) runtime and connects to Ankra through the CLI,
so it can manage clusters, build stacks, query Ankra AI, and provision the
backing services your application needs -- all from chat platforms like Slack,
Discord, and Telegram.

Hermes is built to be given real responsibility. You can hand it full control to
**design and configure the infrastructure your app depends on** -- a Postgres
database, a Redis cache, an ingress, observability -- and it will draft the
architecture, produce a detailed bill of materials, and ask for your
confirmation before it builds anything.

This guide covers:

1. **What Hermes can do** -- skills, the CLI, Ankra AI, stacks, profiles, and
   full architecture design
2. **Deploying Hermes** on any Kubernetes cluster as an Ankra stack
3. **Connecting Hermes to Ankra** by adding the Ankra CLI as a skill
4. **The safeguards** that keep autonomy safe -- confirmations, drafted
   architecture, and a detailed bill of materials

<Note>
  Hermes runs on the OpenClaw runtime. If you are looking for the OpenClaw
  integration, this is now Hermes -- the deployment mechanics are unchanged.
</Note>

***

## What Hermes can do

<CardGroup cols={2}>
  <Card title="Skills" icon="puzzle-piece">
    Extend Hermes with skills. The Ankra CLI skill turns natural language into
    cluster, stack, and credential operations.
  </Card>

  <Card title="Ankra CLI" icon="terminal">
    Hermes drives the full `ankra` CLI -- clusters, stacks, charts, credentials,
    and tokens -- on your behalf.
  </Card>

  <Card title="Ankra AI" icon="sparkles">
    Hermes asks Ankra AI about live cluster state for health checks, root-cause
    analysis, and troubleshooting.
  </Card>

  <Card title="Build stacks" icon="layer-group">
    Hermes composes Helm addons and manifests into stacks and deploys them
    through Ankra's GitOps flow.
  </Card>

  <Card title="Profiles" icon="id-badge">
    Reusable agent profiles bundle a model, skills, guardrails, and an autonomy
    level so Hermes behaves consistently per environment.
  </Card>

  <Card title="Design your app's tools" icon="wand-magic-sparkles">
    Hand Hermes a goal ("my app needs a database and a cache") and it designs the
    architecture, lists the components, and builds them after you confirm.
  </Card>
</CardGroup>

***

## Part 1: Deploy Hermes as an Ankra Stack

Deploy Hermes to any Kubernetes cluster managed by Ankra using the Stack Builder.
This gives you a self-hosted, containerized agent running inside your own
infrastructure.

### Prerequisites

* A cluster imported into Ankra with the agent connected
* An API key from [Anthropic](https://console.anthropic.com/) or [OpenAI](https://platform.openai.com/)
* A Helm registry added for the OpenClaw chart repository (`https://charts.openclaw.ai`)

<Tip>
  If you haven't added the OpenClaw Helm registry yet, go to **Settings** → **Registries** → **Add Registry** and enter `https://charts.openclaw.ai`.
</Tip>

### Step 1: Create the Stack

<Steps>
  <Step title="Open Stack Builder">
    Navigate to your cluster → **Stacks** → **Create Stack**.
  </Step>

  <Step title="Name Your Stack">
    Name it `hermes` or `ai-agent`.
  </Step>
</Steps>

### Step 2: Add the Hermes Chart

<Steps>
  <Step title="Add the Chart">
    Click **+ Add** → search for `openclaw` from the OpenClaw registry (this is the runtime Hermes is built on).
  </Step>

  <Step title="Configure Core Settings">
    Click the component and set these values:

    ```yaml theme={null}
    replicaCount: 1

    image:
      repository: ghcr.io/openclaw/openclaw
      tag: "latest"

    config:
      model: "claude-sonnet-4-20250514"
      port: 8789
      logLevel: "info"
    ```

    <Warning>
      Hermes runs as a single instance -- it does not support horizontal scaling. Keep `replicaCount: 1`.
    </Warning>
  </Step>

  <Step title="Configure API Key">
    For quick setup, set the key directly:

    ```yaml theme={null}
    config:
      anthropicApiKey: "sk-ant-..."
    ```

    For production, use a Kubernetes Secret instead (see [Production Setup](#production-api-key-management) below).
  </Step>

  <Step title="Configure Resources">
    ```yaml theme={null}
    resources:
      requests:
        memory: 512Mi
        cpu: 250m
      limits:
        memory: 1Gi
        cpu: 1000m
    ```
  </Step>

  <Step title="Enable Persistent Storage">
    Hermes stores workspace data and conversation memory. Enable persistence so this survives pod restarts:

    ```yaml theme={null}
    persistence:
      enabled: true
      size: 5Gi
    ```
  </Step>
</Steps>

<Tip>
  **Encrypt sensitive values with SOPS:** In the manifest edit view, click the **SOPS** button to encrypt your API key. This ensures the key is stored encrypted in your GitOps repository. See [SOPS Encryption](/guides/sops) for setup instructions.
</Tip>

### Step 3: Expose the Gateway (Optional)

If you want to access Hermes from outside the cluster, configure an ingress:

```yaml theme={null}
ingress:
  enabled: true
  className: "nginx"
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
  hosts:
    - host: hermes.your-domain.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: hermes-tls
      hosts:
        - hermes.your-domain.com
```

Alternatively, use port-forwarding for local access:

```bash theme={null}
kubectl port-forward svc/hermes 8789:8789 -n hermes
```

### Step 4: Deploy

<Steps>
  <Step title="Review">
    Your stack should contain the chart with your configured values.
  </Step>

  <Step title="Save and Deploy">
    Click **Save**, then **Deploy**. Watch progress in **Operations**.
  </Step>

  <Step title="Verify">
    After 1-2 minutes, the Hermes pod should be running:

    ```bash theme={null}
    kubectl get pods -n hermes
    ```

    ```
    NAME                      READY   STATUS    RESTARTS   AGE
    hermes-6f8d9b7c4-x2k9p    1/1     Running   0          90s
    ```
  </Step>
</Steps>

### Production API Key Management

For production deployments, store your API key in a Kubernetes Secret rather than in plain-text values:

<Steps>
  <Step title="Create the Secret">
    ```bash theme={null}
    kubectl create secret generic hermes-api-key \
      --from-literal=anthropic-api-key="sk-ant-..." \
      -n hermes
    ```
  </Step>

  <Step title="Reference in Values">
    ```yaml theme={null}
    config:
      anthropicApiKey: ""

    existingSecret:
      name: hermes-api-key
      anthropicApiKeyKey: anthropic-api-key
    ```
  </Step>
</Steps>

### Security Hardening

Lock down the Hermes pod with security contexts:

```yaml theme={null}
podSecurityContext:
  runAsNonRoot: true
  runAsUser: 1000
  fsGroup: 1000

securityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  capabilities:
    drop:
      - ALL
```

<Warning>
  Hermes has shell access and can read files inside its container. Kubernetes provides meaningful isolation through container boundaries and network policies. For sensitive environments, apply a `NetworkPolicy` to restrict egress to only the AI provider API endpoints your model requires.
</Warning>

### Network Policy Example

Restrict Hermes' network access to only the AI provider API:

```yaml theme={null}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: hermes-egress
  namespace: hermes
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: openclaw
  policyTypes:
    - Egress
  egress:
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
      ports:
        - protocol: TCP
          port: 443
    - to:
        - namespaceSelector: {}
      ports:
        - protocol: UDP
          port: 53
```

You can add this as a manifest in your stack alongside the chart.

### Connect a Chat Platform

Once Hermes is running in your cluster, connect it to your team's chat:

| Platform     | Configuration                                                                                 |
| ------------ | --------------------------------------------------------------------------------------------- |
| **Slack**    | Set `config.slackBotToken` and `config.slackAppToken` in your values, or use `existingSecret` |
| **Discord**  | Set `config.discordToken` in your values                                                      |
| **Telegram** | Set `config.telegramToken` in your values                                                     |

<Tip>
  Store all chat platform tokens in a Kubernetes Secret and reference them via `existingSecret` for production use.
</Tip>

***

## Part 2: Add Ankra CLI as a Hermes Skill

Once Hermes is running (either via the stack above or any other installation), you
give it the ability to manage your Ankra infrastructure by adding the CLI as a
skill.

### Prerequisites

* [Hermes](https://openclaws.io/) installed and running (or deployed as a stack above)
* [Ankra CLI](/integrations/ankra-cli) installed and authenticated
* An Ankra API token (for non-interactive auth)

### Step 1: Install and Authenticate the Ankra CLI

If you haven't already, install the Ankra CLI:

```bash theme={null}
bash <(curl -sL https://github.com/ankraio/ankra-cli/releases/latest/download/install.sh)
```

Create an API token for Hermes to use (this avoids browser-based SSO, which doesn't work in headless environments):

```bash theme={null}
ankra login
ankra tokens create hermes-agent
```

Save the returned token -- you'll need it in the next step.

### Step 2: Create the Ankra Skill

Create the skill directory and manifest:

```bash theme={null}
mkdir -p ~/.openclaw/skills/ankra
```

Create `~/.openclaw/skills/ankra/SKILL.md` with the following content:

```markdown theme={null}
---
name: ankra
version: 1.0.0
author: your-org
description: >
  Manage Kubernetes clusters and infrastructure on the Ankra platform.
  Use when the user wants to list clusters, deploy stacks, check cluster health,
  manage addons, search Helm charts, scale workers, design application
  infrastructure, or troubleshoot Kubernetes issues.
permissions:
  - shell
  - network
config:
  api_token:
    type: string
    required: true
    description: "Ankra API token for authentication"
    secret: true
---

# Ankra Platform Management

You have access to the `ankra` CLI to manage Kubernetes clusters on the Ankra platform.

## Available Commands

### Cluster Operations
- `ankra cluster list` -- List all clusters
- `ankra cluster get <name>` -- Get cluster details
- `ankra cluster select` -- Select a cluster (use `--name` for non-interactive)
- `ankra cluster reconcile [name]` -- Trigger reconciliation

### AI Chat
- `ankra chat "<question>"` -- Ask Ankra AI about your infrastructure
- `ankra chat health` -- Get cluster health summary
- `ankra chat health --ai` -- Get AI-analyzed cluster health

### Stack Management
- `ankra cluster stacks list` -- List stacks
- `ankra cluster stacks create <name>` -- Create a stack
- `ankra cluster stacks delete <name>` -- Delete a stack
- `ankra cluster stacks history <name>` -- View stack change history

### Helm Charts
- `ankra charts search <query>` -- Search for charts
- `ankra charts info <name>` -- Get chart details
- `ankra charts list` -- List available charts

### Hetzner Cluster Provisioning
- `ankra cluster hetzner create --name <n> --credential-id <id> --location <loc>` -- Create cluster
- `ankra cluster hetzner workers <id>` -- Get worker count
- `ankra cluster hetzner node-group list <id>` -- List node groups
- `ankra cluster hetzner node-group scale <id> <group> <count>` -- Scale a node group
- `ankra cluster hetzner deprovision <id>` -- Deprovision cluster

### OVH Cluster Provisioning
- `ankra cluster ovh create --name <n> --credential-id <id> --region <r>` -- Create cluster
- `ankra cluster ovh workers <id>` -- Get worker count
- `ankra cluster ovh scale <id> <count>` -- Scale workers

### UpCloud Cluster Provisioning
- `ankra cluster upcloud create --name <n> --credential-id <id> --zone <z>` -- Create cluster
- `ankra cluster upcloud workers <id>` -- Get worker count
- `ankra cluster upcloud scale <id> <count>` -- Scale workers

### Credentials
- `ankra credentials list` -- List all credentials
- `ankra credentials get <id>` -- Get credential details

### API Tokens
- `ankra tokens list` -- List API tokens
- `ankra tokens create <name>` -- Create a token
- `ankra tokens revoke <id>` -- Revoke a token

## Guardrails

- Always confirm with the user before running destructive operations like `deprovision`, `delete`, or `scale` (down).
- When scaling workers, show the current count first and ask for confirmation.
- Never expose API tokens or credentials in responses.
- For cluster creation, list the parameters back to the user and ask for confirmation before executing.
- Before building application infrastructure, present a drafted architecture and a bill of materials, then wait for explicit approval.
- Prefer `ankra chat` for troubleshooting questions -- it has access to live cluster data.
```

### Step 3: Configure the Skill

Add the Ankra skill to your Hermes configuration at `~/.openclaw/openclaw.json`:

```json theme={null}
{
  "skills": {
    "entries": {
      "ankra": {
        "enabled": true,
        "apiKey": "your-ankra-api-token",
        "env": {
          "ANKRA_API_TOKEN": "your-ankra-api-token"
        }
      }
    }
  }
}
```

Replace `your-ankra-api-token` with the token you created in Step 1.

<Tip>
  If you already have other skills configured, just add the `ankra` entry to your existing `entries` object.
</Tip>

### Step 4: Verify the Integration

Restart Hermes or wait for the skill watcher to pick up the changes, then test:

```
You: List my Ankra clusters
Hermes: Running `ankra cluster list`...

NAME              PROVIDER   STATE     WORKERS
staging-cluster   hetzner    running   3
production        ovh        running   5
```

***

## Use cases

### Use the Ankra CLI

With the Ankra CLI skill installed, Hermes turns plain language into CLI
operations. You never have to remember command syntax -- describe the outcome and
Hermes runs the right commands.

```
You: Reconcile the production cluster
Hermes: Running `ankra cluster reconcile production`... reconciliation triggered.
```

### Use Ankra AI

Hermes uses `ankra chat` to consult Ankra AI, which has live access to your
cluster state. Use it for health checks, root-cause analysis, and "why is this
broken" questions.

```
You: Why are pods crashing on production?
Hermes: Let me check with Ankra AI...
        Running `ankra chat "Why are pods in CrashLoopBackOff?"` on production...

        Ankra AI found 2 pods in CrashLoopBackOff in the api namespace:
        - api-server-7d8f9: OOMKilled (memory limit 256Mi, usage peaked at 312Mi)
        - api-worker-3k9d2: exit code 1, missing DATABASE_URL env var
```

### Build stacks

Hermes composes Helm addons and manifests into stacks and deploys them through
Ankra's GitOps flow.

```
You: Create a monitoring stack on my staging cluster
Hermes: I'll create a new stack called "monitoring" on staging-cluster.
        Running `ankra cluster stacks create monitoring`... Done.
        I'll add kube-prometheus-stack and Loki. Deploy now? (y/n)
```

### Profiles

A **profile** is a reusable agent configuration that bundles a model, a set of
skills, guardrails, and an autonomy level. Profiles let Hermes behave
consistently and appropriately per environment -- a cautious, read-mostly profile
for production and a freer profile for a sandbox.

Define profiles in your Hermes configuration:

```json theme={null}
{
  "profiles": {
    "production": {
      "model": "claude-sonnet-4-20250514",
      "skills": ["ankra"],
      "autonomy": "confirm-all",
      "guardrails": {
        "require_confirmation": ["delete", "deprovision", "scale-down"],
        "require_architecture_draft": true,
        "require_bill_of_materials": true
      }
    },
    "sandbox": {
      "model": "claude-sonnet-4-20250514",
      "skills": ["ankra"],
      "autonomy": "auto",
      "guardrails": {
        "require_confirmation": ["deprovision"]
      }
    }
  }
}
```

```
You: Switch to the production profile
Hermes: Now using the "production" profile. I'll confirm every change and draft
        architecture with a bill of materials before building anything.
```

### Give Hermes full control to design your app's tools

This is what Hermes is built for. Hand it a goal and let it design and configure
the infrastructure your application needs -- a database, a cache, ingress,
secrets, and observability -- end to end.

Hermes works in three phases: **design**, **confirm**, **build**. It never
provisions anything before you approve the drafted architecture and its bill of
materials.

```
You: My app needs a Postgres database and a Redis cache on staging. Set it up.

Hermes: Here's the architecture I propose for staging-cluster.

        Drafted architecture
        ─────────────────────
        app-data (stack)
          ├─ postgres        primary + 1 read replica, 20Gi PVC, daily backups
          ├─ redis           single master + 1 replica, 2Gi PVC, AOF persistence
          └─ secrets         SOPS-encrypted credentials in the GitOps repo

        Bill of materials
        ─────────────────────
        Component   Chart                       Version   Replicas   Storage   Est. resources
        Postgres    bitnami/postgresql-ha       14.x      2          20Gi      1 vCPU / 2Gi req
        Redis       bitnami/redis               19.x      2          2Gi       0.5 vCPU / 512Mi req
        Secrets     manifest (SOPS)             -         -          -         -

        Connection details will be written to a Kubernetes Secret named
        `app-data-credentials` and referenced by your app via existingSecret.

        Proceed to build this stack? (y/n)

You: y

Hermes: Building...
        Running `ankra cluster stacks create app-data`... Done.
        Adding postgresql-ha, redis, and the SOPS secret manifest...
        Saving and deploying. Watch progress in Operations.
```

Hermes can iterate on the design before building -- ask it to add a read
replica, change storage sizes, swap a chart, or pin versions, and it will
re-draft the architecture and bill of materials before asking again.

***

## Safeguards

Autonomy is only safe with rails. Hermes enforces these by default, and you can
tighten them per profile.

<CardGroup cols={2}>
  <Card title="Confirmations" icon="circle-check">
    Destructive and provisioning actions (`delete`, `deprovision`, scale-down,
    building infrastructure) require explicit approval before they run.
  </Card>

  <Card title="Drafted architecture" icon="pen-ruler">
    Before building anything, Hermes presents the architecture it intends to
    create so you can review and adjust it.
  </Card>

  <Card title="Detailed bill of materials" icon="list-check">
    Every build is accompanied by a bill of materials -- charts, versions,
    replicas, storage, and estimated resources -- so there are no surprises.
  </Card>

  <Card title="Secrets stay secret" icon="lock">
    Credentials are written to Kubernetes Secrets and encrypted with SOPS in
    GitOps. Hermes never echoes tokens or credentials back in chat.
  </Card>
</CardGroup>

<Warning>
  Match the autonomy level to the environment. Use a `confirm-all` profile with
  architecture drafts and a bill of materials required for production, and reserve
  freer profiles for sandbox clusters.
</Warning>

### Sandboxed Environments

If you run Hermes in sandboxed mode (Docker), the `ANKRA_API_TOKEN` environment variable won't be inherited automatically. Add it to your sandbox config:

```json theme={null}
{
  "agents": {
    "defaults": {
      "sandbox": {
        "docker": {
          "env": {
            "ANKRA_API_TOKEN": "your-ankra-api-token"
          }
        }
      }
    }
  }
}
```

You'll also need to ensure the `ankra` binary is available inside the container. Either mount it or install it in a custom image:

```dockerfile theme={null}
FROM openclaw/sandbox:latest
RUN bash <(curl -sL https://github.com/ankraio/ankra-cli/releases/latest/download/install.sh)
```

***

## Troubleshooting

### Stack Deployment Issues

| Issue                  | Solution                                                                                                                    |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Pod stuck in `Pending` | Check for insufficient resources with `kubectl describe pod -n hermes`. Increase node capacity or reduce resource requests. |
| `CrashLoopBackOff`     | Check logs with `kubectl logs -n hermes -l app.kubernetes.io/name=openclaw`. Usually a missing or invalid API key.          |
| Ingress not working    | Verify your ingress controller is installed and the `className` matches. Check cert-manager logs for TLS issues.            |
| PVC not binding        | Ensure a StorageClass exists. Run `kubectl get storageclass` to verify.                                                     |
| Helm chart not found   | Confirm the OpenClaw registry (`https://charts.openclaw.ai`) is added under **Settings** → **Registries**.                  |

### Skill Integration Issues

| Issue                         | Solution                                                                                                        |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------- |
| "ankra: command not found"    | Ensure the Ankra CLI is installed and in PATH. Run `which ankra` to verify.                                     |
| "Unauthorized" errors         | Check that `ANKRA_API_TOKEN` is set correctly. Re-create the token with `ankra tokens create`.                  |
| Skill not appearing           | Verify the file is at `~/.openclaw/skills/ankra/SKILL.md` and the skill watcher is enabled.                     |
| Commands hang                 | The CLI may be waiting for interactive input. Ensure you're using `--name` flags for non-interactive selection. |
| Sandbox can't reach Ankra API | Add `network` to the sandbox's allowed permissions and ensure DNS resolution works inside the container.        |

<Note>
  The Ankra CLI stores its config at `~/.ankra.yaml`. When using API token auth via `ANKRA_API_TOKEN`, no config file is needed.
</Note>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Stacks" icon="layer-group" href="/concepts/stacks">
    Learn more about building and managing stacks in Ankra.
  </Card>

  <Card title="SOPS Encryption" icon="lock" href="/guides/sops">
    Encrypt sensitive values in your stack configuration.
  </Card>

  <Card title="Ankra CLI" icon="terminal" href="/integrations/ankra-cli">
    Full CLI reference for all Ankra commands.
  </Card>

  <Card title="Monitoring Stack" icon="chart-line" href="/guides/monitoring-stack">
    Add observability alongside your Hermes deployment.
  </Card>
</CardGroup>
