On this page

How to Set Up the OpenClaw Calendar Skill

Scheduling is one of the most genuinely automatable tasks in knowledge work. Unlike email (where nuance matters constantly) or code review (where judgment is non-negotiable), a large portion of calendar management is mechanical: find a time that works, block it, send an invite. It’s rule-following, not thinking.

The OpenClaw calendar skill handles the rule-following so you can focus on the decisions. This guide covers OAuth setup for Google Calendar, the time zone disambiguation problem that breaks most scheduling automations, and the “find me 3 slots that work for everyone” recipe.

OAuth Setup

The calendar skill uses OAuth 2.0 for Google Calendar — the same pattern as the email skill, but with calendar-specific scopes.

Google Calendar OAuth

Step 1: Enable the API

  1. Go to console.cloud.google.com
  2. Enable the Google Calendar API under APIs & Services → Library
  3. Go to Credentials → Create Credentials → OAuth 2.0 Client ID
  4. Application type: Desktop app
  5. Download the credentials JSON

If you already set up the email skill with a Google Cloud project, you can add the Calendar API to the same project — no need to create a new one.

Step 2: Choose your scopes

https://www.googleapis.com/auth/calendar.readonly     # Read events only
https://www.googleapis.com/auth/calendar.events       # Read + write events
https://www.googleapis.com/auth/calendar.freebusy     # Free/busy queries only

Start with calendar.events — it covers reading and creating events, which covers 95% of use cases. If you only want OpenClaw to check availability without creating events, calendar.freebusy is the minimal scope.

Step 3: Run the OAuth flow

@openclaw setup google calendar oauth

OpenClaw opens a browser authorization window. Approve access, and the refresh token is stored. Access tokens are managed automatically from that point.

google_calendar:
  credentials_file: "~/.openclaw/calendar-credentials.json"
  token_file: "~/.openclaw/calendar-token.json"
  scopes:
    - "https://www.googleapis.com/auth/calendar.events"

Multiple Calendars

Google accounts often have multiple calendars: personal, work, shared team calendars, birthdays, subscribed calendars. OpenClaw can access all calendars your account has access to.

@openclaw list my Google Calendar accounts
Calendars available:
• Your Name (primary) — personal events
• Work - Company Name — synced from work Google account
• Team Shared Calendar — shared with 8 people
• US Holidays — subscribed
• [3 more]

Which calendars should I use for scheduling? (default: primary only)

Configure which calendars to read from and which to create events on:

google_calendar:
  read_from: ["primary", "work-calendar-id", "team-shared-id"]
  create_events_on: "primary"  # Only create on primary

Microsoft 365 / Outlook Calendar

For Outlook calendar, the skill uses Microsoft Graph API:

outlook_calendar:
  client_id: "your-azure-app-id"
  client_secret: "your-client-secret"
  tenant_id: "your-tenant-id"
  redirect_uri: "http://localhost:8080/callback"

Microsoft’s OAuth flow requires an Azure app registration. The process is similar to Google’s but through portal.azure.com. The required scope is Calendars.ReadWrite.

CalDAV (Self-Hosted, Apple Calendar, Others)

For self-hosted calendar servers (Nextcloud, Fastmail, iCloud via CalDAV, Radicale):

caldav:
  url: "https://caldav.fastmail.com/dav/calendars/user/[email protected]/"
  username: "[email protected]"
  password: "${CALDAV_PASSWORD}"

CalDAV is the universal standard. If your calendar service supports CalDAV, this works.

The Time Zone Problem

Time zone handling is where calendar automations go wrong silently. The error doesn’t throw an exception — the meeting just gets scheduled at the wrong time.

The Disambiguation Issue

Consider this request:

@openclaw schedule a call with John for Thursday at 2pm

Questions this raises:

  • 2pm in whose time zone?
  • Is it your time zone or John’s?
  • Are you assuming John is in the same zone?
  • Is it 2pm local time for the meeting room or for all participants?

