# Daily Prep

> Sends a "Daily Prep for Today" email to yourself summarizing today's multi-attendee meetings (with discussion points from invites, email, and Slack) and listing upcoming VP+ meetings for the next week grouped by date. Omits personal meetings with Lauren Gray only. Use when the user asks for daily prep, today prep, or meeting prep for the current day.

- Skill: `cgray-redhat/daily-prep` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add cgray-redhat/daily-prep`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cgray-redhat/daily-prep/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: cgray-redhat (https://skillmd.com/u/cgray-redhat)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/cgray-redhat/daily-prep

---


# Daily Prep

Send **one** email to yourself: **`Daily Prep for Today - {Today's Date}`**.

For past-meeting follow-up drafts, use the separate **daily-wrapup** skill.

## Prerequisites

1. `gws` CLI authenticated (`gws auth status`). Scopes: `calendar`, `gmail.modify`.
2. Read `ME.md` at the project root (if present).
3. **Slack MCP** (optional) — discussion points from recent Slack messages.
4. **Dataverse MCP** (optional) — one bulk VP roster query per month (cached locally).

## Workflow

```
Daily Prep:
- [ ] Step 0: Ensure VP cache is current (monthly)
- [ ] Step 1: Gather prep context
- [ ] Step 2: Slack search for today's discussion points
- [ ] Step 3: Compose prep email
- [ ] Step 4: Send email (deduplicated)
- [ ] Step 5: Confirm with user
```

### Step 0 — VP cache (monthly, one Dataverse call)

The VP roster is cached at `~/.cursor/skills/daily-meeting-prep/data/vp_cache.json` and refreshed **once per calendar month**. Daily prep uses this cache instead of per-attendee Dataverse lookups.

Check freshness:

```bash
python3 ~/.cursor/skills/daily-meeting-prep/scripts/ensure_vp_cache.py
```

Exit code **2** means refresh is needed. When stale or missing:

1. Run **one** Dataverse bulk query via **dataverse-people-lookup** / RoverPeople MCP pipeline:

   - `identify_dataproducts` → roverpeople
   - `shortlist_tables` → `ROVER_PEOPLE_CURR`
   - `get_sql` with: `List all current Red Hat employees whose TITLE matches VP+ criteria (Vice President, SVP, EVP, Senior/Executive Vice President, Chief Officer roles, C-suite abbreviations). Return MAIL, NAME, TITLE, GEO.`
   - `execute_sql`

2. Save the query result to `/tmp/vp-roster.json` (array of rows or `{ "people": [...] }`).

3. Update the cache and compute changes:

```bash
python3 ~/.cursor/skills/daily-meeting-prep/scripts/update_vp_cache.py \
  --input-file /tmp/vp-roster.json > /tmp/vp-cache-update.json
```

4. Send a **separate** change notification email (deduplicated):

```bash
python3 ~/.cursor/skills/daily-meeting-prep/scripts/send_vp_cache_changes.py \
  --update-result-file /tmp/vp-cache-update.json
```

Change email subject: **`VP Cache Refresh - {Date}`**. Body lists **Added**, **Removed**, and **Title changes** (or "None" per section).

Skip Step 0 when `ensure_vp_cache.py` exits 0.

### Step 1 — Gather prep context

Defaults to today. Optional `--from-date` to prep for a different day.

```bash
python3 ~/.cursor/skills/daily-meeting-prep/scripts/gather_daily_prep.py --format json
```

The gather script loads the VP cache automatically. No per-attendee Dataverse calls.

Output:

- **`todayMeetings`** — calendar events today with **2+ attendees** (non-declined), excluding Lauren Gray-only personal meetings
- **`vipMeetings`** / **`vipMeetingsByDate`** — multi-attendee events today through +6 days with VP+ attendees from cache, grouped by date
- **`vpCache`** — cache path, freshness, VP count

**Excluded meetings:** events where every non-user attendee is Lauren Gray (`lwgray526@gmail.com`, iCal invites, etc.).

### Step 2 — Slack context

For each `todayMeetings[].slackSearchQuery`, use Slack MCP `search_messages` (limit ~10). Enrich **Discussion points** only. Skip if Slack unavailable.

### Step 3 — Compose prep email

**Subject:** `emailSubject` from gather output.

```
Daily Prep for Today - {Today Date}

Today

{For each todayMeetings entry — skip Lauren-only meetings (already filtered):}

**{Meeting Title}**
Time: {timeLabel} ({durationMinutes} min)
Attendees: {names}

Discussion points:
• {2–4 bullets from agenda, inviteEmail, relatedEmails, Slack}
• {Topics to prepare for — not past outcomes}

{If no context: "• [No invite or email context found — review calendar invite]"}

Upcoming VIP Meetings

{For each date in vipMeetingsByDate:}

{dateLabel}

• {vipLine — one bullet per meeting; all VIPs on the same line}
• {Next meeting same day...}

{Or: "• No VP+ meetings in the next week."}
```

**Today section:** synthesize discussion points; do not invent topics. Meeting titles in the Today section are **bolded automatically** when the email is sent (write plain text; the send script converts to HTML).

**VIP section:** group by date (`vipMeetingsByDate`); use each meeting's **`vipLine`** (one bullet per meeting, all VIPs on the same line) — no summaries or discussion points.

### Step 4 — Send email (deduplicated)

```bash
python3 ~/.cursor/skills/daily-meeting-prep/scripts/send_daily_prep.py \
  --subject "Daily Prep for Today - June 8, 2026" \
  --body-file /tmp/daily-prep-body.txt
```

Sends to authenticated user as multipart email (plain text + HTML with **bold meeting titles** in the Today section). Skips if already sent with same subject (use `--force` to send again).

### Step 5 — Confirm with user

Report: today meeting count, VIP count, VP cache status, change email sent/skipped (if refreshed), prep email sent/skipped, link to [Gmail inbox](https://mail.google.com/mail/#inbox).

## Example prompts

- "Daily prep"
- "Daily prep for today"
- "Prep me for today's meetings"

## Additional resources

- [reference.md](reference.md)

