MaestroBot keeps static operator-authored config in config.yaml under the runtime root.

The file is real YAML and is written in a stable, human-oriented layout so operators can edit it directly.

Top-Level Sections

service

  • name Logical service name. Defaults to maestrobot.

runtime

  • resident_limit Max number of resident channel contexts.
  • scheduler_workers Max number of channel runs the daemon may execute concurrently. Each individual channel still executes serially.
  • scheduler_tick Scheduler polling interval.
  • default_timeout_seconds Default foreground timeout after finalization.
  • default_sleep_seconds Default sleep threshold used during channel finalization.
  • llm_timeout_seconds Shared timeout in seconds for MaestroBot LLM API calls and generated Myria LLM request timeouts.
  • log_level Host log level and generated Myria log level.

onboarding

  • notice_limit Number of deterministic onboarding notices an unknown external account may trigger before the daemon silently ignores that account until it is attached. Defaults to 3.
  • archive_after_hours Hours after the last observed message before an unresolved unknown identity moves from the active list to the archive list. Defaults to 24.
  • notice_message Fixed notice sent by the runtime/frontend gate to unknown accounts. This is not generated by the agent and does not enter the agent loop.

The daemon always writes structured JSON logs to logs/service.log. When a chat request asks for verbose tracing, the daemon attaches a channel-run trace_id and emits prompt, LLM, tool, and finalization events into that same log. The CLI only filters and streams those daemon-produced events.

Prompt composition now lives under the runtime-root maestro/ directory:

  • channel_loop.mstr
  • subagent_loop.mstr

The host runtime injects the structured runtime sections, but the prompt layout, ordering, and most operator-facing wording live in those user-editable Maestro files, with prompt text embedded directly in the schema source rather than separate Markdown templates.

