Guides

>

Set Up Google Calendar With OpenClaw

OpenClaw is a local-first AI agent framework built for home lab and personal automation. One of its most practical integrations is Google Calendar — giving your AI agent read access to your schedule so it can answer questions like “What do I have tomorrow?” or “Am I free Friday afternoon?”

This guide walks through the full setup from scratch: creating Google Cloud credentials, completing the OAuth flow, installing gcalcli, writing a credential-injection wrapper script, and wiring it all into OpenClaw’s exec tool.


Prerequisites

Before you begin, make sure you have:

  • OpenClaw installed and running — see openclaw.ai
  • A Google account you want the agent to access
  • Access to Google Cloud Console to create OAuth credentials
  • Python 3.8+ with pip available
  • 1Password CLI (optional, but recommended for secure credential storage)

Step 1: Create a Google Cloud Project and Enable the Calendar API

  1. Go to console.cloud.google.com and sign in.
  2. Click the project selector at the top, then New Project. Name it something like openclaw-calendar and click Create.
  3. In the left sidebar, go to APIs & Services → Library.
  4. Search for Google Calendar API and click Enable.

Step 2: Configure the OAuth Consent Screen

  1. Go to APIs & Services → OAuth consent screen.
  2. Select External and click Create.
  3. Fill in the required fields (App name, support email). Leave scopes for the next step.
  4. On the Test users screen, click Add Users and add your own Google email address. This is required while the app is in testing mode.
  5. Click Save and Continue through the remaining screens.

Note: It may take a few minutes for the test user to propagate before the OAuth flow will work.


Step 3: Create OAuth 2.0 Credentials

  1. Go to APIs & Services → Credentials.
  2. Click Create Credentials → OAuth client ID.
  3. For application type, select Desktop app.
  4. Give it a name (e.g., openclaw-desktop) and click Create.
  5. Note down the Client ID and Client Secret — you’ll need these shortly.

Step 4: Complete the OAuth Flow and Get a Refresh Token

Run the following Python script to generate the authorization URL. Replace the placeholders with your actual credentials:

import urllib.parse

CLIENT_ID = "YOUR_CLIENT_ID"
REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob"
SCOPE = "https://www.googleapis.com/auth/calendar"

params = {
    "client_id": CLIENT_ID,
    "redirect_uri": REDIRECT_URI,
    "response_type": "code",
    "scope": SCOPE,
    "access_type": "offline",
    "prompt": "consent",
}
auth_url = "https://accounts.google.com/o/oauth2/auth?" + urllib.parse.urlencode(params)
print(auth_url)

Open the printed URL in your browser, sign in with your Google account, and authorize the app. You’ll receive an authorization code — copy it.

Now exchange the code for a refresh token:

import requests

CLIENT_ID = "YOUR_CLIENT_ID"
CLIENT_SECRET = "YOUR_CLIENT_SECRET"
AUTH_CODE = "YOUR_AUTH_CODE"
REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob"

resp = requests.post("https://oauth2.googleapis.com/token", data={
    "code": AUTH_CODE,
    "client_id": CLIENT_ID,
    "client_secret": CLIENT_SECRET,
    "redirect_uri": REDIRECT_URI,
    "grant_type": "authorization_code",
})
data = resp.json()
print("Refresh token:", data.get("refresh_token"))

Save the refresh_token, client_id, and client_secret somewhere secure. If you use 1Password, store them in a dedicated item in your vault.


Step 5: Install gcalcli

gcalcli is a command-line interface for Google Calendar. Install it along with its OAuth dependencies:

pip install --user gcalcli google-auth-oauthlib google-auth-httplib2

Verify the install:

gcalcli --version

Step 6: Create the Credential Wrapper Script

Rather than storing credentials in plain text files, this wrapper script reads them from environment variables at runtime (which can be injected by 1Password’s op run command or set manually).

Create ~/.local/bin/gcal-op.sh:

#!/usr/bin/env bash
# gcal-op.sh — run gcalcli with credentials from environment variables
set -euo pipefail

GCALCLI="$HOME/.local/bin/gcalcli"
TOKEN_FILE="$HOME/.local/share/gcalcli/oauth"
mkdir -p "$(dirname "$TOKEN_FILE")"

if [[ -z "${GCAL_CLIENT_ID:-}" || -z "${GCAL_REFRESH_TOKEN:-}" ]]; then
  echo "ERROR: GCAL_CLIENT_ID or GCAL_REFRESH_TOKEN not set." >&2
  exit 1
