AIOps Bot Platform
Console

Deployment

Download the binary, spawn it as a child process, pick port or socket, and configure the browser.

You download the runtime binary from the dashboard and run it yourself — on a laptop, a server, or in a container. Your application spawns it as a child process and communicates with it exclusively over HTTP and WebSocket.

Get the binary

Download from the agent page in the dashboard. Files come from the latest GitHub Release (bot-agent-*-v{version}.zip):

PlatformFile
macOS (universal)bot-agent-macos-universal-v{version}.zip
Linux (x64)bot-agent-linux-x64-v{version}.zip
Windows (x64)bot-agent-windows-x64-v{version}.zip
bot-agent-{platform}-v{version}/
├── bot-agent              # bot-agent-linux-x64 / bot-agent.exe on other OS
├── VERSION
└── lib/rebrowser-playwright/...   # required for browser tool only

macOS Gatekeeper

Unsigned browser downloads are quarantined. If macOS says the app is “damaged”, clear quarantine then ad-hoc re-sign (once per extract):

xattr -cr bot-agent-macos-universal-v0.2.0
codesign --force --sign - bot-agent-macos-universal-v0.2.0/bot-agent

First-run walkthrough (auth + first message): Getting started. How your app talks to the process: Agent API.

Spawn the runtime

DB_TYPE must be set (sqlite or postgres + DATABASE_URL). Prefer --api-key / BOT_AGENT_API_KEY so the local HTTP API is not open.

Desktop app (Node / Electron)

import { spawn } from "node:child_process";
import path from "node:path";

const homeDir = path.join(app.getPath("userData"), "bot-agent");

const proc = spawn(
  "./bot-agent",
  [
    "--home",
    homeDir,
    "--port",
    "4484",
    "--api-key",
    process.env.BOT_AGENT_API_KEY,
    "--cloud-url",
    "https://169.63.180.31.sslip.io",
  ],
  {
    stdio: ["ignore", "pipe", "pipe"],
    env: { ...process.env, DB_TYPE: "sqlite" },
  },
);

proc.stdout.on("data", (d) => console.log("[agent]", d.toString()));
proc.on("exit", (code) => console.log(`agent exited with code ${code}`));

Web / server backend

spawn(
  "./bot-agent",
  [
    "--home",
    "/data/my-agent",
    "--port",
    "4484",
    "--api-key",
    process.env.BOT_AGENT_API_KEY,
    "--cloud-url",
    "https://169.63.180.31.sslip.io",
    "--chrome-url",
    "ws://chrome:9222", // remote Chrome for server environments
  ],
  { env: { ...process.env, DB_TYPE: "sqlite" } },
);

Don't pipe user-facing strings to the process stdin — stdin is ignored. Use stdio: ["ignore", ...].

Port vs. unix socket

OptionWhen to use
--portDefault. Easiest for local dev, browser fetch/WebSocket, and cross-language clients.
--socketTighter desktop integrations — no open TCP port, filesystem-scoped permissions, IPC without TCP.

Use --port when the UI connects directly from a browser; browsers can't open WebSocket over a unix socket.

CLI parameters

ParameterEnv varDescriptionDefault
--home (required)BOT_AGENT_HOMEPath to the agent home directory
DB_TYPE (required)sqlite or postgres
DATABASE_URLPostgres URL when DB_TYPE=postgres
--portPORTHTTP server port. Ignored when --socket is set.4484
--socketBOT_AGENT_SOCKETUnix socket path. Binds here instead of a TCP port when set.disabled
--cloud-urlBOT_AGENT_CLOUD_BASE_URLControl plane URLhttp://127.0.0.1:3000
--api-keyBOT_AGENT_API_KEYAPI key for local HTTP authdisabled if unset
--chrome-urlCHROME_CDP_URLChrome CDP WebSocket URLlaunches local Chrome

CLI args take precedence over env vars. .env and .env.local in the working directory are auto-loaded on startup.

Browser setup (optional)

Two modes:

Local Chrome (desktop) — default. The runtime launches a persistent Chrome instance on the user's machine (point to a binary with CHROME_EXECUTABLE_PATH). Each conversation gets an isolated browser profile, so cookies/localStorage persist per conversation but don't bleed across them.

Remote Chrome via CDP (server) — connect to an external Chrome instance. Set --chrome-url / CHROME_CDP_URL:

./bot-agent --chrome-url ws://localhost:9222

Works with Docker Chrome containers (selenium/standalone-chrome, browserless/chrome), managed browser services, or a Chrome fleet behind a load balancer.

Lifecycle

Startup: poll GET /health until 200 { "status": "ok" } before sending other requests. The runtime boots its SQLite DB, cron scheduler, and HTTP listener during startup.

Graceful shutdown: send SIGTERM (or SIGINT). The runtime stops accepting new connections, then waits up to 5 minutes for active conversations to drain so in-flight runs complete cleanly, then exits.

proc.kill("SIGTERM");

Security considerations

  • Always set --api-key in production to prevent unauthorized access to the local HTTP API. The key is only for the local server — it's never sent to the control plane.
  • Cloud auth uses JWT tokens with refresh rotation; tokens live in cloud.json (treat as a credential — don't commit it).
  • The runtime has full shell access via the bash tool — only run it in trusted environments.
  • Browser sessions are isolated per conversation.

See Security for the full model.