# Scheduled tasks

Commands on a schedule on the VPS through a systemd service and timer, with minute shortcuts, manual runs and logs.

Source: https://ardumaker.com/en/docs/cron/

- Category: Servers and infrastructure
- Status: Available
- Requirements: A running company VPS with systemd; To create, edit, control or delete: being a company admin; To list and view: being a member with access to the VPS
- MCP tools (Read only): `listar_tareas_vps`, `ver_tarea_vps`, `ver_logs_tarea_vps`
- MCP tools (Write or modify): `crear_tarea_vps`, `editar_tarea_vps`, `controlar_tarea_vps`
- MCP tools (Destructive): `eliminar_tarea_vps`

## What can you do with it?

- Run a command on a schedule: every N minutes, at a fixed time, on certain days or with the `hourly`, `daily` and `weekly` shortcuts.
- Run the task once right now, or stop a run in progress.
- Change the command or schedule of an existing task.
- See the next and last run, and read the logs of the command and of the timer.

## When should you use it?

- Periodic cleanups, exports or syncs that do not belong to an ArduMaker app.
- A script that must run even if the VPS was off at that time (it runs on power-up).

> **INFO:** `crontab` is not used: each task is a systemd service + timer pair. The scheduled work of a Git app goes as a `timer` process in its deploy configuration, not here.

## How does it work in ArduMaker?

### Checks before touching the VPS

- **Name**: the same rules as a systemd service (`nombre_invalido`).
- **Command**: a single line, up to 4000 characters, with closed quotes (`comando_invalido`). If it uses pipes, `&&`, variables, redirections or shell builtins, it is wrapped automatically in `/bin/sh -c "…"` with the needed escaping.
- **Schedule**: an `OnCalendar` expression (`daily`, `*-*-* 02:00:00`, `Mon..Fri *-*-* 10:00`, `*-*-* *:0/5:00 Europe/Madrid`). Shortcuts: `5` or `*/5` mean every 5 minutes, and `1` every minute.
- The validation error says which field failed in `data.fields`.

### Creation

1. Copies of the unit and the timer are kept if they already existed.
2. `/etc/systemd/system/<nombre>.service` (`Type=oneshot`, output to the journal under the task name) and `/etc/systemd/system/<nombre>.timer` (`OnCalendar`, `Persistent=true`) are written.
3. `daemon-reload`, the timer is started and enabled at boot. If a step fails, the new files are deleted and the copies restored.
4. With `start=true` the command also runs once right then (if that run fails, the task is still created).

### Edit, control and delete

- **Edit** reads the current command and schedule, **deletes the task and creates it again** with the new values. The edited task is left enabled.
- **`start`** runs the command now; **`stop`** stops that run (it does not stop the timer).
- **`enable`** and **`disable`** change whether the timer starts with the system. `disable` does not stop a timer that is already active: it keeps firing until the next VPS reboot.
- **Delete** stops and disables the timer, removes both files and reloads systemd. There are no protected names.

## What actually changes?

- `/etc/systemd/system/<nombre>.service` and `/etc/systemd/system/<nombre>.timer`, with 644 permissions.
- The command runs as `root`, and its output stays in the journal tagged with the task name.
- An entry in the VPS activity log for each creation, edit, action and deletion.

```ini
# <nombre>.timer
[Unit]
Description=Timer for task: limpieza

[Timer]
OnCalendar=*-*-* 02:00:00
Unit=limpieza.service
Persistent=true

[Install]
WantedBy=timers.target
```

## Diagram

**A scheduled task**

```text
Timer (OnCalendar fires at the set time)
  ↓
Oneshot service (runs the command once and exits)
  ↓
journal (output and errors under the task name)
```

With `Persistent=true`, if the VPS was off at the scheduled time, the task runs on power-up.

## Expected result

- Create, edit and control return `timer_status`, `is_enabled` and, except on create, `next_run`.
- `ver_tarea_vps` shows the service and timer content, the status, and the next and last run.
- `ver_logs_tarea_vps` with `log_type: "service"` shows the command output; with `"timer"`, the timer's.

```bash
systemctl list-timers --no-pager
journalctl -u limpieza.service -n 50 --no-pager
```

## Errors and troubleshooting

| Answer | Cause | What to do |
| --- | --- | --- |
| 400 `nombre_invalido` on `schedule` | The schedule has characters that are not part of an OnCalendar expression (quotes, `$`, `;`) | Fix the schedule |
| 400 `comando_invalido` | Line break, unclosed quotes or more than 4000 characters | Move it into a script and call the script |
| 400 with `data.cause` | The VPS could not write or activate the task; `cause` says which step | Check the step indicated |
| 404 `Task not found` | The task does not exist | List first |
| 403 | Only a company admin can create, edit, control or delete | Ask an admin |
| The task keeps running after `disable` | `disable` only affects boot | Delete the task if it must stop right away |

> **PRECAUCION:** Editing deletes and recreates the task: if the recreation fails (for example, the VPS stops answering halfway), the task is left deleted. Keep the command and schedule before editing.

Creating with the same name replaces the task; retrying after a cut is safe with the same `idempotency_key`. `controlar_tarea_vps` with `start` runs the command again each time.

## MCP access

Yes, in the `/mcp` and `/mcp/vps` profiles.

| Tool | Type | Notes |
| --- | --- | --- |
| `listar_tareas_vps`, `ver_tarea_vps` | Read | Member |
| `ver_logs_tarea_vps` | Read | Untrusted content |
| `crear_tarea_vps` | Write | Admin; accepts `idempotency_key` |
| `editar_tarea_vps` | Write | Admin; deletes and recreates |
| `controlar_tarea_vps` | Write | Admin; `start`, `stop`, `enable`, `disable` (no `restart`) |
| `eliminar_tarea_vps` | Destructive | Admin; no protected names |

Reference at [/mcp/docs](https://ardumaker.com/en/mcp/docs) and examples at [/mcp/servicios](https://ardumaker.com/en/mcp/servicios).

## Related features

- [systemd services](https://ardumaker.com/en/docs/systemd/)
- [Backups](https://ardumaker.com/en/docs/backups/)
- [Monitoring](https://ardumaker.com/en/docs/monitorizacion/)
- [VPS servers](https://ardumaker.com/en/docs/vps/)
