@max1ab/rss-news
v0.1.0
Published
MCP server for incremental RSS news fetching with SQLite-backed read state.
Downloads
56
Readme
RSS News MCP
____ ____ ____ _ _ __ __ ____ ____
| _ \/ ___/ ___| | \ | | _____ _____ | \/ |/ ___| _ \
| |_) \___ \___ \ | \| |/ _ \ \ /\ / / __| | |\/| | | | |_) |
| _ < ___) |__) | | |\ | __/\ V V /\__ \ | | | | |___| __/
|_| \_\____/____/ |_| \_|\___| \_/\_/ |___/ |_| |_|\____|_|
Node.js + TypeScript MCP server for RSS news ingestion with incremental delivery.
Features
- Fetch RSS/Atom feeds with conditional requests (
ETag/Last-Modified) - Support
rsshub://protocol with automatic instance fallback - Persist feed state and entries in SQLite
- Return only undelivered items to the agent
- Deduplicate entries using a stable
entry_uid
Quick Start
npm install
npm run build
npm startDevelopment:
npm run devRun tests:
npm testEnvironment Variables
RSS_MCP_DB_PATH: SQLite path (default:<project-root>/data/rss.sqlite)RSS_MCP_REQUEST_TIMEOUT_MS: fetch timeout in milliseconds (default:15000)RSS_MCP_DEFAULT_LIMIT_PER_FEED: default return limit per feed (default:20)RSS_MCP_MAX_FEEDS_PER_REQUEST: max feed count for each call (default:50)RSS_MCP_USER_AGENT: custom request User-AgentRSS_MCP_DEBUG: set1ortrueto enable debug logsRSS_MCP_DEBUG_PREVIEW_LENGTH: preview length of response body for debug (default:300)
MCP Tool
update_news
Fetch configured feeds and update local entries/feeds state.
Input:
{
"feedUrls": ["https://example.com/rss.xml", "rsshub://deeplearning/the-batch"]
}Output:
ok: whether tool call completedresolvedFeedUrls: actual feed list used by this callsummary: aggregate update stats (feedsTotal,successFeeds,errorFeeds,fetchedTotal,insertedTotal,skipped304Feeds)errors: per-feed error list (feedUrl,message)updatedAt: ISO timestamp
fetch_latest_news
Input:
{
"feedUrls": ["https://example.com/rss.xml", "rsshub://deeplearning/the-batch"],
"limit": 20,
"sinceMinutes": 120,
"includeDelivered": false,
"markAsRead": true
}Output:
items: globally latest news sorted by timestamp (across all selected feeds)includeDelivered: whentrue, return all news in time windowmarkAsRead: whenfalse, do not mark fetched undelivered items as readresolvedFeedUrls: actual feed list used by this calllimit: global result limit (not per feed)
Notes:
feedUrlsis now optional. If omitted, server uses all known RSS sources from the database.- Default mode is
includeDelivered: false(only undelivered news). - Default mode is
markAsRead: true(fetched undelivered items are marked read/delivered). fetch_latest_newsno longer pulls remote RSS by itself; callupdate_newsfirst to refresh data.
get_news_count
Count news in the past N hours.
Input:
{
"pastHours": 24,
"includeDelivered": false,
"feedUrls": ["https://example.com/rss.xml"]
}Output fields:
countType:undeliveredoralltotalCount: summed countcountsByFeed: per-feed count map
set_read_status_by_time_range
Set read/unread status in a date range.
Input:
{
"startDate": "2026-02-20",
"endDate": "2026-02-23",
"status": "read",
"feedUrls": ["https://example.com/rss.xml"]
}Behavior:
status: "read": mark matched entries as read (insert intodeliveries)status: "unread": mark matched entries as unread (delete fromdeliveries)
MCP Config Example
Add this server to your MCP config:
{
"mcpServers": {
"rss-news": {
"command": "npx",
"args": ["-y", "@max1ab/rss-news"]
}
}
}If you want to keep the SQLite file in a custom location:
RSS_MCP_DB_PATH=/ABSOLUTE/PATH/rss-news/data/rss.sqlite npx -y @max1ab/rss-newsIncremental Delivery Model
- Database file is created lazily on first repository usage if it does not exist.
entries: stores fetched entries (feed_url + entry_uidis unique)deliveries: stores which entries were already returned to agent- Tool returns only entries not present in
deliveries, then marks them delivered
