Skip to content
This documentation covers the kagent 1.0 alpha. For the latest 0.x release, see the 0.x docs.

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

Agent harness

Page as Markdown

Configure a Harness, the resource that defines which runtime executes an agent and what infrastructure it runs on.

Review configuration guidelines and reference for the Harness resource: every field it takes, the four runtimes it can select, and what each runtime supports. To understand a Harness and why an Agent, rather than the Harness itself, names the AgentTemplate that runs on it, see the core concepts.

Configure a Harness

The following configuration is for a complete Harness resource. Only workload, substrate, and one runtime block are required.

kubectl apply -f - <<EOF
apiVersion: api.kagent.dev/v1alpha3
kind: Harness
metadata:
  name: my-harness
  namespace: kagent
spec:
  # Exactly one runtime block: kagent, codex, claude, or byo.
  kagent: {}
  workload:
    image: ghcr.io/kagent-dev/kagent/golang-adk@sha256:215417b5401310bb496ae1687bb8622f93fd19991a218c6a218987836e71da84
  env:
    - name: KAGENT_LOG_LEVEL
      value: info
  substrate:
    workerPoolRef:
      name: kagent-default
    snapshotPolicy:
      location: s3://ate-snapshots/kagent/
EOF

Review the following table to understand this configuration. For more information, see the API reference.

FieldRequiredDescription
One of kagent, codex, claude, byoYesThe runtime that executes the agent. Naming none, or more than one, is rejected. For the available runtimes, see Choose a runtime.
workload.imageYesThe runtime image, pinned by sha256 digest. A tag alone is rejected, because a revision must be reproducible.
workload.commandFor byoOverrides the image entrypoint, up to 32 entries. Required for the byo runtime, optional otherwise. Every runtime honors an explicit value, the kagent runtime included, whatever language its image is written in.
workload.argsNoOverrides the image arguments, up to 64 entries. An override that you omit stays unset rather than taking a default.
envNoEnvironment variables for the runtime, up to 100. Each entry sets a literal value, which is required and can be an empty string. The schema defines no secret-backed source, so the API server rejects a credentialRef entry as an unknown field. Put credentials on a ModelConfig or a RemoteMCPServer instead. For more information, see About model providers.
substrate.workerPoolRef.nameYesThe WorkerPoolWorkerPoolA Kubernetes custom resource declaring how many Workers to keep running and which sandbox class they use. An operator must provision one before any Agent can compile.Learn more that this Harness’s Actors are scheduled onto. An operator must provision one before any agent can run.
substrate.snapshotPolicy.locationYesThe object storage location for Actor snapshotsSnapshotThe stored state that an Actor suspends to, held in object storage. Resuming restores the Actor from its most recent snapshot, which is what makes suspending idle agents cheap.Learn more.

A Harness names no AgentTemplate. An AgentAgentA Kubernetes custom resource that pairs one AgentTemplate with one Harness. Each side takes either an inline spec or a reference to an existing resource, and the controller compiles the pair into a revision.Learn more pairs the two through either spec.harnessRef or an inline spec.harness, so whoever writes the Agent decides which template runs on which Harness. For more information about the pairing, see Core concepts.

A command or argument override belongs to the revision that kagent prepares. Changing one prepares a new revision rather than altering a running agent. A SessionSessionA running conversation with one Agent. Unlike the resources it is built from, a Session is not a Kubernetes resource: kagent's gRPC API creates it and its PostgreSQL database tracks it.Learn more pinned to an earlier revision keeps the command it was prepared with until it moves to the new one.

Choose a runtime

A Harness names exactly one of the following four runtimes, and that choice decides what executes an agent and how much of kagent’s feature set the agent can use.

RuntimeWhat it runsWhen to use it
kagentkagent’s own Go and Python enginesYou want the full feature set: every model provider, agent-as-tool composition, skills, plugins, and long-term memory.
codexThe Codex coding agentYou want Codex to do the work, and your model is OpenAI or an OpenAI-compatible Bedrock deployment.
claudeThe Claude coding agentYou want Claude to do the work, with Anthropic, Bedrock, or Anthropic on Vertex AI as the model.
byoAny container image of your own that implements kagent’s A2A contractYou have an agent framework kagent does not adapt, and you would rather bring the image than the integration. For more information, see Bring your own agent.

The kagent and byo runtimes compile through the same path, so they accept the same model providers and the same AgentTemplate features, except structured output, which only the kagent runtime supports. The codex and claude runtimes are purpose-built adapters, and each accepts a narrower slice.

Runtime-specific settings

spec.kagent is the only runtime block that takes settings of its own. The rest are empty.

spec:
  kagent:
    memory:
      modelConfigRef:
        name: embedding-model-config
      ttlDays: 30
