{
  "markdown": "# chrono-mcp\n\n**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.\n\n[![NPM Version](https://img.shields.io/npm/v/@jmoak/chrono-mcp)](https://www.npmjs.com/package/@jmoak/chrono-mcp)\n[![Downloads](https://img.shields.io/npm/dm/@jmoak/chrono-mcp)](https://www.npmjs.com/package/@jmoak/chrono-mcp)\n[![Node Version](https://img.shields.io/node/v/@jmoak/chrono-mcp)](https://nodejs.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue)](https://www.typescriptlang.org/)\n[![Code Style: Biome](https://img.shields.io/badge/Code%20Style-Biome-60a5fa)](https://biomejs.dev/)\n[![Tests: Vitest](https://img.shields.io/badge/Tests-Vitest-6E9F18)](https://vitest.dev/)\n[![MCP Server](https://img.shields.io/badge/MCP-Server-0b7285)](https://modelcontextprotocol.io/)\n[![Powered by Luxon](https://img.shields.io/badge/Powered%20by-Luxon-0a3d62)](https://github.com/moment/luxon)\n[![smithery badge](https://smithery.ai/badge/@JMoak/chrono-mcp)](https://smithery.ai/server/@JMoak/chrono-mcp)\n\n## Quick Start\n\n```bash\nnpx @jmoak/chrono-mcp\n```\n\n### Run as local HTTP server\n\n```bash\nnpm install\nnpm run build\nnpm run start:http\n# Server listens on http://localhost:8000/mcp (health check at /health)\n```\n## MCP Client Configuration\n\nConfigure your MCP client to launch `chrono-mcp` via `npx`. Below are client-specific examples.\n\n### Claude Code\n\nAsk Claude! Here's the configuration:\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"chrono-mcp\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@jmoak/chrono-mcp@latest\"]\n    }\n  }\n}\n```\n\n### Cursor\n\nReference: [Cursor MCP docs](https://docs.cursor.com/context/model-context-protocol#configuring-mcp-servers)\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"chrono-mcp\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@jmoak/chrono-mcp@latest\"]\n    },\n    \"chrono-mcp-http\": {\n      \"type\": \"http\",\n      \"url\": \"http://localhost:8000/mcp\"\n    }\n  }\n}\n```\n\n\n## Why chrono-mcp\n\nLLMs 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.\n\n- **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\n- **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 an `ixdtf` output format — the serialization standard of the JS Temporal API\n- **Recurrence Expansion** - `expand` turns 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\n- **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\n- **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\n- **Token-Optimized Output** - Dynamically shaped responses that maximize information density while minimizing token usage\n- **Global Timezone Support** - All IANA timezone identifiers, with ISO, RFC2822, SQL, and locale-aware formatting\n- **Type Safety** - Zod validation on every parameter, MCP-compliant errors, strict TypeScript throughout\n\n## Documentation\n\n- **[API Reference](./API.md)** - Complete documentation of all tools, parameters, and examples\n- **[Architecture](./ARCHITECTURE.md)** - System architecture and design principles\n- **[Examples](./examples/)** - Practical usage examples and patterns\n\n## Available Tools\n\n### GET TIME\n\nGet current time or convert times across timezones with flexible formatting.\n\n**Parameters:**\n- `datetime` (string, optional): ISO datetime string. Defaults to current time\n- `timezones` (array, optional): List of timezone names for conversions\n- `formats` (array, optional): Output formats (`iso`, `rfc2822`, `sql`, `local`, `localeString`, `short`, `medium`, `long`, `full`)\n- `locale` (string, optional): Locale for formatting (e.g., `en-US`, `fr-FR`, `ja-JP`)\n- `includeOffsets` (boolean, optional): Include UTC offsets in output\n\n**Example:**\n\nInput\n```json\n{\n  \"datetime\": \"2024-01-01T12:00:00Z\",\n  \"timezones\": [\"America/New_York\", \"Asia/Tokyo\"],\n  \"includeOffsets\": true\n}\n```\n\nOutput\n```json\n{\n  \"baseTime\": \"2024-01-01T12:00:00.000Z\",\n  \"America/New_York\": \"2024-01-01T07:00:00.000-05:00\",\n  \"Asia/Tokyo\": \"2024-01-01T21:00:00.000+09:00\"\n}\n```\n\n### TIME CALCULATOR\n\nPerform time arithmetic at any scale — single conversions to 100k-item batch analysis.\n\n**Operations:**\n- `add` - Add duration to a datetime\n- `subtract` - Subtract duration from a datetime\n- `diff` - Calculate simple difference in various units\n- `duration_between` - Detailed duration breakdown between two times\n- `stats` - Statistical analysis of time series and durations (up to **100,000** timestamps per call)\n- `sort` - Sort timestamps chronologically\n- `expand` - Expand an RFC 5545 RRULE or ISO 8601 repeating interval into occurrences\n\nEvery 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.\n\n**Expand example:**\n\nInput\n```json\n{\n  \"operation\": \"expand\",\n  \"recurrence\": \"FREQ=WEEKLY;BYDAY=TU;COUNT=4\",\n  \"base_time\": \"2026-02-24T09:00:00[America/New_York]\",\n  \"occurrence_format\": \"ixdtf\"\n}\n```\n\nOutput (result excerpt — note the wall-clock time held across the DST transition)\n```json\n{\n  \"rule_type\": \"rrule\",\n  \"count\": 4,\n  \"truncated\": false,\n  \"occurrences\": [\n    \"2026-02-24T09:00:00.000-05:00[America/New_York]\",\n    \"2026-03-03T09:00:00.000-05:00[America/New_York]\",\n    \"2026-03-10T09:00:00.000-04:00[America/New_York]\",\n    \"2026-03-17T09:00:00.000-04:00[America/New_York]\"\n  ]\n}\n```\n\nAlso 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.\n\n**Bulk stats example** — hand it your entire event log; the response stays tiny no matter how many timestamps go in (up to 100,000):\n\n```json\n{\n  \"operation\": \"stats\",\n  \"base_time\": [\"2026-01-01T00:00:00Z\", \"...99,998 more...\", \"2026-01-02T03:46:39Z\"]\n}\n```\n\nOutput (aggregates only — real excerpt from a 100,000-timestamp call that ran in ~500ms)\n```json\n{\n  \"input_analysis\": { \"base_time_count\": 100000 },\n  \"timestamp_analysis\": {\n    \"earliest\": \"2026-01-01T00:00:00.000Z\",\n    \"latest\": \"2026-01-02T03:46:39.000Z\",\n    \"total_span_human\": \"1 day, 3 hours, 46 minutes, 39 seconds\",\n    \"std_deviation_ms\": 28867513\n  },\n  \"interval_analysis\": {\n    \"interval_count\": 99999,\n    \"mean_interval_human\": \"1 second\"\n  }\n}\n```\n\n**Parameters:**\n- `operation` (required): Type of calculation\n- `interaction_mode` (optional): `auto_detect` | `single_to_many` | `many_to_single` | `pairwise` | `cross_product` | `aggregate`. Defaults to `auto_detect`.\n- `base_time` (optional): Base ISO datetime(s). String or array. Defaults to current time.\n- `compare_time` (optional): Compare ISO datetime(s) for `diff`/`duration_between`. String or array.\n- `timezone` (optional): Timezone for `base_time`\n- `compare_time_timezone` (optional): Timezone for `compare_time`\n- `years`, `months`, `days`, `hours`, `minutes`, `seconds` (optional): Duration values\n\n**Example:**\n\nInput\n```json\n{\n  \"operation\": \"add\",\n  \"base_time\": \"2024-12-25T10:00:00Z\",\n  \"days\": 5,\n  \"hours\": 3\n}\n```\n\nOutput\n```json\n{\n  \"operation\": \"add\",\n  \"interaction_mode\": \"single_to_single\",\n  \"input\": {\n    \"base_time\": \"2024-12-25T10:00:00.000Z\",\n    \"duration\": { \"days\": 5, \"hours\": 3 }\n  },\n  \"result\": \"2024-12-30T13:00:00.000Z\",\n  \"result_timezone\": \"UTC\"\n}\n```\n\n### Temporal Context Envelope\n\nEvery tool response includes a second content block — a single ~20-token line giving the calling agent passive time-awareness:\n\n```text\n⏱ now 2026-08-09T15:02:11.123-04:00 (Sun) · first call this session\n⏱ now 2026-08-09T15:49:03.456-04:00 (Sun) · +46m52s since last call · session 47m1s · call #2\n```\n\nLLMs 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.\n\n<details>\n<summary><strong>Development</strong></summary>\n\n### Prerequisites\n- Node.js >= 22.0.0\n- npm or yarn\n\n### Setup\n```bash\ngit clone https://github.com/yourusername/chrono-mcp.git\ncd chrono-mcp\nnpm install\n```\n\n### Build\n```bash\nnpm run build\n```\n\n### Testing & Inspector\n```bash\nnpm test\nnpm run test:ui\nnpm run test:mcp\nnpm run inspector\n```\n\n```bash\nnpm run bench\n```\n\n- `npm test` — Vitest **unit** tests for tool handlers\n- `npm run bench` — Vitest benchmarks proving every batch operation at the `MAX_OPERATIONS` cap (10,000 items) completes in well under 100ms\n- `npm run test:mcp` — Vibrissa (npm: [`@jmoak/vibrissa`](https://www.npmjs.com/package/@jmoak/vibrissa)) **MCP protocol** cases (requires `npm run build` first; no Python)\n- Protocol contracts live in `tests/contracts/*.tdd` and emit to `tests/integration/vibrissa/cases/` via tdd-dsl locally (`npm run contracts:emit` if `tdd-dsl` is on your PATH). CI runs only the committed JSON with `vib run`.\n\nVisit `http://localhost:6274` for the web inspector UI.\n\n### Linting\n```bash\nnpm run lint\nnpm run lint:fix\n```\n\n</details>\n\n## Supported Timezones\n\nSupports all IANA timezone identifiers including:\n\n- **Americas**: `America/New_York`, `America/Los_Angeles`, `America/Toronto`, etc.\n- **Europe**: `Europe/London`, `Europe/Paris`, `Europe/Berlin`, etc.\n- **Asia**: `Asia/Tokyo`, `Asia/Shanghai`, `Asia/Dubai`, etc.\n- **Australia**: `Australia/Sydney`, `Australia/Melbourne`, etc.\n- **And 400+ more...**\n\n## Acknowledgments\n\nThis project is powered by [Luxon](https://github.com/moment/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.\n\n## License\n\nMIT License - see the [LICENSE](LICENSE) file for details.\n\n## Releases\n\nSee [GitHub Releases](https://github.com/JMoak/chrono-mcp/releases) for detailed changes.",
  "bytes": 11222,
  "sha": "1ce6b27c9cd6bd92f9541444079c9d798c1aa46460083931139ee77986fef833",
  "repo_slug": "jmoak/chrono-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_ai_smithery_jmoak_chrono_mcp_7bc11468/readme"
}