> ## 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.

# Quickstart

> Install Nanny, configure limits, and run your first enforced process in under five minutes.

## Install

The Nanny CLI is a system tool, install it once and use `nanny run --serve` from any project.

<Tabs>
  <Tab title="macOS">
    ```bash theme={null}
    brew tap nanny-run/nanny
    brew install nannyd
    ```
  </Tab>

  <Tab title="Linux">
    ```bash theme={null}
    curl -fsSL https://install.nanny.run | sh
    ```

    Have Rust installed? `cargo install nannyd` also works.
  </Tab>

  <Tab title="Windows">
    ```powershell theme={null}
    irm https://install.nanny.run/windows | iex
    ```

    Installs the binary to `%LOCALAPPDATA%\nanny\` and adds it to your PATH. Restart your terminal after installing.
  </Tab>
</Tabs>

Verify the installation:

```bash theme={null}
nanny --version
```

For upgrade paths, uninstall, and troubleshooting on each platform, see [Installing Nanny](/v0.6/install).

The CLI is the enforcement engine. The SDK instruments your functions. You need both: `nanny run --serve` owns the process lifecycle and enforces limits; `@tool`, `@rule`, and `@agent` report tool calls and activate named limit sets from inside your agent code.

## Initialise a config

Run this in the root of your project:

```bash theme={null}
nanny init
```

This writes a `nanny.toml` with safe defaults:

```toml theme={null}
[start]
# How to launch your agent. The governor reads this command.
cmd = "python agent.py"

[tools]
# Every tool your agent may call. An empty list denies all of them.
allowed = []
```

Set `[start].cmd` to your agent's entry point, then list the tools it is allowed to call.

`nanny init` also writes `.nanny/app.json`, a permanent, one-time identity for this app (an `app_id` plus a name you'll be prompted for). It's meant to be committed alongside `nanny.toml`.

## Run your agent

```bash theme={null}
nanny run --serve
```

Nanny reads `[start].cmd` from `nanny.toml`, spawns the process, and stops it the moment it tries something outside what you declared.

## Label your tools

Labels say what a tool *is*, so a rule can govern it without knowing its name:

```toml theme={null}
[tools]
allowed = ["web_search", "send_outreach"]

[tools.web_search]
max_calls       = 30
reads_untrusted = true

[tools.send_outreach]
external_effect = true
```

See [Tool labels](/v0.6/concepts/tool-labels) for all five.

## Add rules

Install a pack and pin it:

```bash theme={null}
nanny rules add nanny:recommended@1.0.0 --from ./packs/nanny-recommended
```

That writes one line into `nanny.toml` and vendors the pack into
`.nanny/rules/`, both committed:

```toml theme={null}
[rules]
extends = ["nanny:recommended@1.0.0"]
```

Your own source is untouched. See [Rule packs](/v0.6/guides/rule-packs).

## Read the event log

Every run emits structured NDJSON to stdout:

```json theme={null}
{"event":"ExecutionStarted","ts":1711234567000,"run_id":"a1b2c3d4","seq":0,"command":"python agent.py","allowed_tools":["web_search"],"tool_labels":{"web_search":["reads_untrusted"]},"config_hash":"9f2a41c8"}
{"event":"ToolAllowed","ts":1711234567120,"run_id":"a1b2c3d4","seq":1,"tool":"web_search"}
{"event":"ExecutionStopped","ts":1711234572000,"run_id":"a1b2c3d4","seq":2,"reason":"AgentCompleted","tokens_spent":70,"elapsed_ms":4823}
```

Pipe it to a file or your log aggregator:

```bash theme={null}
nanny run --serve >> nanny.log
```

Or configure file output directly in `nanny.toml`:

```toml theme={null}
[observability]
log = "file"
```

This writes to `.nanny/logs/log.ndjson`, auto-created, gitignored. Set `file = "..."` only
if you want a different filename, see [Event Log](/v0.6/concepts/event-log) for details.
