Skip to content

Cron, cost & config pages

Schedule cron jobs, analyze spend, and edit configuration with the structured/source editor and MCP server tester.

Three dashboard routes in the Operations section cover the day-to-day operator chores: scheduling work, watching spend, and changing settings. The Cron page (/cron) manages scheduled agent and shell jobs and their run history. The Cost page (/cost) is read-only spend analytics — session, daily, and monthly totals broken down by model. The Config page (/config) edits your whole config.toml through either a structured per-section form or a raw source editor, and is where you wire up and test external MCP servers.

Reach for this page when you want a job to run on a schedule, when you need to see what your tokens are costing, or when you want to change a setting without dropping to a shell. All three sit behind the dashboard’s bearer-token auth — see Run the dashboard to pair a browser first.

The Cron page is the visual front end for Revka’s scheduler. It lists every registered job, lets you add, edit, enable/disable, and delete jobs, and expands any row to show that job’s recent run history with duration and output. It is backed by the gateway’s /api/cron endpoints.

ActionMethod + pathAuth
List jobsGET /api/cronBearer
Create a jobPOST /api/cronBearer
Update a jobPATCH /api/cron/{id}Bearer
Delete a jobDELETE /api/cron/{id}Bearer
Run history for a jobGET /api/cron/{id}/runs?limit=20Bearer
Read global settingsGET /api/cron/settingsBearer
Update global settingsPATCH /api/cron/settingsBearer

Click Add Job to open the create modal. The dashboard create form has four fields:

FieldTypeMeaning
namestring (optional)Human-readable label for the job
commandstringThe shell command or agent prompt to run
schedulestringA standard cron expression, e.g. 0 0 * * *
enabledboolWhether the job runs (defaults on)

The modal posts straight to the gateway:

POST /api/cron
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "nightly summary",
"command": "Summarize today's alerts",
"schedule": "0 9 * * *",
"enabled": true
}
{ "status": "ok", "job": { "id": "abc123", "...": "..." } }

The gateway wraps the schedule string in a cron schedule automatically. A job is treated as an agent job when a prompt is present and as a shell job otherwise. The cron expression uses standard 5-field crontab syntax (min hour day month weekday); 0 9 * * * is 09:00 every day.

Editing a job sends a partial update — only the fields you change are touched:

PATCH /api/cron/{id}
Authorization: Bearer <token>
Content-Type: application/json
{ "name": "renamed", "schedule": "0 8 * * *", "command": "...", "enabled": false }

Toggling enabled is how you pause and resume without deleting: a disabled job stays in the database with its schedule intact and simply does not fire. Delete removes the job and its run history permanently (the cron_runs rows cascade) — it cannot be undone.

Click a job’s ID (or its expand control) to load that job’s recent runs:

GET /api/cron/{id}/runs?limit=20
Authorization: Bearer <token>
{
"runs": [
{
"id": "...",
"job_id": "abc123",
"started_at": "2026-06-18T09:00:00Z",
"finished_at": "2026-06-18T09:00:04Z",
"status": "ok",
"duration_ms": 4120,
"output": "..."
}
]
}

Each execution is recorded with start/finish timestamps, a status of ok or error, a duration, and captured output (stored up to 16 KB per run). How many records are kept per job is set by max_run_history (default 50); older records are pruned automatically.

A gear toggle at the top of the page controls the scheduler’s global settings, including catch-up-on-startup:

GET /api/cron/settings
Authorization: Bearer <token>
{ "enabled": true, "catch_up_on_startup": true, "max_run_history": 50 }
PATCH /api/cron/settings
Authorization: Bearer <token>
Content-Type: application/json
{ "catch_up_on_startup": false }

When catch_up_on_startup is true (the default), a daemon start or restart first queries for every overdue job and runs each one once before entering the normal polling loop. This recovers jobs that were missed during downtime — a late boot, a crash, or maintenance. When false, missed jobs are skipped and simply wait for their next naturally scheduled occurrence. The same settings object also carries enabled (the global on/off switch for the whole cron subsystem) and max_run_history. Changes are written to config.toml and applied to the running config immediately — no restart required.

