Smarty pants agent that sends you an email every week for the things you should care about
A Python agent that reads your Google Calendar every week, uses Claude AI to identify what's notable for your family, and emails you a clean HTML digest with sections for Life & Family, Kids, Birthdays, Task Reminders, and Weather.
- A Google Cloud Platform (GCP) account (free tier works) // You can also run this locally on your machine with locally scheduled cron jobs
- A Gmail account (for sending the digest email)
- An Anthropic API key (for Claude — costs ~$0.04/week)
- Go to Google Cloud Console
- Create a new project (or use an existing one)
- Enable the Google Calendar API:
- Go to APIs & Services → Library
- Search for "Google Calendar API"
- Click Enable
- Create a service account:
- Go to APIs & Services → Credentials
- Click "Create Credentials" → "Service account"
- Give it a name (e.g., "calendar-digest")
- Click Done
- Create a key for the service account:
- Click on the service account you just created
- Go to the "Keys" tab
- Click "Add Key" → "Create new key" → JSON
- Save the downloaded JSON file — this is your
creds.json
- Note the service account email (looks like
name@project-id.iam.gserviceaccount.com) — you'll need this in Step 3
Open your downloaded creds.json and add this field at the top level:
"claude_api_key": "sk-ant-api03-YOUR_KEY_HERE"You can get an API key at console.anthropic.com.
For each Google Calendar you want the agent to read:
- Open Google Calendar
- Click the three dots next to the calendar name → "Settings and sharing"
- Under "Share with specific people or groups", click "Add people and groups"
- Paste your service account email from Step 1
- Set permission to "See all event details"
- Click Send
To find a calendar's ID:
- For your primary calendar, it's your Gmail address (e.g.,
you@gmail.com) - For other calendars, go to Settings → scroll to "Integrate calendar" → copy the Calendar ID
The agent sends email via Gmail SMTP. You need an App Password (not your regular password):
- Go to myaccount.google.com/apppasswords
- You may need to enable 2-Step Verification first
- Create a new app password (name it "Calendar Digest" or similar)
- Copy the 16-character password — you'll put this in
config.yaml
Copy config.yaml and replace all INSERT_ placeholders:
| Field | What to put |
|---|---|
creds_path |
Full path to your creds.json file |
calendar.calendars |
Your calendar IDs and labels |
email.from_address |
Your Gmail address |
email.app_password |
The App Password from Step 4 |
email.recipients |
Email addresses to receive the digest |
weather.latitude/longitude |
Your city's coordinates (find at latlong.net) |
weather.city_label |
Display name (e.g., "San Francisco, CA") |
classification.family_context |
Describe your family so Claude understands your calendar |
classification.routine_patterns |
Event name substrings to always skip |
classification.notable_patterns |
Event name substrings to always surface |
logging.log_file |
Where to write the log file |
pip install google-api-python-client google-auth anthropic PyYAMLpython calendar_fam.py --dry-run > test.html && open test.htmlThis fetches your calendar, classifies events with Claude, and outputs the HTML digest to a file without sending email. Open test.html in your browser to verify it looks right.
python calendar_fam.pyCheck your inbox. If it works, you're ready to schedule it.
Note: Your Mac must be awake for cron to fire. If your Mac sleeps overnight, use Option B.
crontab -eAdd:
0 7 * * 0 cd /path/to/calendar && python3 calendar_fam.py
This runs every Sunday at 7 AM.
Deploy to a small GCP/AWS VM that's always on:
- Copy
calendar_fam.py,config.yaml,creds.json, and install dependencies - Update paths in
config.yamlto match the VM - Add a cron job:
crontab -e
# Add:
0 6 * * 0 cd /home/youruser/calendar && python3 calendar_fam.py >> /home/youruser/calendar/cron.log 2>&1- Add/remove calendars: Edit the
calendar.calendarslist inconfig.yaml - Tune what's routine vs notable: Edit
routine_patternsandnotable_patterns— these are case-insensitive substring matches against event names - Change the lookahead window: Edit
get_date_range()incalendar_fam.py— changetimedelta(days=14)to any number - Customize the family context: The more detail you provide in
family_context, the better Claude will classify your events. Include family member names, roles, recurring appointment contexts, and pet names - Disable weather: Remove the
weathersection fromconfig.yamland the agent will skip it - Add recipients: Add more email addresses to the
recipientslist
- Claude API: ~$0.04/week (Sonnet, ~10K input + 3K output tokens per run)
- Google Calendar API: Free
- Gmail SMTP: Free
- Open-Meteo Weather: Free (no API key needed)
| Problem | Fix |
|---|---|
403: Google Calendar API has not been used |
Enable the Calendar API in GCP Console |
404: Not Found for a calendar |
Share that calendar with your service account email |
0 events from a calendar |
Verify the calendar ID is correct and the calendar has events in the next 14 days |
| Email not sending | Check your Gmail App Password and that "Less secure apps" / 2FA is set up correctly |
FileNotFoundError for log |
Make sure the directory for log_file exists |