SOUL.md is the exclusive identity file. Put the agent’s name, voice, persona, and standing preferences there. Keep maestro/*.mstr identity-neutral: those files should define operating behavior and tool flow, not who the agent is. The daemon logs a warning if SOUL.md is missing or empty.

The same Maestro files select the state-local host surface. They can request tool groups such as @plan, @workspace, @web, @browser, @myria, or exact tool names, and they can request a bounded list of context sections for the prompt. The daemon expands those schema requests against the available runtime catalog and fails fast on unknown required tools.

providers

  • keyed provider map
  • v1 expects an openrouter entry with:
    • base_url
    • api_key

profile

Controls durable user-profile memory injected into agent context.

  • autonomous_updates Allows the agent to update known users’ profiles through the host-validated profile tool.
  • max_bytes Maximum size of one users/<user-id>/profile.md file. The default is 20480.
  • max_bullets Maximum number of profile bullets retained across all profile sections. The default is 200.

Profiles are for stable preferences, constraints, communication style, and stable user facts. They are not transcript history, task history, or secret storage.

presets

Concrete model presets keyed by preset id.

Each concrete preset defines:

  • provider id
  • model id
  • provider sort preference
  • context limit in tokens
  • reasoning profile
  • short description of capability and speed tradeoffs

sort controls OpenRouter provider ordering for that preset. Supported values are:

  • default Keep OpenRouter’s default routing and load balancing behavior.
  • exacto Prefer OpenRouter’s quality-first route selection.
  • price Prefer the lowest-price provider.
  • throughput Prefer the highest-throughput provider.
  • latency Prefer the lowest-latency provider.

MaestroBot does not pin a concrete OpenRouter provider. It passes only the configured model and optional provider sort, then lets OpenRouter choose the route. Cache hits still depend on the selected provider and model route. MaestroBot sends stable operating instructions as the first message and high-churn runtime context as the final message to improve provider-side prompt-cache reuse. maestrobot models cache runs a two-request cache probe for each preset and reports cached input and cache-write tokens.

context_limit_tokens caps the prompt, tool-definition, and safety margin budget MaestroBot will send to the model for that preset. The generated default is 262144. Lower it for models with smaller context windows. Before an LLM request, MaestroBot performs deterministic compaction of high-growth context sections and rejects the request if it still cannot fit under the preset cap.

preset_refs

  • quick
  • high
  • subagent_high

These are references to entries under presets.

starting-model is not a config entry. It is a runtime-attached selection chosen from the referenced preset descriptions when a subagent starts.

myria

  • config_path Relative path to generated myria/myria.json under the runtime root.
  • template_path Relative path to the generated OpenRouter request template.
  • postgres_dsn Optional PostgreSQL DSN for Myria.
  • schema PostgreSQL schema name.
  • log_file Runtime log file path for the supervised Myria process.
  • max_tool_rounds Max Myria tool-call rounds written to the generated Myria config.
  • structured_tool_calls Whether the generated Myria config requires structured tool calls.

MaestroBot installs the needed runtime binaries under <root>/bin/ and does not require operator-authored repo paths in config.yaml. The daemon uses:

  • <root>/bin/maestroc to compile the root-local maestro/ source
  • <root>/bin/myria to supervise the Myria subprocess

The actual Myria config and OpenRouter request template are generated from config.yaml during init, preflight tests, and daemon startup. Treat files under <root>/myria/ as derived runtime files.

tools

  • optional map of external MCP servers
  • each server may define:
    • transport
    • command
    • url
    • headers
    • workdir
    • env
    • description
    • manifest
    • source

These servers can also be registered and removed dynamically through the daemon:

maestrobot tools register-stdio example --description "Example MCP server" -- /abs/path/server --stdio
maestrobot tools register-remote remote-example --transport streamable-http --url https://example.invalid/mcp
maestrobot tools discover --path .
maestrobot tools import-manifest /abs/path/mcp.json example
maestrobot tools inspect example
maestrobot tools enable example
maestrobot tools disable example
maestrobot tools remove example

Discovery currently understands:

  • dedicated JSON manifests such as mcp.json, .mcp.json, and mcp-server.json
  • Claude-style claude_desktop_config.json files with mcpServers

Supported external MCP transports are:

  • stdio
  • streamable-http
  • sse

Separate from configured external tool servers, MaestroBot also ships a built-in internal.* developer tool surface for:

  • VFS inspection and mutation
  • recursive file search
  • synchronous command execution
  • long-running command sessions with stdin/poll/wait/kill control
  • Playwright-backed browser sessions
  • direct web fetch/search
  • image metadata and OCR

The Playwright runtime stores its driver, browser binaries, and browser artifacts under:

  • <root>/cache/playwright/driver
  • <root>/cache/playwright/browsers
  • <root>/cache/playwright/screenshots

frontends

  • keyed frontend map
  • built-in frontend types:
    • local-cli
    • telegram

Telegram frontend fields:

  • telegram.bot_token Bot token used for Bot API polling and delivery.
  • telegram.api_base_url Bot API base URL. Defaults to https://api.telegram.org.
  • telegram.poll_interval_seconds Delay between poll attempts.
  • telegram.long_poll_seconds Long-poll timeout used by getUpdates.
  • telegram.prefer_entities Prefer text + entities output over parse-mode HTML.
  • telegram.allow_html_fallback Allow HTML parse-mode fallback when entity rendering fails.
  • telegram.preserve_code_language Preserve fenced-code language metadata when rendering Telegram code blocks.
  • telegram.max_message_units Max Telegram message size in UTF-16 code units.
  • telegram.allowed_chat_ids Optional hard safety allow-list of Telegram chat ids. This is not the normal onboarding mechanism. With no allow-list, unknown Telegram DMs can still be discovered, rate-limited, and listed for operator attachment.

Telegram output is rendered from canonical Markdown through a dedicated frontend pipeline. The runtime does not ask the agent to produce Telegram-specific output directly.

While a Telegram-backed channel run is active, the frontend also sends a Telegram typing chat action until the run delivers its reply or finalizes.

Bootstrap

The simplest bootstrap flow is:

maestrobot init --workspace-root . --openrouter-api-key "$OPENROUTER_API_KEY" --model "$MAESTROBOT_MODEL"
maestrobot init --workspace-root . --openrouter-api-key "$OPENROUTER_API_KEY" --model "$MAESTROBOT_MODEL" --telegram-bot-token "$TELEGRAM_BOT_TOKEN"

After bootstrap, the intended setup surface is only:

$EDITOR ~/.maestrobot/config.yaml
$EDITOR ~/.maestrobot/SOUL.md
maestrobot doctor

Edit config.yaml for deployment mechanics: provider credentials, model presets, frontends, onboarding policy, runtime limits, and optional tools. Edit SOUL.md for identity, voice, and standing preferences. maestrobot doctor checks the edited files and live service prerequisites before the daemon starts.

That command:

  • creates the runtime root
  • writes config.yaml
  • creates state.json
  • writes SOUL.md
  • writes runtime.yaml
  • seeds <root>/maestro/ with editable default Maestro programs
  • writes the OpenRouter request template for Myria
  • writes a default myria/myria.json

Runtime Config

Mutable desired runtime config lives in runtime.yaml, not config.yaml.

Current user entries look like:

users:
  -
    id: usr_k7m4x9q2p8vd
    name: Ada Lovelace

Internal user IDs are generated randomly when you run:

maestrobot user onboard "Ada Lovelace"

External accounts are attached separately:

maestrobot user unknown
maestrobot user attach usr_k7m4x9q2p8vd unknown-0001

The account-to-user mapping is observed daemon state in state.json. That split keeps names and stable internal users editable while keeping platform account discovery and queue state daemon-owned.

Myria Storage

For the current MaestroBot version, SQLite is written as the default backend only for convenience. It gives a persistent local file-backed setup with minimal operator work. It should be treated as the easiest bootstrap mode, not as a statement that Myria is architecturally SQLite-first.

Default generated values:

  • storage.kind = "sqlite"
  • sqlite.path = "<root>/myria/myria.sqlite3"

The SQLite backend is file-backed and persists across restarts. The generated Myria files are derived from MaestroBot config and may be rewritten by maestrobot init, maestrobot test, and daemon startup.