/web opens ChatCLI in your browser, next to the terminal, on the same session. What you type in the browser continues in the terminal, in MCP, in ACP and in your channels, and the other way round, because the browser drives the very same engine and the same saved sessions the other surfaces drive. chatcli web serves it without a terminal.
It is local by construction: the server binds the loopback interface on a free port, every run mints its own token, the token travels in a header the page reads from the address once, and nothing is sent anywhere but your own machine.
Opening it
/web works mid-run, like /dash. A terminal that is not bound to a saved session gets bound to a fresh one first (web-<date>), so the conversation has a name both surfaces can follow; a bound terminal shares its session as is. Closing the terminal stops the web UI: the address carried a token only that process handed out.
chatcli web on its own does the same: without --session it binds the browser to a fresh web-<date> session, created on the first completed turn, so each standalone run keeps its own conversation instead of overwriting the rolling mcp-web mirror. Nothing is saved āat the endā: every completed turn is written through as it finishes, so Ctrl+C or closing the tab loses at most a turn that was still streaming. A terminal bound to a named session, including the web-<date> one /web creates, is flushed once more on exit and is not duplicated as an autosave- file.
The browser only opens from an interactive terminal.
chatcli web --no-browser, or a pipe, prints the address instead.Continuity across surfaces
The web UI is not a second engine. It runs on the shared RPC backend that the MCP server, the ACP server and the chat gateway run on, and it keeps a session the way they do:- the browserās live history is bound to a saved session and written through after every turn;
- before each turn the bound session is re-read when another surface changed it (the terminal, an IDE over ACP, a WhatsApp or Telegram conversation through the gateway), so a reply given elsewhere is in the transcript before you continue;
- the Conversation Hub thread of the principal is resumed, exactly as
chatcli mcp-serverdoes.
/session delete the terminal runs.
What you see
Modes and permissions
Chat turns stream token by token through the providerās streaming path. Coder and agent turns stream the loopās structured events: thoughts, messages, every tool call as it starts and ends, and the plan. When a loop reaches a policy-gated action (anask rule, a dangerous command), the page shows the same permission dialog the IDE gets over ACP: allow once, allow always, deny, deny always. No answer within the timeout (CHATCLI_MCP_PERMISSION_TIMEOUT, default 10 minutes) denies the action once, so a walked-away browser never leaves a loop hanging.
One turn at a time, as in the terminal: while a turn runs, sending another is refused with a clear notice instead of queueing silently. Closing the tab cancels the run.
Provider and model
The selectors show what the engine can reach: providers with credentials, and per provider the models the catalog knows plus what the providerās API lists live. Picking one sets the route for the turns that follow, without touching the terminalās own selection. Skills that pin a model still win for the turns they fire on.Media
Features that are not configured are hidden, not broken.
The API behind the page
The page talks to a small JSON API on the same origin. It is documented here because a script can drive it as well as the page does, with the token from the address:
Every call carries
X-Web-Token: <token>; the token is never accepted from the query, the Host must match the bound address exactly (a DNS-rebinding guard), and the page ships with a strict Content-Security-Policy that allows no external resource.
Privacy and safety
- Loopback only. A request to bind another interface is refused.
- One token per run, 128 bits, in memory. Stop the process and the address is dead.
- The web UI runs the engine unattended like MCP and ACP: dangerous commands follow
CHATCLI_MCP_DANGER(blockturns them into in-band refusals) and the permission dialog covers theaskrules./policyin the terminal changes the rules for both. - The page is one embedded file. No CDN, no fonts, no analytics, works offline.
Configuration
/config web shows whether the web UI runs, its address, the child process, the bound session and the log file (~/.chatcli/web.log).
Relationship to the other surfaces
Live Dashboard
What every process is doing, as a live graph. Open it from the web UIās terminal with
/dash.Session Continuity
How a saved session follows you across the terminal, IDEs and channels.