For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Standalone sandboxes
Run commands and transfer files in a scratch environment that is independent of any agent Session.
A Sandbox is a scratch environment for running commands and working with files. A Sandbox is scoped to the caller who created it, and it expires on a timer. You create one from a SandboxTemplate, run processes and move files in it, then delete it or let it expire.
A Sandbox and 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 are separate runtimes with separate configuration and separate lifetimes. Neither resource references the other.
| What you configure | What runs | What you call it with |
|---|---|---|
| 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 that pairs an AgentTemplate with a Harness | A Session | A2A interactions and tasks |
| A SandboxTemplate that defines a tools environment | A Sandbox | Guest process and file operations |
An agent can create a Sandbox of its own through the kagent Model Context Protocol (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, using the same service that a person calls. The Sandbox’s lifetime stays independent of the agent’s Session.
Before you begin
Install kagent and set the following
config.sandboxesvalues on the installation. Sandbox preparation needs a guest image. The chart does not ship a default guest image, so a SandboxTemplate does not become ready until you set one. The remaining values allocate the compute that each Sandbox runs on and bound how long it lives.config: sandboxes: guestImage: ghcr.io/kagent-dev/kagent/sandbox-guest@sha256:d3c444e3f5472598ff520255b72cfcb9ecdf22815fd87747315aeaf0520801c3 cpu: "1" memory: 1Gi defaultTtl: 3600s maxTtl: 86400sA SandboxTemplate cannot override these values, so they apply to every Sandbox in the installation.
Value Default Description config.sandboxes.guestImage""The digest-pinned guest image, as a complete reference. This value is required. The controller passes the reference to Agent Substrate unchanged and does not resolve tags, so pin a digest. Setting global.imageRegistryrewrites the registry host of this reference.config.sandboxes.cpu1CPU allocated to each Sandbox. config.sandboxes.memory1GiMemory allocated to each Sandbox. config.sandboxes.defaultTtl3600sLifetime applied when kagent sandbox createomits--ttl. Durations in theconfigblock take protobuf seconds notation, so3600srather than1h.config.sandboxes.maxTtl86400sUpper bound on any requested lifetime, which the controller caps at 86400s. A Sandbox expires the configured interval after it is created, regardless of how recently a command ran in it.Download the kagent CLI. The
--versionflag matches the CLI to the release that these docs cover.curl https://raw.githubusercontent.com/kagent-dev/kagent/refs/heads/main/scripts/get-kagent | bash -s -- --version v1.0.0-alpha17To read the Sandbox ID from the CLI’s JSON output, install
jq.
Create a SandboxTemplate
A SandboxTemplate is a namespaced api.kagent.dev/v1alpha3 resource that prepares a reusable runtime. Applying one does not allocate a Sandbox.
Apply a SandboxTemplate.
kubectl apply -f - <<EOF apiVersion: api.kagent.dev/v1alpha3 kind: SandboxTemplate metadata: name: scratch namespace: kagent spec: workload: # Replace with your own tools image and its digest. image: registry.example.com/tools@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa env: - name: LANG value: C.UTF-8 substrate: workerPoolRef: name: kagent-default snapshotPolicy: location: s3://ate-snapshots/kagent/ EOFReview the following table to understand this configuration. For the complete schema, see the API reference.
Field Required Description workload.imageYes The tools image, pinned by sha256digest. A tag alone is rejected, because a prepared revision must be reproducible.envNo Environment defaults for the guest, up to 100. Each entry sets a literal value, which is required and can be an empty string. The schema does not define a secret-backed source, so the API server rejects acredentialRefentry as an unknown field.substrate.workerPoolRef.nameYes The WorkerPool that this template’s Actors are scheduled onto. substrate.snapshotPolicy.locationYes The 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. egressPolicyRefsNo Up to 16 EgressPolicy resources in the template’s namespace that grant the Sandbox outbound access. When this field is omitted, the Sandbox does not have outbound access. For more information, see Egress policies. A SandboxTemplate does not take a startup command or a guest toggle. kagent supplies the guest entrypoint from the image that
config.sandboxes.guestImagereferences. That image replaces the tools image’s own entrypoint. Your tools image contributes the installed programs and nothing else.Confirm that the template prepared a revision before you create a Sandbox from it.
kubectl get sandboxtemplate scratch -n kagent \ -o jsonpath='{range .status.conditions[?(@.type=="Ready")]}{.status} {.reason} {.message}{end}'
Editing a template prepares a new revision. A Sandbox that already exists keeps the revision that it was created from. Deleting the template retires preparation but does not remove the Sandboxes that pinned it.
Run a command
Each kagent sandbox command makes one lifecycle attempt. The create command takes a stable --request-id value. To retry the same creation, reuse that value.
Warning
By default, the gateway denies every outbound connection from a Sandbox. When the template does not select an EgressPolicy resource, kagent compiles an empty egress policy for the Sandbox. A command that fetches a package, clones a repository, or calls an API then fails. To allow a destination, select an EgressPolicy in the SandboxTemplate’s spec.egressPolicyRefs field, as described in Grant access to a destination. Otherwise, move what a command needs into the Sandbox with kagent sandbox upload.
List the templates that your installation prepared.
kagent sandbox templatesExample output:
NAMESPACE NAME IMAGE kagent scratch registry.example.com/tools@sha256:aaaa...Create a Sandbox, and save its ID.
export SANDBOX_ID=$(kagent sandbox create scratch --request-id my-first-sandbox -o json | jq -r '.id') echo $SANDBOX_IDTo see the table, run the command without
-o json.STATEandOPERATIONboth matter, because lifecycle work can still be pending when a call returns.ID TEMPLATE STATE OPERATION EXPIRES FAILURE 0198c3f1-2a44-7c90-b5e1-9d8f3a7b2c04 kagent/scratch RUNTIME_STATE_READY RUNTIME_OPERATION_NONE 2026-10-01T16:30:00ZRun a command in the Sandbox. The default working directory is
/data/workspace, which the guest creates before it reports ready.kagent sandbox exec $SANDBOX_ID -- python --versionA timeout stops the command from waiting, but the remote process keeps running. To reconnect to a process that outlived its
exec, pass its process ID tokagent sandbox wait.kagent sandbox killsendsSIGKILLto a process and returns when the guest delivers the signal. The command does not wait for the process to exit, so its output reports the process state and omits the exit code. To read the exit code, pass the process ID tokagent sandbox wait.Move a file in, run against it, and read the result back out.
kagent sandbox upload $SANDBOX_ID ./script.py /data/workspace/script.py kagent sandbox exec $SANDBOX_ID -- python /data/workspace/script.py kagent sandbox download $SANDBOX_ID /data/workspace/out.txt ./out.txtWhen you are finished, delete the Sandbox to release its compute immediately. Deletion is optional, because the Sandbox expires on its own.
kagent sandbox delete $SANDBOX_ID
Important
Suspending a Sandbox interrupts whatever it is doing. kagent sandbox suspend does not wait for any process, output stream, or file transfer, so a command can be cut off mid-run and a file can be left partly written. Resuming restores the durable files under /data, but a process handle does not survive, because the guest holds it in memory. Suspend a Sandbox only when you can repeat whatever it was running.
Reach a Sandbox from an agent
kagent’s Helm chart installs a RemoteMCPServer named kagent-api in the controller’s namespace, pointing at the controller’s own /mcp endpoint. This server exposes the Session and checkpoint tools alongside the sandbox tools, so an AgentTemplate reaches Sandboxes through an ordinary tool binding.
tools:
- mcp:
server:
kind: RemoteMCPServer
name: kagent-api
tools:
- list_sandbox_templates
- create_sandbox
- list_sandboxes
- write_sandbox_file
- read_sandbox_file
- read_sandbox_outputsAn agent that creates a Sandbox owns it under the identity that the MCP connection authenticated, not under the identity of the person that the agent is talking to. A Session share token does not grant access to a Sandbox. To have an agent act for the person who invoked it, configure credential propagation by setting config.runtimeDefaults.tokenPropagation.enabled to true. The kagent runtime then passes the caller’s credentials and identity to the MCP servers that you trust.
The MCP transfer limits are tighter than the command line’s. A gRPC file transfer is bounded at 64 MiB. write_sandbox_file and read_sandbox_outputs are bounded at 1 MiB and use base64. Output reads return continuation byte offsets.
An agent that starts a process with start_sandbox_process polls get_sandbox_process to learn when the process finishes. The state field reads PROCESS_STATE_RUNNING until the process exits, then PROCESS_STATE_EXITED. The exit_code field appears only in the exited state, and reads 0 for a successful exit. kill_sandbox_process sends SIGKILL in the same way as kagent sandbox kill, so the agent must poll get_sandbox_process for the exit code.
When an agent must inspect a result file, use read_sandbox_file. The tool returns content that the model reads directly, not data_base64. The shape of the content depends on the file type.
Text returns as numbered lines. offset sets the first line to read, counting from 1. limit sets the number of lines, and defaults to 2000. A page also stops at 32 KiB, whichever bound it reaches first. A line longer than 2000 bytes is truncated to 2000 bytes and marked [line cut]. A page that stops before the end of the file reports the offset to continue from.
A PNG, JPEG, or GIF file of at most 10 MiB returns as an image. The claude and codex Harness runtimes resize those images for their models. A larger image returns a message asking the agent to write a smaller copy in the Sandbox. Every other file type returns a description of the file, not its bytes.