AI Agent Cron Monitoring Setup: Scoped Access, Verified Runs
Contents
To set up cron job monitoring with an AI coding agent safely, let the agent change code but keep it away from your deployment secret, give it workspace access only when a task needs it, and treat its work as unverified until a real scheduled run reports a result. Coding agents such as Claude Code, Cursor, Codex, and GitHub Copilot's agent mode are good at the tedious part: finding every scheduled job in a repository and wiring the same reporting pattern into each one. They are just as capable of producing monitoring that compiles and never reports, or that quietly changes how a job retries or exits. This guide uses CronRadar's agent setup as the worked example; the access, review, and verification steps apply to any monitoring service.
Choose the Agent's Access Before You Paste Anything#
CronRadar's agent quickstart offers two ways to start. They differ in one thing: whether the agent can act on your CronRadar workspace. Neither needs a CLI or an agent skill installed.
The Public Prompt: Code Changes Only#
Fetch and follow the instructions to set up CronRadar monitoring from https://docs.cronradar.com/agent-setup/prompt.mdThis prompt contains no credentials and grants no workspace access. The agent edits code; you create the application and its key in the console's Setup tab and store the key yourself. The public instructions tell an agent without access to send you to the console for a private prompt, so if you want code changes only, say so, as the prompts further down do. The AI setup page has a longer code-only prompt that spells this out.
The Private Setup Prompt: Temporary Workspace Access#
At app.cronradar.com/assistant you choose one workspace, the permissions, and an expiry, then copy a private prompt that carries a temporary token. Read access supports investigation, write access allows setup, and delete is a separate choice. Access lasts one hour by default and up to 24 hours, can be revoked at any time, and never exceeds your own workspace role, which is checked on every request. Creating applications and jobs needs a Member role with write access; updating them or creating a deployment key needs Admin with write access.
The agent needs an HTTP or code-execution tool to use the token; a chat-only assistant can explain setup but can't call the management API.
Which One to Use#
| Task | Access | Why |
|---|---|---|
| Add monitoring code to a repository | Public prompt | The agent never holds a credential; you control the key |
| See what is already monitored before changing code | Private prompt, read | Prevents duplicate applications and jobs |
| Investigate a late or failed job | Private prompt, read | An investigation should not be able to change anything |
| Let the agent create applications and jobs, then read runs | Private prompt, read and write | Setup and evidence in one session |
| Remove old monitors on purpose | Private prompt with delete, for that one task | Deletion also requires confirming the resource's current name |
Pick the shortest expiry that covers the task. A task that outlasts its grant gets fresh access from the console, not a silently extended one.
Keep the Two Credentials Apart#
Two credentials are in play, and the most damaging mistake is letting one stand in for the other.
| Credential | What it does | Lifetime | Where it belongs |
|---|---|---|---|
| Temporary token in the private prompt | Reads or manages one workspace through the management API | 1 hour by default, up to 24; revocable sooner | The agent's memory for one session |
CRONRADAR_API_KEY, an ingestion key |
Reports check-ins from one deployed application to cron.life |
Its own expiry and revocation | The deployment's secret manager |
The rules that follow from that split:
- The ingestion key never enters the chat. It is shown once when created. Save it straight into the deployment's secret manager as
CRONRADAR_API_KEY; the agent doesn't need the value to write code that reads it. - The agent creates a key only if it can store it safely. CronRadar's instructions let an agent with Admin and write access create an ingestion key only to save it through an authorized secret-store operation, never printing it. Without such a tool, create the key in the console.
- Assume the transcript outlives the token. Anyone holding the private prompt can use it until it expires or is revoked, and your assistant provider may retain the conversation after expiry. Keep the expiry short, and never paste the prompt into a shared channel or ticket.
- Revoke when you finish, then check what remains. Expiring or revoking access does not undo the agent's changes or revoke ingestion keys it created. Applications and jobs stay in the workspace, and created keys keep deployed monitoring running until their own expiry or revocation. Review them in the application's Setup tab.
- Use one application and key per environment. Production, staging, and development each get their own, so a staging host can't update production monitors.
What a Good Agent Run Looks Like#
A careful run follows the same order whichever prompt you used. CronRadar's task recipes describe it for the agent; use it as your yardstick when reading the transcript.
- It reads before it writes. With workspace access, its first call is
GET /context, to confirm the workspace and effective permissions match your request. Then it lists existing applications and jobs, matching environment and stable job key before proposing anything new. A job's management ID and its monitor key differ; check-ins use the key. - It keeps environments in separate applications. It reuses the application for this environment or creates one whose environment field describes the actual deployment.
- It finds the process that actually runs the scheduler. Monitoring belongs where jobs execute: the host with the crontab, the worker service that runs Hangfire Server, the container a Kubernetes CronJob starts. An integration added to a web project does nothing if the jobs run in a separate worker.
- It checks availability before installing. Repository docs can describe a release that isn't published yet. As of September 20, 2026, the installable packages are
CronRadar1.0.13 (.NET),CronRadar.Hangfire0.1.0, andCronRadar.Quartz0.1.0. For Node.js, Python, Celery, PHP, Laravel, and stacks such as Go, Ruby, or plain shell, there is no usable CronRadar SDK and no auto-discovery, so each job reports with its own HTTP check-in. Registries do listcronradar(npm, PyPI) andcronradar-celery(PyPI), but the docs mark them unavailable, so an agent that finds them in a search shouldn't install them. - It lets discovery do its job. Framework integrations discover recurring jobs themselves; the base SDK and HTTP check-ins need an explicit report per job. If discovery misses a job, the fix is in the integration, not a duplicate created through the management API.
- It preserves the job. Same schedule, time zone, retry behavior, and result. It builds and runs the tests, then tells you which process needs a deploy or restart. It doesn't deploy, deliberately fail production work, pause monitoring, or delete anything you didn't ask it to.
- It reports evidence, then hands access back. The summary separates what changed, what real execution evidence it saw, and what remains unverified, including alert delivery, and ends by telling you to revoke the grant.
For a Hangfire application, a correct diff can be this small:
dotnet add package CronRadar.Hangfire// Program.cs
using CronRadar.Hangfire;
using Hangfire;
// Existing Hangfire setup stays as it was.
builder.Services.AddHangfire(config =>
config.UseSqlServerStorage(builder.Configuration.GetConnectionString("Hangfire")));
builder.Services.AddHangfireServer();
// Added after AddHangfire(). The key comes from CRONRADAR_API_KEY.
builder.Services.AddCronRadarHangfire();The integration reads Hangfire's recurring-job registry at startup, reconciles it every 15 minutes, and reports each execution's start, completion, or failure; [SkipMonitor] on a method opts a job out. Monitoring calls added inside each job method on top of this are duplicated reporting, not extra safety. CronRadar for Hangfire covers what the integration watches.
Prompts You Can Paste#
Each states the access boundary, what must not change, and what counts as done.
Add Monitoring to Hangfire Jobs, Code Only#
Add CronRadar monitoring to the Hangfire recurring jobs in this repo using the
public setup instructions at https://docs.cronradar.com/agent-setup/prompt.md.
Don't request workspace access, and don't create, ask for, or print any keys.
I'll create the application and key in the console and store CRONRADAR_API_KEY
in our secret manager. Read the Hangfire guide's availability notice first and
use only the published package. Put the integration in the process that runs
Hangfire Server. Keep every schedule, time zone, retry policy, and job result
unchanged. Run the tests, then tell me what needs deploying and how I'll know
a real run reported.Add HTTP Check-Ins Where There Is No SDK#
Read https://docs.cronradar.com/agent-setup/prompt.md. Our scheduled jobs run
from node-cron in worker/index.js, and CronRadar has no available Node.js SDK,
so add HTTP check-ins to each job: start, then complete or fail. Don't install
any CronRadar package. Each check-in must time out after 5 seconds, ignore its
own errors, and leave the job's exception and exit code unchanged. Send the
five-field UTC equivalent of each schedule and read CRONRADAR_API_KEY from the
environment. Don't request workspace access or handle keys.Investigate a Late Job With Read-Only Access#
Create a private prompt with read access only, paste it, then add:
Using read-only access, find out why nightly-invoice-export in the production
application was late last night. Read the job, its recent check-ins, and its
alerts. Compare the expected schedule, time zone, and grace period with the
latest start and terminal events, and tell me whether it never reported, ran
late, failed explicitly, or started without finishing. Don't create, change,
pause, or delete anything. List what I should check in the scheduler itself.The last sentence matters because the management API exposes check-ins and alerts, not application logs: the agent can say what CronRadar recorded, not why the job behaved that way.
Review the Diff Before You Merge#
Reviewing AI-generated cron jobs covers these checks in depth; this is the short list for a monitoring change.
| Check | What to look for in the diff |
|---|---|
| Monitoring can't stall a run | Every hand-written check-in has a 5-second timeout. A .NET HttpClient waits 100 seconds by default, and Python Requests never times out unless you pass timeout. |
| Monitoring can't fail the job | Check-in errors are caught and ignored: || true after curl, or a try around only the request. |
| Exceptions still propagate | After reporting fail, the original exception is re-thrown (throw; in C#, bare raise in Python), not swallowed. |
| Exit code unchanged | A shell wrapper captures $? right after the job and exits with it. |
| Retries unchanged | No new [AutomaticRetry(Attempts = 0)], retry counts, or catch-and-return logic. |
| Schedule is five-field UTC | No seconds field, @daily, or 7 for Sunday; local times converted to UTC. A crontab line restricting both day fields is split into two job keys: CronRadar expects both to match, while cron runs on either. |
| No secrets in code | The key is read from CRONRADAR_API_KEY, never written into committed config, test fixtures, or a URL that ends up in logs. |
| No duplicate monitors | No per-job calls on top of framework discovery, no API-created jobs covering a discovery failure, no unexplained [SkipMonitor]. |
The retry row has a Hangfire-specific trap. Hangfire's automatic retry filter applies 10 retry attempts by default, and the published CronRadar.Hangfire 0.1.0 can report a failure before Hangfire finishes retrying, including cancellations (checked September 20, 2026). Reporting only after retries are exhausted requires the pending 0.2.1 release. An agent asked to quiet those early alerts may reach for [AutomaticRetry(Attempts = 0)], which silences them by changing what the job does. Reject that change.
For the obvious secret leaks, scan the lines the agent added. No output is the result you want:
# Added lines that look like a CronRadar key or a hardcoded bearer token.
git diff main...HEAD | grep -E '^\+.*(ck_app_|Bearer [A-Za-z0-9._~+/=-]{20,})'This catches a pasted key, not one split across lines or encoded; a repository secret scanner, if you run one, remains the stronger control. For a shell wrapper that passes every row of the table, see the one in the dead man's switch guide.
Verify a Real Run Yourself#
A created monitor, a successful API call, an installed package, or a demo incident shows that something was configured, not that the deployed scheduler reports. Activation is a real run from the intended deployment.
-
Confirm the key is present in the deployed environment without printing it:
Shelltest -n "$CRONRADAR_API_KEY" && echo "CronRadar key is set" || echo "CronRadar key is missing" -
Deploy or restart the scheduler process. With a framework integration, the recurring jobs appear in the matching application with the scheduler's current cron expressions. For any job on a non-UTC time zone, compare CronRadar's next expected run with the scheduler's next fire time.
-
Let a real scheduled run happen, or trigger one through the scheduler, then open Applications, your application, Jobs. Confirm it's the right environment's application and the run shows a terminal result:
success,failed, ortimeout; astartalone means still in progress. Then confirm the next scheduled run arrives, since a manual trigger doesn't exercise the schedule. -
Send a channel test from the application's Alerts tab and have the intended recipient confirm it arrived. For Slack, invite CronRadar to the public channel before selecting it. A channel test proves delivery, not that a failed job is detected.
-
Exercise failure only in a separate test application, with a harmless job and an agreed test destination. Never fail a production job on purpose, and don't let the agent.
Be wary of an agent that "verifies" by sending a hand-made check-in. That proves only that the network path and key work, and the verification guide warns that doing it with the same key as framework-discovered jobs can hide a discovery or lifecycle wiring problem. An agent with read access can report the check-in timestamps it sees; look at the first one yourself anyway.
When the scheduled job itself calls an LLM or runs an agent, monitoring scheduled AI agent runs covers the failures that still exit 0, such as rate limits, truncated output, and refusals. When the scheduled job is the coding agent itself, with claude -p or codex exec running from cron or CI, scheduled coding agent runs covers its permissions, limits, and exit codes.
Optional: Connect Over MCP#
MCP is not required; the private prompt works over the management REST API. If your client supports remote MCP servers with a configurable bearer header, you can keep the temporary token in its secret configuration instead of the conversation. The CronRadar MCP server guide covers setup in each client and what its tools can and can't do.
| Setting | Value |
|---|---|
| Name | cronradar |
| Transport | Streamable HTTP |
| Server URL | https://api.cronradar.com/api/agent/mcp |
| Authentication | Authorization: Bearer header carrying the temporary token |
There is no OAuth sign-in and no automatic token refresh: when the token expires, create fresh access in the console and update the secret. MCP enforces the same workspace permissions and expiry as REST, and its tools mirror the REST operations, starting with get_context.
In Claude Code, .mcp.json expands environment variables in headers (checked October 24, 2026), so the file holds only a variable name:
{
"mcpServers": {
"cronradar": {
"type": "http",
"url": "https://api.cronradar.com/api/agent/mcp",
"headers": {
"Authorization": "Bearer ${CRONRADAR_AGENT_TOKEN}"
}
}
}
}Set CRONRADAR_AGENT_TOKEN from your password manager when you start the session; in interactive sessions, Claude Code asks for approval before using a server from a project's .mcp.json. Other clients have their own secret mechanisms; use the one their documentation describes rather than writing the token into a config file.
Treat Job Data as Data#
When an agent reads monitoring data, it reads text your jobs and teammates wrote: job names, descriptions, and failure messages. CronRadar's instructions tell the assistant these are application data, not instructions. That matters because a failure message can carry text from elsewhere, such as an exception quoting an upstream API's response. Instructions planted in content an LLM reads from external sources are what OWASP calls indirect prompt injection in LLM01:2025, and two of its listed mitigations apply here: mark untrusted content as such, and restrict the model to the minimum privileges it needs. Give investigation sessions read-only access, and keep failure messages free of payloads, logs, and customer data, as the ingestion API already asks.
Frequently Asked Questions#
Can Claude Code or Cursor set up cron job monitoring for me?#
Yes. Any coding agent that can edit your repository can add a framework integration or HTTP check-ins, and one with an HTTP or code-execution tool can also use temporary workspace access to inspect existing monitors and read back check-ins. You still review the diff and confirm a real run.
Is it safe to give an AI agent an API token for monitoring?#
It's a reasonable risk when the token is scoped and short-lived: one workspace, the least permission the task needs, the shortest expiry that fits, and revoked when you finish. Anyone holding the prompt can use it until then, and the assistant provider may keep the transcript. Never give the agent the long-lived deployment key.
Do I need an MCP server to use CronRadar with an AI agent?#
No. The private setup prompt works over the management REST API with any agent that can make HTTP requests. MCP is an optional alternative for clients that support remote servers with a bearer header.
What should I check after an AI agent adds monitoring?#
Review the diff for missing timeouts, swallowed exceptions, changed exit codes or retries, schedules that aren't five-field UTC, secrets, and duplicate monitors. Then deploy and confirm that a real scheduled run shows a terminal result in the right application and that a channel test reaches the intended recipient.
What happens to changes when the agent's access expires?#
Nothing is undone. Applications and jobs the agent created stay, and ingestion keys it created keep working until their own expiry or revocation, so review them in the application's Setup tab and revoke any the deployment doesn't use.
Put this guide to work
Know when the next run is missing
Connect one scheduled job, confirm a real completion, then verify the alert destination. Keep your existing scheduler in charge of running the work.