maestro/docs/getting-started.md
oss-sync 29ccaf1e92
Some checks failed
CI / build-and-test (push) Has been cancelled
sync: update from private repo (dfadcd5f)
2026-06-23 06:38:48 +00:00

7.4 KiB

English | 日本語

Getting Started

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

1. Prerequisites

  • Node.js 22 or later
  • An OpenAI-compatible LLM endpoint — e.g. Ollama (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).

2. Install (from source)

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.

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):

SETUP_LLM_ENDPOINT=http://localhost:11434/v1 SETUP_MODEL=qwen3:14b npm run setup -- --yes
# 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

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:

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:

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

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:

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.

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.

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.

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.