Server configuration
Every zidane-server command, flag, environment variable and server.json key with its default, generated from source.
The site build generates the tables from the server's source: the help screen, the configuration loader and the Docker image. Each setting comes from the first source that has it:
- a flag of
zidane-server start, - a
ZIDANE_SERVER_*environment variable, - a key in
<data dir>/server.json, - the default.
The server validates everything at start and names the source of a bad value. It never reads the generic PORT variable.
zidane server: Invalid ZIDANE_SERVER_PORT: expected a port (an integer from 0 to 65535).Commands#
zidane server <command> and zidane-server <command> are the same program.
| Command | Description |
|---|---|
zidane server start [flags] | DescriptionServe this machine's chat host to remote windows. |
zidane server token create --name <name> | DescriptionCreate a device token (printed once). |
zidane server token list | DescriptionList tokens (never their secrets). |
zidane server token revoke <id|name> | DescriptionRevoke a token. Its live connections drop. |
zidane server token generate | DescriptionPrint a fresh token without storing it (for ZIDANE_SERVER_BOOTSTRAP_TOKEN). |
zidane server pair | DescriptionPrint a one-time code that logs a browser in to the web app. |
zidane server machine invite | DescriptionPrint a one-time join code that adds a machine (--name, --ttl). |
zidane server machines [--json] | DescriptionList the machines and whether they are online (over the unix socket). |
zidane server health [--timeout <ms>] | DescriptionProbe the running server over its unix socket (exit 0 when healthy). |
zidane server health --http | DescriptionProbe GET /healthz on the server's port instead (no socket needed). |
zidane server wait-idle [--timeout <ms>] | DescriptionWait until no run or background task is in flight (before a restart). |
zidane server backup --out <file|-> | DescriptionArchive the server's state as a tar.gz while it runs (- for stdout). |
zidane server setup | DescriptionInstall or change zidane-server on this machine (zidane server setup --help). |
zidane server doctor [--fix] | DescriptionCheck a server that setup installed. |
zidane server channels check | DescriptionCheck the channels config offline (exit 1 on errors). |
zidane server channels status | DescriptionList the running server's channel integrations. |
zidane server channels reload | DescriptionMake the running server re-read its channels config. |
zidane server start --no-channels | DescriptionNever start channels (as ZIDANE_NO_CHANNELS=1). |
zidane-server --version | DescriptionPrint the version (the standalone binary). |
Start flags#
| Flag | Description |
|---|---|
--host <addr> | DescriptionInterface to listen on (default 127.0.0.1). |
--port <n> | DescriptionPort (default 4280, 0 picks a free one). |
--tls-cert <file> | DescriptionPEM certificate: serve wss:// (with --tls-key). |
--tls-key <file> | DescriptionPEM private key. |
--behind-proxy | DescriptionA TLS-terminating proxy fronts the server (required off loopback without TLS). Every upgrade must then carry X-Forwarded-Proto: https. |
--trusted-proxies <l> | DescriptionWith --behind-proxy: the proxies' addresses / CIDRs (comma-separated). Upgrades from any other peer are refused. |
--name <name> | DescriptionHost name shown to clients (default: the machine's). |
--socket <path|off> | DescriptionUnix socket for local tools (default <data dir>/server.sock). |
--workspace-root <dir> | DescriptionWhere session folders may be. Repeatable, the first is the default (default <data dir>/workspaces, env: path-delimited list). |
--allow-as-machine | DescriptionLend this server as a machine to its clients' computers (local@<server>, docs/MACHINES.md): a client token then runs commands in the workspace roots through it, as it already can with a terminal. Default off. |
--no-remote-installs | DescriptionRefuse installs, updates and removals of skills, extensions and MCP servers from clients (allowRemoteInstalls, default on, audited). |
--no-clone | DescriptionRefuse clones into the workspace roots from clients (allowClone, default on: any client token may clone). |
--no-create-folders | DescriptionRefuse new folders in the workspace roots from clients (allowCreateFolders, default on: any client token may create one). |
--auto-update | DescriptionInstall new releases on its own (release binaries): runs pause at a step and continue after the restart. Default off. |
--web | DescriptionServe the web app at / (log in with a code from "zidane server pair"). Browsers on the server's own origin are admitted. Default off. |
--no-web | DescriptionDon't serve the web app (overrides ZIDANE_SERVER_WEB / server.json). |
--web-root <dir> | DescriptionThe web app to serve (a directory with an index.html, default the one bundled with the server, web-dist/). |
--mcp | DescriptionServe MCP at /mcp, so an MCP client (Claude Code, Cursor) drives this server's sessions with a token as the bearer. Default off. |
--no-mcp | DescriptionDon't serve MCP (overrides ZIDANE_SERVER_MCP / server.json). |
--verbose | DescriptionLog connections and requests to stderr. |
--exposure <mode> | Descriptionprivate (default) or public. Public refuses remote installs, machine lending, a bootstrap token, other browser origins next to the web app, and pairing codes that live longer than 10 minutes. |
--channels-port <n> | DescriptionAlso serve channel webhooks and /healthz alone on this port (same host and TLS, 0 picks a free one). Everything else there is a 404. |
--env-file <file> | DescriptionRead KEY=value lines into the environment before the config loads. Variables already set win. The file must be private (chmod 600). |
Token and health flags#
| Flag | Description |
|---|---|
--data-dir <dir> | DescriptionStorage root, as ZIDANE_STORAGE_DIR (server files live in <dir>/.zidane). Also ZIDANE_SERVER_DATA_DIR. |
--scope <scope> | DescriptionToken scope. A window: chat (sessions, runs and tool approvals) or admin (also the server's settings: everything, the default, also named "client"). Or machine: lends its execution with "zidane machine share" (docs/MACHINES.md). For pair: chat or admin (default chat). |
--expires <duration> | Description(token create) How long the token works: 12h, 30d, 90d, 1y (also m and w), or never (the default). An expired token is refused and its connections drop. |
--ttl <duration> | Description(pair, machine invite) How long the code works: 30s to 1h, as 90s, 10m or 1h (a bare number is minutes). Default 10m. |
--name <label> | DescriptionNames the browser's token "browser: <label>". (machine invite) Names the machine's token. Without it, the machine gives its own name. |
--json | DescriptionPrint JSON: { serverVersion, machines }. |
--socket <path> | DescriptionThe server's unix socket, when not the default (health, wait-idle, machines). |
--out <file|-> | DescriptionWhere the tar.gz goes (mode 0600, not inside a directory it archives). - writes it to stdout. |
--include-workspaces | DescriptionAlso archive the workspace roots (the projects). |
--http | DescriptionProbe http(s)://<host>:<port>/healthz (a wildcard host on loopback). |
Environment variables#
An Image value is what server/Dockerfile sets. The other variables keep their default in the image.
| Variable | Default | Description |
|---|---|---|
ZIDANE_SERVER_DATA_DIR | DefaultZidane's user dir | DescriptionStorage root, as ZIDANE_STORAGE_DIR (server files live in <dir>/.zidane). |
ZIDANE_SERVER_HOST | Default127.0.0.1 | DescriptionInterface to listen on. Off loopback it needs TLS or behindProxy. |
ZIDANE_SERVER_PORT | Default4280 | DescriptionPort to listen on; 0 picks a free one. |
ZIDANE_SERVER_TLS_CERT | DefaultNone | DescriptionPEM certificate: serve wss:// (with --tls-key). |
ZIDANE_SERVER_TLS_KEY | DefaultNone | DescriptionPEM private key. |
ZIDANE_SERVER_BEHIND_PROXY | Defaultfalse | DescriptionA TLS-terminating proxy fronts the server: every upgrade must then carry X-Forwarded-Proto: https. |
ZIDANE_SERVER_NAME | DefaultThe machine's hostname | DescriptionHost name reported to clients. Default: the machine's. |
ZIDANE_SERVER_HEARTBEAT_MS | Default20000 | DescriptionInterval of the server's WebSocket pings, in ms; a connection that misses two in a row is dropped. 0 disables. |
ZIDANE_SERVER_MAX_MESSAGE_BYTES | Default33554432 | DescriptionLargest incoming message in bytes: a bigger frame closes the connection (1009), a bigger reply is answered with a ResponseTooLarge error. |
ZIDANE_SERVER_RATE_LIMIT | Default50 | DescriptionRequests per second on one connection; 0 disables. |
ZIDANE_SERVER_RATE_BURST | Default200 | DescriptionBurst size of that limit: how many may arrive at once. |
ZIDANE_SERVER_ALLOWED_ORIGINS | DefaultNone | DescriptionBrowser origins allowed to connect; empty refuses every browser. |
ZIDANE_SERVER_SOCKET | Default<data dir>/server.sock | DescriptionUnix socket for local tools (default <data dir>/server.sock). |
ZIDANE_SERVER_TRUSTED_PROXIES | DefaultNone | DescriptionBehind a proxy: the only peers believed (IPs, CIDRs, or private); empty believes any peer. |
ZIDANE_SERVER_UPGRADE_RATE_LIMIT | Default5 | DescriptionUpgrades per second from one client address; 0 disables. |
ZIDANE_SERVER_UPGRADE_RATE_BURST | Default30 | DescriptionBurst size of that limit: how many may arrive at once. |
ZIDANE_SERVER_MAX_CONNECTIONS_PER_TOKEN | Default16 | DescriptionOpen connections one token may hold; past it, an upgrade gets a 429. |
ZIDANE_SERVER_MAX_CONNECTIONS_PER_ADDRESS | Default32 | DescriptionOpen authenticated connections per client address; past it, an upgrade gets a 429. |
ZIDANE_SERVER_WORKSPACE_ROOTS | Default<data dir>/workspaces | DescriptionWhere session folders may be (absolute; the first is the default for a session created without one). Default <data dir>/workspaces. |
ZIDANE_SERVER_DRAIN_TIMEOUT_MS | Default8000 | DescriptionBound on draining the host's runs at shutdown (SIGTERM). |
ZIDANE_SERVER_ALLOW_AS_MACHINE | Defaultfalse | DescriptionLend this server as a machine to its clients' local hosts (local@<server>, docs/MACHINES.md § Reverse direction). Default off. |
ZIDANE_SERVER_ALLOW_REMOTE_INSTALLS | Defaulttrue | DescriptionClients may install, update and remove skills, extensions and MCP servers in this server user's scope (audited). Default on. |
ZIDANE_SERVER_ALLOW_CLONE | Defaulttrue | DescriptionClients may clone repositories into the workspace roots (git.clone). Default on. |
ZIDANE_SERVER_ALLOW_CREATE_FOLDERS | Defaulttrue | DescriptionClients may create folders in the workspace roots (fs.mkdir). Default on. |
ZIDANE_SERVER_VERBOSE | Defaultfalse | DescriptionLog every connection, authentication, refusal and disconnect to stderr ([server] and [ipc-ws] lines). Default off. |
ZIDANE_SERVER_COMPRESS_LARGE_MESSAGES | Defaultfalse | DescriptionCompress big outgoing WebSocket messages (64 KiB and up, e.g. transcript pages) for clients that accept it (permessage-deflate). Saves bandwidth on slow links, costs event-loop time per big message. Default off. |
ZIDANE_SERVER_AUTO_UPDATE | Defaultfalse | DescriptionInstall new releases on its own, pausing and resuming runs (./auto-update). Release binaries only. |
ZIDANE_SERVER_AUTO_UPDATE_INTERVAL_MINUTES | Default30 | DescriptionHow often it checks for a release. |
ZIDANE_SERVER_WEB | Defaultfalse | DescriptionServe the web app at / (a pairing code logs a browser in: zidane server pair), and admit browsers on the server's own origin. Default off. |
ZIDANE_SERVER_WEB_ROOT | DefaultNone | DescriptionThe web app's directory (it must hold an index.html). Default: the app bundled with the server (web-dist/). Relative paths in server.json resolve against the data dir. |
ZIDANE_SERVER_MCP | Defaultfalse | DescriptionServe MCP at /mcp (Streamable HTTP, a token as the bearer): an MCP client (Claude Code, Cursor, another agent) drives this server's sessions with the sessions and interactions tools. Default off. |
ZIDANE_SERVER_EXPOSURE | Defaultprivate | Descriptionpublic: the server is reachable from the internet. Start then refuses remote installs, machine lending, a bootstrap token, and other browser origins next to the web app; pair caps a code's lifetime at 10 minutes. Default private. |
ZIDANE_SERVER_CHANNELS_PORT | DefaultNone | DescriptionA second listener on the same host that serves only channel webhooks and /healthz; 0 picks a free port. |
ZIDANE_SERVER_BOOTSTRAP_TOKEN | DefaultNone | DescriptionA token from token generate, stored at start as the client token "bootstrap" (a new value replaces it). Revoke "bootstrap" once device tokens exist. |
ZIDANE_SERVER_BOOTSTRAP_TOKEN_FILE | DefaultNone | DescriptionA file holding it (a mounted secret, which keeps it out of the environment). Not both. |
zidane-server start --no-channels, or ZIDANE_NO_CHANNELS=1, never starts channels. The channels check, status and reload commands are in channels.
Booleans are 1, true, yes, on or 0, false, no, off. Lists are comma-separated (workspace roots are separated like PATH). An empty variable counts as unset.
server.json#
<data dir>/server.json uses JSON types (numbers, booleans, arrays), not strings. An unknown key is a boot error. Relative paths resolve against the data dir.
| Key | Default | Description |
|---|---|---|
host | Default127.0.0.1 | DescriptionInterface to listen on. Off loopback it needs TLS or behindProxy. |
port | Default4280 | DescriptionPort to listen on; 0 picks a free one. |
tlsCert | DefaultNone | DescriptionPEM certificate: serve wss:// (with --tls-key). |
tlsKey | DefaultNone | DescriptionPEM private key. |
behindProxy | Defaultfalse | DescriptionA TLS-terminating proxy fronts the server: every upgrade must then carry X-Forwarded-Proto: https. |
name | DefaultThe machine's hostname | DescriptionHost name reported to clients. Default: the machine's. |
heartbeatMs | Default20000 | DescriptionInterval of the server's WebSocket pings, in ms; a connection that misses two in a row is dropped. 0 disables. |
maxMessageBytes | Default33554432 | DescriptionLargest incoming message in bytes: a bigger frame closes the connection (1009), a bigger reply is answered with a ResponseTooLarge error. |
rateLimit | DefaultperSecond: 50, burst: 200 | DescriptionRequests per connection: a token bucket of perSecond (0 disables) and burst. Over it, a RateLimited error. |
allowedOrigins | DefaultNone | DescriptionBrowser origins allowed to connect; empty refuses every browser. |
socket | Default<data dir>/server.sock | DescriptionUnix socket for local tools (default <data dir>/server.sock). |
trustedProxies | DefaultNone | DescriptionBehind a proxy: the only peers believed (IPs, CIDRs, or private); empty believes any peer. |
upgradeRateLimit | DefaultperSecond: 5, burst: 30 | DescriptionUpgrades per client address. |
maxConnectionsPerToken | Default16 | DescriptionOpen connections one token may hold; past it, an upgrade gets a 429. |
maxConnectionsPerAddress | Default32 | DescriptionOpen authenticated connections per client address; past it, an upgrade gets a 429. |
workspaceRoots | Default<data dir>/workspaces | DescriptionWhere session folders may be (absolute; the first is the default for a session created without one). Default <data dir>/workspaces. |
drainTimeoutMs | Default8000 | DescriptionBound on draining the host's runs at shutdown (SIGTERM). |
allowAsMachine | Defaultfalse | DescriptionLend this server as a machine to its clients' local hosts (local@<server>, docs/MACHINES.md § Reverse direction). Default off. |
allowRemoteInstalls | Defaulttrue | DescriptionClients may install, update and remove skills, extensions and MCP servers in this server user's scope (audited). Default on. |
allowClone | Defaulttrue | DescriptionClients may clone repositories into the workspace roots (git.clone). Default on. |
allowCreateFolders | Defaulttrue | DescriptionClients may create folders in the workspace roots (fs.mkdir). Default on. |
verbose | Defaultfalse | DescriptionLog every connection, authentication, refusal and disconnect to stderr ([server] and [ipc-ws] lines). Default off. |
compressLargeMessages | Defaultfalse | DescriptionCompress big outgoing WebSocket messages (64 KiB and up, e.g. transcript pages) for clients that accept it (permessage-deflate). Saves bandwidth on slow links, costs event-loop time per big message. Default off. |
autoUpdate | Defaultfalse | DescriptionInstall new releases on its own, pausing and resuming runs (./auto-update). Release binaries only. |
autoUpdateIntervalMinutes | Default30 | DescriptionHow often it checks for a release. |
web | Defaultfalse | DescriptionServe the web app at / (a pairing code logs a browser in: zidane server pair), and admit browsers on the server's own origin. Default off. |
webRoot | DefaultNone | DescriptionThe web app's directory (it must hold an index.html). Default: the app bundled with the server (web-dist/). Relative paths in server.json resolve against the data dir. |
mcp | Defaultfalse | DescriptionServe MCP at /mcp (Streamable HTTP, a token as the bearer): an MCP client (Claude Code, Cursor, another agent) drives this server's sessions with the sessions and interactions tools. Default off. |
exposure | Defaultprivate | Descriptionpublic: the server is reachable from the internet. Start then refuses remote installs, machine lending, a bootstrap token, and other browser origins next to the web app; pair caps a code's lifetime at 10 minutes. Default private. |
channelsPort | DefaultNone | DescriptionA second listener on the same host that serves only channel webhooks and /healthz; 0 picks a free port. |
{
"host": "0.0.0.0",
"behindProxy": true,
"trustedProxies": ["10.0.1.0/24"],
"name": "build-box",
"workspaceRoots": ["/srv/code", "workspaces"],
"allowedOrigins": ["https://agents.example.com"],
"rateLimit": { "perSecond": 100, "burst": 400 }
}Exposure, webhooks and the env file#
exposure says whether the internet can reach the port of the clients. It is private (the default) or public. With public, the server refuses remote installs, lending itself as a machine (running another host's commands) and a bootstrap token. It also refuses other browser origins next to the web app, and pairing or join codes that live longer than 10 minutes (exposure).
channelsPort (--channels-port, ZIDANE_SERVER_CHANNELS_PORT) opens a second port. That port serves channel webhooks and /healthz only, and answers 404 to the rest. Make that port public. Keep the port of the clients private.
--env-file <file> on zidane-server start reads an env file, a file of KEY=value lines, before the configuration loads. A variable that is already set wins. The file must be mode 600. zidane machine share --env-file reads the ZIDANE_MACHINE_* variables of a machine the same way (servers and machines).
Data dir#
--data-dir <dir> (or ZIDANE_SERVER_DATA_DIR) sets the storage root, like ZIDANE_STORAGE_DIR for the rest of zidane (folders). Everything, sessions included, lands in <dir>/.zidane. Without it, the server uses zidane's usual folders for its user. The image sets /data (file list).
Provider keys#
The server's agents read provider keys from its environment, under the same names as on a laptop (the list). A key saved from a window into the server's credentials.json wins over the variable. The variables stay in the agents' environment, so their tools can read them.