caps-brief
v0.1.0
Published
Auto-populate your Capacities Daily Note with an AI morning briefing (Hacker News, RSS, weather) via the Capacities API 2.0.
Maintainers
Readme
caps-brief
Status: archived, unmaintained, not published to npm.
caps-brief requires Capacities Pro — API access is a Pro-only feature (~SGD 12.99/mo), which isn't obvious from the Capacities pricing page until you look closely. I don't have Pro, so the OAuth sign-in and the Claude summarisation path have never run against a live account. They're implemented and unit-tested, but unproven end-to-end. Against a Basic account,
caps-brief authfails with a barenotAuthenticated.I'm not going to maintain a tool I can't run, so this is archived rather than deleted. It may still be useful as a reference for building on the Capacities API 2.0 —
src/auth.tshas a working RFC 7591 dynamic client registration and OAuth 2.1 + PKCE flow (registration is confirmed working:/oauth/regreturns 201 for a public client with a localhost redirect URI). The old Beta API shuts down 2026-09-01; this is built entirely on 2.0.MIT — fork it, finish it, no need to ask.
A Node.js CLI that auto-populates your Capacities Daily Note with an AI morning briefing — Hacker News front page, your RSS feeds, and the weather — summarised by Claude and written via the Capacities API 2.0 (launched July 2026, developers.capacities.io).
Every morning your Daily Note starts with:
## ☀️ Morning Briefing
### Top Stories
A 2–4 sentence synthesis of the HN front page, plus the three most notable links…
### RSS Highlights
What's new across your subscribed feeds…
### Weather
Singapore: 🌤️ +31°CBYOK (bring your own keys): you use your own Capacities account and your own Anthropic API key. Nothing goes through anyone else's server.
Requirements
- Node.js ≥ 22
- Capacities Pro — API access is a Pro-only feature (~SGD 12.99/mo; there's a free trial in the app). Basic accounts can't use this tool: both the OAuth sign-in and personal tokens are gated behind Pro.
- An Anthropic API key from platform.claude.com — optional if you run with
--no-llm
Install
Not on npm — build from source:
git clone https://github.com/Booyaka101/caps-brief.git
cd caps-brief && npm install && npm run build && npm link1. Authenticate with Capacities
Option A — browser sign-in (OAuth 2.1 + PKCE):
caps-brief authYour browser opens the Capacities consent screen; approve, and tokens land in ~/.caps-brief/tokens.json. The CLI registers itself as a public OAuth client automatically via the API's dynamic client registration endpoint — no manual app registration needed. Access tokens auto-refresh (rotating refresh tokens), so this is fire-and-forget for cron use. If you are building your own published integration instead, register a permanent OAuth client with the Capacities team via developers.capacities.io.
Option B — personal API token (simplest):
In the Capacities desktop app go to Settings → Capacities API → Generate new token (scopes: api:read + api:write), then:
caps-brief auth --token cap-api-xxxxxxxxEither way, auth verifies the credential against GET /space and tells you which space it's connected to. Note: a token/OAuth grant is bound to one space — the briefing lands in that space's Daily Note.
2. Configure sources
caps-brief config --add-rss https://feeds.arstechnica.com/arstechnica/index
caps-brief config --add-rss https://www.theverge.com/rss/index.xml
caps-brief config --weather "Singapore" # any wttr.in location; omit for IP-based
caps-brief config --listRSS 2.0 and Atom are both supported. Hacker News (top 10 front-page stories) and weather are on by default.
3. Set your Anthropic key and run
# macOS/Linux
export ANTHROPIC_API_KEY=sk-ant-...
# Windows (PowerShell)
$env:ANTHROPIC_API_KEY = "sk-ant-..."
caps-brief run --dry-run # preview without writing
caps-brief run # write to today's Daily NoteSummarisation uses claude-haiku-4-5 (~$0.002/day at typical volumes). No key? caps-brief run --no-llm writes a clean, unsummarised digest instead.
Check everything at a glance any time:
caps-brief status # auth ✔/✖, connected space, key, sources, last runBuilt for unattended mornings:
- Runs are once per day — if your scheduler fires twice, the second run is a clean no-op (
--forceoverrides). - If Claude is transiently unreachable (rate limit, network, 5xx), the run falls back to the plain digest with a warning instead of leaving your note empty. Bad/missing API keys still fail loudly — config problems are never papered over.
- Each source fails independently; the run only aborts if everything is unreachable (it never writes an empty briefing).
Other flags: --date 2026-07-17 (target another day's note, bypasses the once-per-day guard), --no-timestamp (omit the timestamp heading Capacities adds to appended blocks).
4. Schedule it
Linux/macOS (cron):
30 6 * * * ANTHROPIC_API_KEY=sk-ant-... /usr/local/bin/caps-brief run >> ~/.caps-brief/run.log 2>&1Windows (Task Scheduler): — use the full path; scheduled tasks don't reliably inherit your PATH:
$action = New-ScheduledTaskAction -Execute "$env:APPDATA\npm\caps-brief.cmd" -Argument "run"
$trigger = New-ScheduledTaskTrigger -Daily -At 6:30am
Register-ScheduledTask -TaskName "caps-brief" -Action $action -Trigger $trigger(Set ANTHROPIC_API_KEY as a user environment variable first: [Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY","sk-ant-...","User").)
Missed a morning (laptop asleep)? Just run caps-brief run when you're back — the once-per-day guard means double-scheduling is always safe.
How it talks to Capacities
- Auth: OAuth 2.1 authorization-code + PKCE (S256) against
https://api.capacities.io/oauth/authorize//oauth/token, discovered via RFC 8414; or acap-api-…bearer token. - Write:
POST /blocks/daily-note/appendwith amarkdownbody — creates today's Daily Note if needed and appends the briefing (rate limit: 30 req/min; we make 1/day). - The old Capacities Beta API is not used anywhere — it shuts down September 1, 2026. This tool is built entirely on API 2.0.
Troubleshooting
Start with caps-brief status — it diagnoses most of these in one shot.
| Symptom | Fix |
|---|---|
| Not authenticated. Run: caps-brief auth | Token missing/revoked — re-run caps-brief auth |
| forbidden … api:write scope | Regenerate your personal token with the write scope enabled |
| ANTHROPIC_API_KEY is not set | Export the key, or add --no-llm |
| Already briefed today | Working as intended — add --force to send another |
| Note shows the plain digest, not the AI summary | Claude was briefly unreachable that morning; check the run log for the ⚠ line |
| Wrong space gets the briefing | Tokens are per-space — re-auth and pick the right space |
| All sources failed | Network/proxy issue; nothing is written on total failure |
Files live in ~/.caps-brief/: tokens.json (credentials, 0600), config.json (feeds/weather), client.json (OAuth client registration), state.json (last-run marker).
Forking
This repo is archived, so issues and pull requests are closed — but it's MIT, so fork away.
npm install
npm run build
npm test # unit suite (feed parsing, formatting) on Node's built-in test runnerIf you pick this up with a Pro account, the two unverified paths are caps-brief auth (the OAuth browser flow — dynamic client registration works, the consent step is unproven) and src/llm.ts (Claude summarisation; --no-llm skips it and is exercised by the tests).
Adding a source (a new feed type, a calendar, anything else) means a fetcher in src/sources.ts that fails independently of the others — the run should degrade to whatever else succeeded rather than abort.
License
MIT © Booyaka101
