billylui

Temporal Cortex MCP

Community billylui
Updated

Calendar MCP server with atomic booking, conflict prevention, deterministic RRULE expansion, and TOON token compression for AI agents

Temporal Cortex MCP

CInpm versionnpm downloadsSmitheryLicense: MIT

The complete temporal stack for AI agents. Context. Computation. Calendars. Correct.

The Problem

LLMs get date and time tasks wrong roughly 60% of the time (AuthenHallu benchmark). Ask "What time is it?" and the model hallucinates. Ask "Schedule for next Tuesday at 2pm" and it picks the wrong Tuesday. Ask "Am I free at 3pm?" and it checks the wrong timezone. Then it double-books your calendar.

Every other Calendar MCP server is a thin CRUD wrapper that passes these failures through to Google Calendar — no temporal awareness, no conflict detection, no safety net.

What's Different

  • Temporal awareness — Agents call get_temporal_context to know the actual time and timezone. resolve_datetime turns "next Tuesday at 2pm" into a precise RFC 3339 timestamp. No hallucination.
  • Atomic booking — Lock the time slot, verify no conflicts exist, then write. Two agents booking the same 2pm slot? Exactly one succeeds. The other gets a clear error. No double-bookings.
  • Computed availability — Merges free/busy data across multiple calendars into a single unified view. The AI sees actual availability, not a raw dump of events to misinterpret.
  • Deterministic RRULE expansion — Handles DST transitions, BYSETPOS=-1 (last weekday of month), EXDATE with timezones, leap year recurrences, and INTERVAL>1 with BYDAY. Powered by Truth Engine, not LLM inference.
  • Token-efficient output — TOON format compresses calendar data to ~40% fewer tokens than standard JSON, reducing costs and context window usage.

Prerequisites

  • Node.js 18+ (for npx to download and run the binary)
  • Google account with Google Calendar
  • Google OAuth credentials — setup guide

Quick Start

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "temporal-cortex": {
      "command": "npx",
      "args": ["-y", "@temporal-cortex/cortex-mcp"],
      "env": {
        "GOOGLE_CLIENT_ID": "your-client-id.apps.googleusercontent.com",
        "GOOGLE_CLIENT_SECRET": "your-client-secret",
        "TIMEZONE": "America/New_York"
      }
    }
  }
}

Cursor

Add to Cursor's MCP settings (~/.cursor/mcp.json):

{
  "mcpServers": {
    "temporal-cortex": {
      "command": "npx",
      "args": ["-y", "@temporal-cortex/cortex-mcp"],
      "env": {
        "GOOGLE_CLIENT_ID": "your-client-id.apps.googleusercontent.com",
        "GOOGLE_CLIENT_SECRET": "your-client-secret",
        "TIMEZONE": "America/New_York"
      }
    }
  }
}

Windsurf

Add to Windsurf's MCP config (~/.codeium/windsurf/mcp_config.json):

{
  "mcpServers": {
    "temporal-cortex": {
      "command": "npx",
      "args": ["-y", "@temporal-cortex/cortex-mcp"],
      "env": {
        "GOOGLE_CLIENT_ID": "your-client-id.apps.googleusercontent.com",
        "GOOGLE_CLIENT_SECRET": "your-client-secret",
        "TIMEZONE": "America/New_York"
      }
    }
  }
}

Need Google OAuth credentials? See docs/google-cloud-setup.md for a step-by-step guide.

First-Time Setup

On first run, the server needs Google Calendar access. You have two options:

Option A — Run auth before connecting:

npx @temporal-cortex/cortex-mcp auth

This opens your browser for Google OAuth consent. After authorizing, credentials are saved to ~/.config/temporal-cortex/credentials.json and reused automatically.

Option B — The server prompts automatically when an MCP client connects and no credentials are found.

During auth, the server detects your system timezone and prompts you to confirm or override it. This is stored in ~/.config/temporal-cortex/config.json and used by all temporal tools. You can override it per-session with the TIMEZONE env var, or per-call via the timezone parameter.

After authentication, verify it works by asking your AI assistant: "What time is it?" — the agent should call get_temporal_context and return your current local time.

