Short version: kagent has four harnesses, and the one you pick decides what runs your agent and how much of kagent it gets to use. My Claude Code harness post covers one of them. This is the map of all four.
Disclosure: I work at Solo.io, which created kagent (now an open-source project) and sells Solo Enterprise for kagent. This post is built from the public Solo Enterprise for kagent harness docs as of 2026-10-30. kagent 1.0 is alpha, so field names can still move.
What a Harness is
A Harness is the Kubernetes resource that says how an agent is allowed to run: which runtime, which image, and which Agent Substrate worker pool and snapshot bucket. It runs nothing by itself. An Agent pairs one Harness (spec.harnessRef) with one AgentTemplate (prompt, model, tools), and the controller compiles that pair into an immutable, digest-identified revision. For the bigger picture, see what a cloud-native agent harness is
and Agent Substrate
.
The four harnesses
| Harness | What it runs | Use it when |
|---|---|---|
kagent | kagent’s built-in Go engine | You want a declarative agent (prompt, skills, plugins, MCP) and the widest feature set |
claude | Claude Code | You want Claude doing the loop, on Anthropic or Bedrock |
codex | Codex | You want Codex doing the loop, on OpenAI or Bedrock gpt-* |
byo | Your own image implementing kagent’s A2A contract | You already built the agent in another framework |
Deep dives: Codex harness · Claude Code harness · BYO and native kagent harness posts coming next.
Model providers
| Provider | kagent | byo | codex | claude |
|---|---|---|---|---|
| OpenAI | ✅ | ✅ | ✅ | ❌ |
| Anthropic | ✅ | ✅ | ❌ | ✅ |
| Bedrock | ✅ | ✅ | ✅ | ✅ |
| AzureOpenAI, Gemini, Mistral, Ollama, Foundry | ✅ | ✅ | ❌ | ❌ |
| AnthropicVertexAI, GeminiVertexAI, SAPAICore | ❌ | ❌ | ❌ | ❌ |
The last row is a design choice, not a gap someone forgot. kagent reaches models through an egress gateway that injects the credential as a header. Vertex needs a mounted service-account file and SAP AI Core does its own OAuth exchange, so neither fits. Same reason Bedrock wants an AWS_BEARER_TOKEN_BEDROCK key, not IAM access keys.
What each harness drops
Claude Code and Codex run their own agentic loops, so they can’t take everything an AgentTemplate offers.
| Constraint | Applies to |
|---|---|
| Structured output rejected | codex, claude, byo |
MCP tokenPassthrough rejected | codex, claude |
ModelConfig with defaultHeaders, tls or tokenPassthrough rejected | codex, claude |
| Subagents can’t carry their own tools/skills and must share provider + creds | codex, claude |
MCP server must be STREAMABLE_HTTP (SSE rejected) | codex |
| Partial MCP tool selection binds the whole server (warning, not error) | claude |
| File attachments in the kagent UI chat | kagent only |
That Claude one is worth caring about. If you bound three tools from an MCP server, the agent gets all of them. It shows up in status.warnings, and a lot of people won’t look there. If tool scoping matters, enforce it at the gateway too.
Rules every harness shares
- Images pinned by
sha256digest. A bare tag is rejected. Omit the image on kagent/codex/claude to get the release’s built-in one. - A WorkerPool and snapshot location are required. A missing WorkerPool (
WorkerPoolNotFound) is the most common failure. - At most 32 env vars per Actor, 32,768 chars per value, and kagent’s own variables count against that.
- CA trust variables (
SSL_CERT_FILE,NODE_EXTRA_CA_CERTS, etc.) are reserved, because the egress gateway intercepts HTTPS. - Credentials don’t go in
env. They live in a ModelConfig or RemoteMCPServer.
How to tell if it worked
Check the Agent, not the Harness. A Harness has no status of its own, so its READY column is always empty.
kubectl describe agent <agent-name> -n kagent
Look at ResolvedRefs (does everything exist), Compatible (does the harness accept this config) and Ready (is capacity up).
My take
Default to kagent. Reach for claude or codex when you specifically want that loop’s behavior and you can live with whole-server MCP binding or Streamable-HTTP-only tools. Use byo when the agent already exists and rewriting it isn’t worth it. Whichever you choose, the harness is a policy object, so pick it the way you’d pick a security boundary.