Calendar
Overview
Melian connects to Google Calendar via OAuth and syncs events to a local SQLite cache. She provides proactive reminders before upcoming events, detects scheduling conflicts, and can create or modify events through a draft-based approval workflow. Calendar data feeds the morning briefing and is available to the AI during conversations.
Interfaces
export interface CalendarEvent {
id: string;
google_id: string;
summary: string;
description: string | null;
location: string | null;
start_time: number; // Unix timestamp
end_time: number; // Unix timestamp
all_day: boolean;
attendees: Attendee[];
status: string; // "confirmed" | "tentative" | "cancelled"
}
export interface CalendarDraft {
id: string;
summary: string;
start_time: number;
end_time: number;
attendees: Attendee[];
status: string; // "pending" | "approved" | "rejected"
}Draft Workflow
When Melian creates or modifies an event, it is written as a CalendarDraft with status: "pending" rather than committed to Google Calendar immediately. The dashboard surfaces pending drafts; approving one pushes the event to Google and updates the local cache. Rejecting discards it.
Create/modify request
└── write CalendarDraft (status: pending)
├── approve → push to Google Calendar → sync local cache
└── reject → discard draftTools
| Tool | Parameters | Description |
|---|---|---|
calendar_list_events |
start: string, end: string |
List events in a time range (ISO 8601 dates) |
calendar_get_event |
event_id: string |
Fetch full details of a single event |
calendar_find_free_time |
start: string, end: string, duration_minutes?: number |
Find available slots of at least duration_minutes minutes (default 60) |
calendar_create_event |
summary: string, start_time: string, end_time?: string, description?: string, location?: string, attendees?: string[], all_day?: boolean |
Propose a new event (creates a draft) |
calendar_update_event |
event_id: string, summary?: string, start_time?: string, end_time?: string, location?: string, description?: string |
Propose changes to an existing event (creates a draft) |
calendar_delete_event |
event_id: string, reason?: string |
Delete an event from Google Calendar |
calendar_approve_draft |
id?: string |
Approve a pending draft and push to Google (uses most recent pending if omitted) |
calendar_reject_draft |
id?: string, reason?: string |
Reject and discard a pending draft (uses most recent pending if omitted) |
API Endpoints
| Method | Path | Description |
|---|---|---|
GET |
/calendar/events?start=&end= |
List events in range |
GET |
/calendar/events/:id |
Get a single event |
GET |
/calendar/free-time?start=&end=&duration= |
Find free slots |
GET |
/calendar/drafts?status= |
List drafts (pending / approved / rejected) |
POST |
/calendar/drafts/:id/approve |
Approve a draft |
POST |
/calendar/drafts/:id/reject |
Reject a draft |
POST |
/calendar/sync |
Trigger a full sync from Google Calendar |