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

# Deploy a self-hosted agent

> Install the agent base chart with Helm — the command, the values you set, and where your own MCP servers and image registry go.

A self-hosted agent runs as a worker in your own Kubernetes cluster rather than on Komodor cloud.
You install it with Helm, pointed at your Komodor Agentic Operation Platform (KAOP) control plane,
and it authenticates with a worker token minted when you create the agent. See
[Agent identity](https://docs.komodor.com/security-and-governance/identity-and-access/agent-identity.md) for how the token and
the control-plane URL work together.

## Network requirements

The worker connects outbound over HTTPS (`443`) to your KAOP host, `agentops.komodor.com`, which
also serves Komodor's managed model gateway; nothing inbound is required. Your nodes also pull images
from `ghcr.io` unless you [mirror them](#using-your-own-image-registry), and the agent reaches its
model provider (in `byo` mode) and any MCP servers you configure. See
[Network & egress control](https://docs.komodor.com/security-and-governance/architecture-considerations/network-egress-control.md)
for proxy configuration and TLS-inspecting proxies.

## Install the chart

The agent runs from an OCI chart, so there is no `helm repo add` — reference it directly by its
registry path:

```sh theme={null}
helm install <agent-id> oci://ghcr.io/komodorio/charts/agentops-agent-base \
  -n <agent-namespace> --create-namespace -f values.yaml \
  --set-string controlplane.workerToken.value=<worker-token>
```

The agent's **Activate** step in the console generates this command and a matching `values.yaml`
for you, with the worker token filled in.

Use the agent id as the release name so the upgrade commands on
[Upgrade a self-hosted agent](https://docs.komodor.com/manage-your-agents/build/upgrade-a-self-hosted-agent.md) resolve it
without extra lookup. Pin a release with `--version <version>`; omitting it installs the newest
stable release.

A minimal `values.yaml`:

```yaml values.yaml theme={null}
agent:
  agentId: payments-triage
  instructions: |
    You triage failed payment runs ...

controlplane:
  url: https://agentops.komodor.com

llm:
  mode: cloud
  credentialRef: <credential-name>

clusterName: payments-eks-prod
```

The worker token is passed on the command line rather than written into the file; to keep it in a
Secret you manage instead, see [Managing secrets](#managing-secrets).

## Upgrade the chart

```sh theme={null}
helm upgrade <agent-id> oci://ghcr.io/komodorio/charts/agentops-agent-base \
  -n <agent-namespace> --reuse-values
```

`--reuse-values` carries forward everything you set at install — including the worker token and any
model API key, neither of which KAOP holds a copy of to put back for you. To change one value
without retyping the rest, add `--set <key>=<value>` alongside `--reuse-values`; it overrides just
that key and leaves everything else as installed.

`--reuse-values` also carries forward the *previous* chart's defaults for anything you never set
explicitly, so a default introduced by a newer chart version doesn't reach an existing release on
its own. On Helm 3.14 or newer, `--reset-then-reuse-values` resets to the new chart's defaults
first and reapplies your previous overrides on top, so new defaults do take effect — on an older
Helm it fails with `unknown flag`, which is why the command above uses plain `--reuse-values`.

Pin the chart version the same way you would at install, with `--version <version>`; omitting it
upgrades to the newest stable release.

When an upgrade changes the image tag, the Deployment's own rolling update replaces the pods as
soon as the upgrade applies — there is no separate restart step to run. The old pod finishes its
in-flight work before the new one starts, so a rollout can take several minutes while a run drains.

The exact command differs for a catalog agent, which pins an image tag, versus one you built
yourself, which tracks the chart version instead; see
[Upgrade a self-hosted agent](https://docs.komodor.com/manage-your-agents/build/upgrade-a-self-hosted-agent.md) for each path.

## Deploying via GitOps (ArgoCD, Flux)

The agent base chart is published as an OCI artifact, so it works with GitOps tools that support
OCI Helm sources. Point an ArgoCD `Application` or Flux `HelmRelease` at the same chart used
above — `oci://ghcr.io/komodorio/charts/agentops-agent-base` — with no `helm repo add` needed,
though your GitOps tool may still require its own OCI source configuration.

Keep the chart version and `values.yaml` in git. To upgrade, change the chart version or image
configuration there and let your GitOps controller reconcile it, rather than running
`helm upgrade` yourself.

### Rendering manifests into git

If you'd rather commit rendered manifests than have your GitOps controller pull the chart
directly:

```sh theme={null}
helm template <agent-id> oci://ghcr.io/komodorio/charts/agentops-agent-base \
  -n <agent-namespace> \
  --version <chart-version> \
  -f values.yaml > agent.yaml
```

If your GitOps tool can't reference an OCI registry directly, vendor the chart into your repo
instead:

```sh theme={null}
helm pull oci://ghcr.io/komodorio/charts/agentops-agent-base \
  --version <chart-version> --untar
```

That extracts the chart into a local directory you commit and point ArgoCD or Flux at as a
`path`-based Helm source, rather than an OCI `repoURL`.

### Managing secrets

GitOps configuration is typically stored in git.

> [!WARNING]
>
> Don't put the worker token or model API key in `values.yaml` in plaintext. Use
> `controlplane.workerToken.existingSecret` and `llm.anthropicApiKey.existingSecret`, with their
> `key` fields, to reference Secrets you manage separately — created before the agent deploys, with
> a tool like Sealed Secrets, External Secrets Operator, or SOPS. The chart does not create or
> manage these Secrets for you.

## Values reference

### Agent

| Value | Required | Purpose |
| - | - | - |
| `agent.agentId` | Yes | The agent id this worker registers as. Must match the worker token. |
| `agent.instructions` | Yes | The agent's system instructions. |
| `agent.displayName` | | The readable label shown in the console. |
| `agent.model` | | The model the agent runs on, for example `claude-sonnet-4-6`. |
| `agent.capabilities` | | Agent-card capabilities, such as chat. |
| `agent.labels` | | Labels attached to the agent. |
| `agent.skills` | | Skills the agent loads. |
| `agent.agents` | | Subagents this agent can delegate to. |

### Connecting to KAOP

| Value | Required | Purpose |
| - | - | - |
| `controlplane.url` | Yes | Your KAOP control-plane URL — the chart's `AGENTOPS_URL`. |
| `controlplane.workerToken.value` | One of these | The worker token inline. |
| `controlplane.workerToken.existingSecret` / `.key` | | Reference a Secret you manage instead, rather than the token value inline. |
| `caBundle.existingConfigMap` | | Trust an internal or proxy CA on top of the public roots — see [Network & egress control](https://docs.komodor.com/security-and-governance/architecture-considerations/network-egress-control.md#tls-inspection). |

### Model

One of `llm.credentialRef` (`cloud`) or `llm.anthropicApiKey` (`byo`) is required; the chart
refuses to render without one.

| Value | Purpose |
| - | - |
| `llm.mode` | `byo` to supply your own model API key, `cloud` to use a credential configured in KAOP. |
| `llm.anthropicApiKey.value` / `.existingSecret` / `.key` | The API key, in `byo` mode — inline or from a Secret you manage. |
| `llm.credentialRef` | The KAOP credential to use, in `cloud` mode. |

### Scaling with KEDA

| Value | Default | Purpose |
| - | - | - |
| `autoscaling.keda.enabled` | `false` | Turn on KEDA-driven autoscaling for this agent. Requires KEDA 2.10 or newer, with the metrics-api scaler, installed in the cluster. Without KEDA's CRDs, the install fails. |
| `autoscaling.keda.minReplicaCount` | `1` | Set to `0` to allow scaling to zero between runs. |
| `autoscaling.keda.maxReplicaCount` | `5` | Ceiling on replicas. |
| `autoscaling.keda.pollingInterval` | `30` | Seconds between queue-depth checks. Applies only when `minReplicaCount` is `0`. |
| `autoscaling.keda.cooldownPeriod` | `300` | Seconds of no demand before scaling back to zero. Applies only when `minReplicaCount` is `0`. |
| `autoscaling.keda.queueDepthPerReplica` | `1` | Unfinished runs (waiting plus in flight) per replica before KEDA adds one. Leave at `1`. |
| `autoscaling.keda.scaleDown.stabilizationWindowSeconds` / `.podsPerPeriod` / `.periodSeconds` | | How cautiously replicas scale back down. |

### Resources, scheduling and identity

| Value | Default | Purpose |
| - | - | - |
| `resources.requests.cpu` / `.memory` | `50m` / `320Mi` | Per-replica request. |
| `resources.limits.cpu` / `.memory` | `750m` / `1Gi` | Per-replica limit. |
| `clusterName` | | A human-readable name for this cluster, stamped onto every replica as `AGENTOPS_CLUSTER_NAME`. Useful once an agent runs in more than one cluster. |
| `nodeSelector` / `tolerations` / `affinity` | | Standard pod scheduling constraints. |
| `serviceAccount.create` / `.name` / `.annotations` | | The pod's service account, and any annotations your cluster's identity binding needs. |
| `env` | | Extra environment variables, as `[{name, value}]` or `valueFrom`. |

## MCP servers: two lists, one merge

Keep your own in-cluster MCP servers in `agent.mcpServers` — the chart renders them into the
worker's `.mcp.json`. Leave `agent.managedMcpServers` alone; it holds servers KAOP itself adds and
is merged into the same file.

> [!WARNING]
>
> Helm replaces a list rather than merging it. If the two were a single key, an upgrade generated by
> the console would overwrite your own servers with the ones it manages. Keeping them in separate
> keys that the chart merges avoids that. On a name collision, the server in
> `agent.managedMcpServers` wins.

## Using your own image registry

`image.registry`, `image.repository` and `image.tag` point the chart at wherever your cluster pulls
images from; set `imagePullSecrets` if that registry needs one. If your cluster mirrors images into
its own registry rather than pulling from the default, set these to the mirrored location instead.

### What to mirror

An agent you built yourself runs one image, public on `ghcr.io/komodorio`:
`agentops-agent-base`, published for amd64 and arm64. A catalog agent runs its own image instead,
named under `image:` in the values file the console generates; mirror that one, and change
`image.registry` in that file.

Mirror the tag your chart version uses: with `image.tag` left blank, the chart pulls the tag equal
to its own version, so mirroring only `latest` fails.

Mirroring has to preserve the whole multi-arch manifest, not just the image for one platform — a
plain `docker pull` / `docker push` round-trip only carries the local daemon's platform unless you
explicitly request every variant. Use a tool built for registry-to-registry copies instead, such as
`crane copy`, `skopeo copy`, or `docker buildx imagetools create`.

> [!NOTE]
>
> For help mirroring the images into your own registry, contact Komodor support.

### Pointing the chart at the mirror

If you mirror under a `komodorio/` prefix at your destination —
`<your-registry>/komodorio/agentops-agent-base` — you only need to override the registry host:

```yaml values.yaml theme={null}
image:
  registry: us-docker.pkg.dev/your-project/agentops

imagePullSecrets:
  - name: your-registry-pull-secret
```

Mirroring to a different path instead? Also set `image.repository` to match — the chart's default
(`komodorio/agentops-agent-base`) only resolves correctly under that `komodorio/` convention.

## Putting it together

A `values.yaml` that keeps the worker token and model key in Secrets you manage, adds an in-cluster
MCP server whose token comes from a Secret, and scales to zero between runs:

```yaml values.yaml theme={null}
agent:
  agentId: payments-triage
  instructions: |
    You triage failed payment runs ...
  model: claude-sonnet-4-6
  mcpServers:
    - name: internal-tools
      type: http
      url: http://mcp.tools.svc.cluster.local:8080/mcp
      headers:
        Authorization: "Bearer ${INTERNAL_MCP_TOKEN}"

controlplane:
  url: https://agentops.komodor.com
  workerToken:
    existingSecret: agentops-worker-token
    key: token

llm:
  mode: byo
  anthropicApiKey:
    existingSecret: agentops-llm-key
    key: ANTHROPIC_API_KEY

clusterName: payments-eks-prod

env:
  - name: INTERNAL_MCP_TOKEN
    valueFrom:
      secretKeyRef:
        name: internal-mcp
        key: token

autoscaling:
  keda:
    enabled: true
    minReplicaCount: 0
    maxReplicaCount: 5
```

The worker expands `${VAR}` references in an MCP server's settings from the pod's environment, so a
token never has to be written into the values file. Scaling to zero (`minReplicaCount: 0`) is safe
from the first deploy: KEDA polls the control plane
on the worker token alone, so it needs no replica already running to find the agent.

## Next steps

> [card] [Upgrade a self-hosted agent](https://docs.komodor.com/manage-your-agents/build/upgrade-a-self-hosted-agent.md)
>
> Move an installed agent to the newest release.

> [card] [Agent identity](https://docs.komodor.com/security-and-governance/identity-and-access/agent-identity.md)
>
> How the worker token and control-plane URL authenticate a worker.

> [card] [Proving it works](https://docs.komodor.com/manage-your-agents/build/how-it-works.md#proving-it-works)
>
> Confirm the worker is reachable and a real run completes.

> [card] [Troubleshooting](https://docs.komodor.com/reference/troubleshooting.md#an-agent-appears-offline)
>
> What to check when a worker does not come online.


## Related topics

- [Agent marketplace](https://docs.komodor.com/manage-your-agents/build/agent-marketplace.md)
- [Network & egress control](https://docs.komodor.com/security-and-governance/architecture-considerations/network-egress-control.md)
- [Upgrade a self-hosted agent](https://docs.komodor.com/manage-your-agents/build/upgrade-a-self-hosted-agent.md)
- [Deployment methods](https://docs.komodor.com/get-started/deployment-methods.md)
- [Cloud providers](https://docs.komodor.com/manage-your-agents/build/catalog/cloud-providers.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.