Skip to content

Quick start

Synced from agent-operator/docs/documentation/quick-start.md. The repository is the source of truth.

Agent Operator runs composable Dotagents agents on Kubernetes. It provides primitives — a per-agent namespace workspace, generic secret/config exposure, Outfitter settings, and running the agent — and treats what the agent does as composition. Channels (email, and later GitHub notifications or Signal) and tools (a wiki, source ingestion) are supplied by the agent’s Dotagents resources, not by the operator. See architecture.md.

An organization owns generic Git repositories and one pinned agent catalog. An agent runs in its own namespace; that entire namespace is the agent’s workspace, with a durable volume and broad namespaced administrator access, while an operator-owned ResourceQuota bounds its total consumption. This guide stands up the primitives with one example agent; what that agent does is a composition — see the use cases.

Implementation status: the CRDs, controller, local runtime image, and M1 email round trip are implemented. A packaged non-development installation and the M2 research composition remain future work.

To follow this guide you need:

  • a Kubernetes cluster and kubectl configured for it;
  • the Agent Operator installed on that cluster (see step 1); and
  • credentials for the model selected by your Dotagents agent.

To stand up a local cluster with the operator for evaluation or development, see CONTRIBUTING.md.

A composition brings its own inputs on top — for example the researcher wiki maintainer needs a Git wiki repository and a mailbox. These are composition inputs, not operator requirements; a different composition (say a GitHub PR watcher) would need different inputs.

The pinned Dotagents source must use a full commit SHA. Review every agent, skill, MCP server, plugin, and script in it before trusting it. M2 uses one source per organization in Outfitter settings; Outfitter performs fetching and resolution inside the runtime.

Install the controller and the two CRDs with the Helm chart:

Terminal window
helm install agent-operator ./code/operator/dist/chart \
--namespace agent-operator-system --create-namespace

The controller image defaults to the chart’s appVersion, so a chart release ships the controller it was built for. Pin a digest in production:

Terminal window
helm install agent-operator ./code/operator/dist/chart \
--namespace agent-operator-system --create-namespace \
--set controllerManager.container.image.tag="@sha256:<digest>"

This installs no agent runtime image. Agents run the published Outfitter container by default; an organization needing more publishes an image derived from it (FROM ghcr.io/ai-outfitter/outfitter:<version>) from its own <org>/.agents repository, and selects it per agent with Agent.spec.image.

Avoid setting --agent-image on the controller. It is cluster-global — it changes the runtime for every Agent this controller manages — and Agent.spec.image expresses the same thing per agent.

(For a local cluster with the operator preinstalled, see CONTRIBUTING.md.)

Confirm that the two CRDs are installed:

Terminal window
kubectl api-resources --api-group=aioutfitter.com

The output should contain organizations and agents, the only two CRDs.

Copy the sample before editing it:

Terminal window
cp config/samples/link_v1alpha1_organization.yaml /tmp/example-org.yaml

Replace the example repository/catalog URLs and every placeholder revision. A repository the agent commits to (the demo’s wiki) must be writable by the agent’s identity. The catalog revision must be an immutable 40-character commit SHA.

Apply the organization and wait for its catalog composition to resolve:

Terminal window
kubectl apply -f /tmp/example-org.yaml
kubectl wait organization/example-org \
--for=condition=Ready \
--timeout=2m
kubectl get organization/example-org -o yaml

The organization owns generic repositories and one pinned catalog. Projects are not used in this guide.

Review the basic agent sample, then apply it:

Terminal window
kubectl apply -f config/samples/link_v1alpha1_agent.yaml
kubectl wait agent/researcher \
--for=condition=NamespaceReady \
--timeout=1m

The controller creates agent-researcher, its service account, a namespaced binding to the built-in admin ClusterRole, an operator-owned ResourceQuota and LimitRange, a durable workspace volume, and the runtime workload. The agent is not ready yet: it should report CredentialsReady=False until you supply its Secrets. The Deployment and Pod still exist; Kubernetes reports the missing non-optional Secret references in the Pod’s container status until you create them.

Inspect the workspace boundary and budget:

Terminal window
kubectl -n agent-researcher describe resourcequota agent-workspace
kubectl -n agent-researcher get limitrange agent-workspace-defaults -o yaml
kubectl -n agent-researcher get rolebinding

ResourceQuota limits aggregate namespace consumption, including compute, requested persistent storage, and object counts. The LimitRange supplies default CPU and memory values because compute quotas can reject Pods that omit requests or limits. See the Kubernetes ResourceQuota documentation.

The sample grants organization-level membership in example-org. memberships is a list — an agent may belong to many organizations — though this guide uses one entry. See the multi-organization sample for the multi-membership shape.

Agent.spec.credentials references Secrets and ConfigMaps by name and declares how each is exposed to the runtime (as: env or as: volume). The operator waits for them to exist and projects them in; it never inspects their contents (see OPR-004). The keys inside each object are a contract of the composed agent — below, the email channel adapter’s contract.

Use your cluster’s secret manager in production. For local development, create the referenced Secrets/ConfigMaps in the agent-<name> namespace with kubectl; do not commit secret values or put them directly in a custom resource. A generic example:

Terminal window
kubectl -n agent-researcher create secret generic \
researcher-model \
--from-env-file=model.env

Which Secrets and ConfigMaps an agent needs, and the keys inside them, depend on its composition. For a complete concrete set — an email mailbox Secret, a model Secret, and an SSH Secret for the wiki — see the researcher wiki maintainer use case.

Exposed Secret volumes are mounted read-only. The agent is the administrator of its namespace workspace and can manage its namespaced Secrets, but cannot access Secrets in another namespace.

Terminal window
kubectl wait agent/researcher \
--for=condition=Ready \
--timeout=5m
kubectl get agent/researcher -o yaml
kubectl -n agent-researcher get all,pvc,configmap,secret
kubectl -n agent-researcher describe resourcequota agent-workspace

Ready=True means the organization membership, pinned catalogs, credentials, Dotagents profile, namespace workspace and quota guardrails, and runtime Deployment are ready. It does not mean the agent has done any work yet.

If readiness fails, inspect the agent’s conditions first. They distinguish invalid membership, unresolved catalogs, missing credentials, unresolved profiles, and workload failures without exposing secret values.

How a ready agent receives and does work is its composition’s concern — its channel and tools, not the operator. Walk through a concrete end-to-end example in the researcher wiki maintainer use case: email a PDF to the agent and get a threaded reply with a source-traceable wiki commit.

Delete the agent first so its finalizer can remove only its generated namespace, then the organization:

Terminal window
kubectl delete agent/researcher
kubectl delete organization/example-org

Tearing down a local development cluster is covered in CONTRIBUTING.md.