Every hour, a Lambda pulls about 120 items from ~100 RSS feeds, asks a small model to act as an editor, and typesets the result as a 480x800 one-bit page for the Xteink X4 e-ink reader on my desk. The same pipeline now produces a multi-page "Morning Paper" PDF for reMarkable and Kindle, a TRMNL plugin, and an MCP server that agents can call. This is what it does, what broke, and what I learned about "news for agents". Everything below is live at https://briefing-service.wholemind.workers.dev.
The pipeline
- Collect. feedparser over ~100 feeds per briefing (AI, world, US, finance, sports, soccer, frontier-lab blogs). Each item keeps id, source, title, link, canonical link (utm and friends stripped), published, a 320-char summary, and a per-feed weight.
-
Dedupe. Exact duplicates collapse by canonical URL. My first near-duplicate rule (title+summary word-shingle Jaccard >= 0.5) measured zero merges on 480 live candidates, and only five false pairs even at 0.2: outlets rewrite wire copy, and RSS summaries share boilerplate, not story text. What works is headline entity overlap: adjacent capitalised words form one entity ("Wall Street", "Joao Pedro"), punctuation and hyphens end a phrase, Title-Case outlets are filtered against their own summary, and two headlines from different outlets merge on three shared entities or two non-generic ones. On the same 429 news items that gives nine merges, all the same story on inspection. The survivor lists the other outlets in
also_in; the collapsed records are published too, withduplicate_of, the rule and a score, so anyone doing provenance work can audit the merges. -
Rank. Claude Haiku 4.5 on Bedrock gets the candidate list (id, source, age, title, summary) and a persona, and must call a
publish_briefingtool with a lead, N stories, a research section, one-sentence summaries, a three-to-five-sentence detail passage, a why-it-matters line and key points. Facts must come from candidate text; the tool schema is the guardrail. A non-LLM fallback ranker (weight, recency, two-per-outlet cap) runs if the model call fails, so the device never shows a blank page. - Render. Pillow draws a masthead, lead, numbered stories and a research strip into 480x800, dithers to 1-bit, writes BMPs the reader's firmware can page through, plus a wide 800x480 variant for TRMNL-class panels and a PDF for e-readers.
- Publish. S3 + CloudFront, a tiny manifest with a stamp that changes only when the editor's picks change, so the device never re-downloads unchanged pages.
What surprised me
- The editor is the product. The rendering is fun, but the thing people react to is "lead + why it matters" over a hundred sources with duplicates merged. That is why I exposed it as an API and an MCP server rather than keeping it a device toy.
- Agents are terrible customers so far. Listing the MCP server in the official registry, Glama, Smithery and a few awesome-lists produced steady traffic in a day: scanners, auditors, and health checks. Thirteen MCP calls, zero humans. If you are building "for agents", expect the first wave to be bots evaluating you.
- E-ink people want files, not APIs. reMarkable and Kindle owners asked for a PDF in their library each morning, so that exists (rmapi push, Send-to-Kindle email), free for the first ten.
Try it
- Read: the front pages and JSON are free, 25 API/MCP calls per IP per day: https://briefing-service.wholemind.workers.dev
- Provenance work: https://briefing-service.wholemind.workers.dev/v1/briefings/ai/candidates is the full hourly candidate set, free, no key.
- Agents: MCP endpoint at https://briefing-service.wholemind.workers.dev/mcp (streamable HTTP), tools
list_briefings,get_briefing,get_page,render_briefing. Installable:npx -y github:jshelley/briefing-mcp. - Paid: $9/month Reader key, x402 per call (USDC on Base), $49/month Team Briefing over your own feeds.
I would like to hear what a "news" tool should return to your agent: full JSON, a short digest, or the rendered page.
Top comments (0)