Mercury CLI
Documentation

Start

Using Mercury

Mercury has a home screen, a chat screen and a session board (the Session Concourse). The strip lets you move between the available screens.

Screens

  • Home screen: Running mercury with no arguments opens the home screen with no chat behind it. Each menu item opens in place over the home screen, and Esc returns you to the selected row.
  • Chat: This screen displays the focused session’s conversation and tool calls. A burst of tool calls shows as one card that counts up as the calls land. Pressing Esc in the main chat stops the current turn immediately while your crewmates keep running, and any reply already written or streaming when you press Esc stays on the screen and in the transcript. A session restart keeps its running agents and the queued line. The ended call’s result tells the model that the call was stopped on purpose and what may already have happened. Tool output appears as a compact card or as full output according to the Tool output row in /config, and the choice is saved for later boots. Each tool row starts with its tool’s mark, which takes the tool’s colour when the call settles, turns red on an error and reads ✕ when the call was denied; notices keep their dot. Under each settled reply, the turn receipt row summarizes the tools that ran and ends with the turn’s prompt context growth (· ctx +1.2k); a reply turn that ran no tool shows ∙ no tools ran this turn on its receipt row.
  • Session Concourse: This board displays the current project’s live sessions and, beneath them, its parked chats. A live row’s NOW cell shows the reply’s last line or the tool the session is running.
  • The strip: Shift+← and Shift+→ move to the nearest existing screen in the chosen direction. A chat joins the strip when a session is focused and leaves it when the last chat closes. The dim key-map row names only the moves that exist.
  • Terminal queries and handoff: When you open an external editor, suspend Mercury with Ctrl+Z, or exit, Mercury waits up to 250 ms (MERCURY_TERMINAL_QUERY_SETTLE_MS) for pending terminal capability replies to finish so escape codes never leak into your shell or editor, and the input scanner holds partial CSI escape sequences, mouse reports, focus marks and cursor-position replies across two 50 ms input flush windows and rejoins them with their tail bytes so stray characters never leak into the composer. On macOS Terminal.app, Mercury shapes Arabic presentation forms from Unicode's joining tables, orders right-to-left runs (Arabic, Hebrew and Persian) visually, isolates each glyph, and counts zero-width joiners and non-joiners as one cell on Terminal.app and zero elsewhere so right-to-left rows stay inside the frame with joined letters.

Home screen rows

  • New Session: Creates a blank session in the current folder on your default model. When all session slots are full, the notice on the home screen leads with how to free a slot (/concourse or /seats N). A project nested inside a git repository at your home directory scopes its startup git status check to the launch folder.
  • Continue Last Session: Returns to the newest conversation transcript (ignoring sidecar files such as .receipts.jsonl and auth-failure husks). The row appears once session history exists.
  • Boot Menu: Opens the boot settings, organized into six sections: TRUST COMBO (Content-rule wards, Debug tool (real debugger), C/C++ IDE lane (clangd), and Sovereign mode), COMPUTER USE (Computer use and Access type beneath it), SAMPLES (Samples), AGENTS (Crewmates, Crewmates while backgrounded, Workflows, and JEV, which shares its switch with /config and /jev), MISCELLANEOUS (Launch animation, Godot language lanes, Godot control surface (VULCAN), Unity dev lanes, Blender dev lanes, Aseprite dev lanes, Cap failover posture, Session Concourse at boot, and a row that sets how many model calls may run at once across your sessions and crewmates), and PERFORMANCE (Motion, which is auto, full, reduced or off and also in /config: on auto, idle motion drops to reduced on a machine that draws slowly or over a slow terminal link such as ssh, a console host or a slow pipe, comes back only after a longer run of cheap frames, and the status line says reduced or reduced · slow link).
  • MCPs & Skills: Controls what the next session loads.
  • Agents: Opens the Agent Studio to create and edit agents.
  • Health Check: Opens the installation’s health check.
  • Saturn Scheduler: Opens the schedule board over the home screen.
  • Logins: Opens the sign-in catalogue.
  • Session Concourse: Opens the project board as a separate screen.
  • Sessions · Projects: Opens the combined session and repository picker.
  • m: Opens the default model and effort picker over the home screen. The model and effort you pick become the default for new sessions, and the bottom row names the key at every terminal height. Setting engine.sessionDefaults to false switches the key off.

A prompt argument, --continue or --resume opens the chat directly. The MERCURY_CONCOURSE policy changes where a boot lands: always makes the board the boot home, and auto lands on the board when more than one session is live or one is waiting on the user.

