Skip to main content

Mercury Bots — The Fleet

Mercury Bots are persistent, persona-scoped agents that run outside your conversation. Unlike sub-agents (which die with their task) or channels (which answer as one persona), bots are long-lived specialists: each has a name, a character, its own private workspace, its own skill library and permission scopes, a per-bot token budget, and a durable job queue. Dispatch work and keep talking — the bot works in the background and delivers results in its own thread.

Concepts​

ConceptWhat it is
BotA persistent persona agent: bot.yaml manifest + permissions.yaml, sandbox at ~/.mercury/bots/<id>/, journal-backed history
WakeTurning a bot on for a turn (/bots run <id> [routine] or a dispatched task)
ThreadThe bot's own chat — results, thinking streams, and journal history land here, never in your active chat
Fleet leadA bot promoted to organize its own crew (/bots promote <id>) — tell it what, it decides how and who
CrewThe bots under a lead; results bubble up through the lead; multi-level hierarchies supported
BundleShareable export of a bot (or whole fleet): manifests + personas + permissions + skills
DLQDead-letter queue for failed/timed-out jobs, replayable non-destructively
Needs-you alertEscalation to your active channel when a bot is blocked (failed job, permission wall, stopped bot)

Bot vs sub-agent vs channel​

Sub-agentMercury Bot
Lifetimedies with its taskpersists across restarts
Identityanonymousnamed persona with editable character
Workspacesession workspaceprivate sandbox ~/.mercury/bots/<id>/ + shared folder
Resultsyour chatthe bot's own thread
Memorynonejournal history hydrates on reopen
Skillssession skillsnative library + per-bot libraries
Schedule—bot_schedule — bots own their routines

Quick start​

/bots # roster with live states
/bots create researcher "Researcher" "Web research specialist"
/bots persona researcher "Meticulous researcher who cites sources."
/bots promote researcher # make it a fleet lead (optional)
/dispatch_bot bot=researcher task="Compare X vs Y, cite sources"
/bots open researcher # open its thread

The result lands in the researcher's thread — your chat stays clean. Check on it with /bots or open its thread and reply directly.

Commands​

Run these inside a conversation with Mercury (CLI, Telegram, Discord, Slack, or Web):

