Skip to content

Configuration

rluisr edited this page Jul 23, 2026 · 1 revision

Configuration

English | 日本語

Knobs that matter for operators. Three layers:

  1. Environment variables — secrets and process wiring
  2. maestro.config.ts / .json — non-secret product defaults
  3. WebUI / SQLite — prompts, repos, MCP servers (runtime source of truth)

Quick map

Want to change… Where
API keys, GitHub App PEM env / secrets manager
Parent/child model, max sub-issues, run timeout config file or env override
System prompts WebUI Prompts (parent.system, child.system)
Which repos the poller watches WebUI Repositories
Extra MCP servers WebUI MCP servers
Dashboard login OIDC env block

Required environment

Variable Required Description
ANTHROPIC_API_KEY yes Anthropic API key with Managed Agents access
GITHUB_APP_ID yes GitHub App ID
GITHUB_APP_PRIVATE_KEY one of key/path PEM contents (\n escaped if inline)
GITHUB_APP_PRIVATE_KEY_PATH one of key/path Path to PEM file (preferred in containers)
GITHUB_APP_INSTALLATION_ID no Fixed installation; else resolved from owner/repo

Copy from .env.example and fill the required block first.


Config file

Files (first found wins, or set CONFIG_PATH):

  • maestro.config.ts (default export)
  • maestro.config.json

Schema is strict (src/shared/config.ts). Unknown keys fail startup.

// maestro.config.ts
export default {
  models: {
    parent: "claude-fable-5",
    child: "claude-sonnet-5",
  },
  maxSubIssues: 10,
  maxRunMinutes: 120,
  maxChildMinutes: 30,
  pr: { draft: false /* , base: "main" */ },
  commitStyle: "conventional",
  git: {
    authorName: "claude-agent[bot]",
    authorEmail: "claude-agent@users.noreply.github.com",
  },
  // vaultId: "vault_...",           // optional shared vault (avoid multi-repo App installs)
  // consoleWorkspace: "default",    // Claude Console deep-links
  // selfHosted: { environmentId: "env_..." },
};

Env overrides (win over file)

Env Maps to
PARENT_MODEL models.parent
CHILD_MODEL models.child
MAX_SUB_ISSUES maxSubIssues
MAX_RUN_MINUTES maxRunMinutes
VAULT_ID vaultId
CONSOLE_WORKSPACE consoleWorkspace
ANTHROPIC_ENVIRONMENT_ID selfHosted.environmentId

Supported model ids (see SUPPORTED_MODELS in code): claude-fable-5, claude-opus-4-8, claude-sonnet-5.

Self-hosted note

When ANTHROPIC_ENVIRONMENT_ID / selfHosted.environmentId is set:

  • Do not rely on a shared VAULT_ID — maestro uses per-run managed vaults
  • Worker holds ANTHROPIC_ENVIRONMENT_KEY; the app does not
  • See docs/self-hosted-sandboxes.md

Process / HTTP

Variable Default Description
HOST (impl default; container 0.0.0.0) Bind address
PORT / APP_PORT 3000 App port (start.sh may remap PORT for Cloud Run)
DB_PATH .maestro/dashboard.db SQLite path
LOG_LEVEL info Pino level
CONFIG_PATH auto Explicit config file path

GitHub trigger (poller)

Repo list is not env — use WebUI Repositoriespolled_repositories.

Variable Default Description
GITHUB_TRIGGER_POLL_INTERVAL_SECONDS 60 Poll cadence
GITHUB_TRIGGER_LABEL agent-run Label that starts a run
GITHUB_BOT_MENTION bot Username for @bot run comments (no @)

Stale run reaper

Variable Default Description
STALE_RUN_REAPER_ENABLED true Set false to disable
STALE_RUN_REAPER_INTERVAL_SECONDS 60 Check cadence
STALE_RUN_REAPER_REQUIRES_ACTION_STALE_SECONDS 3600 Idle requires_action before stale

OIDC (optional dashboard auth)

Leave all OIDC_* unset for local no-auth mode. If any is set, required fields must all be set.

Variable Description
OIDC_ISSUER_URL IdP issuer
OIDC_CLIENT_ID Client id
OIDC_CLIENT_SECRET Client secret
OIDC_REDIRECT_URI e.g. https://app.example.com/auth/callback
OIDC_ADMIN_EMAILS Comma-separated exact emails → admin; others → viewer
OIDC_SESSION_SECRET Optional HMAC secret; defaults to client secret

Ingress + MCP (production)

Variable Description
INGRESS_AUTH_MODE e.g. load-balancer
INGRESS_APP_HOSTNAME Dashboard hostname
INGRESS_MCP_HOSTNAME MCP hostname (separate recommended)
ENABLE_MCP_SIDECAR / INGRESS_MCP_ENABLED Sidecar toggles (see .env.example)
MCP_GATEWAY_TOKEN Bearer for Managed Agents → gateway
MCP_GATEWAY_ALLOWED_CLIENT_CIDRS Default includes Anthropic egress 160.79.104.0/21
MCP_GATEWAY_DISABLE_CLIENT_IP_CHECK Dev/tunnel only — do not leave open in prod
MCP_PROXY_CONFIG Path to named-server JSON (default ./mcp-proxy.json)
MCP_PROXY_ALLOWED_ENV_NAMES Env names allowed into mcp-proxy children
MCP_PROXY_ALLOW_ORIGIN CORS-ish allow origin for proxy

Local tunnel extras: ENABLE_DEV_TUNNEL, NGROK_AUTHTOKEN, DEV_TUNNEL_TARGET_SERVERS, DEV_TUNNEL_DROP_NODE_EXTRA_CA_CERTS — see docs/DEVELOPMENT.md.


OpenTelemetry

Disabled by default.

OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
# OTEL_SERVICE_NAME=maestro
# OTEL_EXPORTER_OTLP_HEADERS=key=value,key2=value2

Prompts, tokens, bodies, and stack traces are not exported as attributes.


WebUI-managed data

Edit in the browser; stored in SQLite (survives restarts if DB_PATH is durable).

Area Notes
Prompts Editable: parent.system, child.system. Runtime templates *.runtime are read-only
Repositories Polled repos for auto-trigger; registration for multi-repo mounts
MCP servers URL, enabled, token_env_name, permission policy. Builtin github locks name/url/enabled
Locale Cookie dashboard_locale or Accept-Language; switch via GET /locale/:locale?next=... (en/ja)

HTTP API sketch

Base URL: same host as the dashboard (OIDC applies when configured).

Start a run

POST /api/runs
Content-Type: application/json

GitHub issue (default origin):

{
  "issue": 42,
  "repo": "owner/name"
}

Issue URL form (repo inferred):

{
  "issue": "https://github.com/owner/name/issues/42"
}

Linear:

{
  "origin": "linear_issue",
  "linearIssue": "ENG-123",
  "repo": "owner/name"
}

Inspect

Method Path
GET /api/runs
GET /api/runs/:runId
GET /api/runs/:runId/events (SSE)
POST /api/runs/:runId/stop
POST /api/runs/:runId/sessions/:sessionId/resume body: { "instructions": "..." }

Exact validation: src/features/run-api/schemas.ts.


Security checklist

  • PEM and API keys only in env / secret mounts — never in the DB UI as free text long-term if avoidable
  • GitHub App installation scoped to needed repos
  • No shared VAULT_ID across multi-repo App installs (or use self-hosted managed vaults)
  • MCP hostname separate from app; CIDR + Bearer on gateway
  • OIDC on any internet-facing dashboard
  • Single writer process per SQLite file

Next: MCP-Servers · Troubleshooting

Clone this wiki locally