kagent Harnesses Compared: kagent vs Claude Code vs Codex vs BYO

Part of: Agent Runtimes

The four kagent 1.0 harnesses side by side: what each runs, which model providers it takes, what it drops from an AgentTemplate, and how to pick one.

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

HarnessWhat it runsUse it when
kagentkagent’s built-in Go engineYou want a declarative agent (prompt, skills, plugins, MCP) and the widest feature set
claudeClaude CodeYou want Claude doing the loop, on Anthropic or Bedrock
codexCodexYou want Codex doing the loop, on OpenAI or Bedrock gpt-*
byoYour own image implementing kagent’s A2A contractYou already built the agent in another framework

Deep dives: Codex harness · Claude Code harness · BYO and native kagent harness posts coming next.

Model providers

Providerkagentbyocodexclaude
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.

ConstraintApplies to
Structured output rejectedcodex, claude, byo
MCP tokenPassthrough rejectedcodex, claude
ModelConfig with defaultHeaders, tls or tokenPassthrough rejectedcodex, claude
Subagents can’t carry their own tools/skills and must share provider + credscodex, 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 chatkagent 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 sha256 digest. 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.

Frequently asked questions

Which kagent harness should I use?

Use the kagent harness unless you have a reason not to. It runs kagent’s built-in Go engine and accepts every AgentTemplate feature and every supported model provider. Pick claude if you want Claude Code doing the work on Anthropic or Bedrock, codex if you want Codex on OpenAI or Bedrock gpt-* models, and byo if you already have an agent built in another framework that implements kagent’s A2A contract.

How many harnesses does kagent have?

Four: kagent, claude, codex and byo. A Harness resource names exactly one of them. Naming none, or more than one, is rejected.

Can kagent run Claude Code and Codex?

Yes. The claude harness runs Claude Code against Anthropic or Bedrock, and the codex harness runs Codex against OpenAI (with apiFormat: responses) or Bedrock gpt-* models. Both accept a narrower set of AgentTemplate features than the kagent harness, and neither supports structured output.

Which kagent harness supports structured output?

Only the kagent harness. Structured output is rejected on codex, claude and byo.

Disagree or have a war story? Reply on X