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.
Cron Jobs page (/cron)
Section titled “Cron Jobs page (/cron)”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.
| Action | Method + path | Auth |
|---|---|---|
| List jobs | GET /api/cron | Bearer |
| Create a job | POST /api/cron | Bearer |
| Update a job | PATCH /api/cron/{id} | Bearer |
| Delete a job | DELETE /api/cron/{id} | Bearer |
| Run history for a job | GET /api/cron/{id}/runs?limit=20 | Bearer |
| Read global settings | GET /api/cron/settings | Bearer |
| Update global settings | PATCH /api/cron/settings | Bearer |
Create a job
Section titled “Create a job”Click Add Job to open the create modal. The dashboard create form has four fields:
| Field | Type | Meaning |
|---|---|---|
name | string (optional) | Human-readable label for the job |
command | string | The shell command or agent prompt to run |
schedule | string | A standard cron expression, e.g. 0 0 * * * |
enabled | bool | Whether the job runs (defaults on) |
The modal posts straight to the gateway:
POST /api/cronAuthorization: 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.
Edit, enable/disable, and delete
Section titled “Edit, enable/disable, and delete”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.
Run history
Section titled “Run history”Click a job’s ID (or its expand control) to load that job’s recent runs:
GET /api/cron/{id}/runs?limit=20Authorization: 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.
catch_up_on_startup
Section titled “catch_up_on_startup”A gear toggle at the top of the page controls the scheduler’s global settings, including catch-up-on-startup:
GET /api/cron/settingsAuthorization: Bearer <token>{ "enabled": true, "catch_up_on_startup": true, "max_run_history": 50 }PATCH /api/cron/settingsAuthorization: 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 = truecatch_up_on_startup = true # default; set false to skip missed jobs on restartmax_run_history = 50Cost page (/cost)
Section titled “Cost page (/cost)”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": { "...": "..." } }}Reading the three panels
Section titled “Reading the three panels”- 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.
Config page (/config)
Section titled “Config page (/config)”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.
| Action | Method + path | Auth |
|---|---|---|
| Fetch raw TOML | GET /api/config | Bearer |
| Save config | PUT /api/config (Content-Type: application/toml) | Bearer |
| Test an MCP server | POST /api/mcp/servers/test | Bearer |
The Config page groups the most-edited keys into named sections:
- Provider —
default_provider,default_model,default_temperature,provider_timeout_secs,provider_max_tokens - Agent —
max_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, autonomylevel - Security — audit enabled, sandbox backend, cost limits
- Channels — CLI, ack reactions, show-tool-calls, message timeout
- MCP —
enabled,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.
Structured vs source editor
Section titled “Structured vs source editor”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).
The Source editor is the raw config.toml text with TOML syntax highlighting and a live preview panel. Use it for sections the structured form does not surface, for bulk edits, or to paste a config in wholesale. Both tabs edit one underlying document, so a change in one is reflected in the other.
Saving sends the full TOML back to the gateway:
PUT /api/configAuthorization: Bearer <token>Content-Type: application/toml
# ...the complete config.toml body...MCP servers and the Test button
Section titled “MCP servers and the Test button”The MCP section manages your external MCP server connections (the [[mcp.servers]] entries). Each server has these fields:
| Field | Applies to | Meaning |
|---|---|---|
name | all | Tool-name prefix (<name>__<tool>) |
transport | all | stdio, http, or sse |
command | stdio | Executable to launch |
args | stdio | Argument list |
env | stdio | Environment key/value pairs |
url | http / sse | Server URL |
headers | http / sse | HTTP headers |
timeout_ms | http / sse | Per-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/testAuthorization: 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 }