Subshell Docs
Server

Overview

The server is the control plane: the API, the database, and the UI it serves, all on one port.

In Subshell, server names exactly one thing, the control plane: the API, its SQLite database, and the web UI it serves, all running as one process on one port. It does not mean "a machine that runs agents." That word is node: the subshell daemon on any machine that hosts subshell panes. Your control-plane host usually runs agents too, but then it is doing both jobs, and the docs keep the roles apart. Its row in the Nodes list is named by an admin and defaults to "Server"; underneath, it is the local node, launched through the same tmux machinery as any other.

One process, one port

A single subshell-server process answers everything on one port (default 3080):

  • the REST API under /api, and the WebSocket used to attach to live panes;
  • the web UI: the SPA is embedded in the published binary, so the host needs no separate frontend install;
  • /docs, the OpenAPI page generated from the routes;
  • the node binaries and install script that enrolled machines download.

The published form is one self-contained binary per platform (linux-x64, linux-arm64, darwin-arm64); it needs no Bun, no checkout, and no runtime download to boot. What a running instance keeps on disk lives in two places: the config home at ~/.config/subshell-server (the config.env file and the generated auth secret), and the data directory: database, pane logs, channel keypairs, node signing keys, downloaded node binaries, installed plugins, database backups, and the server's own log. subshell-server status prints every one of those paths, and Files & Paths maps them in full.

Who decides what

You manage the control plane from three surfaces, and each owns a different kind of decision:

surfaceowns
The dashboard (Settings pages in the web UI the server serves)Everything about a running instance: users and roles, registration, plugins, nodes, agent CLIs, API keys, and Settings → Service, Networking, Logs and Updates: the process, the addresses, both log tails, and versions.
The subshell-server CLI (on the control-plane host)Everything that must work when the server is not running: init, configure, service, status, update, backup.
config.env (the file both of the above write through)Keys no tool owns, and the escape hatch when a validator refuses something you genuinely mean.

The line between the first two follows one rule: if the act leaves the server unreachable, it cannot be driven from a page the server serves. So over HTTP an admin can change the address settings, restart the process (only when the service manager reports this very pid; a hand-run server refuses), arm or disarm start-at-login, read logs, and trigger an update. stop, start, service install, service uninstall and the reset have no route by design: each one takes down the page you would click it from, so they stay CLI verbs. Reset, which is deliberately off the network entirely, lives in the Subshell Server desktop assistant.

The Subshell Server desktop app adds no management surface of its own. It wraps the same CLI, the page that can act when no server is running (first run, recovery, update, reset), while everything about a live instance stayed in the dashboard where a browser on the LAN and a headless install can both reach it.

This section, one page at a time

See also

Edit on GitHub

Last updated on

On this page