Skip to main content
/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-server does.
The sidebar lists every saved session with its title. Attach one to continue it, fork it, or start a fresh one. Deleting is the same /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 (an ask 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 (block turns them into in-band refusals) and the permission dialog covers the ask rules. /policy in 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.