Runs on your machine from its package; the steps are below.
At most: creates or changes data: records, files, settings.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Run
uvx mcp-feed-reader-crunchtools
MCP client config
{
"mcpServers": {
"mcp-feed-reader": {
"command": "uvx",
"args": [
"mcp-feed-reader-crunchtools"
]
}
}
}Secure MCP server for RSS/Atom feed reading with SQLite backend.
uvx mcp-feed-reader-crunchtools
pip install mcp-feed-reader-crunchtools
podman run -v feedreader-data:/data quay.io/crunchtools/mcp-feed-reader
| Variable | Default | Description |
|---|---|---|
FEED_READER_DB | ~/.local/share/mcp-feed-reader/feeds.db | SQLite database path |
HTTP_PROXY / HTTPS_PROXY / NO_PROXY | (none) | Standard httpx proxy variables, honoured for every feed fetch. Useful when a publisher rate-limits your egress IP — Reddit returns 429 to datacentre ranges regardless of User-Agent |
add_feed_tool — Add an RSS/Atom feed by URLlist_feeds_tool — List all feeds with unread countsget_feed_tool — Get feed detailsdelete_feed_tool — Remove a feedrefresh_feeds_tool — Crawl feed sources for new content (slow, prefer systemd timer)list_entries_tool — List entries (filterable, paginated)read_entry_tool — Read full entry content (auto-marks read)mark_read_tool — Mark entries as readmark_unread_tool — Mark entry as unreadsearch_entries_tool — Full-text search (FTS5)list_categories_tool — List categories with countscreate_category_tool — Create categoryrename_category_tool — Rename categorydelete_category_tool — Delete categoryimport_opml_tool — Import from OPML fileexport_opml_tool — Export as OPMLget_stats_tool — Dashboard statsNothing in the server crawls on its own. list_entries_tool and friends read a
cache; if no one calls --fetch, that cache goes stale and every reader sees an
empty feed with no error anywhere. A deployment without a crawl trigger is a
broken deployment — this bit the daily briefing, which reported "no news" for
days while all 61 feeds sat unfetched.
# Fetch all feeds via CLI
mcp-feed-reader-crunchtools --fetch
deploy/ ships the two units used in production. Copy them to
/etc/systemd/system/, adjust the container name in the service if yours
differs, then:
sudo systemctl daemon-reload
sudo systemctl enable --now mcp-feeds-refresh.timer
The service runs --fetch inside the running container
(podman exec), so the database keeps the SELinux category of the process that
owns it. Do not bind-mount the data directory into a second container with
:Z to run the crawl — that relabels the volume and locks the live server out.
The timer fires hourly, plus once at 05:45. That second entry is not redundant: consumers window entries on publication time, so an entry published between the last crawl and a 06:00 report is missing from that report and already older than the next day's window start — it is lost for good. Any consumer on a fixed schedule wants a crawl shortly before it.
Feeds are fetched conditionally (ETag / If-Modified-Since). A rate limit,
gateway 5xx, or dropped connection is retried with exponential backoff, up to
three attempts in all, before the feed is recorded as failed.
AGPL-3.0-or-later