4 min read 658 words
Tutorials
AI Agents

Claude Code agents

How to author and deploy claude_code-provider agents that run the Claude Agent SDK loop in dedicated Kubernetes pods.

When to use claude_code

Hessian agents can run with one of several providers (anthropic, openai, azure_openai, hessian). The claude_code provider is different: instead of running the LLM tool loop in-process inside the worker, it spins up a dedicated Kubernetes pod that runs the Claude Agent SDK and the @anthropic-ai/claude-code CLI.

Reach for claude_code when you want:

  • The full tool surface of the Claude Code CLI (Read, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch, Monitor, AskUserQuestion) inside an isolated filesystem.
  • Permission modes that match the standalone Claude Code product (acceptEdits, plan, bypassPermissions, etc.).
  • Strong isolation between the agent and the worker process — each agent invocation runs in its own pod with its own resource limits.

If you just need an LLM tool loop without filesystem access, prefer the anthropic provider — it runs in-process, has no cold-start cost, and supports a much wider tool surface (custom tools, MCP servers, subagents).

Provider config

A claude_code agent’s provider_config object accepts the following fields. The shape is validated at agent-creation time; invalid configs are rejected with a 400.

Field Required Description
allowed_tools Yes Non-empty list of built-in Claude Agent SDK tool names. See supported tools.
api_key_secret_id Yes ID of the Hessian secret that holds the Anthropic API key. Resolved at run start, never embedded in the pod.
permission_mode No One of default, acceptEdits, plan, dontAsk, bypassPermissions. Defaults to default (prompt for every tool use).
`mcp_servers` and `agents` (subagents) are not yet supported and will be rejected. They're planned for Phase 2.

Supported tools

allowed_tools accepts any subset of:

  • Read, Write, Edit — filesystem access inside the pod
  • Bash — shell execution
  • Glob, Grep — search
  • WebFetch, WebSearch — outbound HTTP
  • Monitor — long-running stream observation
  • AskUserQuestion — human-in-the-loop input

Anything outside this list is rejected. The whitelist is enforced server-side, not just at the SDK layer.

Setting up the Anthropic API key

Store your Anthropic API key as a Hessian secret:

from hessian import Hessian

h = Hessian()
secret = h.secrets.create(
    name="anthropic-api-key",
    value="sk-ant-...",
)
print(secret.id)  # use this as api_key_secret_id below

The secret is encrypted at rest. The bootstrap inside the pod fetches it from the Hessian API at run start using the pod’s own API key, so the Anthropic key never appears in the pod spec or environment.

Defining a claude_code agent

from hessian import Hessian, Agent

h = Hessian()

agent = h.agents.create(
    name="repo-reader",
    provider="claude_code",
    llm_model="claude-sonnet-4-6",
    system_prompt="You read code and answer questions about it.",
    provider_config={
        "allowed_tools": ["Read", "Glob", "Grep"],
        "permission_mode": "acceptEdits",
        "api_key_secret_id": "sec_...",
    },
)

Use this agent in a workflow the same way as any other agent — wire it into a workflow entity, trigger a run, and the worker will dispatch a claude_code pod for that entity.

How it runs

When a workflow run hits a claude_code entity:

  1. The worker creates a Kubernetes Job (one Job per agent invocation).
  2. hessian-init writes the bootstrap script and a copy of the runner binary into a shared /hessian volume.
  3. hessian-deps either copies a pre-baked virtualenv into /hessian (fast path) or installs Node + the Claude CLI + claude-agent-sdk at runtime (slow path).
  4. hessian-task runs the bootstrap, which fetches the agent’s config + Anthropic API key from the Hessian API and drives the Claude Agent SDK loop.
  5. Tool calls and assistant messages stream back to the Hessian API as agent_output_items — the run trace UI renders them the same way as any other agent.

Cold-start performance

The slow path takes about 45 seconds before the agent does any real work. For development that’s fine. For production, build the pre-baked image once and point the worker at it with --k8s-claude-agent-image:

# Local single-node clusters (kind/minikube): build and load the dev tag directly.
make docker-claude-agent
hessian worker start 
  --type kubernetes 
  --k8s-claude-agent-image hessian/claude-agent:dev

On remote clusters the node won’t be able to pull a local-only :dev tag and the pod will land in ImagePullBackOff. Push the image to a registry the cluster can reach first, then pass that tag to --k8s-claude-agent-image. The Kubernetes worker docs walk through the build + push pattern.

This collapses hessian-deps from ~45s to ~2s. See Claude Code agents in the Kubernetes worker docs for the precedence rules and rollout guidance.

Limitations (Phase 1)

  • No MCP server support yet.
  • No subagent (agents) support yet.
  • The tool whitelist is fixed; you can’t register custom tools the way you can with the anthropic provider.
  • One pod per agent invocation — there’s no warm-pool pooling, so the cold-start cost is paid every time. The pre-baked image keeps it tolerable.