Skip to main content
Glama
MrProLopstar

cronsense-mcp

by MrProLopstar

cronsense

English · Русский

JSR JSR Score CI License: MIT

Turn plain Russian or English schedules into cron expressions, and cron back into plain text.

▶ Try it in the playground

по будням в 9:30                          →  30 9 * * 1-5
каждые 15 минут с 9 до 18 по будням       →  */15 9-17 * * 1-5
1 и 15 числа в 12:00                      →  0 12 1,15 * *
every other day at noon                   →  0 12 */2 * *
mon, wed and fri at 6pm                   →  0 18 * * 1,3,5

0 23 * * 0,1,5,6    →  с пятницы по понедельник в 23:00  /  from friday through monday at 11pm
  • Both directions: toCron for text → cron, describe for cron → text

  • Round-trip guarantee: every description parses back to an equivalent schedule, checked on thousands of random expressions

  • Real Russian: word forms, «в 3 часа дня», «со вторника по четверг», «каждую 21 минуту»

  • No LLM, no dependencies, fully deterministic, runs in Node, Deno, Bun and browsers

  • Refuses to guess: anything cron cannot express exactly is an error with a code and the position of the problem

  • Ready for AI agents: a built-in MCP server, because LLMs often get cron wrong

Install

npx jsr add @mrprolopstar/cronsense

