Web (Gateway)
The Gateway serves a small browser Control UI (Vite + Lit) from the same port as the Gateway WebSocket:- default:
http://<host>:18789/ - optional prefix: set
gateway.controlUi.basePath(e.g./clawdbot)
Webhooks
Whenhooks.enabled=true, the Gateway also exposes a small webhook endpoint on the same HTTP server.
See Gateway configuration → hooks for auth + payloads.
Config (default-on)
The Control UI is enabled by default when assets are present (dist/control-ui).
You can control it via config:
Tailscale access
Integrated Serve (recommended)
Keep the Gateway on loopback and let Tailscale Serve proxy it:https://<magicdns>/(or your configuredgateway.controlUi.basePath)
Tailnet bind + token
http://<tailscale-ip>:18789/(or your configuredgateway.controlUi.basePath)
Public internet (Funnel)
Security notes
- Binding the Gateway to a non-loopback address requires auth (
gateway.authorCLAWDBOT_GATEWAY_TOKEN). - The wizard generates a gateway token by default (even on loopback).
- The UI sends
connect.params.auth.tokenorconnect.params.auth.password. - With Serve, Tailscale identity headers can satisfy auth when
gateway.auth.allowTailscaleistrue(no token/password required). Setgateway.auth.allowTailscale: falseto require explicit credentials. See Tailscale and Security. gateway.tailscale.mode: "funnel"requiresgateway.auth.mode: "password"(shared password).
Building the UI
The Gateway serves static files fromdist/control-ui. Build them with: