Melian

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 draft

Tools

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