Guide

Email Yourself a Daily Calendar Agenda

Every morning, pull today's calendar events, format them into a readable list with jq, and email the summary to yourself or a team. This guide builds the whole pipeline as one script you drop on a cron — no calendar app open before coffee.

Written by Pouya Sanooei Software Engineer

Reviewed by Qasim Muhammad

VerifiedCLI 3.1.17 · Google, Outlook · last tested June 9, 2026

Why email a daily agenda instead of opening a calendar app?

A daily agenda email is a single message, sent each morning, that lists every event on your calendar for that day. It removes the context switch of opening a calendar UI: the day's 4 or 5 meetings arrive in the same inbox you already check first thing. For a shared team calendar, one send keeps everyone aligned.

Many knowledge workers check email within minutes of waking, before a calendar tab is ever opened. A calendar app is a separate tab nobody opens until the first meeting is already starting. Pushing the agenda into email meets people where they already are. The same pipeline scales from one person to a 12-person team by changing a single --to address. Because the CLI authenticates with an OAuth grant, no SMTP server, app password, or calendar export step sits between the events and the inbox.

How do I pull today's events as JSON?

The nylas calendar events list command reads your primary calendar and prints events as structured JSON when you pass --json. The --days 1 flag limits the window to today, so a 30-second query returns only the events the agenda needs.

Each event in the output carries a title, a when.start_time and when.end_time as Unix timestamps, and a participants array. All-day events use when.date instead of timestamps. The default limit is 10 events; raise it with --limit for a packed day.

# Today's events on the primary calendar, as JSON
nylas calendar events list --days 1 --limit 50 --json

How do I format the events into a readable agenda with jq?

You shape the raw JSON into a plain-text agenda with jq, which sorts events by start time and prints one line each. Converting the Unix start_time with strflocaltime gives a 24-hour clock label like 14:00, so a 5-meeting day collapses into 5 readable lines.

The expression below sorts by when.start_time, formats each timestamp, and falls back to a label when an event has no title. jq does the date math inline, so no second tool is needed. An event at epoch 1749632400 (09:00 UTC) renders as 05:00 with America/New_York. Set TZ before the command to render local time.

# Sort by start time, print "HH:MM  Title" per event
TZ="America/New_York" nylas calendar events list --days 1 --limit 50 --json \
  | jq -r 'sort_by(.when.start_time)
      | .[]
      | "\(.when.start_time | strflocaltime("%H:%M"))  \(.title // "(no title)")"'

How do I send the formatted agenda as an email?

The nylas email send command takes the jq output as its --body and delivers it through your OAuth grant. The --yes flag skips the interactive confirmation, which is required for unattended cron runs.

Capture the agenda into a shell variable, then pass it to the send. The same body goes to one address or a comma-separated team list. A typical agenda email is under 500 bytes and sends in roughly 1 second. For a richer layout, wrap the lines in HTML in the body — the --body flag accepts HTML or plain text and the CLI auto-detects it, so the message renders with line breaks instead of running together. Provider delivery latency typically stays under 2 seconds for a single recipient.

AGENDA=$(TZ="America/New_York" nylas calendar events list --days 1 --limit 50 --json \
  | jq -r 'sort_by(.when.start_time) | .[]
      | "\(.when.start_time | strflocaltime("%H:%M"))  \(.title // "(no title)")"')

nylas email send \
  --to me@example.com \
  --subject "Today's agenda" \
  --body "$AGENDA" \
  --yes

How do I run the agenda automatically every morning?

You schedule the agenda with cron, the Unix job scheduler defined in crontab(5). A single crontab line runs the script at a fixed time each day, so the agenda email is waiting before the workday starts. The five-field cron syntax 0 7 * * 1-5 means 07:00, Monday through Friday.

Cron runs with a minimal environment, so set NYLAS_DISABLE_KEYRING and point the CLI at API-key auth for headless runs — the interactive keyring is unavailable without a desktop session. The full script below handles an empty calendar, sends a “nothing scheduled” note instead of a blank email, and exits 0 either way so cron never logs a failure for a quiet day.

#!/usr/bin/env bash
set -euo pipefail
export NYLAS_DISABLE_KEYRING=1
export TZ="America/New_York"

EVENTS=$(nylas calendar events list --days 1 --limit 50 --json)
COUNT=$(echo "$EVENTS" | jq 'length')

if [ "$COUNT" -eq 0 ]; then
  BODY="Nothing scheduled today. Enjoy the open calendar."
else
  BODY=$(echo "$EVENTS" | jq -r 'sort_by(.when.start_time) | .[]
    | "\(.when.start_time | strflocaltime("%H:%M"))  \(.title // "(no title)")"')
fi

nylas email send \
  --to me@example.com \
  --subject "Today's agenda ($COUNT events)" \
  --body "$BODY" \
  --yes

Save the script, make it executable, and add the crontab entry. Install the CLI first with brew install nylas/nylas-cli/nylas (see getting started for other install methods).

chmod +x ~/bin/daily-agenda.sh
( crontab -l 2>/dev/null; echo "0 7 * * 1-5 ~/bin/daily-agenda.sh" ) | crontab -

Next steps