> For the complete documentation index, see [llms.txt](/docs/llms.txt). Markdown versions of all docs pages are available by appending .md to any docs URL.

# Install kagent

kagent 1.0 runs every agent on [Agent Substrate](https://kagent.dev/docs/kagent/1.x/about/architecture/agent-substrate/), so an installation sets up two systems in the same cluster. Agent Substrate provides the sandboxed compute that agents run on, and kagent provides the Harness, AgentTemplate, and Agent API that you author against. The `kagent install` command installs kagent, Agent Substrate, and the development PostgreSQL database together.

> [!NOTE]
> These steps install kagent 1.0 fresh. kagent 1.0 has no in-place upgrade from the 0.10.x version line, and installing its custom resource definitions replaces the ones that a 0.10.x installation uses. To move an existing installation, start with [Upgrade from 0.x](https://kagent.dev/docs/kagent/1.x/operations/upgrade-from-0x#in-place-upgrade-blockers).

## Before you begin

1. Install the following CLI tools.
   
   - [`helm`](https://helm.sh/docs/intro/install/), the Kubernetes package manager. Use Helm 3.
   - [`kubectl`](https://kubernetes.io/docs/tasks/tools/#kubectl), the Kubernetes command line tool.
   - The kagent CLI, matched to the release that these docs cover.
     
     ```bash
     curl https://raw.githubusercontent.com/kagent-dev/kagent/refs/heads/main/scripts/get-kagent | bash -s -- --version v1.0.0-alpha16
     kagent version
     ```
2. Set your model provider API key. The examples in this guide use OpenAI. For other providers, see [Configure model providers](https://kagent.dev/docs/kagent/1.x/setup/model-providers/).
   
   ```bash
   export OPENAI_API_KEY="your-api-key-here"
   ```
3. Prepare a Kubernetes cluster at **1.37 or later**. Agent Substrate depends on the `PodCertificateRequest` and `ClusterTrustBundle` APIs. Both are generally available (GA) in 1.37 and served at `certificates.k8s.io/v1` by default.
   
   You can choose from the following options.
   
   **Option: Local kind cluster**
   
   For local testing and development, create a [kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation) cluster at Kubernetes 1.37 or later. Use kind v0.32.0 or later. No extra API configuration is needed.
   
   ```bash
   kind create cluster --name kagent --image kindest/node:v1.37.0
   ```
   
   **Option: Existing 1.37+ cluster**
   
   Kubernetes 1.37 and later serve the required APIs at `certificates.k8s.io/v1` by default, so you do not need to change the API server configuration.
   
   Confirm that the cluster serves the required APIs.
   
   ```bash
   kubectl api-resources --api-group=certificates.k8s.io
   ```
   
   Example output:
   
   ```console
   NAME                           SHORTNAMES   APIVERSION               NAMESPACED   KIND
   certificatesigningrequests     csr          certificates.k8s.io/v1   false        CertificateSigningRequest
   clustertrustbundles                         certificates.k8s.io/v1   false        ClusterTrustBundle
   podcertificaterequests                      certificates.k8s.io/v1   true         PodCertificateRequest
   ```

## Install kagent

The kagent CLI installs the CRDs, Agent Substrate, the Agent Substrate PodCertificate controller, a development PostgreSQL database, and kagent in the correct order. It also creates the Substrate identity material and database connection Secrets that the releases need.

1. Save a Helm values file that enables gRPC server reflection, so that guides that use `grpcurl` can discover the controller API.
   
   ```bash
   cat > kagent-values.yaml <<EOF
   config:
     server:
       grpcReflection: true
   EOF
   ```
2. Save a CLI configuration file that points the installer at those values. `kagent install` does not take Helm flags of its own, so chart values reach it through this file. A relative path in `valuesFiles` resolves against the configuration file's own directory.
   
   ```bash
   cat > kagent-config.yaml <<EOF
   install:
     kagent:
       valuesFiles: [kagent-values.yaml]
   EOF
   ```
3. Install kagent.
   
   ```bash
   kagent --config kagent-config.yaml install --namespace kagent
   ```
   
   The command reads your provider API key, installs Agent Substrate into `ate-system`, and deploys PostgreSQL as `kagent-postgresql` in the kagent namespace. It then connects kagent and Agent Substrate to that database with Pod Certificates. The development database runs the stock `postgres` image, which omits the `pgvector` extension that [long-term memory](https://kagent.dev/docs/kagent/1.x/agents/agent-memory/) needs.
4. Wait for the controller to roll out.
   
   ```bash
   kubectl rollout status deployment/kagent-controller -n kagent --timeout=300s
   ```
   
   For production database requirements and direct Helm installation, see [Operational considerations](https://kagent.dev/docs/kagent/1.x/operations/operational-considerations#choose-a-database).

## Verify the installation

1. Confirm that the kagent pods are running.
   
   ```bash
   kubectl get pods -n kagent
   ```
   
   Example output:
   
   ```console
   NAME                                              READY   STATUS    RESTARTS   AGE
   kagent-controller-56c67b6cd7-hqj5z                1/1     Running   3          2m
   kagent-default-774d4496bd-sfx4b                   1/1     Running   0          2m
   kagent-grafana-mcp-7c67f5697c-4mf78               1/1     Running   0          2m
   kagent-postgresql-856b475f59-n258n                2/2     Running   0          2m
   kagent-tools-54959b659c-lfkrz                     1/1     Running   0          2m
   kagent-ui-5fdb6fd85c-vzb2z                        1/1     Running   0          2m
   ```
2. Confirm that the WorkerPool reports a ready replica.
   
   ```bash
   kubectl get workerpools -n kagent
   ```
   
   Example output:
   
   ```console
   NAME             DESIRED   REPLICAS   READY   AGE
   kagent-default   1         1          1       2m
   ```
3. Get the address to reach the kagent gRPC API, which serves Agent, AgentTemplate, Session, and conversation calls. The guide to [create your first agent](https://kagent.dev/docs/kagent/1.x/get-started/your-first-agent/) assumes port-forwarding.
   
   You can choose from the following options.
   
   **Option: Port-forward for local testing**
   
   Forward the controller port and leave the command running. The API is then available at `localhost:8083`.
   
   ```bash
   kubectl port-forward -n kagent svc/kagent-controller 8083:8083
   ```
   
   **Option: Cloud Provider LoadBalancer**
   
   Read the external address of the controller service. The gRPC API listens on port `8083`.
   
   ```bash
   kubectl get svc -n kagent kagent-controller \
     -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}"
   ```
   
   To use this address with the kagent CLI, pass it in the `--api-url` flag.
   
   ```bash
   kagent agent list --api-url http://<address>:8083
   ```
4. Optional: Open the kagent UI. The UI is a separate `kagent-ui` service, so it needs its own port-forward in a second terminal. The dashboard is then available at [http://localhost:8082](http://localhost:8082). For the `kagent dashboard` shortcut and a tour of the UI, see [Launch the UI](https://kagent.dev/docs/kagent/1.x/observability/launch-ui/).
   
   ```bash
   kubectl port-forward -n kagent svc/kagent-ui 8082:8080
   ```
   
   To serve the UI behind a reverse proxy under a prefix such as `/ui` (configurable with `ui.basePath`), see [Serve the UI under a sub-path](https://kagent.dev/docs/kagent/1.x/setup/reverse-proxy/).

## Restrict kagent to specific namespaces

By default the controller watches every namespace, and the chart creates cluster-scoped RBAC (ClusterRoles and ClusterRoleBindings). To restrict kagent to a set of namespaces, set `global.watchNamespaces` in your Helm values:

```yaml
global:
  watchNamespaces: [prod-agents, staging-agents]
```

Prefer `global.watchNamespaces` over the per-surface keys. The chart derives both surfaces from this one value, so they cannot disagree: it replaces every kagent ClusterRole with a Role and RoleBinding in each listed namespace, and it limits the controller's watch to the same list. The chart appends the install namespace to the list automatically, so the release's own objects remain managed.

The per-surface keys still exist for installs that scope the surfaces independently, and the validation rules bind them:

- `rbac.namespaces` takes precedence over `global.watchNamespaces` whenever the key is present. An explicit `rbac.namespaces: []` restores cluster-scoped RBAC. When `rbac.namespaces` is set, it must include the install namespace or the render fails.
- `config.kubernetes.watchNamespaces` is an explicit watch override. Under `rbac.namespaces`, a watch entry that names a namespace outside the RBAC scope fails the render, because the controller would loop on `Forbidden` errors at runtime. Under `global.watchNamespaces`, the chart folds the entries into the watch scope instead of failing. In both cases the watch list replaces the default, so the install namespace is not added back once `config.kubernetes.watchNamespaces` is set -- list it explicitly if the controller should keep watching it.
- The `kagent-tool-server` RemoteMCPServer that the chart creates admits references from its own namespace only. An Agent in another watched namespace that binds it does not become ready until you set `allowedNamespaces` on that server. See [Reach kagent-tool-server from another namespace](https://kagent.dev/docs/kagent/1.x/reference/tools-ecosystem#reach-kagent-tool-server-from-another-namespace).

Verify a namespaced install the same way as the default one, plus the negative case. The [create your first agent](https://kagent.dev/docs/kagent/1.x/get-started/your-first-agent/) guide's `kubectl get agents` and conditions checks apply to each namespace; the difference is that an Agent the controller does not watch stays `UNKNOWN` forever.

1. Create one Agent in each watched namespace.
   
   ```bash
   kubectl apply -n prod-agents -f my-agent.yaml
   kubectl apply -n staging-agents -f my-agent.yaml
   ```
2. Create one Agent in a namespace the list does not cover.
   
   ```bash
   kubectl apply -n dev-agents -f my-agent.yaml
   ```
3. Confirm that the controller reconciles the watched Agents.
   
   ```bash
   kubectl get agents -n prod-agents
   kubectl get agents -n staging-agents
   ```
   
   Example output:
   
   ```console
   NAME           AGE   READY
   my-agent       30s   True
   my-agent       30s   True
   ```
4. Confirm that the Agent in the unwatched namespace stays unmanaged: its `READY` value stays `UNKNOWN`, and its conditions stay empty, because the controller has no watch entry for that namespace.
   
   ```bash
   kubectl get agents -n dev-agents
   kubectl get agent my-agent -n dev-agents -o jsonpath='{.status.conditions}'
   ```
   
   Example output:
   
   ```console
   NAME           AGE   READY
   my-agent       30s   UNKNOWN
   null
   ```

## Next steps

[Your first agent](https://kagent.dev/docs/kagent/1.x/get-started/your-first-agent/)

Apply a Harness, an AgentTemplate, and an Agent, then start a conversation with it.

[Configure model providers](https://kagent.dev/docs/kagent/1.x/setup/model-providers/)

Point kagent at OpenAI, Anthropic, Gemini, or a provider of your own.

[Operational considerations](https://kagent.dev/docs/kagent/1.x/operations/operational-considerations/)

Replace the evaluation defaults for the database, controller replicas, and Worker node pools.

[Rotate the model provider API key](https://kagent.dev/docs/kagent/1.x/operations/operational-considerations#rotate-the-model-provider-api-key)

Change the API key in the kagent-openai Secret, which Helm owns, without breaking running agents.
