> ## Documentation Index
> Fetch the complete documentation index at: https://docs.e2b.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Kiro

> Run Kiro CLI in a secure E2B sandbox with full filesystem, terminal, and git access.

[Kiro CLI](https://kiro.dev/cli/) is AWS's coding agent for the terminal. E2B provides a pre-built `kiro` template with Kiro CLI already installed.

## CLI

Create a sandbox with the [E2B CLI](https://docs.e2b.dev/cli.md).

```bash theme={"theme":"css-variables"}
e2b sbx create kiro
```

Once inside the sandbox, start Kiro CLI.

```bash theme={"theme":"css-variables"}
kiro-cli
```

## Run headless

Use `kiro-cli chat --no-interactive` to run a single prompt without user input, and `--trust-all-tools` to auto-approve all tool calls.

Headless runs authenticate with a Kiro API key passed as the `KIRO_API_KEY` environment variable. API keys are available on the Kiro Pro, Pro+, Pro Max, and Power plans. Create one in the [Kiro web console](https://app.kiro.dev). On the Free plan, [log in with device flow](#log-in-without-an-api-key) instead.

> [!NOTE]
>
> Auto-approving tool calls is contained by the sandbox: the agent cannot touch your host machine, local files, or credentials. It can still make outbound network requests — internet access is enabled by default. To limit where an auto-approved agent can connect, configure [outbound network rules](https://docs.e2b.dev/network/internet-access.md) (`allowInternetAccess`, plus allow/deny lists by CIDR or hostname). Hostname rules apply to HTTP(S) traffic only; use CIDR rules for other protocols.

```typescript JavaScript & TypeScript theme={"theme":"css-variables"}
import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create('kiro', {
  envs: { KIRO_API_KEY: process.env.KIRO_API_KEY },
})

const result = await sandbox.commands.run(
  `kiro-cli chat --no-interactive --trust-all-tools "Create a hello world HTTP server in Go"`
)

console.log(result.stdout)
await sandbox.kill()
```

```python Python theme={"theme":"css-variables"}
import os
from e2b import Sandbox

sandbox = Sandbox.create("kiro", envs={
    "KIRO_API_KEY": os.environ["KIRO_API_KEY"],
})

result = sandbox.commands.run(
    'kiro-cli chat --no-interactive --trust-all-tools "Create a hello world HTTP server in Go"',
)

print(result.stdout)
sandbox.kill()
```

### Example: work on a cloned repository

```typescript JavaScript & TypeScript theme={"theme":"css-variables"}
import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create('kiro', {
  envs: { KIRO_API_KEY: process.env.KIRO_API_KEY },
  timeoutMs: 600_000,
})

await sandbox.commands.run(
  'git clone --depth 1 https://x-access-token:$GITHUB_TOKEN@github.com/your-org/your-repo.git /home/user/repo',
  { envs: { GITHUB_TOKEN: process.env.GITHUB_TOKEN } }
)

const result = await sandbox.commands.run(
  `cd /home/user/repo && kiro-cli chat --no-interactive --trust-all-tools "Add error handling to all API endpoints"`,
  { onStdout: (data) => process.stdout.write(data), timeoutMs: 0 }
)

const diff = await sandbox.commands.run('cd /home/user/repo && git diff')
console.log(diff.stdout)

await sandbox.kill()
```

```python Python theme={"theme":"css-variables"}
import os
from e2b import Sandbox

sandbox = Sandbox.create("kiro", envs={
    "KIRO_API_KEY": os.environ["KIRO_API_KEY"],
}, timeout=600)

sandbox.commands.run(
    "git clone --depth 1 https://x-access-token:$GITHUB_TOKEN@github.com/your-org/your-repo.git /home/user/repo",
    envs={"GITHUB_TOKEN": os.environ["GITHUB_TOKEN"]},
)

result = sandbox.commands.run(
    'cd /home/user/repo && kiro-cli chat --no-interactive --trust-all-tools "Add error handling to all API endpoints"',
    on_stdout=lambda data: print(data, end=""),
    timeout=0,
)

diff = sandbox.commands.run("cd /home/user/repo && git diff")
print(diff.stdout)

sandbox.kill()
```

### Stream events as JSON

Add `--output-format stream-json` to get the run as JSON Lines on stdout, one event per line. Each event has a `type` and a `data` field. This option implies `--no-interactive`, so you don't need to pass it. Parse each line as it arrives. See [Kiro headless mode](https://kiro.dev/docs/cli/headless/) for the event format.

```typescript JavaScript & TypeScript theme={"theme":"css-variables"}
import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create('kiro', {
  envs: { KIRO_API_KEY: process.env.KIRO_API_KEY },
})

let buffer = ''
await sandbox.commands.run(
  `kiro-cli chat --output-format stream-json --trust-all-tools "Create a hello world HTTP server in Go"`,
  {
    timeoutMs: 0,
    onStdout: (data) => {
      buffer += data
      const lines = buffer.split('\n')
      buffer = lines.pop() ?? ''
      for (const line of lines.filter(Boolean)) {
        const event = JSON.parse(line)
        console.log(event.type, event.data)
      }
    },
  }
)

await sandbox.kill()
```

```python Python theme={"theme":"css-variables"}
import json
import os
from e2b import Sandbox

sandbox = Sandbox.create("kiro", envs={
    "KIRO_API_KEY": os.environ["KIRO_API_KEY"],
})

buffer = ""

def on_stdout(data):
    global buffer
    buffer += data
    *lines, buffer = buffer.split("\n")
    for line in filter(None, lines):
        event = json.loads(line)
        print(event["type"], event["data"])

sandbox.commands.run(
    'kiro-cli chat --output-format stream-json --trust-all-tools "Create a hello world HTTP server in Go"',
    on_stdout=on_stdout,
    timeout=0,
)

sandbox.kill()
```

### Resume a session

Add `--resume` to continue the most recent conversation in the same working directory.

```bash theme={"theme":"css-variables"}
kiro-cli chat --no-interactive --trust-all-tools --resume "Now add tests for the server"
```

## Log in without an API key

On the Kiro Free plan, or when you sign in with AWS Builder ID, GitHub, or Google, log in once per sandbox with device flow instead of an API key. Run the command from a sandbox terminal (see [CLI](#cli)). It prints a URL and a code — open the URL in your browser, confirm the code, and the command finishes once the login is confirmed.

```bash theme={"theme":"css-variables"}
kiro-cli login --license free --use-device-flow
```

After logging in, run headless commands without `KIRO_API_KEY`.

> [!NOTE]
>
> Kiro stores login credentials inside the sandbox, under `/home/user/.local/share/kiro-cli`. They persist across [pause and resume](https://docs.e2b.dev/sandbox/persistence.md), so anyone with access to the sandbox can act with your Kiro account until the sandbox is killed or you run `kiro-cli logout`.

## Build a custom template

If you need to customize the environment (e.g. pre-install dependencies, add config files), build your own template on top of the pre-built `kiro` template.

```typescript JavaScript & TypeScript theme={"theme":"css-variables"}
// template.ts
import { Template } from 'e2b'

export const template = Template()
  .fromTemplate('kiro')
```

```python Python theme={"theme":"css-variables"}
# template.py
from e2b import Template

template = (
    Template()
    .from_template("kiro")
)
```

```typescript JavaScript & TypeScript theme={"theme":"css-variables"}
// build.ts
import { Template, defaultBuildLogger } from 'e2b'
import { template as kiroTemplate } from './template'

await Template.build(kiroTemplate, 'my-kiro', {
  cpuCount: 2,
  memoryMB: 2048,
  onBuildLogs: defaultBuildLogger(),
})
```

```python Python theme={"theme":"css-variables"}
# build.py
from e2b import Template, default_build_logger
from template import template as kiro_template

Template.build(kiro_template, "my-kiro",
    cpu_count=2,
    memory_mb=2048,
    on_build_logs=default_build_logger(),
)
```

Run the build script to create the template.

```bash JavaScript & TypeScript theme={"theme":"css-variables"}
npx tsx build.ts
```

```bash Python theme={"theme":"css-variables"}
python build.py
```

## Related guides

> [card] [Sandbox persistence](https://docs.e2b.dev/sandbox/persistence.md)
>
> Auto-pause, resume, and manage sandbox lifecycle

> [card] [SSH access](https://docs.e2b.dev/sandbox/ssh-access.md)
>
> Connect to the sandbox via SSH for interactive sessions