The chat’s boxes and rows

  • Session box: The box at the top of the view holds a small critter in five rows and, while a turn runs, the working row beside it, which leaves the chat more rows for the conversation. The turn spinner in the working row shows its verb (from the desert vocabulary), elapsed time, ↓ token count, ~<N> tok/s output rate, and any retry or reconnect count, while the context compaction row shows compacting context, ↓ ~<tokens>, the progress bar and elapsed time. A new home meets the crab first, in its red; a saved pick is kept, and /critter or a click on the critter chooses another. The small critter sits at the left of the box, level with the middle of the working row however tall it grows. The view runs from the top of the screen down to the status row above the composer, and the rails beside it run the same height. The session’s name lives in the terminal’s title, on the Session Concourse and in /sessions.
  • CREW box: Keeps the session’s crewmates and their states until cleared with c. Opening a row shows that crewmate’s transcript in the chat; m targets the composer to it. When you view a crewmate, the bottom model chip shows that crewmate’s model, and returns to the session’s model when you switch back to the main chat. In /zen and the compact layouts, Enter on a crewmate row in the activity screen (Ctrl+T or the bottom work strip) or in /crewmates opens that crewmate’s view, swaps the compact identity band to the crewmate’s card, and adds a Mercury Lead row at the top of the activity screen’s crewmates list (Enter returns to the lead chat without stopping anything; m hands the main chat back).
  • Composer: Keeps its text across views, targets, popups and screens. A sent line leaves immediately and returns on refusal; the hints name its target. Pressing ↓ on the empty composer’s last line moves focus to the bottom work strip (sessions · monitors · crewmates) in every compact layout, /zen included, and ↑, Esc or typing a letter returns to the composer. A message you send while a foreground crewmate holds the turn moves that crewmate to the background and is read at the next tool call. When a streaming reply is cut mid-stream and retried, any withdrawn partial text is dropped and never drawn beneath the final reply. An unknown slash command (typed directly or inside a pasted text chip) shows one notice line and nothing else: it is never sent to the model later and never drawn twice, while // sends a line starting with a slash to the model as text. Running a ! <command> shell command in chat displays a ticking running · … timer and streams a live tail of the latest output lines (six lines at 120 columns, three at 80) while keeping carriage-return progress updates on a single line; clearing a ! shell line with Ctrl+U or by deleting a selection returns the composer to the normal prompt, and a failed ! command’s card shows the command’s own output alone. A block of pasted text longer than a couple of lines becomes a [Pasted text #N +L lines] chip whose words reach the model whole when the line is sent; the bytes are kept under the config home from the moment of the paste, so the chip survives a crash, a relaunch and a refused send. An image goes into the composer three ways: pasted from the clipboard with Ctrl+V on macOS and Linux or Alt+V on Windows, dragged onto the terminal as a file, or pasted as a path. Each attaches as an [Image #N] chip saved in the session’s image store, and the composer says what was attached and what it was shrunk to when the provider’s limits asked for it. After a pasted image, typed letters stay in order and the cursor follows them. A prompt that quotes command markup remains your own row, including a long pasted prompt.
  • RUNS: Opens the runs board through /runs from the side rail. /tasks opens the same board. Ctrl+T opens the ledger tree.
  • Vitals rail: The rail of live readings beside the chat keeps usage, workflow and health under one header. /console opens the Console, the side question with its own pinned model, and /trace opens the invocation trace; each opens its own view over the chat.
  • Zen mode: Enter /zen to hide both the left lanes rail and the right vitals rail so the chat takes the full width of the terminal. /zen flips it, /zen on and /zen off set it, and the setting persists as view.zen and shows on /config as Zen mode: rails hidden.
  • FILES box and /browse: The box on the left rail names the focused session’s folder. Enter on it, a click on it, or entering /browse in the composer (in every layout, /zen and compact windows included) opens the folder’s tree as a menu over the chat. → expands a folder and ← collapses it, / filters the rows by name, Enter on a file puts @ and its path at the composer’s caret and closes the menu, and Esc or a click outside the menu closes it. With a .md file selected, pressing r opens an in-popup Markdown reader wrapped to the popup width: ↑/↓ scroll a row and PageUp/PageDown scroll a page with the visible row range in the footer, ← or Esc returns to the same file in the list, Enter attaches the @-mention, image references show their alt text and path, large files display their first 256 KiB with a truncation notice, git-ignored Markdown files open normally, and reading a file here does not send it to the model or record it in the transcript. Inside a git repository the menu’s second line names the branch and the count of changed files, and a changed file carries its mark. The view.files setting set to false takes the box off the rail.
  • Panels: Every panel over the chat that Esc closes also closes on a click outside it: the model picker, the file tree, and the settings, config and usage panels. In /config, Esc or a click outside undoes only the settings changed while that popup was open, in reverse order, leaving untouched fields and concurrent edits alone. The click closes the panel alone. The config popup fits beside /health. A popup owns the keys it lists while it is open, and every popup and board scrolls the full selected element into view on open, on arrow keys, after a resize, and when a late row lands above the selection. Session popups stay inside the chat view, leaving the top bar, rail and composer visible.
  • Lists: Across popup lists and selectors, ↑/↓ and PageUp/PageDown share measured movement, Home and End reach the ends, independent top and bottom overflow markers show when items continue off-screen, footer key legends wrap to the popup width, the mouse wheel moves the list on top, and the chat beneath stays still under an open list.
  • Status row: When the session is idle with no active crewmates, the status row above the composer reads ready · <model> · <effort>, and while work is running it reads <model> · <effort> followed by what the session is doing: a wait on agents, a request wait, a confirmation notice, a warning, or the crewmate timer. At its right end the row names the folder and the branch the session works on; on a narrow row the state words shorten first, then the folder leaves, then the branch, and the model and its effort stay. While the chat’s advisor is on, the row carries a small chip, advisor · every 10 minutes (or advisor · off in settings when the master setting is off). When the session runs on another provider after a usage-cap handoff, one amber sentence above the composer says so for two minutes, with the way back through /model, and the strip’s model segment keeps a short amber mark while that provider serves. An /effort receipt shows on that row for eight seconds before the words return with the new effort. Its effort control follows the effort the session settled on. On terminals narrower than 100 columns or shorter than 26 rows (the compact layout), the line under the composer also shows the count of sample pages (/samples) created in this session. While no runner is up, the row says what the daemon knows: starting with its seconds, crashed and restarting with the count, or that there is no live runner and how to revive it.
  • Notices on a narrow window: A notice is cut to what fits, and the way back to the concourse keeps the row’s right end. The context.wayBack setting set to false gives the notice the whole row. On Linux and over SSH, a copy receipt keeps its whole sentence and adds advice only when there is room.
  • Notice rows: Monitor output always appears as a muted [Monitor]: row naming the watch, even when it contains command markup, and after the initial 200 ms burst ongoing output is delivered at most once every 30 seconds with the line count and last line instead of waking the model on every 1-second tick. Within a minute of a Mercury install, a live chat on an older build shows one unfolded notice between turns (A newer Mercury build is installed (<tree>). This chat still uses <tree>. /restart switches to it; watches and background shells will stop and be listed.), and /clear carries over the shown-build marker so the notice does not repeat. Task notices and the words a reply writes before a tool call keep their own rows. Two lines sent while a crewmate is returning keep their own rows and are read together. When a reply answers a message you sent while the session was mid-turn, it is marked above the reply with a faint line naming the message’s send clock (answering your HH:MM:SS message), in time order with the tool rows that ran between them left in place, and the headless text row carries in_reply_to. A held notice appears where its time puts it, a message queued across a restart moves into the transcript when it is delivered, and a scheduled wake arrives as its own muted [Saturn] row.