CommandDescription
/botsRoster with live states — on Telegram with tappable Stop/Start/Run/Runs buttons per bot and a fleet row (Cost, Outputs, Doctor, Stop all)
/bots create <id> "Name" "Description"Onboard a bot (persona, permission tier, fleet, budget size, and where results land)
/bots open <id>Open the bot's own thread (TUI)
/bot <id> <message> or @<id> <message>Dispatch a task; the result (and any delivered files) come back to the chat that asked
/bots cost [days]Token spend per bot and fleet, today against the caps
/bots outputs [id] · /bots folder <id> · /bots fetch <id> [name]What was delivered; open the folder; send a file to this chat
/bots show <id> [runId] · /bots journal <id>What a run did (tools, deliveries, reply) · recent runs
/bots tasks <leadId>A lead's delegated tasks and their results
/bots budget <id> <tokens|suggest|none>Daily token cap (default 5M; none = unlimited)
/bots persona <id> <text> · /bots edit <id> <field> <value>Character · any config field
/bots permissions <id> [readonly|builder|operator|full]Capability tier
/bots promote <id> / demote · /bots crew <leadId> · /bots add-crew / remove-crewFleet structure
/bots stop <id> / start <id> · /bots stop all / start allHold and resume one bot (and its crew) · the whole fleet
/bots enable <id> / disable <id>Suspend/reactivate (imported bots start disabled)
/bots run <id> [routine]Fire a routine now, or a bare wake
/bots dlq [clear [id]] · /bots replay <id> <jobId>Failed jobs; drop them; re-run one
/bots doctor · /bots storageFleet health · disk usage
/bots export <id> [path] · /bots import <path>Bundles (a lead's carries its crew; imports start disabled)
/bots helpThis list, inside any chat

CLI mirrors the read-only surface — mercury bots doctor (fleet health check, exit 1 when actionable), mercury bots list, mercury bots storage.

Workspaces & file access​

  • Every bot gets a private sandbox: ~/.mercury/bots/<id>/. Work stays isolated; other bots can't wander into it.
  • The fleet-shared folder ~/.mercury/bots/_shared/ is for cross-bot files — implicit grants for crew members, explicit for leads.
  • Access scopes (read / write / execute per directory) are declared in the bot's permissions.yaml; hand-edits apply live; malformed entries skip + warn rather than crash.
  • Shell approval follows the bot's own allow-list (permissions.yaml autoApproveCommands).
  • Finished results exit via bot_deliver into a folder you can actually find: ~/Documents/Mercury/<Bot name>/ (Windows: Documents; Termux: shared storage; bots.deliverablesDir in mercury.yaml overrides). Finals sit on top, crew work under work/, with a README index and files named 2026-10-10 Oxide Series D explained.md. The path is shown when you onboard a bot and in /bots; /bots outputs lists deliveries and /bots folder <id> opens the folder.
  • Writes to the shared folder are budgeted per run — it is for data other bots consume, not for notes. Bots never write to the deliverables folder by hand.
  • The retention janitor enforces per-bot disk caps (journal rotation, DLQ cap), so a forgotten fleet can't fill your disk.

Scheduling & autonomy​

Bots own routines through bot_schedule — schedule their own future runs and recurring jobs, visible in /tasks and the fleet doctor. Leads additionally self-organize: give a lead a goal and it recruits crew, splits work, and synthesizes results upward.

Every unattended run is governed:

  • A turn is capped at 300k tokens and 20 minutes (autonomy.maxTokensPerTurn, maxTurnMinutes in bot.yaml); long context is compacted automatically.

  • Every bot has a daily token cap — 5M unless you set one with /bots budget <id> <tokens|suggest|none> — and the fleet has one (bots.fleetDailyTokenBudget). You are warned at 80%; at 100% the bot pauses until tomorrow.

  • A routine tick is skipped, never queued, while the bot is still busy or within its routine's minimum interval (schedules[].minIntervalMinutes). A cadence you declare in bot.yaml is honoured as written; routines a bot creates for itself run at most every 30 minutes, at most three per bot.

  • Bots stay online. A bot is idle between runs, never dead: a routine that keeps producing nothing is cooled down (6 hours, doubling to a day) and resumes by itself; budget pauses lift at midnight and queued work is pumped then; /bots doctor flags a bot whose routine has not fired in twice its cadence (stale). Bots run in their own lane — they never touch your main chat or code session.

  • Leads delegate typed tasks with fleet_delegate — several at once, each with a goal and what "done" means — and are woken once with a digest when the batch finishes or its deadline passes. A lead's standard job can be declared as a pipeline in bot.yaml (pipeline.stages), and fleet_pipeline runs it end to end with no lead turn between stages:

    pipeline:
    name: article
    stages:
    - { name: research, bot: source-researcher, goal: "Build a sourced dossier on {{input}}" }
    - { name: draft, bot: article-writer-draft, goal: "Write the 800–1000 word piece from {{previous}}" }
    - { name: check, bot: fact-checker, goal: "Fact-check {{previous}} and fix what fails" }
    - { name: package, bot: delivery-packager, goal: "Finalise {{previous}} for delivery", final: true }
  • Bots remember. After a productive run, durable facts (sources, decisions, where things are) go into the bot's own memory, and every turn starts with a digest of its last five runs plus its own working-state note (bot_state). bots.fleets.crewProvider puts crew work on a cheaper provider.

  • A run is judged by what it did, not by what it says: delivered a file, took an action, delegated, or nothing. A routine that only writes notes gets one nudge to deliver; three empty runs in a row cool it down (6h, doubling to 24h; it resumes by itself, or /bots start resumes it now). Monitoring routines can declare expects: check to be allowed to find nothing.

From Telegram​

Everything above works from your phone: /bots and /bot are in Telegram's command menu, and the roster comes with buttons — Stop / Start, Run and Runs per bot, and a fleet row with Cost, Outputs, Doctor and Stop all. A tap runs the same slash command you would have typed (same permissions, same reply). Creating a bot works there too: /bots create <id> "Name" "Description", then your next message is its persona, and the template, permissions, fleet and budget steps arrive as buttons. When a bot finishes a task you asked for from Telegram, the reply comes back to that chat with the delivered files attached, not a path on your Mac; /bots outputs <id> lists what a bot has delivered with a 📎 button per file, and /bots fetch <id> [name|latest] sends one.

Bundles​

/bots export <id> # single bot (or whole crew if lead / whole fleet)
/bots import <path> # recreate bots — starts disabled by design

Bundles contain manifests, personas, permissions, and skill libraries so a recreated fleet works identically. What never travels: ~/.mercury/bots/<id>/ sandbox state, journals, and .env secrets. Import locally, review, /bots enable.

Web cockpit​

The local dashboard ('Mercury Bots' section) shows the live roster, per-bot threads with streamed thinking, needs-you badges, and a fleet step view that mirrors the TUI (solo / lead auto-build / lead manual).

Observability​

  • /bots roster — live per-bot states (running / waiting / stopped / needs-you).
  • /bots cost [days] — token spend per bot and fleet against the caps; /bots show <id> [runId] — the tool trace, deliveries and reply of a run; /bots stop all — the kill switch; /bots dlq clear — drop dead-lettered jobs.
  • Journals — per-bot run history with real timings, steps, tool calls, the outcome (deliverable, action, delegated, message, none) and delivered paths; a compact transcript per run is kept (last 50).
  • DLQ + replay — failures classify honestly (failed, timed out) and replay non-destructively.
  • /bots doctor (in any chat) and mercury bots doctor — storage health, stale routines, whole-home write grants, outcome ratio, queue depth, journal rotation, and scheduler linkage (routines registered but never wired are flagged before they silently never fire).

Security notes​

  • Bots are persona-scoped: tools, skills, and scopes come from the bot's own manifests, not from your session.
  • Permission tiers (ask / allow) are chosen explicitly at onboarding — nothing defaults silently.
  • Bots stopped with /bots stop hold their queued jobs; nothing sneaks back in via the due-sweep until you /bots start.
  • Imported bundles start disabled — inspect before enabling.