API and MCP setup
The same engine behind the web page is exposed as a JSON API and an MCP server. All three surfaces are thin wrappers over one pure function, so they cannot disagree.
MCP server
Streamable HTTP at https://crontoenglish.com/api/mcp. Three read-only tools: explain_cron, next_cron_runs, and build_cron. No authentication required.
Claude Code
claude mcp add --transport http cron-translator https://crontoenglish.com/api/mcpClaude Desktop or Cursor
Add to your MCP settings file:
{
"mcpServers": {
"cron-translator": {
"type": "http",
"url": "https://crontoenglish.com/api/mcp"
}
}
}Verify it works
curl -X POST 'https://crontoenglish.com/api/mcp' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'JSON API
Every endpoint accepts GET with query parameters or POST with a JSON body. CORS is open. Full machine-readable description at /.well-known/openapi.json.
Explain an expression
curl 'https://crontoenglish.com/api/v1/explain?expression=0%209%20*%20*%201-5&timezone=America/New_York'Parameters: expression (required), timezone (IANA name, default UTC), count (1–25 next runs, default 5).
Next run times only
curl 'https://crontoenglish.com/api/v1/next-runs?expression=@daily&timezone=Asia/Tokyo&count=3'Build from English
curl 'https://crontoenglish.com/api/v1/build?phrase=every%20weekday%20at%209am'Rule-based, not a language model. It refuses phrases outside its grammar rather than guessing. Supported shapes:
every minuteevery 5 minutesevery hourevery 6 hoursevery day at 9amevery day at 14:30every monday at 9amevery weekday at 8:15amevery weekend at 10amon the 1st of every month at midnightevery year on January 1 at noon
Markdown instead of HTML
Every page has a markdown representation at the same canonical URL. Send Accept: text/markdown or append ?format=md. Responses set Vary: Accept. Do not parse the HTML.
curl -H 'Accept: text/markdown' 'https://crontoenglish.com/cron/every-weekday-at-9am'Errors
Every failure returns the same shape, with a stable code and a hint describing what to change before retrying.
{
"error": {
"code": "invalid_cron_expression",
"message": "Hour value 25 is out of range (0-23).",
"fix_hint": "Use a value between 0 and 23.",
"field": "hour",
"token": "25",
"docs": "https://crontoenglish.com/docs"
}
}Rate limits and pricing
- Free: 250 calls per UTC day per caller, on every surface. Quotas apply to humans and agents alike.
- Past the quota: HTTP 402 with an x402 v1 payment requirement — $0.001 per call in USDC on base.
- Settlement is not live yet. While that is true the 402 body carries
payment_enabled: false, so do not attempt payment — wait for the reset time given inquota.resetsAt. - Identification: an
X-API-Keyheader if you send one, then a Web Bot AuthSignature-Agentheader, then a salted hash of the client IP. Raw IPs are never stored. - Headers: every response carries
X-RateLimit-Limit,X-RateLimit-Remaining, andX-RateLimit-Reset.
Machine-readable index
- /llms.txt — endpoints, pricing, page index
- /llms-full.txt — complete docs with worked examples, generated from the live engine
- /.well-known/openapi.json — OpenAPI 3.1
- /changelog.md — breaking changes
Source and issues: https://github.com/bwalvoord/gumball