The OpenClaw Control UI
What port 18789 serves, and what it asks you for
You installed OpenClaw, started the Gateway, and read somewhere that there is a dashboard in the browser. Opening it is one URL, but the page that loads asks for a Gateway secret nobody handed you, and the LAN address printed in the terminal may not answer at all from your laptop. Here is what the Control UI actually is, what that single field accepts, and what the roster behind it does.
What the Gateway serves on port 18789
- The Control UI is a small Vite and Lit single-page app served by the Gateway itself, at http://your-host:18789/ by default, with an optional prefix when you set gateway.controlUi.basePath, for example /openclaw. It speaks directly to the Gateway WebSocket on the same port, so there is no second service to start and no separate API host to point it at.
- On the Gateway host, open http://127.0.0.1:18789/ or http://localhost:18789/. If the page fails to load at all, start the Gateway first with openclaw gateway.
- gateway.controlUi.enabled hot-applies. Switch it off and the Gateway stops serving dashboard pages and assets while bots and existing Gateway connections keep running; switch it back on and serving resumes, with missing assets prepared in the background. Changing the serving base path or the asset root still requires a Gateway restart.
- If the LAN URL works on the host but not from another machine, suspect the host before the network. On native Windows LAN binds, Windows Firewall or organisation-managed Group Policy can block the advertised LAN URL even when 127.0.0.1 works on the Gateway host, and openclaw gateway status --deep, run on that Windows host, reports likely-blocked ports, profile mismatches, and local firewall rules that policy may ignore.
A direct loopback connection does not bypass token or password auth.
Why the page on your own machine still wants a secret
Authentication happens during the WebSocket handshake, not in a login form the app could quietly skip for local visitors. The Gateway accepts the configured shared secret in either connect.params.auth.token or connect.params.auth.password, with gateway.auth.mode selecting which configured value applies; it also accepts Tailscale Serve identity headers when gateway.auth.allowTailscale is true, and trusted-proxy identity headers when gateway.auth.mode is trusted-proxy. Gateway auth runs before device pairing, so a browser proves itself with the shared secret before it can even file a pairing request. A direct loopback browser needs no shared secret only when gateway.auth.mode is explicitly set to none, which disables gateway auth altogether and is not the recommended Control UI setup.
One field, two kinds of value
- The login screen and Settings, then Gateway, use the same single Gateway secret field: paste the token or type the password. The browser does not pick the mode; gateway.auth.mode already picked it on the host.
- After a successful connection the UI keeps the secret in session storage, scoped to the current browser tab and Gateway origin, and only when the Gateway reports token auth. Passwords stay in memory and are never persisted, and once the device is paired the browser can use its stored per-device token on later connections.
- A setup code copied from Devices, Pair device, Copy setup code is a different credential. Paste one into Gateway secret and the UI shows an inline hint before you connect: that code belongs in Settings, then Gateway, in the OpenClaw mobile app, while the Control UI wants the shared token from openclaw gateway auth-token --show, run in an interactive terminal on the Gateway host.
One state looks like a bug and is not. Local onboarding generates a Gateway secret in token mode by default, with no token or password picker, and preserves an existing password mode; explicit password setup is --gateway-auth password or --gateway-password with the value you choose, and Tailscale Funnel requires password mode. But if the Gateway starts in token mode with no configured token, it generates an ephemeral runtime token for that process instead. That token is not written to config, so it cannot be recovered, and a loopback browser without it is rejected: the field in front of you is asking for a value that exists nowhere you can read it. The way out is to run openclaw doctor --generate-gateway-token, restart the Gateway, then run openclaw gateway auth-token --show in an interactive terminal and paste the output into Gateway secret; the OpenClaw doctor covers what else that repair tool may touch, and the Gateway explained covers the process that owns the port in the first place.
The agents roster and team mode
Open Agents in the sidebar, choose All agents in the agent switcher, or visit /agents, and you get a roster instead of a chat: one card per configured agent showing its identity, model, current work status, last activity and a preview from its main chat, with working agents first and the most recently active behind them. Open chat jumps into that agent's main session, Manage agents opens /settings/agents, and New agent opens the custodian chat, which recommends a chief of staff, a researcher, a writer, a reviewer, or a small team with all four, using the same role templates as the CLI and waiting for operator approval before anything is created. Choosing Show all agents turns on team mode: sessions regroup under collapsible agent headers in configured roster order, the top row becomes a workspace header with the configured Gateway display name, and the shared page scope defaults to All agents, so Automations, Dashboards, Sessions, Tasks and Usage show mixed-agent rows with the agent identity attached. Team mode is a browser preference, off by default and remembered per gateway in that browser, so the same Gateway reached from another profile or over remote access to OpenClaw starts in single-agent mode until you turn it on there. How several isolated agents end up inside one Gateway process is its own subject, covered in several agents in one Gateway.
On Diali
Diali hosts OpenClaw, so the port, the token and the certificate stop being your problem: every customer runs their own assistant on its own instance, and we serve the Control UI over HTTPS on a real address instead of a plaintext LAN URL. The runtime configuration is generated from your Diali dashboard and written fresh at every release, so what runs always matches what you selected, and agent state lives on a persistent volume, with daily snapshots and one-click restore available through the Backups add-on (included on Max). Hosted OpenClaw on Diali describes what the hosted assistant includes, and Diali pricing lists the plans.
- The dashboard is the Gateway itself, on one port.
- A loopback browser still needs the configured secret.
- An ephemeral runtime token can never be read back.
Stop reading about it, build one
Set up an agent, pick a channel, and have it working inside the app you already keep open.
