> ## Documentation Index
> Fetch the complete documentation index at: https://meepa.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Cron

> Schedule agents to run tasks on a fixed interval, cron expression, or one-shot trigger

## Overview

MeepaGateway has a built-in cron system that runs agent tasks on a schedule. Each job sends a message to an agent (triggering the full agent loop) and optionally delivers the response to a specific connector and channel.

Jobs are stored per-agent in SQLite and survive restarts. The scheduler uses a next-wake model: it sleeps until the earliest due job (capped at 60 seconds) rather than polling continuously.

***

## Schedule Types

<CardGroup cols={3}>
  <Card title="Every" icon="arrows-rotate">
    Fixed interval: `"30m"`, `"2h"`, `"1d"`. Runs repeatedly at the given interval.
  </Card>

  <Card title="Cron" icon="calendar-days">
    7-field cron expression with seconds: `"0 0 9 * * 1-5 *"`. Full calendar control.
  </Card>

  <Card title="At" icon="bullseye">
    One-shot: fires once at a specific UTC datetime. Use `delete_after_run = true` to clean up automatically.
  </Card>
</CardGroup>

***

## Configuration

Cron jobs are defined per-agent in `config.yaml`:

```yaml theme={null}
agents:
  - id: meepa
    name: Meepa
    default: true

    cron_jobs:
      # Fixed interval — check in every hour
      - name: heartbeat
        message: "Check in: review recent activity and summarize status."
        schedule:
          every: 1h
        delivery:
          connector: discord
          channel_id: general

      # Cron expression — weekday standups at 9 AM UTC
      - name: morning-standup
        message: "Generate a standup summary from yesterday's activity."
        schedule:
          cron: "0 0 9 * * 1-5 *"
        delivery:
          connector: meepachat
          channel_id: standup

      # One-shot reminder — fires once then deletes itself
      - name: deploy-reminder
        message: "Remind the team about the scheduled deploy at 10 AM."
        delete_after_run: true
        schedule:
          at: "2025-07-01T09:00:00Z"
        delivery:
          connector: slack
          channel_id: C0123456789
```

***

## Job Options

<ParamField path="name" type="string" required>
  Unique job name within the agent.
</ParamField>

<ParamField path="message" type="string" required>
  The prompt sent to the agent when the job fires. This is the agent's input — not the final message delivered to users. The agent processes it through the full loop and the response goes to `delivery`.
</ParamField>

<ParamField path="schedule" type="object" required>
  One of:

  * `{ every = "30m" }` — fixed interval (supports `s`, `m`, `h`, `d`)
  * `{ cron = "0 0 9 * * 1-5 *" }` — 7-field cron with seconds
  * `{ at = "2025-07-01T09:00:00Z" }` — one-shot RFC 3339 datetime
</ParamField>

<ParamField path="delivery" type="object">
  Where to post the agent's response. If omitted, the response is discarded (useful for jobs that write to memory or trigger side effects).

  ```yaml theme={null}
  delivery:
    connector: discord   # connector name as defined in channel config
    channel_id: general  # platform channel ID or name
  ```
</ParamField>

<ParamField path="enabled" type="boolean" default="true">
  Enable or disable the job without removing it.
</ParamField>

<ParamField path="delete_after_run" type="boolean" default="false">
  Delete the job after its first successful execution. Useful for one-shot jobs.
</ParamField>

<ParamField path="model" type="string">
  Override the agent's default model for this job.
</ParamField>

<ParamField path="max_iterations" type="integer">
  Override the agent's `max_iterations` for this job.
</ParamField>

<ParamField path="timeout" type="string">
  Per-job execution timeout (e.g. `"2m"`).
</ParamField>

<ParamField path="active_hours" type="array">
  Restrict execution to a UTC hour range. Format: `[start_hour, end_hour]` (0–23). Jobs that fall outside this window are skipped and retried at the next scheduled time.

  ```yaml theme={null}
  active_hours: [9, 17]  # 9 AM UTC to 5 PM UTC
  ```
</ParamField>

***

## Cron Expression Format

MeepaGateway uses a 7-field cron format with seconds as the first field:

```
# second (0-59)
# | minute (0-59)
# | | hour (0-23)
# | | | day of month (1-31)
# | | | | month (1-12)
# | | | | | day of week (0-6, Sunday=0)
# | | | | | | year (optional)
  * * * * * * *
```

Examples:

| Expression            | Meaning                             |
| --------------------- | ----------------------------------- |
| `0 0 9 * * 1-5 *`     | Weekdays at 9:00 AM UTC             |
| `0 */30 * * * * *`    | Every 30 minutes                    |
| `0 0 0 1 * * *`       | First day of each month at midnight |
| `0 0 8,12,18 * * * *` | 8 AM, noon, 6 PM daily              |

***

## Managing Jobs at Runtime

Jobs can be created, updated, and deleted via the Captain Dashboard or API without restarting the gateway.

### Captain API

```bash theme={null}
# List cron jobs for an agent
curl -H "Authorization: Bearer $API_KEY" \
  http://localhost:63372/api/agents/meepa/cron

# Create a job
curl -X POST -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "weekly-report",
    "message": "Generate a weekly activity report.",
    "schedule": {"type": "cron", "value": "0 0 9 * * 1 *"},
    "delivery": {"connector": "discord", "channel_id": "reports"}
  }' \
  http://localhost:63372/api/agents/meepa/cron

# Delete a job
curl -X DELETE -H "Authorization: Bearer $API_KEY" \
  http://localhost:63372/api/agents/meepa/cron/weekly-report
```

***

## Failure Recovery

The scheduler tracks `consecutive_failures` per job. Failed jobs are retried at the next scheduled time. There is no exponential back-off — the schedule drives retry timing.

Jobs that exceed their `timeout` are killed and counted as failures. The scheduler does not block waiting for a failed job; other due jobs continue to fire independently.

***

## Architecture

* **`CronStore`** — per-agent SQLite store for job definitions, run history (`last_run_at`, `next_run_at`), and failure counts
* **`CronScheduler`** — unified scheduler across all agent stores; uses a next-wake model (sleeps until earliest due job, capped at 60s)
* When a job fires, its `message` is dispatched through the same agent loop as a regular incoming message, with `delivery` context set for the response
