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

# nanny.toml reference

> Complete schema for the nanny.toml configuration file.

## Full schema

```toml theme={null}
# ── Start ─────────────────────────────────────────────────────────────────────

[start]
cmd = "python agent.py"   # required, the command nanny run executes

# ── Limits ────────────────────────────────────────────────────────────────────

[limits]
steps   = 100
tokens  = 1000
timeout = 30000

# Named limit sets — inherit from [limits], override only declared fields.
[limits.researcher]
steps   = 200
tokens  = 5000
timeout = 120000

# ── Tools ─────────────────────────────────────────────────────────────────────

[tools]
allowed = ["http_get", "read_file"]   # empty list denies every tool call

# Per-tool configuration — tool name must match the function name in code.
[tools.http_get]
max_calls       = 10    # max number of calls in one execution
tokens_per_call = 20    # overrides the decorator/macro default if set

# ── Observability ─────────────────────────────────────────────────────────────

[observability]
log  = "stdout"   # "stdout" | "file" — "file" writes to .nanny/logs/log.ndjson
# file = "events"   # optional, bare name only, no extension — see below

# ── Proxy ─────────────────────────────────────────────────────────────────────

[proxy]
allowed_hosts = ["api.openai.com", "*.anthropic.com"]   # required when proxy mode is used

# Cloud sync isn't a config field. It turns on for any machine that's run
# `nanny auth login`. There is no endpoint or key in this file.
```

***

## \[start]

| Field | Type   | Default | Description                                                                                                                      |
| ----- | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `cmd` | string | —       | **Required.** The shell command `nanny run` executes. Examples: `"python agent.py"`, `"cargo run --release"`, `"node agent.js"`. |

***

## \[limits]

The global execution ceiling. Any one limit stopping the agent stops the entire run.

| Field     | Type         | Default | Description                                                                         |
| --------- | ------------ | ------- | ----------------------------------------------------------------------------------- |
| `steps`   | integer      | —       | Maximum tool calls allowed. Requires SDK instrumentation.                           |
| `tokens`  | integer      | —       | Maximum tokens allowed. Requires SDK instrumentation.                               |
| `timeout` | integer (ms) | —       | Maximum wall-clock time in milliseconds. Enforced for any process, no SDK required. |

**Named limit sets** — `[limits.<name>]` inherits all fields from `[limits]` and overrides only the fields it declares:

```toml theme={null}
[limits]
steps   = 50
tokens  = 500
timeout = 15000

[limits.researcher]
steps   = 200       # overrides 50
tokens  = 5000      # overrides 500
# timeout inherits 15000

[limits.reporter]
tokens  = 100       # overrides 500 only; steps and timeout inherit
```

Activate a named set from the CLI:

```bash theme={null}
nanny run --limits=researcher
```

Or from inside agent code using `@agent("researcher")` (Python) or `#[nanny::agent("researcher")]` (Rust).

***

## \[tools]

| Field     | Type         | Default | Description                                                                                                                      |
| --------- | ------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `allowed` | string array | —       | Explicit allowlist of tool names. **An empty array denies every tool call.** If `[tools]` is not present, all tools are allowed. |

### Per-tool configuration — `[tools.<name>]`

```toml theme={null}
[tools.http_get]
max_calls       = 10
tokens_per_call = 20
```

| Field             | Type    | Default               | Description                                                                                                                           |
| ----------------- | ------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `max_calls`       | integer | unlimited             | Maximum number of calls to this tool in one execution. Exceeding this limit fires `RuleDenied` with `rule_name = "<tool>.max_calls"`. |
| `tokens_per_call` | integer | decorator/macro value | Tokens charged per call. Overrides the value declared in `@tool(tokens=N)` or `#[tool(tokens = N)]`.                                  |

The tool name in `[tools.<name>]` must exactly match the function name used in the `@tool` decorator or `#[nanny::tool]` macro.

***

## \[observability]

| Field  | Type                   | Default    | Description                                                                                                                                                                                          |
| ------ | ---------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `log`  | `"stdout"` \| `"file"` | `"stdout"` | Destination for the NDJSON event stream.                                                                                                                                                             |
| `file` | string                 | `"log"`    | Optional. A bare name, no extension and no path separators — Nanny always appends `.ndjson`. The directory is always `.nanny/logs/`, owned by Nanny, auto-created and gitignored — not configurable. |

***

## \[proxy]

Optional. Enables HTTP CONNECT proxy mode on the governance server.

Proxy mode is active only when `allowed_hosts` is present and non-empty. An empty list — or omitting `[proxy]` entirely — disables proxy mode.

| Field           | Type         | Default | Description                                                                                                                                                                                         |
| --------------- | ------------ | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allowed_hosts` | string array | `[]`    | Hostnames the proxy may forward to. Supports exact names (`api.openai.com`) and `*.suffix` wildcard patterns. Loopback, link-local, and RFC-1918 ranges are always blocked regardless of this list. |

The CONNECT tunnel authenticates with its own `proxy_token`, separate from the ordinary session token. `nanny run --serve`/`--join` inject it automatically, so nothing in this section needs a credential.

See [HTTP proxy mode](/v0.5/guides/http-proxy-mode) for full details.

***

## Cloud sync

Cloud sync has no config block. It turns on for any machine that's logged in via `nanny auth login`, no separate field to flip. No key, endpoint, or org lives in `nanny.toml`: login handles the credential, so your committed config never holds a secret.

See [Connect to Nanny Cloud](/v0.5/guides/managed-mode) for the full flow, including the `--token` path for CI and headless machines.
