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
| Concept | What it is |
|---|---|
| Bot | A persistent persona agent: bot.yaml manifest + permissions.yaml, sandbox at ~/.mercury/bots/<id>/, journal-backed history |
| Wake | Turning a bot on for a turn (/bots run <id> [routine] or a dispatched task) |
| Thread | The bot's own chat — results, thinking streams, and journal history land here, never in your active chat |
| Fleet lead | A bot promoted to organize its own crew (/bots promote <id>) — tell it what, it decides how and who |
| Crew | The bots under a lead; results bubble up through the lead; multi-level hierarchies supported |
| Bundle | Shareable export of a bot (or whole fleet): manifests + personas + permissions + skills |
| DLQ | Dead-letter queue for failed/timed-out jobs, replayable non-destructively |
| Needs-you alert | Escalation to your active channel when a bot is blocked (failed job, permission wall, stopped bot) |
Bot vs sub-agent vs channel
| Sub-agent | Mercury Bot | |
|---|---|---|
| Lifetime | dies with its task | persists across restarts |
| Identity | anonymous | named persona with editable character |
| Workspace | session workspace | private sandbox ~/.mercury/bots/<id>/ + shared folder |
| Results | your chat | the bot's own thread |
| Memory | none | journal history hydrates on reopen |
| Skills | session skills | native 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):
| Command | Description |
|---|---|
/bots | Roster 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-crew | Fleet structure |
/bots stop <id> / start <id> · /bots stop all / start all | Hold 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 storage | Fleet health · disk usage |
/bots export <id> [path] · /bots import <path> | Bundles (a lead's carries its crew; imports start disabled) |
/bots help | This 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_deliverinto a folder you can actually find:~/Documents/Mercury/<Bot name>/(Windows: Documents; Termux: shared storage;bots.deliverablesDirinmercury.yamloverrides). Finals sit on top, crew work underwork/, with a README index and files named2026-10-10 Oxide Series D explained.md. The path is shown when you onboard a bot and in/bots;/bots outputslists 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,maxTurnMinutesinbot.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 inbot.yamlis 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 doctorflags 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 inbot.yaml(pipeline.stages), andfleet_pipelineruns it end to end with no lead turn between stages:pipeline:name: articlestages:- { 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.crewProviderputs 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 startresumes it now). Monitoring routines can declareexpects: checkto 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
/botsroster — 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) andmercury 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 stophold their queued jobs; nothing sneaks back in via the due-sweep until you/bots start. - Imported bundles start disabled — inspect before enabling.