If you’re in New York and John is in London, “2pm Thursday” means something different to each of you. OpenClaw needs to know — and it needs to ask rather than assume.

Configuring Your Time Zone

Set your home time zone explicitly:

calendar_skill:
  user_timezone: "America/New_York"  # IANA timezone format
  display_format: "12h"  # or 24h
  week_start: "monday"  # monday or sunday

Use IANA timezone names, not abbreviations. America/New_York is unambiguous; EST is ambiguous (Eastern Standard Time is UTC-5, but people use “EST” colloquially to mean Eastern time year-round, which is sometimes UTC-4 during daylight saving).

Handling Attendee Time Zones

When scheduling with others, OpenClaw checks their calendar’s time zone if available:

@openclaw find a time to meet with [email protected] next week

OpenClaw:

  1. Queries Sarah’s free/busy data (if she’s on Google Calendar and sharing)
  2. Detects her calendar’s time zone from her event data
  3. Shows you slots in your time zone with Sarah’s local time in parentheses
Available slots for meeting with Sarah Chen:
• Monday May 20, 10am-11am (your time: 10am ET / her time: 3pm BST)
• Tuesday May 21, 2pm-3pm (your time: 2pm ET / her time: 7pm BST) ← late for her
• Wednesday May 22, 9am-10am (your time: 9am ET / her time: 2pm BST) ← recommended

Note: Sarah appears to be in BST (UTC+1). Tuesday slot is late in her evening.
Recommend Wednesday 9am.

The “Ambiguous Time” Rule

Configure OpenClaw to always clarify when time zone is ambiguous:

calendar_skill:
  always_confirm_timezone: true
  flag_late_times: true  # Warn if a slot is after 6pm for any attendee
  flag_early_times: true  # Warn if a slot is before 8am for any attendee

With this config, ambiguous requests trigger a clarification:

@openclaw schedule a call with the London team at 3pm Friday

> Which time zone for 3pm? 
> • 3pm ET → 8pm BST (London) — late for them
> • 3pm BST → 10am ET — works for both
> Which did you mean?

This adds one round-trip but prevents wrong-time meetings.

Reading and Summarizing Your Calendar

@openclaw what's my week look like?
Week of May 19-23, 2026

MON
• 10am-11am: Team standup (recurring)
• 2pm-3pm: Product review with Alex

TUE
• 9am-10am: 1:1 with manager
• Free afternoon

WED
• All-day: Focus day (no meetings scheduled)

THU
• 11am-12pm: Client call — Acme Corp
• 3pm-4pm: Design review

FRI
• 9am-9:30am: Weekly retrospective
• Free rest of day

Busiest day: Monday (3.5 hours in meetings)
Most available: Wednesday (good for deep work)
@openclaw do I have any back-to-back meetings this week with no break?
Yes — Thursday has a potential issue:
• 11am-12pm: Client call (Acme Corp)
• 12pm-1pm: [No break]
• 1pm-2pm: Lunch blocked (you blocked this yourself)

You have 1 hour between the client call and lunch — that's fine.
No back-to-back issues this week.

The “Find Me 3 Slots That Work for Everyone” Recipe

This is the scheduling automation that saves the most time. Instead of the back-and-forth of “are you free Tuesday? No. Wednesday? Maybe afternoon. What time?” — OpenClaw does it in one step.

Setup

@openclaw find a 45-minute slot next week for me, [email protected], and [email protected]

OpenClaw:

  1. Queries free/busy for all three people (if they’re on Google Calendar or have shared availability)
  2. Applies your working hours preference (9am-6pm, Monday-Friday by default)
  3. Applies buffer rules (no meetings before 9:30am, 30-min lunch block)
  4. Finds overlapping free windows
  5. Ranks by quality (avoids Mondays before 10am, Fridays after 3pm)
  6. Returns 3 options
Found 3 slots for 45-min meeting (all times ET):

