Your indie hacker morning briefing — one glance, one focus, one question.
Pulls GitHub, your task list, and your reading queue into one 30-second morning brief. BYOK Claude. Works on any machine with Node 18+.
You wake up. You open GitHub. Then Linear. Then your bookmarks. Then Slack. Then your notes app. 20 minutes later you still haven't decided what to actually do today.
morning-brief pulls from every source you care about and asks Claude to write you a scannable brief:
- One-line orientation — what IS today about?
- Today's shape — compact section per source
- What demands attention first — ranked, with "why now" reasons
- What can wait — the noisy stuff that looks urgent but isn't
- One question worth sitting with — based on the signal mix
Everything is BYOK (you bring your own Claude key). Nothing gets stored or sent anywhere but Claude.
# 1. Install
npm install -g morning-brief
# 2. Set your Claude API key
export ANTHROPIC_API_KEY=sk-ant-... # https://console.anthropic.com/settings/keys
# 3. Plug in sources via env vars (or brief.json, see below)
export GITHUB_TOKEN=ghp_... # https://github.com/settings/tokens
export GITHUB_USER=your-username
export BURN_MCP_TOKEN=... # from burn451.cloud → Settings → MCP Server
# 4. Brief me
morning-brief --output today.mdOr skip install:
ANTHROPIC_API_KEY=sk-ant-... GITHUB_TOKEN=ghp_... GITHUB_USER=foo \
npx morning-brief| Source | What it shows | Status |
|---|---|---|
github |
Open PRs (yours), assigned issues, review requests | ✅ v0.1 |
tasks |
Local JSON list of priorities / TODOs | ✅ v0.1 |
calendar |
Today's meetings, conflicts, prep time | 🔜 v0.3 |
linear |
Current sprint, assigned, blocking others | 🔜 v0.3 |
slack |
Threads waiting on you, unread DMs | 🔜 v0.3 |
| Source | What it shows | Status |
|---|---|---|
burn |
24h Flame countdown — articles about to expire, recent Vault | ✅ v0.1 |
readwise |
Reader queue (later/new/shortlist) + stale-unread signal |
✅ v0.2 |
rss |
Fresh items from feeds you care about (last 24h) | ✅ v0.2 |
urls |
Plain text file of URLs — the zero-service fallback | ✅ v0.2 |
raindrop |
Favorites + collections + highlights | 🔜 v0.3 |
karakeep |
Self-hosted bookmarks + tags | 🔜 v0.3 |
pocket |
RIP 2025 — use Readwise (Pocket imports land there) | ⚰️ never |
Any reading source works. Use Readwise, an RSS feed, or a plain text file — morning-brief adapts the brief to what signal the source provides. Burn brings the most (24h urgency, kept vs. burned triage), but the tool is not Burn-only.
Two ways to configure — mix freely.
export ANTHROPIC_API_KEY=sk-ant-...
export GITHUB_TOKEN=ghp_...
export GITHUB_USER=Fisher521
# Pick one reading source:
export BURN_MCP_TOKEN=... # burn451.cloud → Settings → MCP
export READWISE_TOKEN=... # readwise.io/access_token
export MORNING_BRIEF_URLS=/path/to/reading.txt # or plain text file
# Optional:
export MORNING_BRIEF_TASKS=/path/to/tasks.json{
"anthropic_api_key": "sk-ant-...",
"sources": {
"github": {
"enabled": true,
"token": "ghp_...",
"user": "Fisher521"
},
"burn": { "enabled": true, "token": "..." },
"readwise": { "enabled": false, "token": "...", "location": "later" },
"rss": { "enabled": false, "feeds": ["https://simonwillison.net/atom/everything/"], "hours": 24 },
"urls": { "enabled": false, "file": "./reading.txt" },
"tasks": { "enabled": true, "file": "./tasks.json" }
}
}morning-brief looks for ./brief.json first, then ~/.morning-brief.json.
["Ship morning-brief v0.1", "Write weekly digest post", "Refactor auth middleware"]Or with metadata:
[
{ "title": "Ship morning-brief v0.1", "priority": "P0", "due": "2026-04-14" },
{ "title": "Write weekly digest post", "priority": "P1" },
{ "title": "Refactor auth middleware", "priority": "P2", "notes": "blocked on auth team" }
]Or grouped:
{ "priorities": [...], "someday": [...] }morning-brief [options]Options:
| Flag | Default | Description |
|---|---|---|
--config=<path> |
./brief.json, then ~/.morning-brief.json |
Config file |
--output=<path> |
stdout | Write brief to file |
--dry-run |
— | Print assembled prompt, skip LLM call |
--help |
— | Show help |
# crontab -e
0 7 * * * /usr/local/bin/morning-brief --output ~/brief/$(date +\%F).md# .github/workflows/morning-brief.yml
on:
schedule:
- cron: '0 12 * * *' # 7am EST
workflow_dispatch:
jobs:
brief:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx morning-brief --output brief-$(date +%F).md
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_USER: ${{ github.repository_owner }}
BURN_MCP_TOKEN: ${{ secrets.BURN_MCP_TOKEN }}
- run: |
git config user.name "morning-brief"
git config user.email "bot@users.noreply.github.com"
git add brief-*.md
git commit -m "brief: $(date +%F)" && git pushmorning-brief | slack-cli post --channel=self
morning-brief | mail -s "Morning brief" me@example.com- Each adapter (
src/sources/<name>.mjs) fetches from one source and returns a normalized signal. - All signals get stapled into one prompt.
- Claude writes the brief — structured, scannable, opinionated about what matters first.
No storage, no server, no account. Just env vars → API calls → markdown.
- v0.1 — GitHub + Burn + tasks adapters, Claude synthesis
- v0.2 — Readwise + RSS + urls-file reading sources (pluralize reading)
- v0.3 — Calendar (Google/iCal), Linear, Slack, Raindrop, Karakeep
- v0.4 — Output formats: HTML email, TTS podcast, Telegram push
- v0.5 — MCP server wrapper:
morning-briefbecomes a tool Claude/Cursor can call on demand
PRs welcome — especially new source adapters. Each adapter:
- Lives in
src/sources/<name>.mjs - Exports an async
collect<Name>(config)function - Returns
{ source: '<name>', items: ..., summary: {...} }or throws
See src/sources/github.mjs for the simplest example.
Built by @hawking520 — exploring AI-era content & attention workflows in public.
Part of an open ecosystem:
- Burn — reading triage MCP server (26 tools)
- reading-digest — weekly digest from your bookmarks
morning-brief— this
MIT — see LICENSE