# Daily Brief

> Combines daily news briefing and daily meeting prep into a single email. Gathers scored tech news with IBM stock and today's meeting context, then sends one "Daily Brief" email at 6am Eastern. Use when the user asks for daily brief, morning brief, or combined news and meeting prep.

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

---


# Daily Brief

Send **one** email to yourself: **`Daily Brief - {Today's Date}`** combining tech news and today's meeting prep.

For separate emails, use **daily-news-briefing** or **daily-meeting-prep** instead.

## Prerequisites

1. `gws` CLI authenticated (`gws auth status`). Scopes: `calendar`, `gmail.modify`.
2. Read `ME.md` at the project root (if present).
3. Read `TEAM.md` at the project root (if present).
4. **Slack MCP** (required) — refresh before each run; discussion points from recent Slack messages.
5. **Dataverse MCP** (optional) — attendee title lookup for VIP section.
6. Network access for RSS fetch and WebFetch.

## Workflow

```
Daily Brief:
- [ ] Step 0: Check connections and refresh Slack if needed
- [ ] Step 1: Read role context (ME.md, TEAM.md)
- [ ] Step 2: Gather news + meeting prep
- [ ] Step 3: Dataverse title lookup for VIP attendees
- [ ] Step 4: Slack search for today's discussion points
- [ ] Step 5: Research and summarize each article
- [ ] Step 6: Compose and send combined email
- [ ] Step 7: Confirm with user
```

### Step 0 — Check connections and refresh Slack (required)

Run **refresh-connections** before gathering. **Google Workspace (gws)** and **Slack MCP** are both required — do not compose or send the brief until Slack passes the connection check.

1. Run the connection check.
2. If **slack-mcp** is expired, run **slack-login** (browser opens for user sign-in), update MCP config, ask user to reload MCP servers, and re-run the check.
3. **Stop** if Slack is still unavailable after refresh — do not send a brief with calendar/email-only context unless the user explicitly overrides for a one-off run.

```bash
python3 ~/.cursor/skills/refresh-connections/scripts/check_connections.py \
  --project-mcp .cursor/mcp.json
```

| Check result | Action |
|---|---|
| gws expired | Run `gws auth login`; stop if still failing |
| slack-mcp expired | Follow **slack-login** skill, update MCP config, ask user to reload MCP servers, re-run check |
| dataverse needs auth | Optional — proceed if VP cache loaded; otherwise call `mcp_auth` |
| the-source expired | Ignore for daily brief |

**Slack refresh (when expired):**

```bash
python3 ~/.cursor/skills/slack-login/scripts/slack-login.py \
  --workspace https://redhat.enterprise.slack.com \
  --json --output ~/.slack_tokens.env --timeout 300
```

Update Slack tokens in `~/.cursor/mcp.json` and project `.cursor/mcp.json`. Re-run the connection check — Slack must show **ok** before Step 2.

### Scheduled run (6:00 AM Eastern — primary delivery)

The **6:00 AM America/New_York** automation is the primary delivery channel for **that day's** meetings and overnight news (24h lookback). Manual runs use the same workflow; `--from-date` overrides the prep day only. Late manual sends are fine when automation missed or for testing.

Cursor Automation prefill: `automations/daily-brief-6am.json` in the **my-cursor-claw** project repo. Import via Cursor **Automations** editor or ask the agent to create the scheduled automation from that file.

### Step 1 — Read role context

From `ME.md` and `TEAM.md` (if present), keep in mind:
- VP, Renewals, Dealmaking, and Enterprise Ecosystem at Red Hat
- IBM synergy, open source, hybrid cloud, partner/ISV ecosystem
- Renewals, subscriptions, dealmaking, customer success

### Step 2 — Gather news + meeting prep

```bash
python3 ~/.cursor/skills/daily-brief/scripts/gather_daily_brief.py --format json
```

Output:

- **`emailSubject`** — canonical subject for dedup (`Daily Brief - {Today}`)
- **`stockLine`** — IBM price and prior-day change
- **`news.articles`** — scored articles (title, url, source, snippet, relevanceScore, matchedTopics)
- **`meetingPrep.todayMeetings`** — today's multi-attendee meetings (Lauren Gray-only excluded)
- **`meetingPrep.vipMeetingsByDate`** — VP+ meetings for the next week, grouped by date; each meeting includes **`vipLine`** (one formatted line with all VIPs)
- **`meetingPrep.attendeesNeedingTitleLookup`** — emails needing Dataverse lookup
- **`warnings`** — merged feed/stock/gather issues

