Agents & API
CLI
Manage monitors, wrap cron jobs with heartbeats, report incidents and mark deploys from a terminal, CI job or agent. Every command takes --json.
Install
npm install -g upbutler # Node 18+
upbutler --helpThe CLI has no runtime dependencies. It can also be compiled to a single binary with bun build --compile.
Log in
upbutler login --key ub_live_... # verifies the key and saves it
echo "$KEY" | upbutler login --key - # read the key from stdin
upbutler whoami
upbutler logoutThe key is saved to ~/.config/upbutler/config.json (or $XDG_CONFIG_HOME/upbutler/config.json) with mode 0600. Flags win over environment variables, which win over the saved login:
| Flag | Environment | Meaning |
|---|---|---|
--api-key | UPBUTLER_API_KEY | API key |
--base-url | UPBUTLER_BASE_URL | API origin, default https://upbutler.com |
wrap --heartbeat | UPBUTLER_HEARTBEAT | Heartbeat URL, token or monitor id for wrap |
Monitors
upbutler monitors ls
upbutler monitors add https://api.example.com/health --name "Search API" --page acme --group APIs
upbutler monitors add db.internal:5432 --name Postgres
upbutler monitors add --name "Nightly backup" --period 86400 --grace 1800 # prints the ping URL
upbutler monitors get mon_...
upbutler monitors check mon_... # runs it now, exits 1 if down
upbutler monitors rm mon_...The target decides the kind: an https:// URL is an HTTP check, host:port is TCP, and --period without a target creates a heartbeat. --page also publishes the monitor on a status page, creating the page if needed. Run upbutler monitors add --help for all options.
Status pages
$ upbutler status upbutler
UpButler: All systems operational
COMPONENT STATUS UPTIME
Platform / Website & dashboard operational 100%
Platform / REST API operational 100%
Platform / MCP server operational 100%upbutler status <slug> shows any public status page and needs no API key.
Incidents
upbutler incidents ls --open
upbutler incidents report "Elevated API errors" -m "Investigating 5xx on search" \
--impact minor --component cmp_123=partial_outage
upbutler incidents update inc_... -m "Fix deployed, monitoring" --status monitoring
upbutler incidents resolve inc_... -m "Error rates are back to normal"Heartbeats
upbutler heartbeat https://upbutler.com/hb/hb_Xf3kq9LmR2vT8wYzN4bC1dE7 -m "backup ok"
upbutler heartbeat hb_Xf3kq9LmR2vT8wYzN4bC1dE7 --fail -m "pg_dump exited 1"
upbutler heartbeat mon_... --duration 48210 # monitor ids are resolved with your API keyPass a ping URL, an hb_… token or a mon_… monitor id. URLs and tokens need no API key.
Wrap a command
upbutler wrap --heartbeat "$UPBUTLER_HB_URL" -- ./backup.sh --full
# crontab: the heartbeat can also come from UPBUTLER_HEARTBEAT
0 2 * * * UPBUTLER_HEARTBEAT=hb_Xf3kq9LmR2vT8wYzN4bC1dE7 upbutler wrap -- /usr/local/bin/backup.shwrap runs the command with its output streamed as usual, then reports success with the duration, or failure with the exit code and the last lines of stderr. It exits with the command's exit code, and a failed ping never changes it. Everything after -- is passed to the command untouched.
Deploys
upbutler deploy mark --service api --version v1.42.0 --env production
# --commit defaults to $GITHUB_SHA or $CI_COMMIT_SHAMCP setup
$ upbutler mcp config --client claude-code
# Claude Code
claude mcp add --transport http upbutler https://upbutler.com/mcp --header "Authorization: Bearer $UPBUTLER_API_KEY"upbutler mcp config prints ready-to-paste config for Claude Code, Cursor (~/.cursor/mcp.json) and generic MCP clients. It references $UPBUTLER_API_KEY by default. Pass --with-key to inline your saved key. See MCP server.
Any API operation
upbutler api # list every operation
upbutler api monitors.get --input '{"id":"mon_..."}'
upbutler api pages.push --input @statuses.json
echo '{"slug":"acme"}' | upbutler api public.status --input -upbutler api is the escape hatch: it calls any operation from the API reference by id and prints the JSON result.
Scripts and agents
$ upbutler monitors ls --json | jq -r '.[] | select(.state=="down") | .name'
Search API
$ upbutler monitors get mon_nope --json
# stderr:
{"error":{"code":"not_found","message":"Monitor not found","status":404}}
$ echo $?
1For programmatic use from code, see the SDKs.