FieldDescription
memory.modelConfigRef.nameThe ModelConfig supplying the embedding model, in the Harness’s namespace. Required when memory is set.
memory.ttlDaysHow many days a stored memory entry stays valid. Minimum 1. When omitted, the server applies a default of 15 days.

Setting memory gives every agent on this Harness memory that persists across conversations. For how agents store and retrieve it, see Agent memory.

Setting compaction summarizes older session events so an agent’s prompt stays bounded as a conversation grows. For the two strategies and the rules the API server enforces, see Context management.

Model provider support

The runtime that a Harness selects decides which ModelConfig an Agent that runs on it can use. This table covers every value that the ModelConfig provider field accepts, including the four that kagent 1.0 rejects on every runtime.

Providerkagentbyocodexclaude
OpenAI✅✅✅❌
Anthropic✅✅❌✅
Bedrock✅✅✅✅
AnthropicVertexAI❌❌❌❌
GeminiVertexAI❌❌❌❌
AzureOpenAI✅✅❌❌
Gemini✅✅❌❌
Ollama✅✅❌❌
SAPAICore❌❌❌❌
Foundry✅✅❌❌
Mistral❌❌❌❌

kagent rejects AnthropicVertexAI, GeminiVertexAI, and SAPAICore on every runtime, because each authenticates with a credential that the egress gateway cannot place in an HTTP header. The ModelConfig never compiles, so no agent can use these providers. For the alternatives, see About model providers.

kagent rejects Mistral for a different reason. The controller does not resolve the provider at all, so a Mistral ModelConfig reports unsupported model provider: Mistral and compiles no revision.

Some supported combinations still carry restrictions.

CombinationRestriction
codex with OpenAIRequires openAI.apiFormat: responses, and accepts no other openAI settings beyond baseUrl.
codex with BedrockAccepts only OpenAI gpt-* model IDs, and no bedrock settings beyond region.
claude with AnthropicAccepts no anthropic settings beyond baseUrl.
claude with BedrockAccepts no bedrock settings beyond region.
Bedrock on any runtimeThe Secret must hold an AWS_BEARER_TOKEN_BEDROCK key. A Secret of IAM access keys is rejected, because IAM signs each request locally.

Important

Neither codex nor claude accepts a ModelConfig that sets defaultHeaders, tls, or apiKeyPassthrough. Separately, every runtime rejects a credential that the egress gateway cannot place in an HTTP header, such as an IAM key pair or a Google service account key. For more information about that limitation, see About model providers.

Tool and skill support

The coding-agent runtimes also constrain what an AgentTemplate can ask for.

ConstraintApplies to
A subagent binding cannot itself carry tools, skills, plugins, or nested agents, and must use the same provider and credentials as the agent that binds it.codex, claude
An MCPMCPModel Context Protocol, an open protocol for exposing tools and resources to a model. kagent reaches an MCP server through a RemoteMCPServer resource, and an AgentTemplate binds individual tools from it.Learn more server is bound whole. Claude does not support partial tool selection, so the agent sees every tool the server offers rather than only the ones a binding names. The compiler warns rather than failing.claude
A RemoteMCPServer must use the STREAMABLE_HTTP protocol. SSE is rejected.codex

The kagent and byo runtimes take the full set. For more information about what an AgentTemplate can bind, see About tools.

Telemetry content settings

Tracing carries the prompts and replies that an agent exchanges with a model, and so does log export on the claude runtime. Two settings in the kagent Helm chart decide whether that content leaves the runtime, and each one reaches a different set of runtimes. Both default to false, and both take effect only where tracing or log export is already enabled.

otel:
  captureSensitiveContent: false
  logging:
    captureRawApiBodies: false
SettingWhat it includesApplies to
otel.captureSensitiveContentPrompts, tool details, and assistant replies in the runtime’s telemetry. On the kagent runtime, the content appears in the spans for each model call. On the claude runtime, tool results require tracing, and assistant replies require log export through otel.logging.kagent, codex, claude
otel.logging.captureRawApiBodiesThe complete provider API request and response bodies. This setting returns more than otel.captureSensitiveContent does, and it takes effect only when otel.logging.enabled is true.claude

The controller sets OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT in every compiled runtime from otel.captureSensitiveContent, so setting that variable in the Harness spec.env field has no effect.

The controller sends the byo runtime no telemetry configuration, so neither setting reaches it. A byo image that implements OpenTelemetry itself reads whatever the Harness spec.env field holds. For more information, see Tracing.

Check that a Harness is ready

The READY column reports whether a Harness’s dependencies resolved.

kubectl get harness -n kagent

A Harness that is not Ready most often names a WorkerPool that does not exist yet. For the specific reason, read its conditions with kubectl describe harness <harness-name> -n kagent.

Ready covers the Harness’s own dependencies, not whether a given agent runs on it. Whether a template compiles against this Harness is reported on the Agent that pairs the two, because an AgentTemplate carries no status of its own. For that check and the conditions it reports, see Your first agent.

Next steps