MAESTROBOT
Operations
MaestroBot is managed as a Linux systemd --user service.
Install
For a normal user install:
bash install.sh
bash install.sh --shell bash --shell zsh --shell fish
That builds maestrobot, installs it to ~/.local/bin, bootstraps
~/.maestrobot when needed, and installs the systemd --user unit.
Without --shell, the installer writes completions for the user’s
default login shell when that shell is bash, zsh, or fish. When
--shell is provided, the installer writes completion files for the
requested shell or shells instead. Unsupported shells are rejected.
If the installer cannot reach the systemd --user bus, it still writes
the unit files and prints the systemctl --user commands to run later
from a normal login session.
Initialize
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 install or init, normal operator setup is editing two files:
$EDITOR ~/.maestrobot/config.yaml
$EDITOR ~/.maestrobot/SOUL.md
config.yaml is the deployment config: credentials, model presets,
frontends, onboarding policy, Myria generation, runtime limits, and
optional MCP tools. SOUL.md is the agent’s identity, voice, and
standing preferences. Avoid putting identity text in config.yaml.
Run the setup doctor before starting or after any config change:
maestrobot doctor
doctor validates config loading, SOUL.md, runtime binaries,
derived Myria startup, user service reachability, model preset
availability and compatibility, and Telegram bot credentials when a
Telegram frontend is configured. Use maestrobot doctor --skip-network
for a local-only check.
If you cloned the repo fresh, run make git-hooks once before normal
development so checkout/merge hooks keep maestro/ and myria/
submodules synchronized.
Start
maestrobot daemon start --verbose
daemon start writes or updates ~/.config/systemd/user/maestrobot.service,
runs systemctl --user daemon-reload, and enables/starts the unit.
Add --debug when you want frontend-visible gateway telemetry:
maestrobot daemon start --verbose --debug
--verbose controls daemon log verbosity. --debug sends compact
operator messages through configured frontends for tool calls, sanitized
parameters, tool results, cumulative LLM token usage, prompt
compaction, and final sleep/wake bookkeeping. These messages are
telemetry only: they are not written to the channel transcript and are
not emitted to Myria as conversation events.
The daemon then:
- loads
config.yaml,runtime.yaml, andstate.json - ensures the root-local
maestro/source files exist - compiles
root/maestro/*.mstrinto a runtime artifact when needed - generates the Myria template and config files from
config.yaml - starts Myria as a supervised stdio subprocess
- starts any enabled external MCP servers
- starts any configured frontends such as Telegram
- starts the multi-worker channel scheduler
- serves the Unix socket control plane
The generated Myria config uses SQLite by default in the current
MaestroBot version only as a convenience path for local setup.
myria/myria.json is derived from config.yaml and is regenerated by
MaestroBot, so do not treat it as the source of truth.
Stop
maestrobot daemon stop
Status And Logs
maestrobot daemon status
maestrobot daemon logs --lines 100
maestrobot status
maestrobot config show
daemon status reports both systemd --user state and daemon IPC
reachability. daemon logs reads from journalctl --user-unit
maestrobot.
Channel Operations
Register a channel:
maestrobot channels add local demo
maestrobot channels add telegram <telegram-chat-id>
maestrobot add-channel local demo
maestrobot add-channel telegram <telegram-chat-id>
Queue a normalized inbound message:
maestrobot channel send channel-0001 "hello"
Deliver a canonical outbound message directly through the channel frontend:
maestrobot channel deliver channel-0001 "**hello** from MaestroBot"
Use the local CLI chat helper:
maestrobot chat "hello"
maestrobot chat --channel demo
maestrobot chat --channel demo --verbose "read /notes.txt and report back"
chat is black-box. It only talks to the daemon through Unix IPC.
chat --verbose still stays black-box from the CLI side, but it tails
only matching daemon trace events from logs/service.log.
channel deliver is the simplest operator-facing way to test frontend
rendering and delivery without waiting for a live model reply.
The verbose trace boundary is one full channel run:
- it starts when the channel leaves a finalized/waiting boundary and a new active run begins
- it ends when the runtime reaches the next finalizing boundary
That means one verbose trace may cover more than one inbound message if the current run consumes them before finalization. The streamed daemon events include the built prompt, model/preset selection, raw LLM response payload, tool execution results, and finalization.
The built prompt now comes from the root-local Maestro surface:
- state-machine source in
~/.maestrobot/maestro/*.mstr
So chat --verbose exposes both the host-provided runtime sections and
the current user-editable Maestro schema boundary, including prompt text
embedded directly in the .mstr source.
Verbose traces also include the schema-requested tool policy and context section list. That is the quickest way to confirm whether a behavior is coming from the Maestro schema surface or from host-side tool execution.
Telegram-specific output formatting is handled later by the Telegram frontend. The canonical runtime output remains Markdown.
For Telegram-backed channels, the frontend emits a typing chat action
while the channel run is actively executing. The typing indicator stops
when the reply is delivered or the run finalizes without sending one.
Probe every configured preset directly without the daemon:
maestrobot test
This uses a plain hello world probe for availability and a
single-tool probe for agent compatibility. It is useful when a model is
reachable for plain completions but a particular OpenRouter route does
not currently support tool parameters. daemon start runs the same
check before it tries to start the user service.
Model presets may configure an OpenRouter sort value, but MaestroBot
does not pin concrete providers. Runtime calls let OpenRouter choose the
route for the configured model and sort mode.
Probe provider-side prompt caching:
maestrobot models cache
This sends the same long stable prompt twice for each preset and reports
cached_tokens, cache_write_tokens, latency, and resolved provider
metadata. A zero cache hit usually means the selected provider/model
route does not support prompt caching, the prompt is below that
provider’s cache threshold, or the provider did not reuse the same
cache backend.
Inspect transcript history:
maestrobot channel history channel-0001
The local channel transcript is also the daemon’s canonical recent same-channel conversation source. Myria remains global persistent memory for older, cross-channel, or uncertain recall.
Wake or force-page a channel:
maestrobot channel wake channel-0001
maestrobot channel page channel-0001
channel wake schedules a host/runtime wake, not a synthetic user message.
The next run sees it as a runtime wake in retained wake metadata.
Scheduled automatic wakes created by the agent carry a private wake
self-note from the prior run. That self-note is context for the next
run, not a user-facing message. Agent finalization always
schedules a future wake. If there is no concrete future work or useful
check, the agent should schedule a long wake and tell its future self
not to message the user if nothing changed.
Pause or resume the scheduler:
maestrobot runtime show
maestrobot runtime reload
maestrobot runtime pause
maestrobot runtime resume
Identity Operations
Internal users live in runtime.yaml. External account mappings and
unknown account discoveries live in daemon-owned state. An unknown
account cannot trigger the agent until it is attached to an internal
user.
Create an internal user:
maestrobot user onboard "Ada Lovelace"
List known internal users:
maestrobot user list
List unresolved active identities:
maestrobot user unknown
maestrobot list-unknown-identities
List archived unresolved identities:
maestrobot user unknown --archive
Attach one unresolved identity to a stable internal user:
maestrobot user attach usr_k7m4x9q2p8vd unknown-0001
Rename an internal user:
maestrobot user rename usr_k7m4x9q2p8vd "Ada Byron"
The old associate command remains as a compatibility shorthand:
maestrobot associate unknown-0001 "Ada Lovelace"
The preferred flow is user onboard followed by user attach, because
internal account creation and platform-account linking are separate
operations.
Unknown Telegram accounts receive the deterministic onboarding notice from the runtime/frontend gate, not from the agent. The default notice limit is three messages per unknown account. After that, messages from the same unknown account are ignored until attachment. Unknowns move to the archive view after the configured archive window, which defaults to 24 hours from last seen.
Workspace Inspection
maestrobot workspace path channel-0001
maestrobot workspace mounts channel-0001
The runtime presents a VFS view with:
/writable channel workspace/.host-path/<n>read-only hostPATHmounts
The built-in developer tools use that same VFS and lease system:
internal.fs_stat,internal.fs_read,internal.fs_read_window,internal.fs_find,internal.fs_grep,internal.fs_replaceinternal.exec,internal.exec_start,internal.exec_poll,internal.exec_stdin,internal.exec_wait,internal.exec_kill
Use internal.fs_read_window for large files. It reads a 1-based
inclusive line range and returns the total line count plus the next
start line, so the agent can inspect repositories incrementally without
loading whole files into context.
Long-running command sessions keep the channel workspace lease until they exit, so side effects remain host-serialized across the main agent and subagents.
Browser Support
Install the Playwright driver and Chromium into the runtime root:
maestrobot browser install
Probe a live browser session directly:
maestrobot browser probe https://example.com
The agent-facing browser tools are:
internal.browser_openinternal.browser_navigateinternal.browser_clickinternal.browser_typeinternal.browser_waitinternal.browser_extractinternal.browser_evalinternal.browser_screenshotinternal.browser_close
Separate non-browser retrieval helpers also exist:
internal.web_fetchinternal.web_searchinternal.image_infointernal.image_ocr
Tool Server Management
List known servers:
maestrobot tools list
Discover MCP manifests and probe them for compatibility:
maestrobot tools discover --path .
Register a new stdio MCP server and start it immediately:
maestrobot tools register-stdio example --description "Example MCP server" --enable=true -- /abs/path/server --stdio
Register a remote MCP server and connect to it immediately:
maestrobot tools register-remote remote-example --transport streamable-http --url https://example.invalid/mcp --enable=true
Import a discovered server from a manifest and start it immediately:
maestrobot tools import-manifest /abs/path/mcp.json example --enable=true
Inspect one configured server and re-probe its exposed tools:
maestrobot tools inspect example
Toggle or remove it:
maestrobot tools enable example
maestrobot tools disable example
maestrobot tools remove example
Registration updates config.yaml and live daemon state. Removal stops
the server, drops the runtime record, and removes the config entry.
Discovery/import currently supports:
- dedicated JSON MCP manifests such as
mcp.json,.mcp.json, andmcp-server.json - Claude-style
claude_desktop_config.jsonfiles withmcpServers
Supported execution transports are:
stdiostreamable-httpsse