fi

# Refresh the access token and write it in pickle format for gcalcli
python3 - "$GCAL_CLIENT_ID" "$GCAL_CLIENT_SECRET" "$GCAL_REFRESH_TOKEN" << 'PYEOF'
import sys, pickle, requests
from google.oauth2.credentials import Credentials

CLIENT_ID, CLIENT_SECRET, REFRESH = sys.argv[1], sys.argv[2], sys.argv[3]
import os
TOKEN_FILE = os.path.expanduser("~/.local/share/gcalcli/oauth")

resp = requests.post("https://oauth2.googleapis.com/token", data={
    "refresh_token": REFRESH,
    "client_id": CLIENT_ID,
    "client_secret": CLIENT_SECRET,
    "grant_type": "refresh_token"
})
data = resp.json()
if "access_token" not in data:
    print("ERROR:", data, file=sys.stderr)
    sys.exit(1)

creds = Credentials(
    token=data["access_token"],
    refresh_token=REFRESH,
    token_uri="https://oauth2.googleapis.com/token",
    client_id=CLIENT_ID,
    client_secret=CLIENT_SECRET,
    scopes=["https://www.googleapis.com/auth/calendar"],
)
with open(TOKEN_FILE, "wb") as f:
    pickle.dump(creds, f)
PYEOF

exec "$GCALCLI" --client-id="$GCAL_CLIENT_ID" --client-secret="$GCAL_CLIENT_SECRET" --nocolor "$@"

Make it executable:

chmod +x ~/.local/bin/gcal-op.sh

Test it by setting the environment variables manually and running:

GCAL_CLIENT_ID="YOUR_CLIENT_ID" 
GCAL_CLIENT_SECRET="YOUR_CLIENT_SECRET" 
GCAL_REFRESH_TOKEN="YOUR_REFRESH_TOKEN" 
gcal-op.sh agenda

You should see your upcoming calendar events in the terminal.


Step 7: Configure OpenClaw to Allow Exec on the Gateway Host

By default, OpenClaw’s exec tool runs commands in a sandboxed environment. To allow the agent to run gcal-op.sh on your actual machine, you need to configure the exec host and enable elevated mode.

Edit your OpenClaw config file (~/.openclaw/openclaw.json) and add the following to your agent’s tools section and the global tools section:

{
  tools: {
    exec: {
      host: "gateway",
      security: "full",
      ask: "off",
      pathPrepend: ["~/.local/bin"],
    },
    elevated: {
      enabled: true,
    },
  },
}

Also create or update ~/.openclaw/exec-approvals.json for your personal agent:

{
  "version": 1,
  "agents": {
    "personal": {
      "security": "full",
      "ask": "off",
      "askFallback": "full"
    }
  }
}

If you use 1Password for credential injection, add the credential references to your agent’s environment file (e.g., ~/1password-runtime/openclaw-dev.1password.env):

GCAL_CLIENT_ID=op://YourVault/google-calendar-oauth/ClientID
GCAL_CLIENT_SECRET=op://YourVault/google-calendar-oauth/Client Secret
GCAL_REFRESH_TOKEN=op://YourVault/google-calendar-oauth/refresh_token

Step 8: Restart the OpenClaw Gateway

If OpenClaw runs as a systemd service:

systemctl --user restart openclaw-gateway.service

Or if it’s running as a background process, stop and restart it using your usual wrapper script.


Step 9: Test the Integration

Send a message to your OpenClaw personal agent asking about your calendar:

openclaw agent --agent personal 
  --message "What do I have on my calendar in the next 7 days? Run gcal-op.sh agenda to check."

If everything is configured correctly, the agent will use the exec tool to run gcal-op.sh agenda and return a formatted list of your upcoming events.


Summary

You now have an OpenClaw personal agent that can read your Google Calendar on demand. The key components are:

  • gcalcli — the calendar CLI that interfaces with Google Calendar API
  • gcal-op.sh — a wrapper script that refreshes credentials at runtime from secure environment variables
  • OpenClaw exec config — configured to run commands on the gateway host with elevated permissions
  • 1Password integration (optional) — keeps credentials out of plain text files and injects them at runtime

From here, you can extend this setup by adding calendar queries to your agent’s HEARTBEAT.md so it proactively surfaces upcoming events, or by wiring it into automations that notify you about schedule conflicts.