Re-run with titles after Dataverse lookup:

```bash
python3 ~/.cursor/skills/daily-brief/scripts/gather_daily_brief.py \
  --titles-json /tmp/attendee-titles.json \
  --format json
```

Default: **5 articles**. Override lookback: `--hours 48`. Override article count: `--max-articles 5`. Prep for a different day: `--from-date YYYY-MM-DD`.

### Step 3 — VIP title lookup (Dataverse)

For each email in `meetingPrep.attendeesNeedingTitleLookup`, use **dataverse-people-lookup**. Save map to `/tmp/attendee-titles.json` and re-run gather.

**VP+ criteria:** Vice President, SVP, EVP, Senior/Executive Vice President, Chief … Officer, CEO/CFO/CTO/COO/CMO/CPO.

### Step 4 — Slack context

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

Slack `search_messages` is required for discussion-point enrichment once Step 0 passes. If Slack fails mid-run after a successful Step 0 check, note it in the confirmation and add a one-line footnote under **Meeting Prep for Today**.

### Step 5 — Research and summarize each article

For each article in `news.articles`:

1. Use `snippet` when substantial (>100 chars); otherwise **WebFetch** the article URL
2. Write **~2 short executive paragraphs**:
   - **Paragraph 1:** What happened (facts only, from the article)
   - **Paragraph 2:** Why it matters for **Red Hat**, **IBM**, and your scope (renewals, dealmaking, enterprise ecosystem)
3. End with `Read more: {url}`
4. Do not invent facts; mark gaps `[needs input]` if the article is thin

**Supplemental news check:** After gather, if no selected article covers **Anthropic/Mythos export controls**, **Chinese or Asian AI cybersecurity alternatives**, or another major IBM/Red Hat-relevant story from the last 48 hours, **WebSearch** for the missing topic and include the best result — replacing the lowest-scored article if already at 5.

If `warnings` notes fewer than 5 articles, report honestly — do not pad with invented stories.

### Step 6 — Compose and send combined email

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

```
Daily Brief - {Today Date}

{stockLine from gather output}

News Briefing

{Article Title}
{Paragraph 1}

{Paragraph 2}

Read more: {url}

---
(repeat for each article)

Meeting Prep for Today

Today

{For each todayMeetings entry:}

{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 meeting start is already past when sending: use Gemini notes / relatedEmails for **follow-through** bullets instead of prep topics}

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

Upcoming VIP Meetings

{For each date in vipMeetingsByDate:}

{dateLabel}

• {vipLine from meeting — or: Meeting — timeLabel — VIP1, title; VIP2, title}
• {Next meeting same day...}

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

**News section:** article titles and section headers are formatted automatically in HTML. `Read more` links are clickable.

**Meeting prep section:** meeting titles in the Today section are **bolded automatically** when sent.

**VIP section:** group by date (`vipMeetingsByDate`); one bullet per meeting listing all VIP attendees on the same line — no summaries or discussion points.

```bash
python3 ~/.cursor/skills/daily-brief/scripts/send_daily_brief.py \
  --subject "Daily Brief - June 8, 2026" \
  --body-file /tmp/daily-brief-body.txt
```

Sends to authenticated user as multipart email (plain text + HTML). Skips if already sent with same subject (use `--force` to send again).

### Step 7 — Confirm with user

Report: article count, today meeting count, VIP count, any warnings, email sent/skipped, link to [Gmail inbox](https://mail.google.com/mail/#inbox).

## Example prompts

- "Daily brief"
- "Morning brief"
- "Send my combined news and meeting prep"

## Illustrative sample (sharing)

For demos or sharing without personal calendar detail, use **`samples/daily-brief-illustrative.txt`** in the my-cursor-claw project: same format as the live brief but with **one example meeting** (Broadcom takeout) and anonymized-safe discussion points. Do not send the illustrative file via the production dedup send script unless the subject is clearly marked `(Sample)`.

## Additional resources

- [reference.md](reference.md) — combined JSON schema, troubleshooting, links to child skills