1. ⭐ Tuesday May 21, 10am-10:45am
   • You: Free (before product standup at 11)
   • Sarah: Free (confirmed via calendar)
   • James: Free (confirmed via calendar)
   
2. Wednesday May 22, 2pm-2:45pm
   • You: Free
   • Sarah: Free
   • James: Tentative conflict (might clear)
   
3. Thursday May 23, 11am-11:45am
   • You: Free
   • Sarah: Free
   • James: Free

Recommend option 1. Want me to send invites?

Availability Preferences

Configure your scheduling preferences so OpenClaw produces realistic slots:

calendar_skill:
  working_hours:
    start: "09:00"
    end: "18:00"
    days: ["monday", "tuesday", "wednesday", "thursday", "friday"]
  buffers:
    before_meeting: 5    # minutes
    after_meeting: 10    # minutes
    lunch_start: "12:30"
    lunch_end: "13:30"
  avoid:
    - "monday_morning_before_10"  # Usually catch-up time
    - "friday_after_15"           # End-of-week focus time
  prefer_back_to_back: false      # Cluster meetings or spread them

Creating Events

@openclaw schedule the Tuesday 10am slot, invite Sarah and James, title "Q3 Planning Sync", add a Zoom link

OpenClaw:

  1. Creates the event on your primary calendar
  2. Adds Sarah and James as attendees (sends invites)
  3. Generates or attaches a video conference link (Google Meet auto-generated, or your Zoom URL if configured)
  4. Adds you as organizer
calendar_skill:
  video_conference:
    default: "google_meet"  # or "zoom", "teams", "none"
    zoom_personal_link: "https://zoom.us/j/your-meeting-id"

Meeting Prep Summaries

@openclaw I have a call with Acme Corp in 1 hour, what do I know about them?

OpenClaw cross-references the calendar event with your email, Notion, and any other connected tools:

Upcoming: Acme Corp Call in 58 minutes

? Context from your notes:
• Last meeting: April 3 (discovery call, 45 min)
• Key contact: Jennifer Walsh, VP Product
• Status: They're evaluating your proposal, response expected this week
• Open question: Budget sign-off timing

? Recent email:
• Jennifer replied May 17: "Looking forward to Thursday's call"
• No specific agenda items mentioned

? Suggested topics to cover:
• Follow up on proposal timeline
• Budget approval status
• Next steps / who signs off

Recurring Meeting Management

@openclaw find recurring meetings on my calendar that nobody has attended in the last 3 weeks

Useful for calendar hygiene — identifying zombie meetings that should be cancelled.

@openclaw cancel the Tuesday 4pm "Weekly Sync" series — nobody's attended in a month

OpenClaw cancels the entire series and sends cancellation notices to attendees.

PaioClaw vs. Self-Hosted

The calendar skill works well self-hosted for single-account Google Calendar setups. PaioClaw adds value in:

External availability sharing: The “find me 3 slots” feature queries other attendees’ free/busy. This works when they’re on Google Calendar and sharing availability. For external attendees (clients, candidates) who don’t share calendars, PaioClaw can generate a Calendly-style availability link that shows your open slots without requiring Google Calendar access.

Multi-calendar routing: If you manage separate personal and work Google accounts, routing scheduling across both without conflicts is more complex to configure self-hosted.

Mobile scheduling: Approving and sending meeting invites from mobile is smoother in PaioClaw’s interface than in the terminal.

Plans start free, Smart at $15/mo, Genius at $25/mo.

Summary

OAuth setup with calendar.events scope covers all standard use cases. Set your IANA time zone explicitly, configure working hours and buffer preferences, and always enable the time zone disambiguation prompt — the one extra question it asks saves real confusion.

The free/busy slot-finding recipe is the highest-value use of the calendar skill. Run it before any meeting request and you skip 3-5 rounds of back-and-forth scheduling emails. The meeting prep summary adds a useful layer — 60-second context before a call beats 5 minutes of frantic note-reviewing.

Join Our Community

Connect with other PaioClaw users, share tips, and stay up to date.