Tools available from the first request

On hosted models, the file tools (Read, Edit, Write, Glob, Grep and ChangeSet), Bash, Eval, ScheduleWakeup and ToolSearch load in full when their settings and dependencies allow them. Models that support deferred tools load the remaining descriptions through ToolSearch, including Crewmate, Skill, Test, LspRead, AstSearch, Debug and the refactor tools. Local models keep their core tools loaded in full, including Crewmate, Skill and, when the project has tests, Test. A deferred tool discovered during a conversation is available at once; a tool that loads in full joins at the next compaction or /clear. No tool is dropped to fit a size limit.

Read accepts lossless: true with offset + limit or ranges to return complete lines past 2,000 characters within the output budget, Write and Read with ranges (when the whole file fits within the size cap) return a whole-file (anchor: fa:…) anchor, and Edit, Write and ChangeSet refuse to replace or overwrite a line that was clipped in Read or omitted in Grep. Glob respects .gitignore and ignore files by default and counts the paths hidden by ignore rules in its closing line (· N paths under ignore rules not listed) instead of listing them first; naming an ignored folder as the search path searches inside it. Grep accepts literal: true (rg -F) to match exact text containing regex characters without escaping. Bash measures cwd and cd against the persistent shell’s current working directory so a cd back to the project root is a real move and the cwd parameter is preserved, strips ANSI colour codes from tool results before they reach the model while keeping their colours on the screen card, clamps a timeout above the tool’s ceiling and names the requested value, the cap and the run_in_background option, and when shell.filterOutput is true in settings collapses progress-bar redraws, drops package-manager install chatter and folds runs of identical lines while saving the raw output to a file named in the footer. When the model calls an unknown tool name, the refusal lists the session’s available tools so a resumed session recovers in one step; restarting or resuming a session onto a new build replays the recorded tool roster (unless a bound tool is no longer offered by the build and has no recorded definition) so the request prefix and signed thinking stay intact; and when an MCP server’s tools change through notifications/tools/list_changed or /mcp reconnect, an unreferenced deferred tool takes the live schema while a bound or referenced tool receives a tool_schema_delta attachment with its updated parameters without moving the bound prefix. The Browser tool launches Chrome with a persistent per-origin profile under <config-home>/browser-profiles/<origin>, moves, clicks and types at human pace, and states on back when a page came back from the browser’s cache (restored from the browser's cache; the server was not asked or served from the browser's cache; the server was not asked) or only changed its URL fragment. When Browser (op set to type) fills a credential-shaped field through secretRef (resolved from MERCURY_BROWSER_SECRET_<NAME>, <config-home>/browser-secrets.json in 0600 mode, or the macOS Keychain after you approve the secretRef and origin pairing), a secret read from browser-secrets.json on macOS moves into the macOS Keychain only after an exact read-back verification (keeping the file entry if the write or read-back fails), and a saved { origin, totp } entry mints a six-digit TOTP code bound to that exact origin and checked again on the active page before filling. Named services (Service) are keyed by the session’s project so a follow-up call finds its service whatever the shell’s working directory, and Service start accepts pty: true to run interactive programs inside a 120×40 pseudo-terminal (input modes write, submit and eof).

