cron-check
Cron Check is an offline, read-only MCP server for explaining, validating, converting, and scheduling cron expressions across six dialects.
explain_cron: explains and checks up to 20 cron expressions in plain English, with detected or specified dialect, errors, gotchas, never-firing schedules, and next 3 UTC runs.next_runs: returns next runs in an IANA time zone (default UTC), local and UTC, after a given moment or now, with daylight-saving gap/repeat flags; count 1–50.convert_cron: rewrites a cron expression between unix, github, kubernetes, aws, quartz, and spring, handling seconds/year fields,?rules, weekday names, and refusing targets that cannot express the schedule.Supports dialects: unix, github, kubernetes, aws, quartz, spring; all tools are read-only, idempotent, open-world false, and require no key.
Supports checking, explaining, converting, and computing next runs for GitHub Actions cron schedules, including its UTC-only behavior and 5-minute minimum interval rule.
Supports checking, explaining, converting, and computing next runs for Kubernetes CronJob cron expressions, including macros and its handling of ? as *.
Supports checking, explaining, converting, and computing next runs for Spring cron expressions, including seconds-first syntax and Sunday numbering as 0 or 7.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@cron-check What does '0 0 13 * 5' mean, and when are its next 3 runs in UTC?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Cron Check
Cron is where agents make confident mistakes: 0 0 13 * 5 runs every Friday and every 13th, not
only on Friday the 13th; */7 in the minute field leaves a 4-minute gap at the top of each hour;
Quartz and AWS count Sunday as 1 where Unix cron counts it as 0; GitHub Actions never runs a schedule
more often than every 5 minutes. Cron Check answers with the rules of the scheduler in question:
Explain and check up to 20 expressions: plain English, the dialect (detected or given), errors with the field that is wrong, the gotchas above, schedules that never fire (February 30), and the next runs.
Next runs in any time zone, local and UTC, with runs that fall into a daylight-saving gap or repeat flagged, because schedulers treat them differently.
Convert between Unix cron, GitHub Actions, Kubernetes, AWS EventBridge, Quartz and Spring: seconds and year fields, the
?rule, weekdays written as names so the numbering cannot bite. What a target cannot express (Unix's day-of-month OR day-of-week in AWS) is refused with the fix.
Runs offline. No key needed.
Built and maintained by Arhan Canli.
Install
Needs Node.js 20 or newer. No account or key.
Claude Code
claude mcp add cron-check -- npx -y cron-check-mcpClaude Desktop: download cron-check-mcp-<version>.mcpb from the latest release and open it. The bundle is signed; verify it with gh attestation verify <file> --repo arhancanli/cron-check-mcp.
Any other client (Windsurf, Zed, Cline, Continue and others), in its MCP config file:
{
"mcpServers": {
"cron-check": {
"command": "npx",
"args": [
"-y",
"cron-check-mcp"
]
}
}
}Docker
docker build -t cron-check-mcp https://github.com/arhancanli/cron-check-mcp.git && docker run -i --rm cron-check-mcpHosted (Streamable HTTP): node src/server.mjs --http serves stateless MCP at POST /mcp (port from PORT, default 3000).
Related MCP server: cron-mcp
Example
An agent calls explain_cron with:
{
"expressions": [
"0 9 * * 1-5",
"*/7 * * * *",
"0 0 1 * 1",
"0 0 30 2 *",
"cron(0 12 ? * MON-FRI *)",
"0 0/5 14 * * ?",
"0 10 ? * 6#3",
"@daily",
"61 * * * *",
"0 0 L * *"
]
}and gets back (recorded from the live server on 2026-09-26):
{
"results": [
{
"expression": "0 9 * * 1-5",
"valid": true,
"dialect": "unix",
"description": "At 09:00, Monday through Friday",
"next_utc": [
"2026-09-28T09:00:00Z",
"2026-09-29T09:00:00Z",
"2026-09-30T09:00:00Z"
]
},
{
"expression": "*/7 * * * *",
"valid": true,
"dialect": "unix",
"description": "Every 7 minutes",
"next_utc": [
"2026-09-26T17:14:00Z",
"2026-09-26T17:21:00Z",
"2026-09-26T17:28:00Z"
],
"warnings": [
"*/7 in the minute field restarts at 0 each hour, so the last gap is shorter than 7."
]
},
{
"expression": "0 0 1 * 1",
"valid": true,
"dialect": "unix",
"description": "At 00:00, on day 1 of the month, and on Monday",
"next_utc": [
"2026-09-28T00:00:00Z",
"2026-10-01T00:00:00Z",
"2026-10-05T00:00:00Z"
],
"warnings": [
"Both day fields are restricted, so it runs on days matching either one (day-of-month OR day-of-week), not only days matching both."
]
},
{
"expression": "0 0 30 2 *",
"valid": false,
"dialect": "unix",
"description": "At 00:00, on day 30 of the month, only in February",
"error": "It never fires: no date in the next six years matches (for example February 30)."
},
{
"expression": "cron(0 12 ? * MON-FRI *)",
"valid": true,
"dialect": "aws",
"description": "At 12:00, Monday through Friday",
"next_utc": [
"2026-09-28T12:00:00Z",
"2026-09-29T12:00:00Z",
"2026-09-30T12:00:00Z"
],
"warnings": [
"EventBridge cron runs in UTC unless the schedule sets a time zone (EventBridge Scheduler)."
... (44 more lines)Tools
Tool | What it does |
| Rewrites a cron expression for another scheduler (unix, github, kubernetes, aws, quartz, spring): seconds and year fields, ? rules, weekday numbering (written as names). Says why when the target cannot express it. |
| Explains up to 20 cron expressions in plain English and checks them: valid or why not, the dialect, gotchas (day-of-month OR day-of-week, uneven steps, GitHub's 5-minute floor), schedules that never fire, and the next 3 runs in UTC. |
| The next runs of a cron expression in an IANA time zone (default UTC), as local time with weekday and UTC, after a given moment or now. Runs that land in a daylight-saving gap or repeat are flagged, as schedulers differ there. |
How it behaves
Offline and read-only: no network call at all (
factory.allowHostsis empty). Descriptions come from cronstrue (MIT); parsing, matching and next runs from this server's own engine, time zones from Node's ICU database.Dialects:
unix(Vixie cron: two restricted day fields match either one),github(UTC, 5-minute floor),kubernetes(macros,?read as*),aws(EventBridge: six fields with a year, Sunday is 1,?required in one day field),quartz(seconds first, optional year, Sunday is 1),spring(seconds first, Sunday is 0 or 7).L,Wand#are understood where the dialect has them.Results are compact JSON with a matching output schema.
Benchmark
Measured 2026-09-26 with gpt-5.4-mini, 10 fixed tasks graded by fixed checks (bench/tasks.json, raw results in bench/results/).
Server | Correct | Input tokens | Output tokens | Tool calls | Median time |
This server | 10/10 | 13063 | 485 | 10 | 2.0 s |
@pipeworx/mcp-crontab, a published cron MCP server | 6/10 | 9967 | 444 | 11 | 1.9 s |
Performance
Measured 2026-09-26 from Dubai, home connection against the live upstream, Node 24.19.0 (bench/perf.json, scripts/perf.mjs in the factory).
Call | First call | Repeat | Result size |
explain_cron: 10 expressions across dialects | 13 ms | 4 ms | 2,248 chars |
next_runs: 02:30 daily in New York across the spring-forward change | 8 ms | 0.4 ms | 452 chars |
convert_cron: weekdays at 09:00 to AWS EventBridge | 4 ms | 0.4 ms | 187 chars |
First call: a fresh server process, including the TLS connection and the upstream's own time. Repeat: the same call again, answered from the in-process cache, so it shows this server's own overhead.
Tool definitions the model reads on every turn (name, description, input schema): 1,872 characters, against 834 for @pipeworx/mcp-crontab, a published cron MCP server. The full tool list, with the output schemas and annotations clients use to validate results, is 3,017 characters (832 for the alternative).
More MCP servers by Arhan Canli
Actions Check: Checks GitHub Actions workflows: outdated actions, old Node runtimes, retired runners, injection.
Config Check: Validates config files against their official schemas: tsconfig, compose, workflows, 1,400+ more.
Dockerfile Check: Checks Dockerfiles: build-breaking mistakes, base image tags that exist, digests, platforms, EOL.
Domain Health: Email and domain checks: SPF lookup limits, DKIM keys, DMARC, DNS records, registration expiry.
End of Life: Is this version still supported? EOL dates, latest patch and upgrade target for 470+ products.
Internet Standards: RFC sections, status, obsoleted-by chains, errata and IANA registries for coding agents.
Kube Check: Checks Kubernetes manifests for your version: removed APIs, unknown fields, Pod Security, risks.
License Check: Open source license answers: SPDX ids, copyleft, and whether a dependency's license fits yours.
The whole collection, 12 more
License
MIT, Copyright (c) 2026 Arhan Canli.
Available Tools
3 toolsconvert_cronConvert cron between schedulersARead-onlyIdempotent
Rewrites a cron expression for another scheduler (unix, github, kubernetes, aws, quartz, spring): seconds and year fields, ? rules, weekday numbering (written as names). Says why when the target cannot express it.
Inputs: to (required), expression (required), from. Returns: to, expression
explain_cronExplain and check cron expressionsARead-onlyIdempotent
Explains up to 20 cron expressions in plain English and checks them: valid or why not, the dialect, gotchas (day-of-month OR day-of-week, uneven steps, GitHub's 5-minute floor), schedules that never fire, and the next 3 runs in UTC.
Inputs: expressions (required), dialect. Returns: results
next_runsWhen a cron expression firesARead-onlyIdempotent
The next runs of a cron expression in an IANA time zone (default UTC), as local time with weekday and UTC, after a given moment or now. Runs that land in a daylight-saving gap or repeat are flagged, as schedulers differ there.
Inputs: expression (required), from, count, dialect, +1 more. Returns: runs, timezone, expression
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 3 tools
Each tool serves a distinct purpose: conversion between schedulers, explanation/validation, and computing future runs. There is no overlap in functionality, and an agent can easily select the appropriate tool based on the task.
All tools follow a consistent verb_noun pattern (convert_cron, explain_cron, next_runs). The naming is clear and predictable, with 'cron' as the subject and a specific action verb prefix.
With exactly 3 tools, the server is tightly scoped to core cron operations: conversion, explanation, and scheduling. Each tool is essential and there is no bloat or unnecessary redundancy.
The tool set covers the full lifecycle of working with cron expressions: understanding (explain), adapting (convert), and planning (next_runs). No obvious missing operations exist for the server's stated purpose.
Maintenance
Related MCP Connectors
Validate and explain cron expressions; list next/previous run times in any time zone, DST-aware.
Explain cron expressions in English, list next run times, and catch scheduling gotchas.
Cron expression parser: explains any cron + returns next N fire times. Timezone-aware.
Validates cron expressions and finds DST bugs that make jobs silently skip or double-fire.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables exploration, explanation, and management of crontab entries, including translating cron expressions into plain English and calculating upcoming execution times.84MIT
- AlicenseAqualityCmaintenanceEnables AI agents to parse, validate, explain, and preview cron expressions, surfacing common silent bugs before deployment.463 npmMIT
- AlicenseNot gradedqualityCmaintenanceProvides tools to parse and describe cron expressions in plain English, and compute future run times.116 npmMIT
- AlicenseNot gradedqualityCmaintenanceParse, validate, and explain cron expressions with pay-per-call via x402 (USDC on Base L2), returning next run times in any timezone.1MIT