OAuth setup and subcommand testing verified. Natural language fallback remains to test. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5.8 KiB
5.8 KiB
Google Calendar Integration Design
Date: 2025-01-02 Status: Approved Primary Use Case: Agenda overview
Overview
Build a /gcal slash command for Google Calendar access, following the same architectural pattern as /gmail:
- OAuth credentials (reuse existing
~/.gmail-mcp/) - Python API wrapper with tiered delegation
- Skill file defining usage patterns
- Read-only by default
Architecture
User types /gcal
│
▼
Command (gcal.md)
│
├─→ invokes: skill:gcal
│
▼
Skill determines tier
│
├─→ Haiku: today, tomorrow, week, next (fetch + format)
└─→ Sonnet: summary (fetch + analyze)
│
▼
Python helper (gcal_delegate.py)
│
├─→ Google Calendar API via OAuth
└─→ Returns structured JSON
│
▼
PA formats response for user
Components
| File | Format | Purpose |
|---|---|---|
~/.claude/commands/gcal.md |
Markdown | Slash command definition |
~/.claude/skills/gcal/SKILL.md |
Markdown | Usage patterns and routing |
~/.claude/mcp/delegation/gcal_delegate.py |
Python | API wrapper + delegation |
~/.gmail-mcp/credentials.json |
JSON | OAuth credentials (add Calendar scope) |
Command Interface
Subcommands
| Subcommand | Description | Tier |
|---|---|---|
today |
Today's agenda | Haiku |
tomorrow |
Tomorrow's agenda | Haiku |
week |
Next 7 days, grouped by day | Haiku |
next |
Next upcoming event | Haiku |
summary |
Smart analysis of your week | Sonnet |
Routing
/gcal → Smart default (today if before 6pm, tomorrow if after)
/gcal today → Today's agenda
/gcal tomorrow → Tomorrow's agenda
/gcal week → Next 7 days, grouped by day
/gcal next → Next upcoming event only
/gcal summary → Sonnet-powered week analysis
/gcal <natural> → PA interprets intent, routes to appropriate subcommand
Hybrid Approach
- Exact subcommand match first:
today,tomorrow,week,next,summary - Natural language fallback:
- "what's on today" → today
- "this week" → week
- "next meeting" → next
- "am I busy tomorrow" → tomorrow
- "give me an overview" → summary
- Ambiguous input: Ask for clarification
Smart Default
from datetime import datetime
def default_view():
return "today" if datetime.now().hour < 18 else "tomorrow"
Output Format
Simple List (today/tomorrow/next)
📅 Today — Thursday, Jan 2
9:00 AM Team standup (30m)
📍 Zoom · 👥 5 attendees
10:30 AM 1:1 with Sarah (45m)
📍 Conference Room B
2:00 PM Project review (1h)
📍 Google Meet · 👥 8 attendees
📝 Q4 roadmap discussion
No more events today.
Grouped by Day (week)
📅 This Week — Jan 2-8
━━━ Thursday, Jan 2 ━━━
9:00 AM Team standup (30m)
2:00 PM Project review (1h)
━━━ Friday, Jan 3 ━━━
11:00 AM Client call (1h)
━━━ Monday, Jan 6 ━━━
(no events)
...
Context Fields
- 📍 Location or meeting link
- 👥 Attendee count
- 📝 Description snippet (first ~50 chars)
Smart Summary (Sonnet)
"Your week is front-loaded — Thursday and Friday are packed with 6 meetings totaling 5.5 hours. Monday-Wednesday are mostly clear, good for deep work. Heads up: the Client call Friday overlaps with your blocked focus time."
Python Helper
Structure
#!/usr/bin/env python3
"""
Google Calendar Delegation Helper
Usage:
gcal_delegate.py today
gcal_delegate.py tomorrow
gcal_delegate.py week
gcal_delegate.py next
gcal_delegate.py summary
"""
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
CREDENTIALS_PATH = "~/.gmail-mcp/credentials.json"
# Core functions
def get_calendar_service() # OAuth flow, returns Calendar API client
def fetch_events(start, end) # Returns list of event dicts
def format_event(event) # Extracts: time, title, location, attendees, description
def delegate(model, prompt) # Calls Claude CLI for Sonnet-tier tasks
# Subcommand handlers
def cmd_today() # fetch_events for today, format, return JSON
def cmd_tomorrow() # fetch_events for tomorrow
def cmd_week() # fetch_events for 7 days, group by date
def cmd_next() # fetch next single event
def cmd_summary() # fetch week, delegate to Sonnet for analysis
Output Format
{
"tier": "haiku",
"operation": "today",
"date": "2025-01-02",
"events": [...],
"count": 3
}
OAuth Setup
One-Time Setup
- Go to Google Cloud Console → APIs & Services
- Enable "Google Calendar API"
- OAuth consent screen → Add scope:
calendar.readonly - Delete local token:
rm ~/.gmail-mcp/token.json - Run
/gcal today— triggers re-auth with new scope
Scope Detection
Helper detects missing scope and prompts:
Calendar scope not authorized. Run:
rm ~/.gmail-mcp/token.json
Then retry /gcal today to re-authenticate.
Delegation Tiers
| Tier | Operations | Reason |
|---|---|---|
| Haiku | today, tomorrow, week, next | Fetch + format only |
| Sonnet | summary | Requires analysis |
| Opus | (reserved) | Strategic planning if needed |
Policy
- Read-only operations only
- Show context (attendees, location) by default
- Summarize results, don't dump raw data
- Start with lowest capable model tier
Implementation Checklist
- Add Calendar scope to GCP OAuth app
- Create
~/.claude/skills/gcal/SKILL.md - Create
~/.claude/commands/gcal.md - Create
~/.claude/mcp/delegation/gcal_delegate.py - Test OAuth re-authorization
- Test all subcommands
- Test natural language fallback