Dashboard
Use the local web UI to inspect and manage agents, models, channels, and runs.
The dashboard is the local web UI started by pepe serve. Use it to chat with agents, inspect traces, manage model connections, configure channels, review scheduled work, and generate API tokens without editing JSON by hand.
pepe serve # API, dashboard and gateways, all in one process
# then open http://localhost:4000
From a source checkout, build the assets once with mix assets.build before running mix pepe serve.
Sessions and chat
The dashboard opens on a live list of sessions on the left and a streaming chat panel on the right. Pick a session to read its history and talk to its agent, and the reply streams in token by token. New chat starts a fresh session, and each session shows its agent, its model, and its turn count; a session currently running a turn gets a small live indicator, with a Stop button right there in the list to interrupt one that’s stuck without opening it first.
Sessions live inside the running process, so run everything from the one pepe serve process. The dashboard then sees every session, including the ones that arrived over Telegram.
Risky tools are authorized inline here too. The run pauses and shows an allow/deny prompt, which is the web version of the buttons a Telegram user gets, unless the agent has already pre-approved that tool. The omnipotent owner agent never prompts. See Security and sandbox for how the gate decides.
What the sidebar holds
The left sidebar mirrors the CLI, so almost everything you can do with the pepe command you can also do here:
- Chat: talk to a session.
- Projects: create, edit and delete tenant scopes and their billing markup. See Projects.
- Agents: create, edit and delete agents, with their persona, model, tools, routes, admin scope, and which one is the default.
- Models: add, remove and edit model connections, set a per-model price, and pick the default.
- Usage and billing: token usage and cost by cycle, per project. See Usage and billing.
- Learning: the TimeLearn timeline. See Learning.
- Scheduled: create, run and manage scheduled tasks. See Scheduled tasks.
- Watches: one-shot “notify me when X”. See Watches.
- Channels: add, remove and edit Telegram bots, applied live. See Telegram.
- MCP: external tool servers. See MCP servers.
- Config file: edit
~/.pepe/config.jsoninline, validated on save.
Keeping it running
pepe serve runs in the foreground: closing the terminal or logging out stops it, and the dashboard with it. For a real deployment, install it as a persistent background service instead: launchd on macOS, systemd --user on Linux. It survives logout/reboot and restarts itself if it crashes.
pepe serve install [--port 4000]
pepe serve status
pepe serve uninstall
Only works from the installed pepe binary, not mix pepe serve install. If your model connections reference ${ENV_VAR} secrets, install lists them, because the service starts with a minimal environment and they need to be added to the generated unit/plist by hand.
Dashboard access
The dashboard is open on localhost by default, which is convenient for local development. The moment you expose it beyond your machine, put it behind a password:
pepe dashboard password '${PEPE_DASHBOARD_PASSWORD}'
You can pass a literal password or a ${ENV_VAR} reference so the secret stays out of the file. A literal password is hashed before it’s written to the config, so it’s never readable from the file (or a backup of it) once set. A ${ENV_VAR} reference has nothing to hash, since the real secret already lives outside the file. Once a password is set, the dashboard requires signing in at /login. Clear it with pepe dashboard password --clear.
Run pepe dashboard password with no value and it prompts instead, with the input hidden as you type, useful so the password never lands in your shell history or a ps listing:
pepe dashboard password
The password is read from dashboard.password in the config (interpolated), with a fallback to the PEPE_DASHBOARD_PASSWORD environment variable. Two related settings harden a dashboard served behind a domain:
pepe dashboard hosts app.example.com,dash.example.comsets the extraHostheader values the dashboard accepts. This doubles as the anti DNS-rebinding allowlist.pepe dashboard trusted-proxies 127.0.0.1,10.0.0.0/8lists the reverse proxies whoseX-Forwarded-Forheader may be trusted. Empty by default, meaning no forwarding header is trusted.
Reachable from beyond your machine with no password set, the dashboard blocks every remote client until you set one: only the machine itself can open it, and a VM, a proxy or your office network count as outside (it fails closed rather than open).
Reaching it remotely
To reach the dashboard or API from outside your machine without opening a port or setting up a reverse proxy, pepe serve can open a Cloudflare tunnel (needs cloudflared installed):
pepe serve --tunnel
This is a quick tunnel: it prints a random https://<something>.trycloudflare.com URL that lasts only while the process runs and changes every time. No Cloudflare account needed.
For a stable URL you choose on your own domain, use a named tunnel. Two ways:
# Headless (best on a server): create the tunnel and its public hostname in the
# Cloudflare Zero Trust dashboard, point its service at http://localhost:4000,
# copy the connector token, then:
pepe serve --tunnel --token '${CLOUDFLARE_TUNNEL_TOKEN}' --hostname pepe.example.com
# Or via a one-time browser login (stores a cert.pem), no token:
cloudflared tunnel login
pepe serve --tunnel --hostname pepe.example.com
With --token, the hostname and its service mapping live in the Cloudflare dashboard; there --hostname is optional, used only to print the URL at startup. The token is a secret, so pass it as a ${ENV_VAR} reference. A tunneled request is always treated as public, so set a dashboard password before relying on any of these.