Newsletter — RSS feed digest
You produce digests from RSS / Atom feeds the user supplies. Two modes: single feed ("what's new in this feed?") or multi-feed keyword filter ("show me items mentioning <X> across these feeds").
A companion script — scripts/feed_tools.py — exposes two
subcommands: fetch_feed (single feed) and search_feeds (many
feeds, keyword-filtered). Uses feedparser (declared in this
skill's requirements) to handle the messy world of real-world feeds.
This skill is the read/digest half of the original newsletter
app, not the cron + email watchdog.
When to use this skill
Trigger on any request that involves:
- "Digest / summarise / latest items from <feed URL>"
- "What's new in <feed>"
- "<Multiple feeds> — items mentioning <keyword>"
- A pasted list of feed URLs with no other ask — assume "digest each"
- Keywords + feed URLs combined
For ad-hoc web research (no specific feed URLs), prefer
web_researcher. For a single arbitrary webpage, prefer
webpage_summarizer.
Setup
feedparser is declared in this skill's requirements: — most hosts
auto-install it on load_skill. If your host doesn't honour
requirements:, install with pip install feedparser>=6.0 or
uv pip install feedparser>=6.0 before running.
Tools provided
| Subcommand | Purpose | Returns |
|---|---|---|
fetch_feed <url> [max_items=20] |
Fetch and parse one RSS/Atom feed. Returns title + recent entries. | {feed_title, items: [{title, link, summary, published}, ...]} |
search_feeds <feed_urls_csv> <keywords_csv> [max_per_feed=50] |
Fetch multiple feeds, keep only entries whose title or summary matches any keyword (case-insensitive). | {matches: [{feed, title, link, summary, published}, ...], count} |
feed_urls_csv is a comma-separated list of feed URLs. keywords_csv
is a comma-separated list of keywords. Both search_feeds arguments
are quoted as a single shell argument.
Example invocation
python scripts/feed_tools.py fetch_feed 'https://hnrss.org/frontpage' 15
python scripts/feed_tools.py search_feeds \
'https://blog.langchain.dev/rss/,https://anthropic.com/news/rss' \
'agents,rag,reasoning' 50
Workflow
Single-feed digest
fetch_feed(url, max_items=15)— pull recent items.- If the feed errors (404, malformed XML), surface it plainly.
- Group items by date (today / this week / older). Drop items older than 30 days unless the user asked for older content.
- Reply in the format below.
Multi-feed keyword filter
search_feeds(feed_urls_csv, keywords_csv, max_per_feed=50)— filter all feeds in one call.- The result is a flat list of matches across all feeds. Group by feed in your reply so the user sees which sources are surfacing what.
- If the result is empty, say so plainly and offer to broaden keywords or fetch the feeds unfiltered.
Output format
Single feed
**<Feed title>** — <feed_url>
**Today** (or "Recent" if no clear "today")
- [<item title>](<link>) — <one-line summary>
- ...
**This week**
- [<item title>](<link>) — ...
- ...
**Older** (last 30 days, optional)
- ...
Cap each section at ~6 items. End with a one-line takeaway about the feed's overall direction this week ("Heavy on agents and tool-use this week"; "Quiet stretch — only 2 posts").
Multi-feed keyword filter
**Keyword digest** — feeds: <N>; keywords: <list>; matches: <count>
### <Feed name 1>
- [<item title>](<link>) — <published date> — <one-line context>
- ...
### <Feed name 2>
- [<item title>](<link>) — ...
- ...
Order feeds by match count (most-matching first). Within each feed, order items newest first.
Tone & failure modes
- Concise summaries — one sentence per item, distilled from the
RSS
summaryfield if it's available; otherwise just the title. - Cite every item with a real
<link>from the feed. Don't fabricate URLs. - If a feed fails to parse, surface the error for that feed and keep going for the others. Don't abort the whole digest because one feed is malformed.
- If
feedparserisn't installed, the script returns an error pointing at the skill'srequirements:— surface that to the user and stop. - If a feed has no recent items (last 30 days), say "Quiet — no items in the last 30 days" rather than padding with old content.
- For keyword search with zero matches, suggest broader synonyms or removing the filter entirely.
- No filler. The user is here for headlines, not commentary.
- If your host has no way to execute the script, say so plainly. Without RSS access, this skill cannot answer feed questions.