Available Tools (11)

Layer 1 — Temporal Context

Tool Description
get_temporal_context Current time, timezone, UTC offset, DST status, day of week. Call this first.
resolve_datetime Resolve human expressions ("next Tuesday at 2pm", "tomorrow morning", "+2h") to RFC 3339.
convert_timezone Convert any RFC 3339 datetime between IANA timezones.
compute_duration Duration between two timestamps (days, hours, minutes, human-readable).
adjust_timestamp DST-aware timestamp adjustment ("+1d" across spring-forward = same wall-clock).

Layer 2 — Calendar Operations

Tool Description
list_events List calendar events in a time range. Output in TOON (~40% fewer tokens) or JSON.
find_free_slots Find available time slots in a calendar. Computes actual gaps between events.
expand_rrule Expand recurrence rules into concrete instances. Handles DST, BYSETPOS, leap years.
check_availability Check if a specific time slot is available against events and active locks.

Layer 3 — Availability

Tool Description
get_availability Merged free/busy view across multiple calendars with privacy controls.

Layer 4 — Booking

Tool Description
book_slot Book a calendar slot safely. Lock → verify → write with Two-Phase Commit.

See docs/tools.md for full input/output schemas and usage examples.

The RRULE Challenge

Most AI models and calendar tools silently fail on recurrence rule edge cases. Run the challenge to see the difference:

npx @temporal-cortex/cortex-mcp rrule-challenge

5 cases where LLMs consistently fail

1. "Third Tuesday of every month" across DST (March 2026, America/New_York)

The third Tuesday is March 17. Spring-forward on March 8 shifts UTC offsets from -05:00 to -04:00. LLMs often produce the wrong UTC time or skip the month entirely.

2. "Last Friday of every month" (BYSETPOS=-1)

RRULE:FREQ=MONTHLY;BYDAY=FR;BYSETPOS=-1 — LLMs frequently return the first Friday instead of the last, or fail to handle months with 4 vs 5 Fridays.

3. "Every weekday except holidays" (EXDATE with timezone)

EXDATE values with explicit timezone offsets require exact matching against generated instances. LLMs often ignore EXDATE entirely or apply it to the wrong date.

4. "Biweekly on Monday, Wednesday, Friday" (INTERVAL=2 + BYDAY)

RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE,FR — The INTERVAL=2 applies to weeks, not individual days. LLMs frequently generate every-week occurrences instead of every-other-week.

5. "February 29 yearly" (leap year recurrence)

RRULE:FREQ=YEARLY;BYMONTH=2;BYMONTHDAY=29 — Should only produce instances in leap years (2028, 2032...). LLMs often generate Feb 28 or Mar 1 in non-leap years.

Truth Engine handles all of these deterministically using the RFC 5545 specification. No inference, no hallucination.

How It Works

The MCP server is a single Rust binary distributed via npm. It runs locally on your machine and communicates with MCP clients over stdio (standard input/output) or streamable HTTP.

  • Truth Engine handles all date/time computation: temporal resolution, timezone conversion, RRULE expansion, availability merging, conflict detection. Deterministic, not inference-based.
  • TOON (Token-Oriented Object Notation) compresses calendar data for LLM consumption — fewer tokens, same information.
  • Two-Phase Commit ensures booking safety: acquire lock, verify the slot is free, write the event, release lock. If any step fails, everything rolls back.

Stdio vs HTTP Transport

Transport mode is auto-detected — set HTTP_PORT to switch from stdio to HTTP.

  • Stdio (default): Standard MCP transport for local clients (Claude Desktop, VS Code, Cursor). The server reads/writes JSON-RPC messages over stdin/stdout.
  • HTTP (when HTTP_PORT is set): Streamable HTTP transport per MCP 2025-11-25 spec. The server listens on http://{HTTP_HOST}:{HTTP_PORT}/mcp with SSE streaming, session management (Mcp-Session-Id header), and Origin validation. Requests with an invalid Origin header are rejected with HTTP 403.
# HTTP mode example
HTTP_PORT=8009 npx @temporal-cortex/cortex-mcp

Lite Mode vs Full Mode

