rss-digest-mcp
A stateless RSS competitive-intelligence MCP server that fetches and filters RSS/Atom feeds by keywords, deduplicates, and sorts by recency to return a focused digest.
README
rss-digest-mcp
A stateless RSS competitive-intelligence MCP server. Point it at a list of public RSS/Atom feeds — competitor blogs, industry news, release notes, job boards — and get back a keyword-filtered, de-duplicated, recency-sorted digest. No database, no API keys, no login.
"What did my three competitors and the two industry news sites publish in the last 24 hours that mention pricing or layoffs?" — one tool call.
What it does
rss-digest-mcp turns a pile of feed URLs into a single, focused digest. It
fetches and parses each feed, keeps only items that (a) are recent enough and
(b) match your keywords, removes duplicates across feeds, sorts newest-first,
and returns clean structured items your LLM can summarise or act on.
It is stateless and privacy-respecting: nothing is stored. Feeds are fetched on demand, filtered, returned, and forgotten. No personal data is collected.
Why MCP
Reading feeds is easy; deciding what matters is the work. By exposing this as an MCP server, the filtering/dedup/recency logic runs deterministically in the tool, and the LLM (Claude, Cursor, Cline…) does what it is good at on top: summarising the digest, spotting themes, drafting an alert. The model never has to fetch or page through raw XML, and the same server works identically across every MCP client — so a "morning competitive brief" is one natural-language request away.
Quick Start
This is a tool server, not a CLI reader. It does not print feeds on its own. It exposes tools that an MCP client (Claude Code, Claude Desktop, Cursor, Cline) calls for you. You get RSS digests by connecting it to a client and asking in plain language — not by running a command here.
So the only required step is Configuration (connect it to your client). The steps below are an optional sanity check.
Requires Python ≥ 3.10; the client launches the server via
uv.
# (optional) clone + run the tests — stdlib only, no install, proves it works
git clone https://github.com/tefunamu/rss-digest-mcp.git
cd rss-digest-mcp
python3 -m unittest discover -s tests -v # 16 tests, expect "OK"
You do not need to start the server by hand — your MCP client does that.
If you just want to confirm it boots, uvx --from . rss-digest-mcp will sit
silently waiting for a client to speak MCP over stdio (that silence is correct —
there is no output until a client calls a tool). Press Ctrl-C to stop.
Once connected (next section), ask your client something like:
"Use get_digest on
https://hnrss.org/frontpageandhttps://zenn.dev/feed, keywords AI, last 24 hours."
Configuration
The server speaks MCP over stdio. Add one of the blocks below to your client, then ask: "Use get_digest on these feeds for the last 24h with keywords pricing, funding."
Use the absolute path to this repo in every example below. A wrong/relative path is the #1 reason the server silently fails to start.
Windows ARM64 users: install the package with the constraints file first — see Troubleshooting › Windows ARM64.
Claude Code
# from anywhere — register the server (use the absolute repo path)
claude mcp add rss-digest -- uvx --from /ABSOLUTE/PATH/TO/rss-digest-mcp rss-digest-mcp
# add -s user to make it available in every project:
# claude mcp add -s user rss-digest -- uvx --from /ABSOLUTE/PATH/TO/rss-digest-mcp rss-digest-mcp
claude mcp list # should show rss-digest: ✓ connected
Then in a new session: "Use get_digest on https://zenn.dev/feed, keywords AI, last 24h."
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json (macOS) /
%APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"rss-digest": {
"command": "uvx",
"args": ["--from", "/ABSOLUTE/PATH/TO/rss-digest-mcp", "rss-digest-mcp"]
}
}
}
Cursor
~/.cursor/mcp.json (or Settings → MCP → Add):
{
"mcpServers": {
"rss-digest": {
"command": "uvx",
"args": ["--from", "/ABSOLUTE/PATH/TO/rss-digest-mcp", "rss-digest-mcp"]
}
}
}
Cline (VS Code)
cline_mcp_settings.json (Cline → MCP Servers → Configure):
{
"mcpServers": {
"rss-digest": {
"command": "uvx",
"args": ["--from", "/ABSOLUTE/PATH/TO/rss-digest-mcp", "rss-digest-mcp"],
"disabled": false
}
}
}
Tools provided
What these tools are not:
get_digestis a deterministic filter over the feeds you give it — it matches keywords as plain substrings and sorts by recency. It does not search the web, and it does not infer which feeds a topic belongs to. Choosing the right feed URLs, turning a question into keywords, and judging whether a hit is actually relevant is the client's (the LLM's) job — the tool just fetches, filters and dedups. So "find what Japanese electronics makers said about pricing" only works if the client first supplies those makers' feed URLs and sensible keywords.
| Tool | Arguments | Returns |
|---|---|---|
get_digest |
feeds: string[], keywords?: string[], hours: int = 24, max_items: int = 30, summary_max_chars: int = 0 |
Combined digest across all feeds: matched items (newest first, deduped by link), count, feeds_ok, per-feed errors. Empty keywords = pure recency digest; hours = 0 disables the time filter; summary_max_chars > 0 shortens each summary (default 0 = full). |
fetch_feed |
url: string, limit: int = 20, summary_max_chars: int = 0 |
Latest items of one feed (newest first), plus feed_title and any parse error. summary_max_chars > 0 shortens summaries. |
load_opml |
path: string |
Feed list (title + xmlUrl) parsed from a local OPML export, for bulk onboarding. Reads only the file you point at. |
Each returned item has: title, link, summary (HTML-stripped),
source (feed title), published (ISO-8601 UTC), published_ts (epoch).
Example feeds (incl. Japanese sources)
Works with any RSS/Atom feed. feedparser decodes legacy Japanese encodings
(Shift_JIS / EUC-JP) transparently, so Japanese sources work out of the box:
- Hacker News front page —
https://hnrss.org/frontpage - NHK 主要ニュース —
https://www.nhk.or.jp/rss/news/cat0.xml - Zenn (trending) —
https://zenn.dev/feed - Qiita (popular) —
https://qiita.com/popular-items/feed - GitHub repo releases —
https://github.com/<owner>/<repo>/releases.atom
Usage examples
Once connected, you drive it in plain language — your MCP client turns the request into the right tool call. Examples (paste into Claude / Cursor / Cline):
Competitive / industry monitoring
Use
get_digestonhttps://hnrss.org/frontpageandhttps://techcrunch.com/feed/, keywordspricing, layoffs, funding, last 24 hours, then summarize the themes.
Japanese tech news, compact summaries
get_digestonhttps://zenn.dev/feedandhttps://qiita.com/popular-items/feed, keywordAI, last 24h,summary_max_chars200.
Just the latest from one source
fetch_feedhttps://news.ycombinator.com/rss, limit 10.
Onboard a feed list, then digest it
load_opml./feeds.opml, thenget_digeston those URLs with keywordAI.
A real run — 2 feeds, keyword AI, last 24h, summary_max_chars=200 — returns:
{
"count": 5,
"feeds_requested": 2,
"feeds_ok": 2,
"errors": [],
"items": [
{
"title": "OpenAI unveils its first custom chip, built by Broadcom",
"link": "https://techcrunch.com/2026/06/24/openai-unveils-its-first-custom-chip-built-by-broadcom/",
"summary": "Announcement: …",
"source": "Hacker News: Front Page",
"published": "2026-06-24T17:47:00Z",
"published_ts": 1782323220.0
}
// … 4 more, newest first, deduped across both feeds
]
}
The client (the LLM) chooses the feeds + keywords and reads this back to you as a brief; the tool just fetches, filters and dedups.
Architecture
MCP client (Claude Desktop / Cursor / Cline)
│ stdio (MCP)
▼
server.py ── FastMCP tools: get_digest / fetch_feed / load_opml
│ │
│ └─ feedparser → fetch + parse RSS/Atom/JSON (handles JP encodings)
▼
core.py ── pure, stdlib-only logic: recency filter · keyword match ·
dedup-by-link · newest-first sort · cap
The split is deliberate: core.py has zero third-party imports, so the
business logic is fully unit-tested without the network or the MCP SDK
(server.py is the thin I/O shell). Stateless by design — no storage layer.
Testing
python3 -m unittest discover -s tests -v
The suite covers HTML cleaning, UTC timestamp handling, keyword matching, the recency window (including undated items), and the dedup/sort/cap pipeline — all with a fixed clock for determinism.
Troubleshooting
MCP client shows "Failed to connect"
The launch command isn't runnable. Either install uv (pip install uv) so
uvx works, or use the no-uv path: pip install -e . then register the server
as python -m rss_digest_mcp. After changing the client config, start a new
session — existing sessions don't pick up new servers.
Windows ARM64: cryptography fails to build / uvx won't connect
On native win-arm64, cryptography ≥ 47 ships no prebuilt wheel, so pip
falls back to a Rust source build that needs MSVC link.exe and fails on a clean
machine (cryptography arrives transitively via the MCP SDK → pyjwt[crypto]).
The uvx --from . launch in Configuration also fails here,
because uvx builds the package in a fresh isolated env and ignores the
constraints file, re-triggering that same source build.
Use the pip + python -m path instead:
# 1. install, pinned to cryptography's last win-arm64 wheel (46.0.3)
python -m pip install -e . -c constraints-winarm64.txt --only-binary=cryptography
# 2. register with the module launcher (NOT uvx)
claude mcp add -s user rss-digest -- python -m rss_digest_mcp
claude mcp list # rss-digest ... ✓ connected
Notes:
- The pin is environment-specific — x64 / macOS / Linux have current wheels —
so it lives in
constraints-winarm64.txt, not inpyproject.toml(which would needlessly hold those platforms back). claude mcp addrecords the absolute path of thepythonyou used. If you later move or replace that interpreter, re-runclaude mcp add.- If you must keep using
uvx, pass the constraints via theUV_CONSTRAINTenvironment variable — but that still rebuilds the isolated env, so the directpython -mlaunch is lighter and more reliable.
License
MIT — see LICENSE.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。