English | [日本語](getting-started.ja.md)

# Getting Started

A guide that takes you from launching MAESTRO to running your first task. For setting details see
[configuration.md](configuration.md), and for the overall structure see [architecture.md](architecture.md).

## 1. Prerequisites

- **Node.js 22 or later**
- **An OpenAI-compatible LLM endpoint** — e.g. [Ollama](https://ollama.com/) (`http://localhost:11434/v1`), vLLM, etc. Not needed to build/test MAESTRO itself, but required to run tasks.
- **Optional (for the Bash sandbox)**: `bwrap` (bubblewrap, with unprivileged user namespaces enabled) and `python3`/`pip`. Enabling it is recommended for multi-user operation ([operations/bash-sandbox-provisioning.md](operations/bash-sandbox-provisioning.md)).

## 2. Install (from source)

```bash
git clone https://gitea.example.com/your-org/maestro.git
cd maestro
npm ci                 # backend dependencies
npm --prefix ui ci     # UI dependencies
```

## 3. Minimal configuration (interactive wizard)

`npm run setup` interactively configures the LLM connection target and generates a minimal `config.yaml`.

```bash
npm run setup
```

- Choose the connection type (`direct` = Ollama/vLLM, etc. / `aao_gateway` = via a separate MAESTRO Gateway).
- Enter the LLM endpoint URL (e.g. `http://localhost:11434/v1`). It checks the connection and lets you select from the discovered models (you can continue by entering a model name manually even if the connection fails).
- For `aao_gateway`, also enter the API key (`sk-aao-...`) (it is saved in `config.yaml` with permission 0600).
- Finally, set the listen port of the MAESTRO server (default 9876).

Non-interactive (Docker / CI):

```bash
SETUP_LLM_ENDPOINT=http://localhost:11434/v1 SETUP_MODEL=qwen3:14b npm run setup -- --yes
```

```bash
# Via a separate MAESTRO Gateway
SETUP_CONNECTION_TYPE=aao_gateway \
  SETUP_LLM_ENDPOINT=http://gateway-host:9876/v1 \
  SETUP_LLM_API_KEY=sk-aao-... \
  SETUP_MODEL=qwen3:14b \
  npm run setup -- --yes
```

For advanced settings (multiple workers, tools, auth, etc.), edit `config.yaml` directly after generation, or use the Settings UI after launch. `config.yaml.example` documents every option.

## 4. Build and launch

```bash
scripts/build-all.sh          # build the backend (dist/) and the UI (ui/dist/)
scripts/server.sh start       # build + launch (with PID management)
```

Open **http://localhost:9876** in your browser.

Server management:

```bash
scripts/server.sh status      # check status
scripts/server.sh logs        # tail -f the logs
scripts/server.sh restart
scripts/server.sh stop
```

> At the end, `scripts/build-all.sh` automatically pre-bakes the Python packages for the Bash sandbox
> (`runtime/python-requirements.txt`). To skip this, use
> `--skip-python`. In environments where writing to the system Python requires permissions, run
> `sudo bash scripts/prebake-python.sh` separately.

### Updating an existing install (after `git pull`)

To update a bare-metal install, run:

```bash
scripts/upgrade.sh            # git pull -> rebuild (deps + server + UI) -> restart
```

A plain `scripts/server.sh restart` rebuilds only the server, **not** the UI
(`ui/dist` is gitignored and built separately) and never refreshes npm deps, so
after a pull that changed dependencies or the frontend it can leave a stale UI
bundle. `scripts/upgrade.sh` runs the full, correct sequence instead.

It also handles the **network bind migration**: since 2026-06-10 the server
binds `127.0.0.1` (loopback only) by default instead of `0.0.0.0`, for security
(the agent API includes a Bash tool, so an auth-less instance on the LAN is
effectively unauthenticated RCE). If you reach MAESTRO from another machine and
suddenly get `ERR_CONNECTION_REFUSED` after updating, that is why — set `HOST`
explicitly (e.g. `HOST=0.0.0.0` in `.env`) and enable auth in `config.yaml`
first. The upgrade script detects this and offers to set it for you.

## 5. Launch with Docker

```bash
docker compose up -d
# http://localhost:9876
```

The DB and workspaces are persisted in named volumes (`maestro-data` / `maestro-workspaces`). By default Compose publishes `9876` on all interfaces, so the instance is reachable from your LAN — and unauthenticated until you configure `auth`. Enable auth/TLS before leaving it on a shared network, or pin the mapping to `127.0.0.1:9876:9876` for local-only. If you want to mount `config.yaml` from the host, see the comments in `docker-compose.yml`.

### Browser setup wizard (no `config.yaml` editing)

When you start with no LLM configured, opening the UI shows a **full-screen setup wizard** instead of the app — the browser equivalent of `npm run setup`. It walks you through:

1. **Language model** — connection type, endpoint, a live connection test, then pick a model. Applied immediately, no restart.
2. **Server port** (optional) — takes effect after a restart.
3. **Sign-in** (optional) — email + password (first admin) or Google/Gitea OAuth. Takes effect after a restart.

Because the wizard can bootstrap an admin account, mutating setup calls require a **one-time setup token**. It is printed to the server logs at startup — read it with:

```bash
docker compose logs | grep "setup token"
```

Paste that token into the wizard's first field. The token only exists during the initial no-auth window and stops working once an LLM is configured (or once auth is enabled and the server restarts). If you'd rather configure non-interactively, set `OLLAMA_BASE_URL` / `OLLAMA_MODEL` in a `.env` file (`cp .env.example .env`) before `docker compose up` — the wizard then doesn't appear.

## 6. Your first task

1. Open the UI and create a new task (enter a title + the request body).
2. The LLM classifies the task and automatically routes it to the appropriate Piece (workflow).
3. Check the Movement progress and tool calls in the Progress tab; preview deliverables in the Output/Files tabs.

## 7. Enable authentication (optional)

By default it runs without authentication. To use Google / Gitea OAuth, configure the
`auth` section of `config.yaml` (client ID/secret/callback URL). For details, see the
[auth section of configuration.md](configuration.md#auth).

Do not expose it to an untrusted network until authentication is enabled. When exposing it externally, also use a TLS-enabled
reverse proxy. For operational caveats, see [../SECURITY.md](../SECURITY.md).

### Share a workspace (invite links)

With authentication enabled, a case workspace can be shared with several users. The
member picker only lists users in the same organization (to avoid leaking the user
list), so a user with no organization — for example a Google login the admin has not
assigned a local org to — may see an empty picker.

For that case, use an **invite link**. An owner or admin generates the link from the
workspace's **Settings → Members** and picks the granted role (editor / viewer) and an
optional expiry (never / 7 days / 30 days). Any logged-in user who has the link joins by
opening `/ui/invite/<token>`. Links can grant editor or viewer only (never owner), and
only an owner or admin can create or revoke them. Each workspace has at most one active
link; regenerating it immediately invalidates the old one, and an invalid or expired link
returns no workspace information. Invite links are disabled in no-auth mode.

## 8. Enable the Bash sandbox (optional, recommended for multi-user)

Isolates the agent's Bash execution per task. In production:

1. Pre-bake the Python packages on the host: `sudo bash scripts/prebake-python.sh`
2. Set `safety.bash_sandbox: always` in `config.yaml`
3. Restart the server

For the procedure and troubleshooting, see [operations/bash-sandbox-provisioning.md](operations/bash-sandbox-provisioning.md).
