Hermes Agent

Alert when a Hermes cron stops

Hermes runs scheduled jobs from its gateway daemon, on a 60-second tick. If the gateway stops, agent jobs stop with it, silently. CronObserver alerts when a job fails, hangs or simply doesn't happen.

No credit card. Free plan with 3 monitors after the trial.

Your agent's scheduler can't be its own watchdog

In Hermes, cron execution is handled by the gateway daemon. Its own status command can tell you a job is overdue, but only if you run it, on the same machine. When the gateway dies, the laptop sleeps or the VPS reboots, a nightly job just doesn't happen.

A heartbeat monitor flips the logic: the job proves it ran by calling a URL. If CronObserver doesn't hear from it on schedule, it alerts you, from outside the box.

1. Create a monitor in CronObserver

Use the same schedule as the job, a grace period for normal delays and a max runtime for runs that hang. Copy the check-in URL: the token at the end is the secret.

Schedule:     cron  0 2 * * *   (same time zone as the job)
Grace period: 10 min
Max runtime:  30 min
Alerts:       email (Free) · Slack, Teams, webhook (Orbital)

Check-in URL: https://cronobserver.com/checkin/<token>

2. Give the token to Hermes scripts

Cron scripts run with a sanitized environment, so pass the token through explicitly.

# ~/.hermes/.env
CRONOBSERVER_TOKEN=<token>

# ~/.hermes/config.yaml   (cron scripts get a clean environment)
terminal:
  env_passthrough:
    - CRONOBSERVER_TOKEN

3. Wrap the job in a script

Hermes only runs scripts from ~/.hermes/scripts. The script signals start, then success or failure. On success stdout stays empty, so Hermes posts nothing; on failure the line it prints is delivered.

#!/usr/bin/env bash
# ~/.hermes/scripts/nightly-report.sh
set -u
CO="https://cronobserver.com/checkin/${CRONOBSERVER_TOKEN:?add CRONOBSERVER_TOKEN to ~/.hermes/.env}"
ping() { curl -fsS -m 10 --retry 3 -o /dev/null -X POST "$CO$@" || true; }

ping /start
if python3 ~/jobs/nightly_report.py >/dev/null 2>&1; then   # your job
  ping ""                     # success: empty stdout = Hermes stays silent
else
  rc=$?
  ping /fail -H 'Content-Type: application/json' \
    -d "{\"exitCode\":$rc,\"message\":\"nightly_report.py failed\"}"
  echo "nightly report failed (exit $rc)"   # Hermes delivers this line
  exit "$rc"
fi

4. Schedule it as a no-agent job

With --no-agent the script is the whole job, with no LLM call. A non-zero exit also marks the run as failed in Hermes.

# No-agent job: the script is the job, no LLM call
hermes cron create "0 2 * * *" --no-agent --script nightly-report.sh \
  --deliver local --name nightly-report

# Run it on the next tick and check the result
hermes cron run <job_id>
hermes cron runs <job_id>

What you get alerted about

  • The job failed: /fail arrives with the exit code and message, and the alert goes out right away.
  • The job hung: it called /start but neither success nor /fail came within the max runtime.
  • The job never ran: no check-in by the scheduled time plus the grace period, for example because the gateway was down.
  • It came back: the next successful check-in closes the incident.

Good to know

  • Tested on Hermes Agent 0.19.0: the job above produced start, success and fail check-ins in production, and Hermes recorded the runs as completed and failed.
  • Hermes runs .sh files with bash and ignores the shebang, so keep the script in bash.
  • After a long outage Hermes runs a missed job once, not once per missed slot. CronObserver has already alerted by then.
  • To monitor an agent prompt, call your agent from the script in place of nightly_report.py, so the wrapper sees its exit code.

Based on the Hermes Agent documentation: hermes-agent.nousresearch.com/docs/user-guide/features/cron · hermes-agent.nousresearch.com/docs/guides/cron-script-only

Hermes Agent is a Nous Research project. CronObserver is not affiliated with or endorsed by it; this page uses plain HTTPS check-ins.

Other agent platforms: OpenClaw · OpenAI dots · Check-in docs