· 4 min read · Billy Lui

Building Your First AI Scheduling Agent with Temporal Cortex

This tutorial walks through building a working AI scheduling agent — from zero to a booked meeting — using Temporal Cortex and any MCP-compatible AI client (Claude Desktop, VS Code with Copilot, Cursor, or the Claude CLI).

What you’ll build

By the end of this guide, your AI agent will be able to:

  1. Know the current time, timezone, and DST status
  2. Resolve natural language like “next Tuesday at 2pm” to precise timestamps
  3. List your calendars across Google, Outlook, and iCloud
  4. Find free slots in your schedule
  5. Book a meeting without double-booking

Step 1: Install the MCP server

npx @temporal-cortex/cortex-mcp

This downloads a native binary for your platform (macOS, Linux, or Windows) and runs the setup wizard. The wizard handles timezone detection, week-start preference, and telemetry consent.

No account required. No Docker. No infrastructure.

Step 2: Connect a calendar provider

npx @temporal-cortex/cortex-mcp auth google

This opens OAuth in your browser. Grant calendar access, and the credentials are stored locally at ~/.config/temporal-cortex/. Temporal Cortex supports three providers — run the auth command for each one you want to connect:

npx @temporal-cortex/cortex-mcp auth google     # Google Calendar
npx @temporal-cortex/cortex-mcp auth outlook    # Microsoft Outlook
npx @temporal-cortex/cortex-mcp auth caldav     # iCloud, Fastmail, etc.

You can connect multiple providers simultaneously. The agent will see all of them.

Step 3: Configure your AI client

Add the MCP server to your client’s configuration. Here’s the JSON for Claude Desktop (paste into claude_desktop_config.json):

{
  "mcpServers": {
    "temporal-cortex": {
      "command": "npx",
      "args": ["-y", "@temporal-cortex/cortex-mcp"]
    }
  }
}

For Claude Code (CLI):

claude mcp add temporal-cortex -- npx -y @temporal-cortex/cortex-mcp

For VS Code, Cursor, or Windsurf, add to your workspace settings (.vscode/mcp.json):

{
  "servers": {
    "temporal-cortex": {
      "command": "npx",
      "args": ["-y", "@temporal-cortex/cortex-mcp"]
    }
  }
}

Restart your AI client. You should see 15 new tools available.

Step 4: The 5-step scheduling workflow

Now ask your agent to schedule a meeting. Behind the scenes, it follows this workflow:

Discover: What calendars are connected?

The agent calls list_calendars to see all connected providers:

// Tool call
{ }

// Response
{
  "content": [
    { "id": "google/primary", "provider": "google", "name": "My Calendar", "label": "Work" },
    { "id": "outlook/calendar-uuid", "provider": "outlook", "name": "Calendar", "label": "Personal" }
  ],
  "total": 2
}

Each calendar has a provider-prefixed ID (google/primary, outlook/calendar-uuid). This disambiguates when the same account appears in multiple providers.

Orient: What time is it?

The agent calls get_temporal_context to ground itself in the current time:

// Tool call
{ }

// Response
{
  "utc": "2026-03-16T18:30:00+00:00",
  "local": "2026-03-16T14:30:00-04:00",
  "timezone": "America/New_York",
  "day_of_week": "Monday",
  "dst_active": true,
  "next_dst_transition": "2026-11-01T06:00:00+00:00",
  "next_dst_direction": "fall-back"
}

This is critical. Without it, the agent might assume UTC or a timezone from its training data. With it, “next Tuesday at 2pm” is unambiguous.

Resolve: Turn natural language into timestamps

The agent calls resolve_datetime with the user’s expression:

// Tool call
{ "expression": "next Tuesday at 2pm" }

// Response
{
  "resolved_utc": "2026-03-17T18:00:00+00:00",
  "resolved_local": "2026-03-17T14:00:00-04:00",
  "timezone": "America/New_York",
  "interpretation": "Tuesday, March 17, 2026 at 2:00 PM"
}

“Next Tuesday” is computed from the current date, not guessed. “2pm” is in the user’s configured timezone, not UTC. The interpretation field gives the agent a human-readable confirmation to show the user.

Query: Is that time free?

The agent calls get_availability to check across all calendars:

// Tool call
{
  "start": "2026-03-17T18:00:00+00:00",
  "end": "2026-03-17T18:30:00+00:00",
  "calendar_ids": ["google/primary", "outlook/calendar-uuid"]
}

// Response
{
  "busy": [],
  "free": [
    { "start": "2026-03-17T18:00:00+00:00", "end": "2026-03-17T18:30:00+00:00", "duration_minutes": 30 }
  ],
  "calendars_merged": 2
}

The slot is free across both calendars. If it were busy on either one, the agent would see it here — even if the busy event is on a different provider than the one being booked.

Act: Book the meeting

The agent calls book_slot with Two-Phase Commit:

// Tool call
{
  "calendar_id": "google/primary",
  "start": "2026-03-17T18:00:00+00:00",
  "end": "2026-03-17T18:30:00+00:00",
  "summary": "Meeting with Alice",
  "attendees": ["[email protected]"]
}

// Response
{
  "success": true,
  "event_id": "abc123",
  "booking_id": "def456",
  "summary": "Meeting with Alice",
  "start": "2026-03-17T18:00:00+00:00",
  "end": "2026-03-17T18:30:00+00:00"
}

The 2PC flow ran behind the scenes: lock acquired, no conflicts found, event created in Google Calendar, lock released. If another agent had tried to book the same slot simultaneously, one would succeed and the other would get a conflict error with instructions to find alternative times.

For scenarios where you’re scheduling with external participants who don’t have agents, the compose_proposal tool generates a shareable booking link instead of directly writing to a calendar. This provides a backward-compatible path — the recipient clicks a link and picks a time, no agent required.

What if the slot is busy?

If get_availability returns a busy period, the agent can call find_free_slots to suggest alternatives:

// Tool call
{
  "calendar_id": "google/primary",
  "start": "2026-03-17T12:00:00-04:00",
  "end": "2026-03-17T18:00:00-04:00",
  "min_duration_minutes": 30
}

// Response
{
  "slots": [
    { "start": "2026-03-17T16:30:00+00:00", "end": "2026-03-17T18:00:00+00:00", "duration_minutes": 90 },
    { "start": "2026-03-17T19:00:00+00:00", "end": "2026-03-17T22:00:00+00:00", "duration_minutes": 180 }
  ],
  "count": 2
}

The agent presents these alternatives to the user and books whichever they choose.

Adding the Agent Skill

The MCP server gives your agent the tools. The Agent Skill teaches it the correct workflow. Install both:

npx @temporal-cortex/cortex-mcp         # 18 MCP tools
npx skills add temporal-cortex/skills          # Procedural knowledge

The Skill teaches the agent to always call get_temporal_context first, to resolve datetimes before querying calendars, and to check availability before booking. Without the Skill, agents may skip steps or call tools in the wrong order.

Next steps

  • Connect multiple providers to see unified availability across Google + Outlook + iCloud
  • Try RRULE expansion — ask your agent “when does our biweekly standup happen for the rest of the quarter?”
  • Explore the full tool reference at /docs for all 18 tools with parameters and examples
  • Read about the Truth Engine to understand why RRULE expansion needs deterministic computation, not LLM inference
  • Learn why scheduling is infrastructure — not just a feature — in Scheduling Is Infrastructure