Skip to content

Managing Your Gateway with the Control UI

Managing a backend service often feels like flying blind. You spend time setting up the core logic, but then you realize you need a way to actually see what is happening or trigger actions without digging through CLI logs every time. It is frustrating to have a powerful tool but no easy way to interact with it from your browser.

I find that having a dedicated interface makes a huge difference. The Gateway includes a built-in browser Control UI (built with Vite and Lit) that runs on the same port as your WebSocket. It gives you a direct way to manage your setup without extra complexity.

Before you get the interface running, make sure you have these pieces ready:

  1. Static assets located in dist/control-ui.
  2. The pnpm package manager to build the UI.
  3. The openclaw binary.
  4. Tailscale (if you want remote access).

You can get the Control UI running in about five minutes. The UI is enabled by default as long as the build assets exist.

  1. Build the UI assets: Run this command to install dependencies and build the static files.

    Terminal window
    pnpm ui:build
  2. Verify your config: By default, the UI is enabled. You can customize the path if you want.

    {
    gateway: {
    controlUi: { enabled: true, basePath: "/openclaw" },
    },
    }
  3. Start the Gateway: Use the CLI to bring the service up.

    Terminal window
    openclaw gateway
  4. Access the Dashboard: Open your browser to http://<host>:18789/ or your custom basePath.

If you want to access your UI outside of your local machine, I recommend using Tailscale. It handles the encryption and identity for you.

Keep your Gateway on loopback and let Tailscale Serve handle the proxying. This is the cleanest way to manage access.

{
gateway: {
bind: "loopback",
tailscale: { mode: "serve" },
},
}

You can then access it via https://<magicdns>/.

If you need the UI to be available on the public internet, use the Funnel mode. Note that this requires a password.

{
gateway: {
bind: "loopback",
tailscale: { mode: "funnel" },
auth: { mode: "password" },
}
}

Security is active by default. Here are two things to remember:

  • Non-loopback binds always require a shared token or password.
  • The UI uses anti-clickjacking headers and restricts WebSocket connections to the same-origin unless you specify gateway.controlUi.allowedOrigins.

If you need to trigger actions from external services, you can enable webhooks. When hooks.enabled=true is set in your config, the Gateway exposes a webhook endpoint on the same HTTP server.

If things aren’t working, check these common issues:

  • UI not loading: Ensure you have run pnpm ui:build. The Gateway cannot serve the UI if the dist/control-ui folder is missing.
  • Connection refused on Tailnet: If you are binding to tailnet instead of using serve, remember that a token is strictly required for non-loopback binds. Check your gateway.auth settings.

If you have questions about specific configuration parameters, check out the AI Setup Assistant.

OpenClaw

OpenClaw Expert

Still stuck?

If this page didn't answer your case, ask OpenClaw Expert for step-by-step guidance.