JMoak-chrono-mcp
Convert and compare dates and times across any timezone with flexible, locale-aware formatting. Ad…
Install
mcp_config.json
{
"mcpServers": {
"ai-smithery-jmoak-chrono-mcp": {
"url": "https://server.smithery.ai/@JMoak/chrono-mcp/mcp",
"type": "streamable-http"
}
}
}Documentation
chrono-mcp
The MCP server for time math at scale. Batch-crunch up to 100,000 timestamps in a single tool call, speak the industry's temporal interchange standards (RFC 9557 IXDTF, RFC 5545 RRULE, ISO 8601 repeating intervals), and give your agent a passive sense of passing time on every response. Powered by Luxon, DST-correct by construction, and every limit is benchmark-backed.
Quick Start
npx @jmoak/chrono-mcp
Run as local HTTP server
npm install
npm run build
npm run start:http
# Server listens on http://localhost:8000/mcp (health check at /health)
MCP Client Configuration
Configure your MCP client to launch chrono-mcp via npx. Below are client-specific examples.
Claude Code
Ask Claude! Here's the configuration:
{
"mcpServers": {
"chrono-mcp": {
"command": "npx",
"args": ["-y", "@jmoak/chrono-mcp@latest"]
}
}
}
Cursor
Reference: Cursor MCP docs
{
"mcpServers": {
"chrono-mcp": {
"command": "npx",
"args": ["-y", "@jmoak/chrono-mcp@latest"]
},
"chrono-mcp-http": {
"type": "http",
"url": "http://localhost:8000/mcp"
}
}
}
Why chrono-mcp
LLMs are famously bad at time: they miscount weekdays, lose track of elapsed time between turns, and fall apart on DST math. chrono-mcp fixes all three — and does it at bulk scale, in the formats the rest of the industry already speaks.
- Bulk by design - 10,000 calculations per request for per-item operations; 100,000 timestamps for
stats, which returns pure aggregates. Every cap is proven by a benchmark you can run yourself (npm run bench) — per-item ops finish in under 100ms at the cap, 100k-item stats in ~460ms - RFC 9557 (IXDTF) Interchange - All datetime inputs accept bracketed IANA zone annotations (
2026-08-09T15:00:00-04:00[America/New_York]) with Temporal-compatible offset-consistency validation, plus anixdtfoutput format — the serialization standard of the JS Temporal API - Recurrence Expansion -
expandturns RFC 5545 RRULEs (the format Google Calendar, Outlook, and Apple Calendar store) and ISO 8601 repeating intervals into concrete occurrences — DST-correct, window-bounded, with explicit truncation reporting - Temporal Context Envelope - Every tool response carries a compact trailing line with the current time, weekday, elapsed time since the agent's previous call, session age, and tzdb version — passive time-awareness on every interaction
- Batch Error Isolation - One bad timestamp doesn't sink a 10,000-item batch: invalid entries are skipped and reported (
invalid_count+ samples), never silently dropped - Token-Optimized Output - Dynamically shaped responses that maximize information density while minimizing token usage
- Global Timezone Support - All IANA timezone identifiers, with ISO, RFC2822, SQL, and locale-aware formatting
- Type Safety - Zod validation on every parameter, MCP-compliant errors, strict TypeScript throughout
Documentation
- API Reference - Complete documentation of all tools, parameters, and examples
- Architecture - System architecture and design principles
- Examples - Practical usage examples and patterns
Available Tools
GET TIME
Get current time or convert times across timezones with flexible formatting.
Parameters:
datetime(string, optional): ISO datetime string. Defaults to current timetimezones(array, optional): List of timezone names for conversionsformats(array, optional): Output formats (iso,rfc2822,sql,local,localeString,short,medium,long,full)locale(string, optional): Locale for formatting (e.g.,en-US,fr-FR,ja-JP)includeOffsets(boolean, optional): Include UTC offsets in output
Example:
Input
{
"datetime": "2024-01-01T12:00:00Z",
"timezones": ["America/New_York", "Asia/Tokyo"],
"includeOffsets": true
}
Output
{
"baseTime": "2024-01-01T12:00:00.000Z",
"America/New_York": "2024-01-01T07:00:00.000-05:00",
"Asia/Tokyo": "2024-01-01T21:00:00.000+09:00"
}
TIME CALCULATOR
Perform time arithmetic at any scale — single conversions to 100k-item batch analysis.
Operations:
add- Add duration to a datetimesubtract- Subtract duration from a datetimediff- Calculate simple difference in various unitsduration_between- Detailed duration breakdown between two timesstats- Statistical analysis of time series and durations (up to 100,000 timestamps per call)sort- Sort timestamps chronologicallyexpand- Expand an RFC 5545 RRULE or ISO 8601 repeating interval into occurrences
Every operation accepts arrays as well as single values, with interaction_mode controlling how base and compare arrays combine (pairwise, cross_product, single_to_many, …). Invalid entries in a batch are skipped and reported — never silently dropped, never fatal.
Expand example:
Input
{
"operation": "expand",
"recurrence": "FREQ=WEEKLY;BYDAY=TU;COUNT=4",
"base_time": "2026-02-24T09:00:00[America/New_York]",
"occurrence_format": "ixdtf"
}
Output (result excerpt — note the wall-clock time held across the DST transition)
{
"rule_type": "rrule",
"count": 4,
"truncated": false,
"occurrences": [
"2026-02-24T09:00:00.000-05:00[America/New_York]",
"2026-03-03T09:00:00.000-05:00[America/New_York]",
"2026-03-10T09:00:00.000-04:00[America/New_York]",
"2026-03-17T09:00:00.000-04:00[America/New_York]"
]
}
Also accepts ISO 8601 repeating intervals (R5/2026-03-01T14:00:00Z/P1D), window_start/window_end bounds, and max_occurrences caps (default 100, max 10,000) with explicit truncated reporting.
Bulk stats example — hand it your entire event log; the response stays tiny no matter how many timestamps go in (up to 100,000):
{
"operation": "stats",
"base_time": ["2026-01-01T00:00:00Z", "...99,998 more...", "2026-01-02T03:46:39Z"]
}
Output (aggregates only — real excerpt from a 100,000-timestamp call that ran in ~500ms)
{
"input_analysis": { "base_time_count": 100000 },
"timestamp_analysis": {
"earliest": "2026-01-01T00:00:00.000Z",
"latest": "2026-01-02T03:46:39.000Z",
"total_span_human": "1 day, 3 hours, 46 minutes, 39 seconds",
"std_deviation_ms": 28867513
},
"interval_analysis": {
"interval_count": 99999,
"mean_interval_human": "1 second"
}
}
Parameters:
operation(required): Type of calculationinteraction_mode(optional):auto_detect|single_to_many|many_to_single|pairwise|cross_product|aggregate. Defaults toauto_detect.base_time(optional): Base ISO datetime(s). String or array. Defaults to current time.compare_time(optional): Compare ISO datetime(s) fordiff/duration_between. String or array.timezone(optional): Timezone forbase_timecompare_time_timezone(optional): Timezone forcompare_timeyears,months,days,hours,minutes,seconds(optional): Duration values
Example:
Input
{
"operation": "add",
"base_time": "2024-12-25T10:00:00Z",
"days": 5,
"hours": 3
}
Output
{
"operation": "add",
"interaction_mode": "single_to_single",
"input": {
"base_time": "2024-12-25T10:00:00.000Z",
"duration": { "days": 5, "hours": 3 }
},
"result": "2024-12-30T13:00:00.000Z",
"result_timezone": "UTC"
}
Temporal Context Envelope
Every tool response includes a second content block — a single ~20-token line giving the calling agent passive time-awareness:
⏱ now 2026-08-09T15:02:11.123-04:00 (Sun) · first call this session
⏱ now 2026-08-09T15:49:03.456-04:00 (Sun) · +46m52s since last call · session 47m1s · call #2
LLMs have no innate sense of elapsed time between turns; the envelope makes time passage visible on every interaction with the server — including the weekday, which models frequently miscompute. Disable it by setting CHRONO_ENVELOPE=off in the server environment.
Development
Prerequisites
- Node.js >= 22.0.0
- npm or yarn
Setup
git clone https://github.com/yourusername/chrono-mcp.git
cd chrono-mcp
npm install
Build
npm run build
Testing & Inspector
npm test
npm run test:ui
npm run test:mcp
npm run inspector
npm run bench
npm test— Vitest unit tests for tool handlersnpm run bench— Vitest benchmarks proving every batch operation at theMAX_OPERATIONScap (10,000 items) completes in well under 100msnpm run test:mcp— Vibrissa (npm:@jmoak/vibrissa) MCP protocol cases (requiresnpm run buildfirst; no Python)- Protocol contracts live in
tests/contracts/*.tddand emit totests/integration/vibrissa/cases/via tdd-dsl locally (npm run contracts:emitiftdd-dslis on your PATH). CI runs only the committed JSON withvib run.
Visit http://localhost:6274 for the web inspector UI.
Linting
npm run lint
npm run lint:fix
Supported Timezones
Supports all IANA timezone identifiers including:
- Americas:
America/New_York,America/Los_Angeles,America/Toronto, etc. - Europe:
Europe/London,Europe/Paris,Europe/Berlin, etc. - Asia:
Asia/Tokyo,Asia/Shanghai,Asia/Dubai, etc. - Australia:
Australia/Sydney,Australia/Melbourne, etc. - And 400+ more...
Acknowledgments
This project is powered by Luxon, the excellent DateTime library that provides robust timezone handling and date arithmetic. We're grateful to the Luxon team for creating such a reliable foundation for temporal operations.
License
MIT License - see the LICENSE file for details.
Releases
See GitHub Releases for detailed changes.
Sourced from the repository README.
More in AI & Agents
- PonytailMakes your AI agent think like the laziest senior dev in the room. The best code is the code you never wrote.109,599
- AgentsMulti-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity39,079
- Frontend SlidesCreate beautiful slides on the web using a coding agent's frontend skills28,060
- Agent Skills Search ServerSearch and discover Agent Skills from the skills.sh registry. Powered by HAPI MCP server.24,658
- Agency Agents Zh🎭 267 个即插即用的 AI 专家角色 — 支持 Hermes Agent/Claude Code/Cursor/Copilot 等 18 种工具,覆盖工程/设计/营销/金融等 20 个部门。含 52 个中国市场原创智能体(小红书/抖音/微信/飞书/钉钉等)。搭配编排器 agency-orchestrator,一句话即可让多位专家按 DAG 自动协作。19,868
- Watermarks RemoverStrip multi-vendor AI provenance marks: Unicode text hygiene, statistical rewrite hooks, and C2PA/metadata from PNG/JPEG/SVG/PDF/DOCX/HTML/MD17,822