DocsAutomation

REST API, MCP server and read-only CLI

View source on GitHubdocs/mcp-and-cli.md

On this page

REST API#

Everything the web app does goes through the REST API under /api/v1, and you can use it too. The machine-readable description is OpenAPI 3: the hub serves it at /api/v1/openapi.json, and a copy is kept at openapi.json in this folder (bun run openapi:export regenerates it). Each operation lists the role it needs.

export YARRIX_URL=https://yarrix.example.net
export YARRIX_TOKEN=yx_...        # create one on the hub: yarrix-hub auth token create --name me --scope read
curl -fsS -H "Authorization: Bearer $YARRIX_TOKEN" "$YARRIX_URL/api/v1/status"
curl -fsS -H "Authorization: Bearer $YARRIX_TOKEN" "$YARRIX_URL/api/v1/hosts"
  • Tokens are yx_... secrets with a scope: read (the viewer's reads), operate (a read-write key for an AI agent, below), report (backup run reports, optionally limited to named backups) or admin. A token is shown once when created and stored hashed. Heartbeat pings use their own URL token instead (heartbeats.md).
  • What a token cannot do: manage tokens, enrollments and the SSH test need an admin signed in to the web app; changing a command-bearing config field does too (security.md); and the terminal and its recordings are never opened by a token (terminal.md).
  • Groups of routes: status and problems; hosts, their metrics and capabilities; apps; backups and their runs and reports; heartbeats; alerts, silences, deliveries and routing; config files (read, validate, write); tokens, users, audit log; and GET /api/v1/events, a server-sent event stream of changes.
  • The web app's API screen lists every operation with a runnable curl, and the tokens you can create (auth.md).

The rest of this page is the MCP server and the CLI. With a read token (or an admin token) both are read-only: neither takes a command or changes state. With a read-write key (operate scope) they can also act, as described under Connecting an AI agent. Create a token on the API screen or in Config, Tokens, or with POST /api/v1/tokens.

MCP#

Streamable HTTP at {base_path}/mcp (for example https://yarrix.example.net/mcp), stateless, JSON responses. Send Authorization: Bearer yx_.... A request without a valid token gets 401 before anything is routed; a token without the read scope gets 403. Only POST is served.

Example client entry (any MCP host that speaks Streamable HTTP):

{ "mcpServers": { "yarrix": { "type": "http", "url": "https://yarrix.example.net/mcp", "headers": { "Authorization": "Bearer yx_..." } } } }
ToolReturns
yarrix_statusOverall state and counts per domain, open incidents, agent versions (GET /api/v1/status).
yarrix_problems(domain?)What is failing, critical first.
yarrix_is_green(kind, id){green, state, reason}. kind is host, app, backup or heartbeat. An unknown id is not green.
yarrix_get(kind, id)The object's full read view. A heartbeat's ping path (its credential) is never included.
yarrix_alerts(state?)open (default) or resolved incidents.
yarrix_incident(id)One incident with its timeline: who acked, snoozed or noted it.
yarrix_availability(kind, id, range?)Availability over range (a duration such as 24h or 7d; default 30d): the percentage, seconds up, degraded and down, time not observed, a per-day breakdown, incident count and run counts.
yarrix_metrics(host, metric, range)A host's time series (cpu, mem, gpu, disk, temp; 1h, 24h, 48h, 7d, or a duration such as 30m).

Each tool is a GET of the REST read API made with the caller's own credentials, so MCP never shows more than REST would. List results are returned as the REST array in the text block and as {items: [...]} in structuredContent.

Connecting an AI agent#

To let an agent monitor and act, an admin makes it a key (API screen or Config, Tokens: Read-only or Read-write).

  • Watching: a read-only key reads everything a viewer can, through REST, MCP, the CLI and the GET /api/v1/events stream. To be pushed alerts instead of polling, add a webhook destination with format: yarrix_json and a signing secret.
  • Acting: a read-write key also gets these, as REST calls, MCP tools (listed only for such a key) and CLI commands:
ActionRESTMCP toolCLI
AcknowledgePOST /alerts/{id}/ackyarrix_ackyarrix ack ID
SnoozePOST /alerts/{id}/snoozeyarrix_snoozeyarrix snooze ID 2h
NotePOST /alerts/{id}/notesyarrix_noteyarrix note ID text...
Silence, end a silencePOST /silences, DELETE /silences/{id}yarrix_silence, yarrix_end_silenceyarrix silence host:atlas 2h, yarrix end-silence N
Pause, resumePOST /pauses, DELETE /pauses/{id}yarrix_pause, yarrix_resumeyarrix pause host:atlas 2h, yarrix resume N
Run a check nowPOST /checks/{id}/runyarrix_run_checkyarrix run-check ID
Re-verify a backupPOST /backups/{id}/verifyyarrix_verify_backupyarrix verify-backup ID
List and run a host's declared commandsGET /hosts/{id}/commands, POST /hosts/{id}/commands/{name}/runyarrix_commands, yarrix_run_commandyarrix commands HOST, yarrix run-command HOST NAME

People do the same from the web app: an operator or admin adds a Note under an incident's timeline on the Alerts tab, and uses Run now in an app check's drawer and Re-verify in a backup's drawer. An admin signed in to the web app sees a host's declared commands in its drawer, under Commands, and runs one by name with its output and exit status. A viewer sees the timeline and none of these buttons.

The key can run any command an admin declared in the host's agent.yaml, and nothing else: it names the command, and the agent runs the argv it already has. Mutes last at most auth.token_limits.max_mute (24h by default), every action is audited under the key's name, and every mute and command run is announced to the default destination. A key's pause also obeys the operator rule for pauses: the scope's paused time in the last 30 days plus the new pause must stay within 30 days, and past that only an admin can pause it. What a key cannot do: security.md.

CLI#

yarrix status [--json]                   exit 0 ok, 1 warn, 2 critical
yarrix problems [--domain D] [--json]
yarrix is-green <kind> <id> [--json]     exit 0 green, 1 not green (unknown ids too)
yarrix get <kind> <id>
yarrix alerts [--state open|resolved] [--json]

The action commands (ack, snooze, note, silence, end-silence, pause, resume, run-check, verify-backup, commands, run-command) need a read-write key; yarrix ack --help lists them. Exit 0 done, 1 the hub refused (not a read-write key, over the cap, rate limited, unknown name), 3 no answer.

yarrix status also prints an agents line (how many agent hosts are current, outdated or not reporting a version, and the version the hub expects) and names the hosts that are behind. --json and yarrix_status carry the same under agents; each host from GET /hosts has an agent block. See AGENT.md.

Exit code 3 means no answer was obtained (bad usage, no token, hub unreachable, token rejected), so a script can tell a bad answer from no answer.

Every command that talks to a hub (ping, run, report, these read commands, and the agent's join, redeem and discover) trusts the system's certificate roots plus a private CA given with --ca-file PEM or YARRIX_CA_FILE. The agent's own connection trusts the same roots and also the bundled Mozilla set.

Settings, first match wins: --hub / --token / --token-file; then YARRIX_HUB (the hub address, the same name the agent uses; the older YARRIX_HUB_URL and YARRIX_URL still work), YARRIX_TOKEN, YARRIX_TOKEN_FILE; then $XDG_CONFIG_HOME/yarrix/cli.toml (default ~/.config/yarrix/cli.toml):

url = "https://yarrix.example.net"
token_file = "/etc/yarrix/read-token"   # or: token = "yx_..."