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 no agent conversation owns.
A Sandbox is a scratch environment for running commands and working with files. It is scoped to the caller who created it, it expires on a timer, and no agent conversation owns it. 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 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 agent’s conversation and the Sandbox’s lifetime stay independent of each other.
Before you begin
Install kagent and set the following
controller.sandboxvalues on the installation. Sandbox preparation needs a guest image digest, and the chart ships no default, so a SandboxTemplate never becomes ready until you set one. The remaining values allocate the compute that each Sandbox runs on and bound how long it lives.controller: sandbox: guestImage: digest: sha256:1821780ef01958f63cb9a1a1d9a175f7e386e7c72859dd29ab86d8644a47d2d4 cpu: 1 memory: 1Gi defaultTTL: 1h maxTTL: 24hA SandboxTemplate cannot override these values, so they are the installation’s policy rather than a per-template choice.
Value Default Description controller.sandbox.guestImage.digest""The digest-pinned guest image. Required: preparation fails without it. The controller passes the digest to Agent Substrate unchanged and resolves no tags, so supply a digest rather than a tag. controller.sandbox.cpu1CPU allocated to each Sandbox. controller.sandbox.memory1GiMemory allocated to each Sandbox. controller.sandbox.defaultTTL1hLifetime applied when kagent sandbox createomits--ttl.controller.sandbox.maxTTL24hUpper bound on any requested lifetime. Note that activity does not extend a Sandbox’s lifetime. A Sandbox expires the configured interval after it is created, however 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-alpha7Install
jqto read the Sandbox ID out of the CLI’s JSON output.
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 may be an empty string. The schema defines no 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. A SandboxTemplate takes no startup command and no guest toggle. kagent supplies the guest entrypoint from the image that
controller.sandbox.guestImage.digestnames. 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 it was created from, and deleting the template retires preparation without removing the Sandboxes that pinned it.
Run a command
Warning
The gateway denies every outbound connection from a Sandbox. kagent compiles an empty egress policy as it creates a Sandbox, and the gateway rejects any destination that the policy does not name, so a command that fetches a package, clones a repository, or calls an API fails. The SandboxTemplate schema defines no destination field, so no configuration opens one. Move what a command needs into the Sandbox with kagent sandbox upload.
Each kagent sandbox command makes one lifecycle attempt rather than retrying for you, so create takes a stable --request-id that you reuse to retry the same creation.
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_IDRun the command without
-o jsonto see the table instead.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 rather than stopping the remote process. To reconnect to a process that outlived its
exec, pass its 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.txtDelete the Sandbox when you are finished. Deleting is not required, because the Sandbox expires on its own. Deleting it releases the compute immediately.
kagent sandbox delete $SANDBOX_ID
Important
Suspending a Sandbox interrupts whatever it is doing. kagent sandbox suspend waits for no 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_sandboxesAn agent that creates a Sandbox owns it under whatever identity the MCP connection authenticated, not under the identity of the person it is talking to. A Session share token grants no access to a Sandbox. To have an agent act for the person who invoked it, configure credential propagation. The Go kagent runtime reads KAGENT_PROPAGATE_TOKEN=true to pass 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. An MCP transfer or output read is bounded at 1 MiB, encodes bytes as base64, and returns a continuation offset for reading more.