Mode is auto-detected — there is no configuration flag.

  • Lite Mode (default): No infrastructure required. Uses in-memory locking and local file credential storage. Designed for individual developers with a single Google Calendar account.
  • Full Mode (activated when REDIS_URLS is set): Uses Redis-based distributed locking (Redlock) for multi-process safety. Designed for production deployments with multiple concurrent agents.

Configuration

Variable Required Default Description
GOOGLE_CLIENT_ID Yes* Google OAuth Client ID from Cloud Console
GOOGLE_CLIENT_SECRET Yes* Google OAuth Client Secret
GOOGLE_OAUTH_CREDENTIALS No Path to Google OAuth JSON credentials file (alternative to CLIENT_ID + CLIENT_SECRET)
TIMEZONE No auto-detected IANA timezone override (e.g., America/New_York). Overrides stored config and OS detection.
REDIS_URLS No Comma-separated Redis URLs. When set, activates Full Mode with distributed locking.
TENANT_ID No auto-generated UUID for tenant isolation
LOCK_TTL_SECS No 30 Lock time-to-live in seconds
OAUTH_REDIRECT_PORT No 8085 Port for the local OAuth callback server
HTTP_PORT No Port for HTTP transport. When set, enables streamable HTTP mode instead of stdio.
HTTP_HOST No 127.0.0.1 Bind address for HTTP transport. Use 0.0.0.0 only behind a reverse proxy.
ALLOWED_ORIGINS No Comma-separated allowed Origin headers for HTTP mode (e.g., http://localhost:3000). All cross-origin requests rejected if unset.

* Either GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET, or GOOGLE_OAUTH_CREDENTIALS must be set.

See docs/google-cloud-setup.md for a complete setup guide.

Troubleshooting

Problem Solution
"No credentials found" Run npx @temporal-cortex/cortex-mcp auth to authenticate with Google
OAuth error / "Access blocked" Verify GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are correct. Ensure the OAuth consent screen is configured in Google Cloud Console.
Port 8085 already in use Set OAUTH_REDIRECT_PORT to a different port (e.g., 8086)
Server not appearing in MCP client Ensure Node.js 18+ is installed (node --version). Check your MCP client's logs for errors.

See docs/google-cloud-setup.md for detailed OAuth troubleshooting.

Going to Production?

The MCP server in Lite Mode handles single-provider computation with conflict prevention for individual use. For teams and production deployments:

  • Multi-provider unification — Google + Outlook + CalDAV (iCloud, Fastmail) in one query
  • Distributed Two-Phase Commit — Redis Redlock quorum for multi-process, multi-host safety
  • Enterprise OAuth management — HashiCorp Vault integration, per-tenant credential isolation
  • Usage metering — Per-operation billing with daily aggregation
Operation Price
Calendar read $0.001
Availability check $0.002
Booking (with 2PC safety) $0.01
Connected account $0.50/mo
Free tier 100 bookings/mo + 5 accounts

No credit card required.

Request Platform Early Access

Comparison with Alternatives

Feature temporal-cortex-mcp temporal-awareness-mcp google-calendar-mcp (nspady) calendar-mcp (rauf543)
Temporal context (time/timezone) Yes (5 tools) Yes (1 tool) No No
Human expression parsing Yes ("next Tuesday at 2pm") No No No
Double-booking prevention (2PC) Yes No No No
Deterministic RRULE expansion Yes No No Partial
Multi-calendar availability merge Yes No No No
Prompt injection firewall Yes No No No
TOON token compression Yes No No No
Multi-provider (Google + Outlook) Yes No No Yes
Price Free (Lite) Free Free Free

Built on Temporal Cortex Core

The computation layer is open source:

  • temporal-cortex-core — Truth Engine (temporal resolution, RRULE expansion, availability merging, timezone conversion) + TOON (token compression)
  • Available on crates.io, npm, and PyPI
  • 510+ Rust tests, 42 JS tests, 30 Python tests, ~9,000 property-based tests

Contributing

Bug reports and feature requests are welcome. See CONTRIBUTING.md.

License

MIT

MCP Server · Populars

MCP Server · New