Skip to main content
Glama
mcp-feed-reader-crunchtools

mcp-feed-reader-crunchtools

by crunchtools

mcp-feed-reader-crunchtools

Secure MCP server for RSS/Atom feed reading with SQLite backend.

Installation

uvx mcp-feed-reader-crunchtools

pip

pip install mcp-feed-reader-crunchtools

Container

podman run -v feedreader-data:/data quay.io/crunchtools/mcp-feed-reader

Related MCP server: @missionsquad/mcp-rss

Configuration

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

Tools (17)

Feed Management

  • add_feed_tool — Add an RSS/Atom feed by URL

  • list_feeds_tool — List all feeds with unread counts

  • get_feed_tool — Get feed details

  • delete_feed_tool — Remove a feed

  • refresh_feeds_tool — Crawl feed sources for new content (slow, prefer systemd timer)

Entry Management

  • list_entries_tool — List entries (filterable, paginated)

  • read_entry_tool — Read full entry content (auto-marks read)

  • mark_read_tool — Mark entries as read

  • mark_unread_tool — Mark entry as unread

  • search_entries_tool — Full-text search (FTS5)

Category Management

  • list_categories_tool — List categories with counts

  • create_category_tool — Create category

  • rename_category_tool — Rename category

  • delete_category_tool — Delete category

Import/Export

  • import_opml_tool — Import from OPML file

  • export_opml_tool — Export as OPML

  • get_stats_tool — Dashboard stats

Background Fetching

Nothing 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.

License

AGPL-3.0-or-later

Available Tools

17 tools
add_feed_toolAdd Feed ToolB

Add an RSS/Atom feed by URL, optionally assign to a category.

Inputs: url (required), category. Returns: object

create_category_toolCreate Category ToolC

Create a new category.

Inputs: name (required). Returns: object

delete_category_toolDelete Category ToolB

Delete a category. Feeds in this category become uncategorized.

Inputs: category_id (required). Returns: result

delete_feed_toolDelete Feed ToolB

Remove a feed and all its entries.

Inputs: feed_id (required). Returns: result

export_opml_toolExport Opml ToolA
Read-only

Export all feeds as OPML XML string.

Inputs: no named parameters. Returns: result

get_feed_toolGet Feed ToolA
Read-only

Get details for a single feed including entry counts.

Inputs: feed_id (required). Returns: object

get_stats_toolGet Stats ToolA
Read-only

Get dashboard stats: total feeds, unread count, entries per category.

Inputs: no named parameters. Returns: object

import_opml_toolImport Opml ToolB

Import feeds from an OPML file, creating categories from outline groups.

Inputs: file_path (required). Returns: result

list_categories_toolList Categories ToolA
Read-only

List all categories with feed counts.

Inputs: no named parameters. Returns: result

list_entries_toolList Entries ToolA
Read-only

List entries with optional filters.

Date-window filters apply to COALESCE(published, created_at), so entries with no publish date still fall in the window by ingest time. Use them to fetch only a trailing period instead of paging through everything.

Inputs: limit, offset, feed_id, since_days, +4 more. Returns: result

list_feeds_toolList Feeds ToolB
Read-only

List all feeds with unread counts.

Inputs: category_id. Returns: result

mark_read_toolMark Read ToolC

Mark entries as read.

Inputs: feed_id, entry_id, all_entries. Returns: result

mark_unread_toolMark Unread ToolC

Mark an entry as unread.

Inputs: entry_id (required). Returns: result

read_entry_toolRead Entry ToolA

Get full content of an entry (auto-marks as read).

Inputs: entry_id (required). Returns: object

refresh_feeds_toolRefresh Feeds ToolA

Crawl feed sources over the network for new content. Slow — takes 30-60s for all feeds.

Prefer the systemd timer for background updates. Use list_entries to read cached content.

Inputs: feed_id. Returns: result

rename_category_toolRename Category ToolC

Rename a category.

Inputs: name (required), category_id (required). Returns: object

search_entries_toolSearch Entries ToolB
Read-only

Full-text search across entry titles and content.

Inputs: query (required), limit. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 17 tools

    Disambiguation4/5

    Most tools target distinct resources and actions (feeds, entries, categories each have clear verbs). Minor overlap exists between read_entry_tool (which auto-marks as read) and mark_read_tool, and between list_entries_tool and search_entries_tool, but the descriptions clarify the boundaries well enough.

    Naming Consistency5/5

    Every tool follows a consistent snake_case verb_noun_tool pattern (list_feeds_tool, add_feed_tool, delete_category_tool, etc.). The convention is uniform across all 17 tools with no style mixing.

    Tool Count4/5

    17 tools is slightly above the ideal range but each earns its place across three resource domains (feeds, entries, categories) plus OPML import/export and refresh. No redundant or filler tools are present.

    Completeness4/5

    Core lifecycle is well covered: feeds (list/get/add/delete/refresh/OPML), entries (list/search/read/mark read/unread), and categories (list/create/rename/delete). Gaps include updating an existing feed (rename or move category) and bulk mark-all-read, but these are minor workarounds.

    Maintenance

    ActivityActive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers