Skip to content

Feature matrix

A scannable projection of every mono-agent capability for non-linear readers: each feature id mapped to its coverage type, the config key(s) and env var(s) that reach it, the prose page that explains it, and any playbook that puts it to work.

docs/reference/feature-registry.md is the canonical long-form source of truth — when this matrix and the registry disagree, the registry wins. This page projects the same rows into a grid for quick lookup.

CodeMeaning
configDeclarable in mono-agent.config.json; an env override exists only where one is listed (-- means JSON-only / no env form)
cliReached through a mono-agent CLI flag/command
autoAlways active when the app runs; needs no declaration
codeProgrammatic escape hatch only — see Programmatic API
devDevelopment/test-time tooling, not part of a running agent

Core precedence: mono-agent.config.json > built-in defaults. Adapter-owned environment inputs remain documented by their packages.

Feature idCoverageConfig key(s)Env var(s)Prose pagePlaybook(s)
runtime.multi-backendconfigruntime.model—Pi runtimeMulti-model fallback
runtime.fallback-modelsconfigruntime.fallbacks[].{model,effort?}; CLI uses repeated --fallback (legacy --fallback-models flag removed)—FallbackMulti-model fallback
runtime.effortconfigruntime.effort, runtime.fallbacks[].effort—Execution, effort, permissions—
runtime.per-trigger-modelconfig + codecron.jobs[].{model,effort}; webhook.endpoints[].{model,effort} + request body {model,effort}; Telegram built-ins /model and /effort; Slack Block Kit selectors through thread-local @agent /model / @agent /effort and channel-wide workspace commands /<bot>-model / /<bot>-effort, all over configured primary/fallback models—Cron · Webhook · Telegram · Slack—
runtime.max-turnsconfigruntime.maxTurns—Pi runtime—
runtime.workspaceconfigruntime.workspace—Pi runtime—
runtime.provider-sessionsconfigruntime.session.mode, runtime.session.idleTimeoutMs, runtime.session.rollover, runtime.session.rolloverTimezone, runtime.session.rolloverNotice—Sessions & concurrency—
runtime.concurrencyconfigconcurrency.maxConcurrentRuns, concurrency.maxPendingRuns—Sessions & concurrency—
runtime.local-providersconfigproviders.local[]—Local providersLocal-only Ollama agent
runtime.providersconfigproviders.<providerId>, providers.local[], providers.piAuthPath, providers.piNative.*—Providers—
runtime.pi-credentialsconfigproviders.piAuthPath (OAuth/account and API-key credentials such as OpenCode-Go)—Local providers—
runtime.pi-native-tuningconfigproviders.piNative.transport, providers.piNative.piMaxRetries, providers.piNative.maxRetryDelayMs, runtime.session.root—Sessions & concurrency—
runtime.tool-parallelismcoderuntimeOptions.piToolExecutionMode—Tools & guards—
runtime.web-researchconfig + autotools.web.search.*, tools.web.fetch.*—Local-first web researchLocal-first web research agent
runtime.webfetch-retryauto(built into WebFetch)—Tools & guards—
runtime.context-compactionconfig + providerruntime.compaction.*—Tools & guards—
runtime.tool-bloat-guardauto(artifacts land in artifacts.dir)—Tools & guards—
runtime.cost-trackingauto(recorded in JSONL artifacts)—Artifacts & traces—
runtime.builtin-toolsconfigtools.allowedTools, tools.disallowedTools—Tools & guards—
runtime.structured-outputcoderuntimeOptions.outputSchema (every Pi runtime route)—Approval & structured output—
runtime.live-inputauto + codeSlack/Telegram active-turn steering plus the web console’s single server-authoritative Send path, with exact host-operation ownership, separate native acceptance, exact transcript consumption, uncertainty/no automatic retry, durable UUID receipts, and confirmed safe-preview Steered activity; custom runtimeOptions.liveInput—Approval & structured output—
runtime.approval-gatescodecreateMonoRuntime({ onToolApprovalRequest, ... })—Approval & structured output—
runtime.customcodestartMonoAgentApp({ runtime })—Composition—
Feature idCoverageConfig key(s)Env var(s)Prose pagePlaybook(s)
sandbox.modeconfigsandbox.mode—SandboxSandboxed code agent
sandbox.network-policyconfigsandbox.network.mode, sandbox.network.allowlist—SandboxSandboxed code agent
sandbox.filesystem-scopesconfigsandbox.readableRoots, sandbox.writableRoots, sandbox.denyWrite—SandboxSandboxed code agent
sandbox.fallbackconfigsandbox.fallback, sandbox.unsafeAllowHostProcess—SandboxSandboxed code agent
sandbox.monotonic-mergeauto(harness merges configured + request policies)—Sandbox—
sandbox.managed-srtcli + auto`mono-agent sandbox status| —check`; automatic managed runtime resolution—Sandbox
Feature idCoverageConfig key(s)Env var(s)Prose pagePlaybook(s)
memory.liteconfigmemory.mode: "lite", memory.path, memory.maxBytes, memory.writeMode—Capture & recall—
memory.journalconfigmemory.mode: "journal", memory.path, memory.embeddings.{provider,model,dim}—Embeddings—
memory.bujoconfigmemory.mode: "bujo", memory.path, memory.embeddings.{provider,model,dim}, memory.llm.{provider,model,endpoint}—Capture & recallTelegram BuJo assistant
memory.bujo-consolidationconfigmemory.consolidation.{enabled,cron}—ConsolidationTelegram BuJo assistant
memory.bujo-clicliRemoved — use config-aware mono-agent memory <subcommand> from the agent folder—Validation & CLI—
memory.preview-clicli`mono-agent memory stats| —show |search |top|audit|rebuild|rollback [—limit ] [—json]; owner-only forget prepare|apply|restore`—Validation & CLI
memory.validateclimono-agent validate [--consumer] [--config]—Validation & CLI—
memory.write-modeconfigmemory.writeMode—Capture & recall—
memory.per-turn-captureconfigmemory.writeMode: "capture" (requires memory.mode: "bujo")—Capture & recallTelegram BuJo assistant
memory.recall-toolconfigmemory.recallTool.enabled—Capture & recallTelegram BuJo assistant
memory.journal-browseconfig + autoShared memory.recallTool.enabled; local Lite/Journal/BuJo capability; policy-gated MemoryJournal; no new key—Capture & recall—
memory.remember-toolconfigmemory.rememberTool.enabled; allowlist-gated Remember; bujo backend only—Capture & recall—
memory.llm-timeoutconfigmemory.llm.timeoutMs (in-app; 1000–600000, default 60000)—Validation & CLI—
memory.custom-storecodecreateConfiguredAgentResponder({ memory })—Composition—
Feature idCoverageConfig key(s)Env var(s)Prose pagePlaybook(s)
agent.public-nameconfigagent.name—Identity & soul—
context.identityconfigcontext.identityPath—Identity & soul—
context.soulconfigcontext.soulPath—Identity & soul—
context.historyauto(owner-only disk-backed store; 64 messages per exact conversation id independent of runtime.maxTurns; aggregate committed defaults 256 MiB / 10,000 conversations / 365 inactive days plus an independent 256 MiB live-stage cap; staged atomic publication, immediate markerless-stage recovery, exact-key cross-process claims in fixed registry shards, bounded pre-provider dirty-fence retirement journals, provider epoch/revision coordination, exact-id durable transcript retirement, and post-commit pruning; custom store via code; completed blocking asks retain a bounded interaction transcript)—Assembly—
skills.selected-activationconfigcontext.skillsRoot, context.selectedSkills—SkillsSlack team bot + MCP tools
skills.byte-cappingconfigcontext.skillMaxBytes—Skills—
Feature idCoverageConfig key(s)Env var(s)Prose pagePlaybook(s)
tool-policy.allow-allconfigomitted / ["*"] = all tools (default; risk disclosed and reconfirmed unsandboxed in guided init)—Tool policy—
tool-policy.allowlist / tool-policy.denylistconfigPi runtime reports tool_policy as projected on every route; custom structural bridges without the field should be treated conservatively—Tool policy—
tool-policy.mcp-serversconfigtools.mcpConfigPath—MCPSlack team bot + MCP tools
agent-app.rich-repliesconfig + autoPublishReplyFile under allow-all, or name it in a restrictive tools.allowedTools; MCP Apps are capability-gated to an all-Pi-native route chain; web-only SuggestReplies attaches non-blocking choices that become normal user turns; retention follows artifacts.retention.maxAgeDays—Reply files and MCP AppsInteractive transcription and large media
agent-app.durable-continuationsconfig + codetools.continuationServers, continuations.{enabled,host,port,stateDir,namedRoutes,detachedServices}MONO_AGENT_CONTINUATION_SERVERS; detached bearer env names are operator-selectedDurable continuations—
agent-app.run-history-toolautoGuided settled-run recovery/list/ranked search plus compact, cursor-paged inspect over one logical conversation, including an exact SessionHistory handoff for cancelled/interrupted evidence; daily rollover-independent. RunHistory under allow-all; restrictive policy explicitly lists RunHistory (legacy policy alias run_history); no new config key—Artifacts & traces—
agent-app.session-history-toolautoCrash-safe managed-tool invocation/result sidecar plus bounded SessionHistory search/get for the current logical conversation, with trusted navigation from invocation/result ids to exact isolated 8 KiB record reads; daily-rollover-independent. Automatic cold projection fails soft, while explicit reads fail closed. SessionHistory under allow-all; restrictive policy explicitly lists SessionHistory (legacy policy alias session_history); no new config key—MCP—
agent-app.conversation-history-toolconfig + autoDefault-on deterministic cold packs (runtime.session.continuity.packEnabled, no paid upkeep) plus opt-in bounded ledger upkeep and retained conversation search/get with digest-bound ≤8 KiB chunks; runtime.session.continuity.enabled: false opts out. Normal policy ConversationHistory/conversation_history, MCP/global wildcard allow and deny-wins; no memory dependency—MCP evidence—
agent-app.memory-journal-toolconfig + autoRequest-scoped MemoryJournal over a frozen bounded local curated-memory snapshot. Shares the memory-read enablement, needs affirmative Lite/Journal/BuJo capability, and is normal-policy-gated; no config key or legacy alias—MCP—
agent-app.web-conversation-titleautoRequest-scoped SetConversationTitle for writable interactive web threads; names the conversation as a whole and is refined whenever a better whole-thread name emerges, never used as a status line; proposal-only result, with permanent user-rename precedence and no trigger/archive writes. Allow-all exposes it on compatible routes; restrictive policy explicitly lists it; direct OpenCode suppresses it; no new config key—MCP—
agent-app.adapter-send-toolsconfigauto-available under allow-all once the channel is enabled; a specific tools.allowedTools needs the exact names (SlackSendMessage, TelegramSendMessage) + valid slack.* / telegram.* config; confirmed posts are idempotently recorded in destination history—Delivery & send toolsCron digest + native notify
interaction.bridgeconfig + autointeraction.bridge.{host,port}, interaction.askUser.timeoutMs (default 600000; null disables automatic expiry), interaction.progress.enabled, tools.mcpRequestContextServers; auto-starts for configured send tools, allowed structured AskUser, configured interaction JSON/env, or enabled opted project-MCP progressMONO_AGENT_INTERACTION_BRIDGE_HOST, MONO_AGENT_INTERACTION_BRIDGE_PORT, MONO_AGENT_ASK_USER_TIMEOUT_MS (none disables automatic expiry), MONO_AGENT_PROGRESS_ENABLED, MONO_AGENT_MCP_REQUEST_CONTEXT_SERVERSDelivery & send toolsInteractive transcription
tool-policy.filesystem-rootsconfigtools.filesystem.{readableRoots,writableRoots}; extra managed file-tool roots while sandbox.mode: "off", with write roots also readable and lexical plus realpath containment—Sandbox—

Built-in channels are independent JSON sections: telegram, slack, webhook, openaiApi, cron, tui, and live. External channel packages are declared under channels.plugins[] and return the same ChannelDriver shape; the current cataloged channel extras are @mono-agent/channel-a2a, @mono-agent/channel-whatsapp, and @mono-agent/channel-messenger. Most are opt-in via an enabled flag (default off); tui and live are default-on loopback operator surfaces. An off channel reports disabled; an enabled channel with incomplete config reports waiting_for_config. Adapter fields can also have MONO_AGENT_<CHANNEL>_* env vars.

Feature idCoverageConfig key(s)Env var(s)Prose pagePlaybook(s)
telegram.long-pollingconfigtelegram.enabled, telegram.botToken, telegram.allowedChatIds / telegram.allowAllChats, telegram.groupMode / telegram.stripMentionText, telegram.topics (per-forum-topic groupMode; listen keeps unaddressed chatter as next-turn context), telegram.pollWatchdogMs, telegram.transport.ipFamily (+ built-in self-healing restart)MONO_AGENT_TELEGRAM_BOT_TOKEN, MONO_AGENT_TELEGRAM_*TelegramTelegram BuJo assistant
telegram.interactiveconfig + codebuilt-in /new, plus /model and /effort via adapter runtimeControls; telegram.commands[], telegram.reactions, telegram.quietHours; structured AskUser buttons/custom replies, non-blocking TelegramSendMessage.reply_options, and TelegramSendFileMONO_AGENT_TELEGRAM_REACTIONS; runtime controls have no env keyTelegram—
telegram.projectsconfigJSON-only telegram.projects.enabled (needs mono-agent web run): forum topics become web-console projects whose context reaches every turn in the topic; project tools on human Telegram turns and projectId on TelegramSendMessage/TelegramSendFile via tool policy—Telegram—
slack.ask-userauto + codestructured AskUser renders one Block Kit question at a time with option buttons, Other/custom thread reply, and multi-select Done; no Slack-specific config—Slack—
slack.socket-modeconfigslack.enabled, slack.botToken, slack.appToken, slack.allowedChannelIds / slack.allowAllChannels, slack.botUserIds, slack.mentionTextAliases, slack.stripMentionText, slack.unfurlLinks, slack.unfurlMedia. When unset, preserves one readable authenticated self-mention marker; true restores legacy full stripping and false keeps raw mention forms. Omitted unfurl settings preserve Slack’s current native-message defaults. Resilience tuning (all optional, on by default): slack.heartbeatIntervalMs, slack.heartbeatTimeoutMs, slack.reconnectInitialBackoffMs, slack.reconnectMaxBackoffMs, slack.reconnectStabilityMs, slack.reconnectStartupGraceMs, slack.drainDeadlineMsMONO_AGENT_SLACK_* (incl. MONO_AGENT_SLACK_UNFURL_LINKS, MONO_AGENT_SLACK_UNFURL_MEDIA, MONO_AGENT_SLACK_HEARTBEAT_*, MONO_AGENT_SLACK_RECONNECT_*, MONO_AGENT_SLACK_DRAIN_DEADLINE_MS)SlackSlack team bot + MCP tools
slack.speaker-namesconfigslack.resolveUserNames (default true); requires the users:read bot scopeMONO_AGENT_SLACK_RESOLVE_USER_NAMESSpeaker names—
channels.surface-awarenessconfigAlways on for Slack and Telegram; slack.resolveChannelNames (default true) adds the Slack channel name and requires channels:read/groups:readMONO_AGENT_SLACK_RESOLVE_CHANNEL_NAMESSurface awareness—
slack.thread-contextconfigslack.threadContext.{enabled,maxMessages,requestLimit,timeoutMs,includeBotMessages}; defaults true/15/15/4000/true; requires a *:history scopeMONO_AGENT_SLACK_THREAD_CONTEXT_*Thread and channel context—
slack.shortcutsconfigslack.shortcuts[]: {callbackId, prompt, channelId?, ackText?, threadReply?}— (JSON-only; no environment-variable form)Slack shortcuts—
slack.app-homeconfigslack.homeTab: {enabled?, headerText?, buttons?:[{actionId, label, prompt, channelId?, ackText?, threadReply?}]}; enabled defaults false, buttons defaults []— (JSON-only; no environment-variable form)Slack App Home—
channel.pluginsconfigchannels.plugins[]: { package, id?, label?, config? }—Write your own channel adapter—
whatsapp.baileysconfigchannels.plugins[].package: "@mono-agent/channel-whatsapp" plus plugin config.{enabled,allowedChatJids,allowAllChats,groupMode,botJids,mentionTextAliases,stripMentionText}. When unset, defaults to true only when mentionTextAliases is non-empty; botJids alone does not enable stripping, so otherwise it defaults to false.MONO_AGENT_WHATSAPP_*WhatsApp—
messenger.graphconfigchannels.plugins[].package: "@mono-agent/channel-messenger" plus plugin config.{enabled,allowedUserIds,allowAllUsers,host,port,webhookPath,apiVersion,allowNonLoopback,proactiveMessagingType,proactiveTag}; secrets via MONO_AGENT_MESSENGER_PAGE_ACCESS_TOKEN, MONO_AGENT_MESSENGER_APP_SECRET, MONO_AGENT_MESSENGER_VERIFY_TOKEN.MONO_AGENT_MESSENGER_*Messenger—
webhook.http-invokeconfigwebhook.enabled, host, port, path, prompt, notify, notifyConversationId, defaultMode, allowNonLoopback, apiKey, retentionMs, maxStoredRequests, maxRunMs, webhook.endpoints[] (incl. per-endpoint model/effort/maxRunMs; a request body may set model/effort, request winning over endpoint config; endpoint maxRunMs wins over the adapter fallback), webhook.dir; a non-loopback bind requires opt-in + bearer keyMONO_AGENT_WEBHOOK_* (incl. MONO_AGENT_WEBHOOK_API_KEY, MONO_AGENT_WEBHOOK_MODEL, MONO_AGENT_WEBHOOK_EFFORT, MONO_AGENT_WEBHOOK_MAX_RUN_MS), MONO_AGENT_WEBHOOK_ENDPOINTS_JSON, MONO_AGENT_WEBHOOK_DIRWebhookWebhook automation (sync/async)
openai-api.chat-completionsconfigopenaiApi.enabled, host, port, basePath, allowNonLoopback, apiKey, modelId; non-loopback requires opt-in + key and wildcard binds report concrete client URLsMONO_AGENT_OPENAI_API_{ENABLED,HOST,PORT,BASE_PATH,ALLOW_NON_LOOPBACK,KEY,MODEL_ID}OpenAI-compatible APIOpenAI endpoint + Open WebUI
a2a.providerconfigchannels.plugins[].package: "@mono-agent/channel-a2a" plus plugin config.provider.* (including maxRequestBytes; durable identity: provider.idempotency.{namespace,stateDir,retentionMs,maxRecords}), config.agent.*, config.skill.*MONO_AGENT_A2A_*A2AA2A provider & consumer
a2a.consumerconfig + codeplugin config.consumer.{remoteAgentUrls,defaultRemoteAgentUrl,bearerToken,timeoutMs}; sendA2AMessage({idempotencyKey}) or createA2AConsumerResponder({idempotencyKeyForRequest})MONO_AGENT_A2A_*A2A consumerA2A provider & consumer
tui.stream-endpointconfigtui.{enabled,host,port,basePath,allowNonLoopback,apiKey} — on by default (loopback web/ACP/jobs operator surface; /v1/info separately advertises additive attachment, legacy verbatim-history, canonical v1 context import, exact structured AskUser, and agent-owned cron capabilities without a wire-schema bump)MONO_AGENT_TUI_*Operator stream endpoint—
agent-app.peer-agentconfigpeers maps names to local source IDs, and PeerAgent must be tool-allowed; named ACP sessions resume without prompt replay, background needs exact-origin ProcessJobs; AskUser interaction relay is unsupported—ACP bridge—
acp.worklab-bridgecli + codemono-agent bridge acp --discover; mono-agent bridge acp --source-id <id>; discoverAcpBridgeAgents()—ACP bridge—
cron.scheduled-promptsconfigcron.jobs[]: {id, enabled, expression, timezone, prompt, conversationId, maxRunMs, notify, notifyConversationId, notifyFailureCooldownHours, model, effort}, cron.dir; durable agent-owned run history; opt-in confirmed/idempotent/audited operator API controls via cron.operatorActions.enabled (default off; runtime enable state never rewrites config)MONO_AGENT_CRON_JOBS_JSON, MONO_AGENT_CRON_* (incl. MONO_AGENT_CRON_NOTIFY_FAILURE_COOLDOWN_HOURS, MONO_AGENT_CRON_MODEL, MONO_AGENT_CRON_EFFORT, MONO_AGENT_CRON_OPERATOR_ACTIONS_ENABLED), MONO_AGENT_CRON_DIRCronCron digest + native notify
cron.run-watchdogconfig + codejobs[].maxRunMs or maxRunMs frontmatter; programmatic fallback via startCronAdapter—Cron—
cron.preflight-gateconfig + codecron.jobs[].preflight (explicit argv; frontmatter takes one single-line JSON array) and cron.jobs[].preflightTimeoutMs (default 5000, cap 60000); programmatic startCronAdapter({ preflight, onPreflight, preflightTimeoutMs })MONO_AGENT_CRON_PREFLIGHT_JSON, MONO_AGENT_CRON_PREFLIGHT_TIMEOUT_MSCron—
channel.native-notifyconfigper cron job / webhook endpoint notify; explicit notifyConversationId wins, including exact web:new for one new marked web thread per result; web is never inferred and other web:* values reject; otherwise infer only with exactly one notify-capable Telegram/Slack candidate; 0 or 2+ candidates skip with a warning; cron model-exhaustion notices require explicit notifyConversationId, never infer, and may set notifyFailureCooldownHours; Telegram/Slack stay bounded by channel allowlists, while web requires the running local console and is one-attempt/no-outboxMONO_AGENT_CRON_NOTIFY, MONO_AGENT_CRON_NOTIFY_CONVERSATION_ID, MONO_AGENT_CRON_NOTIFY_FAILURE_COOLDOWN_HOURS (+ webhook equivalents except cooldown)Delivery & send toolsCron digest + native notify
channel.final-only-deliverycodeAdapter stream.finalOnly (default true for telegram/slack; answer deltas stay hidden while a transient tool ledger may be visible)—Delivery & send tools—
channel.transient-tool-activitycodeResilientMessageStream({ finalOnly: true, showHints: true }); terminal subagent groups remove child tool lines but retain metrics plus an optional bounded Result/Reason; proactive delivery forces showHints: false; Telegram and Slack post the answer separately then best-effort delete progress; optional transport deletion also supports /cancel cleanup—Delivery & send tools—
channel.stream-tuningcodeAdapter stream / messages options (createTelegramChannelDriver etc.)—Write your own channel adapter—
channel.customconfig + codechannels.plugins[] package loading or startMonoAgentApp({ drivers }) (implement ChannelDriver)—Write your own channel adapter—
Feature idCoverageConfig key(s)Env var(s)Prose pagePlaybook(s)
observability.jsonl-artifactsconfigartifacts.dir, artifacts.retention.{maxAgeDays,maxCount,dryRun}, artifacts.memoryRetention.{maxAgeDays,maxCount,dryRun}—Artifacts & traces—
observability.latency-attributionauto(emitted into run JSONL artifacts)—Artifacts & traces—
observability.trace-registryconfigtraceability.{registryDir,sourceId,sourceLabel,heartbeatMs,staleAfterMs}—Artifacts & traces—
observability.artifact-auditcli / codeauditRecordedRuns(artifactDir, { staleAfterMs }); `mono-agent runs audit [—artifacts | ——Artifacts & traces—
observability.artifact-metricscli / codesummarizeRecordedRunMetrics({ artifactDir, since, until, groupBy }); mono-agent runs report [--artifacts] [--since] [--until] [--by] [--json]—Artifacts & traces—
observability.stale-run-reconciliationauto(reconcileStaleRunArtifacts() at startup over artifacts.dir; rewrites orphaned running → interrupted)—Artifacts & traces—
web.consolecli`mono-agent web [startrestartstopstatus
Feature idCoverageConfig key(s)Env var(s)Prose pagePlaybook(s)
app.cli-initcli--name, exact IDENTITY.md → ## Role prompt/outcome, managed project skills, --preset (legacy --recipe removed), canonical repeated --fallback/--fallback-effort (legacy --fallback-models removed), --auth; any flag/non-TTY remains scaffold-only—Quickstart—
app.cli-setupclibare TTY mono-agent init: searchable catalogs, Escape-back, optional-capabilities gate (channels/memory, default No for the custom journey), concrete review, all-route proof, interrupt resume/restart; macOS starts the background agent and prints the browser-first handoff (status → mono-agent web run --loopback → http://127.0.0.1:5050), while unsupported platforms print the manual start plus the same console command—CLI reference—
app.secure-secret-persistenceclifail-closed owner-only .env merge + external lock + pathname no-clobber/recovery checks; Windows manual onlychannel/provider-native secret varsEnv vars—
app.provider-authclimono-agent auth login <provider> [--pi-auth-path] [--api-key-stdin]; Agent settings honest passive status, explicit bounded live checks, plus Pi-native GitHub/Codex device code, Anthropic paste-back, ChatGPT sign-in on openai with remote full-URL paste-back, and masked provider API-key prompts; shared owner-only locked/no-clobber Pi-store write—CLI reference, Providers—
app.cli-presetsclimono-agent presets list | show <id> (old recipes alias removed)—Presets & modules—
app.cli-no-tools-guardrailclipart of mono-agent validate / doctor; the tools step of mono-agent init—Presets & modules—
app.cli-validateclimono-agent validate [--consumer] [--config] [--env-file]—Blueprint—
app.provider-credentials-checkclipart of mono-agent validate; primary/fallback/memory/enabled static trigger refs; exact Pi built-in model + providers.piAuthPath, or custom model/key contract through providers.local[]—CLI reference—
app.cli-startclimono-agent start [--config] [--env-file] [--foreground]—Install—
app.cli-stopclimono-agent stop [--config]—Install—
app.cli-logsclimono-agent logs [--config] [--follow|-f] [--lines <n>]—CLI reference—
app.cli-restart-cleanclimono-agent restart [--config] [--clear-sessions]—CLI reference—
app.managed-project-skillscli + configgenerated mono-agent-memory; retired mono-agent-configure is ignored at runtime and reported as waiting until mono-agent install-skill --project --update safely removes exact managed legacy state—Skills—
app.docs-mcp-companioncli + codemono_agent_docs({action: "search", query, limit?, scope?}); mono_agent_docs({action: "read", target}); expanded mono-agent-docs://chunk/{chunkId} resources—Documentation MCP companion—
app.cli-install-skillclimono-agent install-skill [--target claude|codex|both] [--force] [--no-docs-mcp]; --project --check reports four active and four retirement states; --project --update transactionally updates active state and retires only exact managed legacy state—CLI reference—
app.cli-webclibare read-only status/help; web start|restart|stop|status|logs|run|reset; --host <addr> | --loopback, --port <n>, --theme <name> on start/restart/run; restart retains the stored theme; status reports it; reset requires --all --yes—Web console—
app.env-filecliautomatic; --env-file <path> to override—Env vars—
harness.failure-handlingauto(built into every run)—Composition—
harness.external-summary-safetyautopublic harness/webhook summaries exclude systemPrompt; private artifacts retain it—Artifacts & tracesWebhook automation
agent-app.blocking-ask-historyautoapp interaction journal + configured harness history commit; no config key—AssemblyInteractive long jobs
harness.request-runtime-optionscodecreateConfiguredAgentResponder({ runtimeOptionsForRequest })—Composition—
orchestrator.ask-collaboratorcodecreateCollaboratorToolRuntimeExtension + runtimeOptionsForRequest—Multi-agentMulti-agent orchestration

A code-only feature has no mono-agent.config.json key — you reach it through startMonoAgentApp options or lower-level packages. See Programmatic API for the entry points referenced above (createConfiguredAgentResponder, createMonoRuntime, createCollaboratorToolRuntimeExtension, custom ChannelDriver/runtime/memory/historyStore injection).