Mercury CLI
Documentation

Sessions

Saturn scheduling

Saturn is Mercury's scheduler. A schedule belongs to a session and is saved in the durable session record. The background daemon fires it, and every fire decision lands as a receipt row on that session. The sessions themselves are the schedule store. The box schedule belongs to the machine, and its record is one file in the daemon's home.

Schedule kinds

  • Fire: Delivers a prompt to an existing session once with at or on a recurrence with every. A fire due while the session is parked wakes it by default; onParked: "queue" holds the fire for the session's own next wake. A scheduled run appears in the chat as a muted [Saturn] row showing the time and the schedule's prompt on the first line: a self-paced wake shows its cadence and reason, and a cron schedule shows its title and the spelling it was scheduled with. A fire due while the account's usage window is closed waits for the reset and says so once. A fire bills as scheduled work, in its own row on the usage popup and the side rail.
  • New session: Creates a fresh session at a scheduled time, with its model, workspace and prompt chosen up front. The new session's first receipt names the schedule that created it.
  • Box schedule: A new-session schedule that belongs to the machine and is stored in the daemon's home. It needs no existing session.

Inside a session, the model schedules through the tools CronCreate, CronList, CronDelete and ScheduleWakeup, and the /loop skill builds on them. A schedule given a title shows it on its Saturn row and in CronList in place of the schedule id.

Schedule board

  • /saturn: Opens the board inside the chat.
  • Saturn Scheduler: Opens the same board from the home screen, and Esc returns to the home screen.
  • ↑ and ↓: Move between rows.
  • a: Opens the form for scheduling a new session.
  • x: Deletes the selected schedule.
  • n: Runs the selected schedule now.
  • p: Pauses or resumes the selected schedule.
  • r: Refreshes the board.

Rows group under the session that owns them, and box schedules sit under their own box section. A row's trail shows the time expression as typed, the account it will fire on as an identity, held fires with their reasons, and the trail of fired-late and missed receipts. Adding, deleting, pausing or resuming a schedule from the /saturn board updates the live conversation immediately, so CronList and the model's schedule view never list a schedule you already deleted.

The status rows distinguish an upcoming fire from one that is held. The label due now belongs only to a fire whose scheduled instant has arrived, which the next scheduler tick will run. While a future fire is pending, the session's row on the Session Concourse shows it in the NOW cell, next fire in 2h, beside whatever the session is doing, and the side rail's SATURN row and the home screen's Saturn Scheduler row say what is scheduled across every session in the board's own words, such as 2 scheduled · in 4m or 1 scheduled · 1 held.

A fire whose account is not ready is held, with its reason typed and receipted: a sign-in that expired, a signed-out family, a rate limit until the window's end, or no local server answering, where the words name MERCURY_LOCAL_BASE_URL. When the same family answers under a different identity, the fire holds as account-mismatch until the identity matches again or a fresh sign-in makes the schedule ready; /logins or run-now releases it. Signing back in releases the held fires whole, in order, each receipted as fired late. Resuming a session whose schedules are stranded shows one display-only warning row beside the away recap, with the worst verdict across its unpaused schedules and /logins named.

Schedule a new session

To schedule a new session, open /saturn or the home screen's Saturn Scheduler row, press a, fill in the form fields below, review the preview and press s. Saturn saves a box schedule whose firing creates the specified session without needing an existing session open.

The form's fields are:

  • When: Accepts a supported time expression or recurrence.
  • Model: Selects from the full model catalogue.
  • Workspace: Selects one of the saved projects or a custom path.
  • Presence: headless runs unattended. screen-present needs Mercury open; a run due while Mercury is closed waits for the next boot and then obeys the catch-up window from its due instant.
  • Kit preset: Selects which saved MCPs & Skills preset the new session loads when it starts.
  • Opening mission: audit and review provide complete missions. custom opens a text field, and none creates a blank session that waits.
  • Contract, Title and Note: Supply the session contract pre-answered at start, the new session's name and a note for the board.

The live preview displays the compiler's errors as written, the account the session would run on and the verdict sentence, including the held notice when the account is already stranded.

Time expressions

  • One-time expressions: Examples include 6am, 18:30, tomorrow 07:30 and in 20m.
  • Recurrences: Examples include every 5 minutes, every hour at:07, every day 09:00, weekdays 9am and every mon,fri 17:00.
  • Cron: Raw five-field cron passes through unchanged.

The spelling typed is stored and echoed on every surface as written, and a phrase the compiler cannot read is refused with a working form named.

Held and late fires

A schedule records the account when it is saved: the provider family, sign-in method and signed-in identity. The identity is a label kept apart from any token or key. If that sign-in expires, the account is signed out, a local server stops responding or the account is rate-limited, the scheduled action waits and records the reason. It waits on its own provider family. Signing in again or bringing the local server back releases the waiting actions in full and in order. Each is recorded as fired late, with its origin identified.

A fire that comes due while the daemon is down runs inside the catch-up window, six hours by default, and its receipt carries how late it fired. Outside that window it is recorded as missed-expired: a one-time schedule is spent and a recurrence waits for its next fire.

If a scheduled wake is due while the session has reached its usage limit, it waits until the provider's stated reset time (measured from the standing limit window the ticker observed for that family). This applies to OpenAI, Gemini, OpenRouter, Hugging Face and Anthropic. A command that is not yet due does not wake a headless lead during that closed window. Watches hold incoming updates while the usage window is closed and deliver them together on the first turn after it reopens. If a watch did not survive a pause, Mercury reports it once when the session resumes. A self-paced wake created by ScheduleWakeup uses the wake arm (onParked: "wake"): parking a session preserves its scheduled wakes and a due self-paced wake wakes the session that set it, while interrupting or stopping that session cancels its pending self-paced wakes, including any already held, with a receipt. Schedules you created yourself remain in place.

  • MERCURY_DAEMON_CATCHUP=0: Turns late fires off, so every late fire is recorded as missed-expired.
  • MERCURY_DAEMON_CATCHUP_MINUTES: Resizes the catch-up window.
  • MERCURY_SATURN_DISABLE: When truthy, the daemon stops firing, holding and replaying. The schedules and their editing surface stay, and the scheduling tools leave the catalogue.