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 exposes only `127.0.0.1:9876`. 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/`. 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).