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

# Choose a Catalog Agent

> List the agents your workspace can launch, inspect what one runs, and choose how it gets model access.

A catalog agent is a ready-made agent that BoxRouter maintains. Its manifest lists its setup commands, the command that starts it, and
the model keys it accepts. Launch one by name, then sign in inside its terminal or pass a saved key with
`--secret`.

The ten interactive agents come preinstalled in a dedicated agents image ([versions](https://boxrouter.ai/docs/image-contents.md#agents-image)), so a launch typically takes a few seconds. The two [hosted services](#hosted-agent-services) run unattended and install their runtimes during launch. One polls a Claude Managed Agents environment for tool calls; the other connects an OpenAI Agents API session.

**Before You Begin:** The [CLI](https://boxrouter.ai/docs/cli.md#install), `jq`, and an API key that can create sandboxes and read the catalog. Run the commands in an interactive terminal.

## List and Inspect

`boxrouter agents` prints the catalog as JSON, the same list `GET /agents` returns. Each entry shows the agent's `name` and `description`, whether it is `interactive`, how it gets
model access (`model_access` and `sign_in`), its `ports`, and the secret names it needs.

```python Python theme={"theme":"css-variables"}
from boxrouter import BoxRouter

with BoxRouter() as client:
    for agent in client.agents.list().agents:
        print(f"{agent.name}\tinteractive={agent.interactive}")
```

```typescript TypeScript theme={"theme":"css-variables"}
import { BoxRouter } from '@boxrouter/sdk';

const client = new BoxRouter();
try {
  const page = await client.agents.list();
  for (const agent of page.agents) console.log(`${agent.name}\tinteractive=${agent.interactive}`);
} finally {
  await client.close();
}
```

```bash CLI theme={"theme":"css-variables"}
boxrouter agents | jq -r '.agents[] | "\(.name)\tinteractive=\(.interactive)"'
```

Entries with `interactive=true` connect your terminal to the agent once the sandbox is ready. The others
start their command and return right away, so a successful launch doesn't tell you the work finished. Their inputs are listed under
[Hosted agent services](#hosted-agent-services).

Two reads show more about one agent. Neither prints a secret value.

```python Python theme={"theme":"css-variables"}
import json

from boxrouter import BoxRouter

with BoxRouter() as client:
    entry = next(agent for agent in client.agents.list().agents if agent.name == "codex").to_dict()
    print(json.dumps({"model_access": entry.get("model_access"), "sign_in": entry.get("sign_in")}))

    details = client.agents.get("codex")
    print(json.dumps(details.manifest.to_dict()))
```

```typescript TypeScript theme={"theme":"css-variables"}
import { BoxRouter } from '@boxrouter/sdk';

const client = new BoxRouter();
try {
  const page = await client.agents.list();
  const entry = page.agents.find(agent => agent.name === 'codex');
  if (!entry) throw new Error('codex is not in the catalog');
  console.log(JSON.stringify({ model_access: entry.model_access, sign_in: entry.sign_in }));

  const details = await client.agents.get('codex');
  console.log(JSON.stringify(details.manifest));
} finally {
  await client.close();
}
```

```bash CLI theme={"theme":"css-variables"}
boxrouter agents show codex
boxrouter api agents get codex
```

The first read gives the model-access options and the sign-in path (`agents show` in the CLI). The second returns the full
manifest, including `setup`, `command` and `env`: read it to see exactly what runs in your sandbox.
The [manifest reference](https://boxrouter.ai/docs/launch/manifest.md) defines each field.

## Give an Agent Model Access

You can start an interactive agent without selecting a saved secret. Follow its terminal instructions
to sign in or configure model access.

To use an API key instead, save it as a [workspace secret](https://boxrouter.ai/docs/launch/secrets.md) under a name the agent recognizes, then
select that name at launch. The name tells BoxRouter how to configure the agent for that model service.

The agent and any command it runs can read the value. Saving from the CLI needs `credentials:manage`
on your BoxRouter API key and replaces the saved value if the name already exists.

```python Python theme={"theme":"css-variables"}
from getpass import getpass

from boxrouter import BoxRouter
from boxrouter.models import PutSecret

with BoxRouter() as client:
    client.api.secrets.put("ANTHROPIC_API_KEY", body=PutSecret(value=getpass("ANTHROPIC_API_KEY: ")))
```

```typescript TypeScript theme={"theme":"css-variables"}
import { BoxRouter } from '@boxrouter/sdk';

const value = process.env.ANTHROPIC_API_KEY;
if (!value) throw new Error('Set ANTHROPIC_API_KEY in your environment');

const client = new BoxRouter();
try {
  await client.api.secrets.put({ path: { name: 'ANTHROPIC_API_KEY' }, body: { value } });
} finally {
  await client.close();
}
```

```bash CLI theme={"theme":"css-variables"}
boxrouter secrets set ANTHROPIC_API_KEY
```

Enter the model key at the hidden prompt (Python) or set it in your environment (TypeScript). After the call finishes, launch the agent:

```python Python theme={"theme":"css-variables"}
from boxrouter import BoxRouter

with BoxRouter() as client:
    with client.sandboxes.launch("claude-code", secret_names=["ANTHROPIC_API_KEY"]) as box:
        print("Sandbox:", box.id)
```

```typescript TypeScript theme={"theme":"css-variables"}
import { BoxRouter } from '@boxrouter/sdk';

await using client = new BoxRouter();
await using box = await client.sandboxes.launch('claude-code', { secretNames: ['ANTHROPIC_API_KEY'] });
console.log('Sandbox:', box.id);
```

```bash CLI theme={"theme":"css-variables"}
boxrouter launch claude-code --secret ANTHROPIC_API_KEY --rm
```

The CLI opens Claude Code in your terminal. The SDK returns the sandbox once the launch is ready, without
attaching your keyboard. The example prints the sandbox ID, and leaving the block requests deletion.

In the CLI, send a short prompt to check that the agent can
reach the model service. Exit the agent when you finish; `--rm` requests sandbox deletion after
the terminal session ends. If cleanup fails, follow the CLI's cleanup instructions.

`secrets set` reads the value from stdin or a hidden prompt, so it never lands in your shell history.
The dashboard's **Secrets** page also saves one. Names are case sensitive, so `anthropic_api_key` is not recognized.

Other secrets you select reach
the sandbox as plain environment variables and configure no model service. Credits cover sandbox compute
only; your model account bills the model calls ([Cost](https://boxrouter.ai/docs/cost.md)).

Select at most one recognized name per launch. If you select several that configure different
model services, the launch is refused with `422 invalid_request` (`details.reason` is
`model_access_ambiguous`, and `details.names` lists them) before any sandbox exists. Remove all but one and retry.
Other secrets stay plain environment variables.

| Agent | Model Access | Sign-in Path |
| - | - | - |
| `claude-code` | To use the Anthropic API, add `ANTHROPIC_API_KEY`. To use OpenRouter, add `OPENROUTER_API_KEY`. | Otherwise, sign in with a Claude account inside claude after you connect. |
| `codex` | To use the OpenAI API, add `OPENAI_API_KEY`. To use OpenRouter, add `OPENROUTER_API_KEY`. | Otherwise, sign in with ChatGPT inside codex after you connect. |
| `cursor` | To use Cursor, add `CURSOR_API_KEY`. | Otherwise, sign in with a Cursor account inside agent after you connect. |
| `hermes` | To use OpenRouter, add `OPENROUTER_API_KEY`. | Otherwise, run hermes setup to choose a model provider after you connect. |
| `junie` | To use OpenRouter, add `OPENROUTER_API_KEY`. | Otherwise, run junie in the terminal to set up authentication after you connect. |
| `kilocode` | To use OpenRouter, add `OPENROUTER_API_KEY`. | Otherwise, run kilocode auth login in the terminal after you connect. |
| `openclaw` | To use the Anthropic API, add `ANTHROPIC_API_KEY`. To use OpenRouter, add `OPENROUTER_API_KEY`. | Otherwise, follow openclaw's model setup inside the terminal after you connect. |
| `opencode` | To use OpenRouter, add `OPENROUTER_API_KEY`. To use the Anthropic API, add `ANTHROPIC_API_KEY`. To use the OpenAI API, add `OPENAI_API_KEY`. | Otherwise, use /connect inside opencode after you connect. |
| `pi` | To use the Anthropic API, add `ANTHROPIC_API_KEY`. To use the OpenAI API, add `OPENAI_API_KEY`. To use OpenRouter, add `OPENROUTER_API_KEY`. | Otherwise, use /login inside pi after you connect. |
| `t3code` | To use the Anthropic API, add `ANTHROPIC_API_KEY`. To use the OpenAI API, add `OPENAI_API_KEY`. To use OpenRouter, add `OPENROUTER_API_KEY`. | Otherwise, sign in to Claude Code or Codex inside t3code after you connect. |

### Hosted Agent Services

These entries run unattended and require their service-specific inputs before launch.
They do not use the interactive sign-in paths above.

* [`claude-managed-agents-worker`](https://boxrouter.ai/docs/integrations/claude-managed-agents): required inputs and unattended launch instructions.
* [`openai-agents-environment`](https://boxrouter.ai/docs/integrations/openai-agents-api): required inputs and unattended launch instructions.

## Use Your Own Repository

Add `--repo owner/repo@ref` to run a catalog agent against your code. The catalog form requires the ref
(`@HEAD` is the default branch); without it the CLI stops with `Repository override must use
owner/repo@ref`. [Launch your own agent](https://boxrouter.ai/docs/launch/your-own-agent.md) covers repositories, manifests, and
images.

## Read an Agent's Logs and Files

Each agent writes its own logs and files inside its sandbox, usually under the sandbox user's home
directory. BoxRouter does not collect them. For example, `codex` writes `~/.codex/log/codex-login.log`
once you start its sign-in.

While the sandbox runs, list a directory with `exec` and read one file with `read`, which needs an
absolute path. Take `SANDBOX_ID` from the CLI's connection message or from `box.id`.

```python Python theme={"theme":"css-variables"}
from boxrouter import BoxRouter

with BoxRouter() as client:
    box = client.sandboxes.get("SANDBOX_ID")
    print(box.exec("ls ~/.codex/log", check=True).stdout, end="")
    print(box.files.read("/home/user/.codex/log/codex-login.log").decode(), end="")
```

```typescript TypeScript theme={"theme":"css-variables"}
import { BoxRouter } from '@boxrouter/sdk';

const client = new BoxRouter();
try {
  const box = await client.sandboxes.get('SANDBOX_ID');
  process.stdout.write((await box.exec('ls ~/.codex/log', { check: true })).stdout);
  process.stdout.write(new TextDecoder().decode(await box.files.read('/home/user/.codex/log/codex-login.log')));
} finally {
  await client.close();
}
```

```bash CLI theme={"theme":"css-variables"}
boxrouter exec SANDBOX_ID 'ls ~/.codex/log'
boxrouter read SANDBOX_ID --path /home/user/.codex/log/codex-login.log
```

```text theme={"theme":"css-variables"}
codex-login.log
<TIMESTAMP>  INFO codex_cli::login: starting browser login flow
```

Deleting the sandbox deletes these files. Read what you need first, or [store it in a Volume](https://boxrouter.ai/docs/volumes.md).

## Next Steps

> [card] [Launch Your Own Agent](https://boxrouter.ai/docs/launch/your-own-agent.md)
>
> A repository, a manifest or an image instead of the catalog.

> [card] [Supply an Agent's Secrets](https://boxrouter.ai/docs/launch/secrets.md)
>
> How a selected secret is resolved, stored, and exposed.

> [card] [Run Copies of an Agent](https://boxrouter.ai/docs/launch/copies.md)
>
> Start N unattended copies and read what each wrote.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.