From GitHub Packages (needs a .npmrc line @mrprolopstar:registry=https://npm.pkg.github.com and a GitHub token with read:packages):

npm install @mrprolopstar/cronsense

Or straight from GitHub:

npm install github:MrProLopstar/cronsense

Related MCP server: cron-mcp

Usage

import { describe, nextRuns, parse, safeParse, toCron } from '@mrprolopstar/cronsense';

toCron('каждый день в 9 утра');
// '0 9 * * *'

const schedule = parse('every 2 hours from 8:00 to 20:00');
schedule.cron;
// '0 8-20/2 * * *'
schedule.fields.hour;
// { kind: 'step', from: 8, to: 20, step: 2 }

describe('*/15 9-17 * * 1-5', { locale: 'ru' });
// 'каждые 15 минут с 9 до 18 по будням'
describe('0 12 1,15 * *');
// 'on the 1st and 15th at noon'

nextRuns(schedule, { count: 3, timezone: 'utc' });
// [Date, Date, Date]

const result = safeParse('по будням кроме пятницы');
if (!result.ok) {
  result.error.code;    // 'UNSUPPORTED'
  result.error.span;    // { start: 10, end: 15 }
  result.error.excerpt; // input with a ^^^^^ marker under the problem
}

CLI

npx cronsense "по будням в 9:30"
npx cronsense -n 5 "every 15 minutes between 9 and 17"
npx cronsense --cron -n 3 --utc "0 9 * * 1-5"
npx cronsense --json "1 числа каждого месяца"
npx cronsense --cron --explain --locale ru "0 9 * * 1,3,5"

With your scheduler

cronsense only produces cron strings, so it works with any scheduler:

import cron from 'node-cron';
import { toCron } from '@mrprolopstar/cronsense';

cron.schedule(toCron('по будням в 9:30'), sendDailyReport);
import { Queue } from 'bullmq';
import { toCron } from '@mrprolopstar/cronsense';

await new Queue('reports').add('weekly', {}, { repeat: { pattern: toCron('every monday at 8am') } });

For user-facing apps such as Telegram bots, parse what the user typed and echo back the canonical wording to confirm:

const result = safeParse(message.text);
reply(result.ok ? `Буду напоминать ${describe(result.schedule, { locale: 'ru' })}` : result.error.excerpt);

MCP server for AI agents

LLMs regularly produce subtly wrong cron. cronsense-mcp gives agents deterministic tools instead:

Tool

What it does

to_cron

Schedule text → cron plus canonical description

describe_cron

Cron → natural Russian or English

next_runs

Upcoming run times as ISO 8601

Claude Code:

claude mcp add cronsense -- npx -y -p github:MrProLopstar/cronsense cronsense-mcp

Claude Desktop, Cursor and other clients (mcpServers config):

{
  "mcpServers": {
    "cronsense": {
      "command": "npx",
      "args": ["-y", "-p", "github:MrProLopstar/cronsense", "cronsense-mcp"]
    }
  }
}

The server has no dependencies and speaks MCP over stdio (protocol versions 2024-11-05 to 2025-06-18).

API

Function

Description

parse(text, options?)

Returns Schedule, throws CronsenseError

safeParse(text, options?)

Returns { ok: true, schedule } or { ok: false, error }

toCron(text, options?)

Returns the cron string

parseCron(expression)

Parses a 5-field cron expression or macro (@daily, …) into a Schedule

nextRuns(schedule | expression, options?)

Next run times; options: count (default 5), from, timezone ('local' or 'utc')

describe(schedule | expression, options?)

Natural-language description; locale: 'en' (default) or 'ru'

formatCron(fields)

Formats structured fields back into a cron string

ParseOptions.weeklyOn sets the weekday used by "weekly" / «еженедельно» (default 0, Sunday, as in @weekly).

Error codes

Code

Meaning

EMPTY_INPUT

Nothing to parse

UNKNOWN_WORD

A word is not in the vocabulary

UNEXPECTED_TOKEN / UNEXPECTED_END

Words are in an order the grammar does not accept

OUT_OF_RANGE

Hour 25, 30 February, every 90 minutes, …

AMBIGUOUS

A bare number could be a time or a day: add «в»/"at" or «числа»/"th"

CONFLICT

Parts contradict each other or cron would treat them with OR semantics

INCOMPLETE

«с 9 до 18» without an interval, "every" without a unit

UNSUPPORTED

Last day of month, seconds, exclusions, every 2 weeks, …

INVALID_CRON

parseCron received a malformed expression

What it understands

  • Intervals: every N minutes / hours / days / months, «через день», "every other hour", «раз в 5 минут», "once a day"

  • Frequencies: hourly, daily, weekly, monthly, yearly / «ежечасно», «ежедневно», …

  • Minutes of the hour: «каждый час в 15 минут», "every hour at 15 minutes past"

  • Times: 9:30, 9.30, 9am, 7 p.m., noon / midnight, «в 3 часа дня», «в 11 ночи», «9 часов 45 минут», several times at once

  • Time ranges for intervals: «с 9 до 18», "between 9 and 17", «до 12», overnight windows like «с 22 до 6»

  • Weekdays: names, abbreviations, ranges (пн-пт, "monday through friday"), weekdays / weekends

  • Days of month: «1 и 15 числа», «с 1 по 10 число», "on the 1st and 15th", «15 января», "jan 15"

  • Months: names, lists, ranges, including ranges across the new year («с ноября по февраль»)

Describing cron

describe picks the most natural wording: intervals, time ranges, weekday and month ranges, «15 января», noon and midnight. Every description it produces is accepted by parse and yields an equivalent schedule; this is checked on thousands of random expressions in both languages. The only exception is a cron that restricts both day-of-month and weekday: cron joins them with OR, so the text says «или» / "or" and is intentionally not parseable.

30 9 * * 1-5       по будням в 9:30                            on weekdays at 9:30am
0 23 * * 0,1,5,6   с пятницы по понедельник в 23:00            from friday through monday at 11pm
0 8-20/2 * * *     каждые 2 часа с 8 до 20                     every 2 hours from 8am to 8pm
5-59/10 * * * *    каждый час в 5, 15, 25, 35, 45 и 55 минут   every hour at 5, 15, 25, 35, 45 and 55 minutes past

Semantics worth knowing

  • «с 9 до 18» with a minute interval ends before 18:00 (9-17); with an hour interval, 18:00 is included (9-18).

  • Cron ORs day-of-month and day-of-week, so «по понедельникам 1 числа» is rejected instead of silently meaning "every Monday or the 1st".

  • Several times must form a grid (the same minutes for every hour): 9:00, 9:30, 18:00, 18:30 works, while 9:00 and 18:30 needs two schedules.

  • nextRuns supports local time and UTC and skips times that fall into a DST gap.

Versioning

cronsense follows semver. The public API (parse, safeParse, toCron, describe, parseCron, nextRuns, formatCron, exported types and error codes) only changes in a major release. New vocabulary and new locales can make previously rejected phrases parse; that is not a breaking change. See CHANGELOG.md.

To release, run Actions → Release → Run workflow and pick patch, minor, major or an exact version.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables exploration, explanation, and management of crontab entries, including translating cron expressions into plain English and calculating upcoming execution times.
    8
    4
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides date, time, and timezone tools for AI agents via MCP, including timezone conversion, date calculation, cron parsing, timestamp conversion, and duration formatting.
    22 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Parses cron expressions, returns next fire times, and provides an English description.
    MIT