Skip to main content
Glama

Temporal Cortex MCP

CI npm version npm downloads Smithery License: 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 credentialssetup 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

-
security - not tested
A
license - permissive license
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/billylui/cortex-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server