[cron]
enabled = true
catch_up_on_startup = true # default; set false to skip missed jobs on restart
max_run_history = 50

The Cost page is read-only token and spend analytics. It shows three spend windows, a per-model breakdown with bar charts, and token-efficiency metrics. It pulls from a single endpoint:

GET /api/cost
{
"session_cost_usd": 0.4213,
"daily_cost_usd": 1.8740,
"monthly_cost_usd": 22.5106,
"request_count": 318,
"total_tokens": 1542300,
"by_model": { "anthropic/claude-sonnet-4-6": { "...": "..." } }
}
  • Left panel — four metric cards (session cost, daily cost, monthly cost, request count) plus a token-efficiency sub-panel (total tokens, average tokens per request, cost per 1,000 tokens).
  • Centre panel — the model workspace. Each model row shows total cost, token count, request count, its percentage share of monthly spend, and a bar-chart strip. Click a row to select it.
  • Right panel — the selected model’s detail: monthly spend, requests, tokens, average tokens, cost per 1,000 tokens, and percentage share. An interpretation panel narrates what the numbers mean.

The three windows mean different things: session is the current daemon process lifetime, daily is the rolling day, and monthly is the calendar month. The session-scoped by_model breakdown reflects the current process only, while the daily and monthly totals are read from the full ledger.

The Config page views and edits your entire Revka config.toml. A section map on the left jumps between sections; the editor body offers two modes via tabs. Save persists the whole file.

ActionMethod + pathAuth
Fetch raw TOMLGET /api/configBearer
Save configPUT /api/config (Content-Type: application/toml)Bearer
Test an MCP serverPOST /api/mcp/servers/testBearer

The Config page groups the most-edited keys into named sections:

  • Providerdefault_provider, default_model, default_temperature, provider_timeout_secs, provider_max_tokens
  • Agentmax_tool_iterations, max_context_tokens, max_history_messages, context-window settings, parallel_tools, thinking level
  • Memory[kumiho] settings, backend, auto_save, snapshots
  • Runtime — gateway host/port, require_pairing, session persistence, autonomy level
  • Security — audit enabled, sandbox backend, cost limits
  • Channels — CLI, ack reactions, show-tool-calls, message timeout
  • MCPenabled, deferred_loading, and the external server list

For the meaning, type, and default of every key in these sections, see the Configuration overview and the section-specific references.

The two tabs are two views of the same file — pick whichever suits the change:

The Structured editor is a per-section form. Each TOML section becomes a labelled group of typed inputs — toggles for booleans, number fields for limits, dropdowns for enums like the autonomy level or MCP transport. Use it when you know which setting you want and would rather not hand-write TOML, and to avoid syntax mistakes. The MCP servers section here is a full CRUD UI with a per-server Test button (below).

Saving sends the full TOML back to the gateway:

PUT /api/config
Authorization: Bearer <token>
Content-Type: application/toml
# ...the complete config.toml body...

The MCP section manages your external MCP server connections (the [[mcp.servers]] entries). Each server has these fields:

FieldApplies toMeaning
nameallTool-name prefix (<name>__<tool>)
transportallstdio, http, or sse
commandstdioExecutable to launch
argsstdioArgument list
envstdioEnvironment key/value pairs
urlhttp / sseServer URL
headershttp / sseHTTP headers
timeout_mshttp / ssePer-call timeout in milliseconds

The Test button on each server runs a real connection check before you save — it performs a full initialize + tools/list handshake against the configured server and reports back:

POST /api/mcp/servers/test
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "filesystem",
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
"env": {},
"url": null,
"headers": {},
"timeout_ms": 30000
}

On success you get the discovered tool count, the tool names, and the round-trip latency; on failure you get an error message:

{ "ok": true, "tool_count": 5, "tools": ["read_file", "write_file", "..."], "latency_ms": 234 }
{ "ok": false, "error": "connection refused", "latency_ms": 10 }