Use ChangeSet for a coordinated edit across files, AstSearch and AstEdit for code patterns, LspRead and the refactor tools for symbol questions and refactors, Test for test records, Git for repository state, and Debug for a running program’s state. Monitor delivers updates from a running command. Checkpoint and Rewind let the agent explore a detour and carry back a report; the /rewind command separately restores recorded turns and files. Eval runs code cells in a runtime that keeps its state, the bundled mercury-media extension generates local images and video on your computer (Local images and video), Video generates MP4 clips and optional 1-second PNG preview frames (when ffmpeg is on PATH) when a videoProvider is configured in settings (Video), JevEval asks a second opinion on a closed question, and ScheduleWakeup wakes the session once after a delay.

Open a session

Select New Session on the home screen and press Enter. The session opens in the chat and gains its board row without sending a message.

Move from the chat to another session

Enter /concourse, select a session row and press Enter. The selected session becomes the focused chat while every other session’s runner keeps working.

On the board, → opens a peek at the selected live row. Ctrl+X Ctrl+X stops the selected session; the row stays on the board marked stopped and shows the next step, the chord again archives it, and a third chord deletes it. Esc returns to the focused chat when one exists; when none does, it returns to the home screen, as the board legend reads.

When sessions exist, a new-session line sits at the top of the board and names the model and the effort the next session starts on. ↑ reaches it, Enter starts a session, and m on it opens the default model picker; m on a session row opens that session’s own picker.

Move a running command to the background

While a shell command runs and the hint row under the composer names the key, press Shift+B. The command goes to the runner as a background task, the turn goes on without waiting, and a notice says where the command went. The agent is told the command was moved and that its output arrives as a notification. With a draft in the composer the key types its letter. A refusal to move the command shows its sentence on the notice row. The view.backgroundKey setting set to false turns the key and its hints off, and Esc keeps its meaning either way. A background shell that ends with a non-zero code is reported as ended with its code.

Boot without the Session Concourse

Start Mercury with mercury --chat, select New Session and press Enter. The strip holds the home screen and the chat, and Shift+← returns from the chat to the home screen directly.

--concourse-off saves that choice for every later boot. --concourse-on or the Session concourse row in /config turns the board back on, and with both switches on one line the later one wins. /concourse remains available as a plain live view of the sessions.

Choose an appearance

Open /appearance, or the appearance row in /config, to choose True Black, Oasis dark or Black and white. The first-run setup lists the same choices and previews each one as you browse. True Black is the default.

Black and white adds no colour: it uses the terminal’s own text and background colours and leaves the background alone. Mercury also leaves the background alone when NO_COLOR or TERM=dumb is set, and diffs keep their + and − lines without colour.