{"slug": "rssmonster-an-agentic-rss-reader-built-on-local-embeddings-and-small-models", "title": "RSSMonster – An agentic RSS reader built on local embeddings and small models", "summary": "RSSMonster, a self-hosted intelligent RSS reader developed by Piethein Strengholt, adds a semantic and ranking layer to traditional feed reading, grouping articles by event and personal interest while evaluating quality, freshness, originality, and source trust. The tool, which runs on local embeddings and small language models, offers declarative Smart Folders and explainable ranking decisions, with support for SQLite or MySQL for deployment.", "body_md": "Copyright (c) 2026 Piethein Strengholt, [piethein@strengholt-online.nl](mailto:piethein@strengholt-online.nl)\n\nRSSMonster is a **self-hosted, intelligent RSS reader** designed to help you cut through information overload and focus on what actually matters.\n\n[Learn more about RSSMonster in the complete documentation.](https://pietheinstrengholt.github.io/rssmonster/)\n\nTraditional RSS readers are primarily organized around feeds, folders, and chronological article streams. RSSMonster adds an intelligent semantic and ranking layer on top: it groups articles covering the same event and your personal interests, evaluates signals such as quality, freshness, originality, and source trust, explains why stories rank highly, and lets you create declarative **Smart Folders** for the views that matter to you.\n\nAt its core, RSSMonster treats your feeds as a stream of signals rather than a pile of unread items. New articles are enriched with quality, freshness, originality, trust, attention, and semantic relationship metadata. That extra context lets the application answer better questions: *is this worth reading now?*, *is this just syndicated copy?*, *which sources are covering the same event?*, and *which broader storyline does this belong to?*\n\nA conventional reader effectively sees:\n\n```\nArticle\nArticle\nArticle\nArticle\nArticle\nArticle\n```\n\nRSSMonster can increasingly interpret that as:\n\n```\n               Topic\n                 │\n          Nintendo / Zelda\n                 │\n        ┌────────┴─────────┐\n        │                  │\n      Event             Related\n        │               content\n    ┌───┼───┐\n    A   B   C\n        │\n   duplicates\n```\n\nRSSMonster combines advanced search expressions, semantic clustering, quality analysis, and personal-interest-based rankings into a system where **views are declarative, not hard-coded**. Instead of fixed tabs and opaque algorithms, you define *what matters* using composable queries that power dynamic **Smart Folders** such as:\n\n*Top Stories Today*— importance-ranked, deduplicated coverage*Worth Your Time*— high-quality, original long-form content*Quick Scan*— summary-first daily overview*Low Noise Mode*— maximum signal, minimal volume\n\nRanking decisions are explainable and views are customizable. The result is a reader that can behave like a quick daily briefing, a research inbox, a low-noise monitoring tool, or a classic feed reader depending on the view you choose.\n\n**Semantic event discovery**: RSSMonster groups reporting about the same real-world story into one expandable event, so several headlines from different sources become one event with multiple articles.**Importance- and quality-aware ranking**: Freshness, personal interest, article quality, breadth of coverage, source diversity, corroboration, and source trust help surface worthwhile stories without hiding the underlying signals.**Declarative Smart Folders**: Composable search expressions turn your own definition of “important” into reusable, dynamic reading views.** Simple self-hosting**: Run RSSMonster with SQLite and no separate database service, or use MySQL for larger and higher-concurrency deployments.**Self-hosted, local, and transparent**: Your feeds and reading data stay under your control, ranking dimensions remain inspectable instead of disappearing inside an opaque recommendation system, and pluggable small language models let the feed-processing pipeline run locally.\n\nChoose the reading experience that fits the moment, follow stories instead of duplicate headlines, and keep the same focused workflow across devices. Click any screenshot to view it at full resolution.\n\nEvents and TopicsGroup related reporting into current stories and connect them to longer-running themes. |\nInterest IslandsSee the subjects your reading, favorites, and clicks keep reinforcing. |\n\nLandscapeA full dark-mode reading workspace on wider mobile and tablet screens. |\nPortraitA focused, touch-friendly article stream that travels with you. |\n\nThe default Docker Compose deployment is designed for quickly seeing RSSMonster in live action. It uses SQLite, requires no separate database or model service, and starts the web application plus its dedicated crawl worker.\n\nFor the comprehensive deployment—with MySQL and local inference using Qwen and ModernBERT—use [MySQL Deployment](#mysql-deployment).\n\n```\ngit clone https://github.com/pietheinstrengholt/rssmonster.git\ncd rssmonster\n```\n\nCreate a `.env`\n\nfile in the repository root:\n\n```\nJWT_SECRET=replace-with-a-long-random-secret\nFEVER_CREDENTIAL_SECRET=replace-with-a-long-random-secret\n```\n\nGenerate secure values with:\n\n```\nopenssl rand -hex 32\n```\n\nRun the command twice and use a different value for each secret.\n\n```\ndocker compose up -d\n```\n\nThe default `docker-compose.yml`\n\nis the quick live-action profile. It uses SQLite and stores the database in a persistent Docker volume. It disables inference-backed classifications, embeddings, the assistant, AI feed repair, and Smart Folder recommendations so it can start without downloading or running local models.\n\nOn first startup RSSMonster automatically:\n\n- creates the SQLite database file;\n- initializes the database schema;\n- starts the application; and\n- starts a dedicated crawl worker that keeps due feeds updated.\n\nOpen:\n\n```\nhttp://localhost:3000\n```\n\nand create your first account.\n\nCheck the deployment:\n\n```\ndocker compose ps\n```\n\nThe application validates database readiness, while the dedicated worker has its own crawl-health check. By default, three consecutive crawl failures or 15 minutes without a worker-state update mark the worker unhealthy.\n\nFollow the application and crawl-worker logs:\n\n```\ndocker compose logs -f rssmonster rssmonster-worker\n```\n\nSQLite data is stored in the persistent Docker volume mounted inside the container at:\n\n```\n/app/data\n```\n\nThe SQLite files can include:\n\n```\nrssmonster.sqlite\nrssmonster.sqlite-wal\nrssmonster.sqlite-shm\n```\n\nDo not remove the Docker volume unless you intentionally want to delete your RSSMonster database.\n\nTo stop RSSMonster without deleting its data:\n\n```\ndocker compose down\n```\n\nAvoid:\n\n```\ndocker compose down -v\n```\n\nunless you deliberately want to remove the persistent database volume.\n\nThe MySQL Compose deployment is the comprehensive RSSMonster profile. It is intended for installations that want higher write concurrency, multiple active users, and the local intelligent-content pipeline.\n\nIt starts:\n\n- the RSSMonster web application, dedicated crawl worker, and\n`rssmonster-ai-worker`\n\nbackground-enrichment worker; - MySQL 8.4;\n- Qwen3 Embedding for 1024-dimensional semantic vectors;\n- Qwen3.5 for local classification text generation, Smart Folder recommendations, and feed rediscovery; and\n- ModernBERT for local article scoring.\n\nThe comprehensive profile enables RSSMonster's AI-backed interface and processing features. No OpenAI API key is required for classification, embeddings, scoring, Smart Folder recommendations, or feed rediscovery. The optional natural-language assistant remains hidden unless `INFERENCE_ASSISTANT_ENABLED=true`\n\nis set after configuring `ASSISTANT_PROVIDER=openai`\n\nand `OPENAI_API_KEY`\n\n, because its current inference adapter is OpenAI-only.\n\nAdd the comprehensive deployment secrets and database passwords to the repository-root `.env`\n\n:\n\n```\nJWT_SECRET=replace-with-a-long-random-secret\nFEVER_CREDENTIAL_SECRET=replace-with-a-long-random-secret\nDB_PASSWORD=replace-with-a-strong-database-password\nMYSQL_ROOT_PASSWORD=replace-with-a-different-strong-database-password\n```\n\nUse the separate MySQL Compose configuration:\n\n```\ndocker compose -f docker-compose.mysql.yml up -d --build\n```\n\nOn the first startup, the inference container downloads Qwen and ModernBERT into the persistent `inference-model-cache`\n\nvolume. This can take several minutes depending on the host and network connection. RSSMonster, its crawl worker, and its AI worker wait until MySQL is healthy and the inference models are loaded. Each worker reports its own health. Later starts reuse the downloaded models.\n\nFollow the complete deployment while it starts:\n\n```\ndocker compose -f docker-compose.mysql.yml logs -f inference rssmonster rssmonster-worker rssmonster-ai-worker\n```\n\n**Flexible reading modes**: Use Reader Mode for summaries beside a details panel, List Mode for fast headline scanning, or Expanded Mode for distraction-free full articles. Keyboard shortcuts, drag-and-drop organization, dark mode, and mobile swipe gestures support efficient reading.**Semantic event discovery**: Group related reporting, compare sources, identify duplicate coverage, and connect events to broader topics and personal interest islands.**Smart Folders**: Build reusable views with queries such as`@today unread:true sort:recommended`\n\n,`unread:true quality:>0.7 sort:quality`\n\n, or`event:true island:true eventCount:>=3 sort:recommended`\n\n.**Advanced search**: Combine article state, dates, tags, text, semantic filters, score thresholds, and sorting. See the[search guide](/pietheinstrengholt/rssmonster/blob/master/docs/search.md)for the supported operators.**Transparent ranking signals**: Recommended ordering emphasizes personal interest, with freshness, Quality, corroboration, and rule tags as supporting signals. Top Stories separately ranks current multi-source event importance without personalization. Quality, uniqueness, attention, and feed trust remain inspectable signals where supported; attention sorting is retained only for legacy search expressions.**PWA and mobile support**: Install RSSMonster on supported devices for an app-like experience with offline support and responsive controls.** OPML and generated RSS**: Import or export subscriptions through OPML, and create filtered RSS feeds from stored articles through the`/rss`\n\nendpoint.**Third-party client compatibility**: Connect Fever clients such as Reeder or Google Reader clients including News+, FeedMe, Reeder, Vienna RSS, and ReadKit.**Automated actions**: Use regular-expression rules to delete, star, mark as read, flag as advertising, or mark matching articles as low quality.**Multi-user support**: Keep accounts, subscriptions, reading state, preferences, and assistant interactions user-scoped.** Optional AI assistant**: Enable natural-language search, summarization, classification, tagging, and feed interactions through the Model Context Protocol (MCP).\n\nRSSMonster can notify a user when a completed crawl has persisted new articles, even when the installed web app is closed. Web Push is optional: RSSMonster continues to work normally when the VAPID variables are unset.\n\nVAPID identifies your RSSMonster server to browser push services. It uses one public/private key pair for the whole RSSMonster installation:\n\n`VAPID_PUBLIC_KEY`\n\nis sent to browsers when they create a push subscription. It is not secret.`VAPID_PRIVATE_KEY`\n\nsigns outgoing push requests. Keep it secret and only provide it to the RSSMonster server.`VAPID_SUBJECT`\n\nsupplies operator contact information. Use a`mailto:`\n\naddress or an HTTPS URL that belongs to the server operator.\n\nEach browser creates its own endpoint and encryption keys after the user selects **Enable notifications**. RSSMonster stores that subscription against the authenticated user. After a crawl, the server signs and encrypts a notification for each of that user's active browser subscriptions. The browser push service can route the encrypted message but does not receive the RSSMonster login token or VAPID private key.\n\nKeep the same VAPID key pair for the lifetime of an installation. Replacing it can invalidate existing browser subscriptions and require users to enable notifications again. Never commit the private key or paste it into client-side configuration.\n\nInstall the server dependencies, then use the bundled `web-push`\n\ncommand:\n\n```\ncd server\nnpm install\nnpx web-push generate-vapid-keys\n```\n\nThe command prints a public and private key. Copy them without adding quotes or whitespace.\n\nFor a source installation, add them to `server/.env`\n\n:\n\n```\n# Optional Web Push notification configuration (VAPID).\nVAPID_PUBLIC_KEY=replace-with-the-generated-public-key\nVAPID_PRIVATE_KEY=replace-with-the-generated-private-key\nVAPID_SUBJECT=mailto:admin@example.com\n```\n\nFor Docker Compose, add the same values to the repository-root `.env`\n\nused by Compose:\n\n```\nVAPID_PUBLIC_KEY=replace-with-the-generated-public-key\nVAPID_PRIVATE_KEY=replace-with-the-generated-private-key\nVAPID_SUBJECT=https://rss.example.com\n```\n\nBoth included Compose configurations pass these optional values into the application container. Restart RSSMonster after changing them:\n\n```\ndocker compose up -d\n```\n\nRestart a source installation after changing these values:\n\n```\ncd server\nnpm start\n```\n\n- Serve RSSMonster through HTTPS in production. Browser service workers and Push subscriptions require a secure context; localhost is the development exception.\n- Install or open RSSMonster in a supported browser. On iOS and iPadOS, add RSSMonster to the Home Screen and launch that installed web app before enabling notifications.\n- Sign in, open the mobile Options sheet, and select\n**Enable notifications**. - Allow notifications in the browser or operating-system prompt.\n\nThe control changes to **Disable notifications** after a subscription is active. It can also restore a missing subscription, remove the current browser subscription, explain unsupported or unconfigured states, and remove endpoints that a push service reports as expired.\n\nIf RSSMonster says that Web Push is not configured, confirm that all three VAPID variables are present in the server process and restart it. If permission was denied, re-enable notifications through the browser or operating-system settings; a web application cannot reverse a denial itself.\n\nRSSMonster's newer architecture adds a semantic layer between feed crawling and the article list. Rather than storing articles as isolated feed entries, the system enriches them with vectors, scores, cluster membership, topic membership, and engagement signals. Those derived signals are then used by search expressions, Smart Folders, ranking, and the UI.\n\nThe semantic pipeline works in stages:\n\n**Article enrichment**: crawled articles are normalized, summarized where applicable, scored for quality, and embedded into vectors that capture meaning beyond exact keyword overlap.**Event clustering**: each article is compared with recent candidate events using semantic similarity, headline overlap, named-entity overlap, and time proximity. Strong matches update an existing event; otherwise RSSMonster can create a new event cluster.**Topic grouping**: events are assigned to broader topics using ranked membership. An event can have a primary topic while still retaining secondary topic relationships, which keeps broad storylines stable without forcing every article into a single rigid category.**Signal aggregation**: event size, source diversity, topic density, freshness, quality, uniqueness, trust, and engagement are aggregated into ranking signals. This allows larger corroborated stories to surface without letting repetitive coverage drown out more original work.**Declarative retrieval**: Smart Folders and searches consume supported signals through visible query operators such as`quality:>0.7`\n\n,`freshness:>=0.5`\n\n,`event:true`\n\n,`island:true`\n\n,`hot:true`\n\n,`tag:security`\n\n, and`sort:recommended`\n\n.\n\nThis design keeps the intelligence of the reader inspectable. RSSMonster does not only decide what to show; it exposes the dimensions behind that decision so you can build views for different reading modes. A morning scan might prefer fresh event clusters with multiple sources, while deeper research might expand the full cluster, inspect related topic groups, and compare how different feeds covered the same story.\n\nHistorical semantic rebuilding is available through `npm run semantic:all`\n\n. It rebuilds event, topic, and interest-island assignments for existing articles and is intended for explicit repair after large imports or algorithm changes.\n\nThe visible sort order is **Newest, Oldest, Top Stories, Recommended, Quality**.\n\n**Recommended**: Emphasizes signed personal interest, then freshness and Quality, with small corroboration and rule-match contributions. It does not add a separate raw feed-trust preference boost.**Top Stories**: Ignores personalization and combines event coverage, cross-source diversity, corroboration, freshness, and Quality to surface broadly supported current stories.**Article quality**: Evaluates one article's writing, tone, and promotional content as an independent`0–1`\n\nsignal.**Quality ranking**: Combines`70%`\n\narticle quality with`30%`\n\nFeedTrust while keeping both concepts separate.**Uniqueness**: Describes how standalone an article is. Articles in larger event clusters receive a lower uniqueness signal, helping the interface identify redundant coverage without removing access to the underlying articles.\n\nLegacy `sort:attention`\n\nqueries remain accepted for compatibility, but Most\nEngaged is no longer a visible sort option. Legacy `sort:trust`\n\nqueries resolve\nto Quality.\n\nFor the recommended Docker deployment:\n\n- Docker Engine or Docker Desktop\n- Docker Compose\n\nNo separate MySQL installation is required when using the default SQLite deployment.\n\nFor running RSSMonster directly from source:\n\n**Node.js**: Version 22.x or higher** npm**: Comes bundled with Node.js** Git**: For cloning the repository** SQLite**: Recommended for simple local and personal installations** MySQL**: Optional; recommended for higher-concurrency installations\n\n```\ngit clone https://github.com/pietheinstrengholt/rssmonster.git\ncd rssmonster\n# Install server dependencies\ncd server\nnpm install\n\n# Install client dependencies\ncd ../client\nnpm install\n\n# Install inference dependencies\ncd ../inference\nnpm install\ncd ..\n```\n\nCopy the `.env.example`\n\nfiles to `.env`\n\n:\n\n```\ncp server/.env.example server/.env\ncp client/.env.example client/.env\ncp inference/.env.example inference/.env\n```\n\nRSSMonster sends all model requests to the standalone inference service.\nConfigure the server connection in `server/.env`\n\n:\n\n```\nINFERENCE_URL=http://127.0.0.1:3001\nINFERENCE_TIMEOUT_MS=30000\nINFERENCE_AI_ENABLED=true\nINFERENCE_ASSISTANT_ENABLED=false\nSKIP_ARTICLE_CLASSIFICATION_ANALYSIS=false\nSKIP_ARTICLE_EMBEDDINGS=false\nSKIP_SEMANTIC_LABELING=false\n```\n\nSet `INFERENCE_AI_ENABLED=false`\n\nto prevent every server and worker inference\nrequest. This master switch overrides the feature-specific skip settings.\nLeave `INFERENCE_ASSISTANT_ENABLED=false`\n\nto hide chat while keeping the other\nintelligent features enabled. Set it to `true`\n\non the server only after the\nassistant provider and credentials are configured in inference.\n\nUse a longer timeout such as `600000`\n\nwhen running Qwen on low-power hardware.\n\nThe inference service selects providers independently for semantic embeddings,\ntext generation, article scoring, and assistant responses. A complete OpenAI\nconfiguration in `inference/.env`\n\nis:\n\n```\n# OpenAI\nEMBEDDING_PROVIDER=openai\nGENERATION_PROVIDER=openai\nARTICLE_SCORING_PROVIDER=openai\nASSISTANT_PROVIDER=openai\nASSISTANT_MODEL=gpt-4o-mini\nOPENAI_API_KEY=your-openai-api-key\nOPENAI_EMBEDDING_MODEL=text-embedding-3-small\nOPENAI_EMBEDDING_DIMENSIONS=1536\n```\n\nAlternatively, embeddings, article generation, and scoring can run locally while the assistant remains on OpenAI:\n\n```\n# Qwen and ModernBERT\nEMBEDDING_PROVIDER=qwen\nGENERATION_PROVIDER=qwen\nARTICLE_SCORING_PROVIDER=modernbert\nEMBEDDING_MODEL=onnx-community/Qwen3-Embedding-0.6B-ONNX\nEMBEDDING_DIMENSIONS=1024\nGENERATION_MODEL=onnx-community/Qwen3.5-0.8B-ONNX\nGENERATION_DTYPE=q4\nASSISTANT_PROVIDER=openai\nASSISTANT_MODEL=gpt-4o-mini\nOPENAI_API_KEY=your-openai-api-key\nINFERENCE_MODEL_CACHE_DIR=.cache/models\n```\n\nRun inference with `cd inference && npm run dev`\n\nduring development. Selected\nQwen3 Embedding, Qwen3.5 generation, and ModernBERT models are downloaded and\nloaded during service startup, then reused from the model cache. The service\nlogs when all configured models are ready and crawling can start. Development\nmode also logs content-safe activity for embeddings, summaries, tags, article\nscoring, assistant calls, Smart Folder recommendations, and feed rediscovery.\nAssistant responses currently continue to use OpenAI.\nSee [Model Usage](/pietheinstrengholt/rssmonster/blob/master/docs/model-usage.md) and\n[Inference administration](/pietheinstrengholt/rssmonster/blob/master/docs/inference.md) for production setup and\nmodel-specific guidance.\n\nFor a simple local installation, configure `server/.env`\n\nwith:\n\n```\nNODE_ENV=development\n\nDB_DIALECT=sqlite\nDB_STORAGE=./data/rssmonster.sqlite\n```\n\nRSSMonster creates the SQLite parent data directory when required.\n\nSQLite installations use conservative crawl concurrency settings automatically to reduce write contention.\n\nTo use MySQL instead, configure:\n\n```\nNODE_ENV=development\n\nDB_DIALECT=mysql\nDB_DATABASE=rssmonster\nDB_USERNAME=rssmonster\nDB_PASSWORD=your_database_password\nDB_HOSTNAME=localhost\nDB_PORT=3306\n```\n\nConfigure `client/.env`\n\n:\n\n```\nVITE_APP_HOSTNAME=http://localhost:3000\n```\n\nCreate the database schema:\n\n```\ncd server\nnpm run db\n```\n\nIf you explicitly need the project seeders:\n\n```\n./node_modules/.bin/sequelize db:seed:all\n```\n\nThis section applies only to MySQL installations.\n\nWhen processing or querying large numbers of articles, increasing MySQL sort memory can reduce sort-related bottlenecks.\n\nAdd the following to your MySQL configuration, for example in `my.cnf`\n\n:\n\n```\n[mysqld]\nsort_buffer_size = 4M\n```\n\nRun a crawl manually with:\n\n```\ncd server\nDISABLE_LISTENER=true npm run crawl\n```\n\nThis runs a crawl of active feeds and prints the crawl and semantic-processing results to the console.\n\nProduction installations can run the dedicated crawl worker using the process-management approach appropriate to the deployment environment.\n\nIf you need to rebuild article clusters from scratch:\n\n```\ncd server\nnpm run semantic:all\n```\n\nThis command rebuilds historical event assignments, topics, interest islands, and interest scores for every user.\n\nUse:\n\n```\nnpm run semantic:all -- --userId=3\n```\n\nto limit the rebuild to one user.\n\n**When to use this:**\n\n- after bulk importing articles;\n- when cluster quality degrades over time;\n- after changing clustering algorithms or parameters;\n- to repair cluster assignment inconsistencies.\n\nThis is an explicit historical rebuild workflow. Normal post-crawl semantic processing only considers newly created, unfiltered articles.\n\nTaxonomy-vector generation is **not required for a normal SQLite installation or Docker Quick Start**.\n\nIf you explicitly need to generate or regenerate taxonomy vectors:\n\n```\ncd server\nnpm run taxonomy:vectors\nnpm run seed:island-taxonomy\n```\n\n`npm run taxonomy:vectors`\n\nuses the embedding model selected by the running\ninference service, so it works with either OpenAI or Qwen.\n\nFeed trust estimates how consistently valuable a subscribed source has been as a source of articles:\n\n```\ncd server\nnpm run feedtrust\n```\n\nThis command calculates trust scores from `0.0`\n\nto `1.0`\n\nfor active feeds using:\n\n**Article quality (50%)**: Average existing normalized article quality** Engagement (20%)**: Usefulness observed through reads, favorites, and clicks** Originality (15%)**: Canonical articles versus deterministically linked duplicates** Negative-feedback quality (15%)**: Explicit negative feedback among exposed articles\n\n**When to use this:**\n\n- periodically to update feed rankings;\n- after significant changes in reading patterns;\n- to identify low-quality or noisy feeds.\n\nEach signal has its own evidence confidence and shrinks toward the neutral score of `0.75`\n\nwhen evidence is sparse. Recalculating unchanged data produces the same result.\n\n[Read the conceptual FeedTrust model](/pietheinstrengholt/rssmonster/blob/master/docs/feedtrust.md).\n\nRSSMonster can expose an AI-powered assistant for natural-language interactions with your RSS feeds. It is optional and complements the core semantic pipeline rather than replacing event discovery, ranking, topics, or Smart Folders.\n\nExample requests include:\n\n- \"Show me technology articles from the last week\"\n- \"What are my favorite articles?\"\n- \"Find unread posts about JavaScript\"\n\nTo enable the AI assistant and other OpenAI-backed capabilities, configure:\n\n**Server ( server/.env):**\n\n```\nINFERENCE_AI_ENABLED=true\nINFERENCE_ASSISTANT_ENABLED=true\nINFERENCE_AGENT_TIMEOUT_MS=300000\n```\n\n**Inference ( inference/.env):**\n\n```\nOPENAI_API_KEY=your-openai-api-key-here\nASSISTANT_PROVIDER=openai\nASSISTANT_MODEL=gpt-4o-mini\n```\n\nThe server keeps no OpenAI credential; all provider calls go through inference. After configuration, restart the client, server, and inference processes.\n\nThe assistant provides:\n\n- natural-language search across articles;\n- time-based filtering;\n- article summarization;\n- classification and tagging;\n- favorite and trending article discovery;\n- Smart recommendations based on reading interests.\n\nRSSMonster automatically tracks article interactions and can use AI to classify content with three quality metrics:\n\n**advertisementScore**— promotional or advertising-content detection;** sentimentScore**— emotional-tone analysis;** qualityScore**— content depth and writing-quality analysis.\n\nThese scores provide additional inspectable signals for filtering and ranking.\n\n**Note:** All interactions are user-scoped, ensuring privacy and data isolation in multi-user environments.\n\n**Note for Developers:** The MCP server is available at `/mcp`\n\nfor programmatic integration. Authentication requires a valid JWT token passed through the `Authorization: Bearer <token>`\n\nheader. Obtain a token by authenticating through `/api/auth/login`\n\n.\n\nThe GitHub Actions workflow runs independent jobs for the server on MySQL, the server on SQLite, inference, and the client. The inference job also validates both Compose configurations and builds the inference Docker image.\n\n**Client with hot reload:**\n\n```\ncd client\nnpm run dev\n```\n\n**Server with hot reload:**\n\n```\ncd server\nnpm run dev\n```\n\nTo attach a debugger:\n\n```\nnpm run debug\n```\n\nNode exposes its inspector on port `9229`\n\n.\n\nThe client will typically run on:\n\n```\nhttp://localhost:8080\n```\n\nand the server on:\n\n```\nhttp://localhost:3000\n```\n\nTo quickly see RSSMonster in live action, use the SQLite deployment described in [Docker Quick Start](#docker-quick-start):\n\n```\ndocker compose up -d\n```\n\nThis quick profile requires no separate database server or inference models and keeps persistent application data in a Docker volume.\n\nFor the comprehensive MySQL and local-inference deployment:\n\n```\ndocker compose -f docker-compose.mysql.yml up -d --build\n```\n\nFor environments where RSSMonster runs directly on the host rather than through Docker:\n\nSQLite:\n\n```\nNODE_ENV=production\nDB_DIALECT=sqlite\nDB_STORAGE=/path/to/persistent/rssmonster.sqlite\n```\n\nOr MySQL:\n\n```\nNODE_ENV=production\nDB_DIALECT=mysql\nDB_HOSTNAME=localhost\nDB_PORT=3306\nDB_DATABASE=rssmonster\nDB_USERNAME=rssmonster\nDB_PASSWORD=your_database_password\ncd server\nnpm ci\nnpm run db\ncd ../client\nnpm ci\nnpm run build\nrm -rf ../server/dist\ncp -R dist ../server/dist\ncd ../server\nnpm run start\n```\n\nUse a suitable process manager or service manager for long-running production installations.\n\nFor production environments, use Let's Encrypt with Certbot for SSL/TLS certificates.\n\n```\ncertbot certonly --standalone -d yourdomain.com --agree-tos -q\n```\n\nFor example, create a weekly cron job:\n\n```\n0 0 * * 0 certbot renew --quiet && cp /etc/letsencrypt/live/yourdomain.com/* /path/to/rssmonster/cert/\n```\n\nAdd the following to `server/.env`\n\n:\n\n```\nENABLE_HTTPS=true\n```\n\nRSSMonster will use certificates from:\n\n```\ncert/fullchain.pem\ncert/privkey.pem\n```\n\nRestart the server after updating the configuration.\n\nRSSMonster is compatible with the Fever API, enabling integration with third-party RSS clients.\n\n**Fever API Endpoint:**`http://your-rssmonster-url/api/fever`\n\n**Authentication:** Any valid RSSMonster username and password\n\n**Reeder (iOS)**: Configure by adding a Fever account with the endpoint above\n\nRSSMonster supports the Google Reader API, providing compatibility with a wide range of RSS clients.\n\nSee the [Google Reader API compatibility matrix](/pietheinstrengholt/rssmonster/blob/master/docs/google-reader-api.md) for the exact endpoint contract, authentication examples, client checklist, identifier formats, and unsupported behavior.\n\n**API Endpoint:**`http://your-rssmonster-url/api/greader`\n\n**Authentication:** Use your RSSMonster username and password\n\n| App | Platform | Notes |\n|---|---|---|\n|\n\n[FeedMe](https://play.google.com/store/apps/details?id=com.seazon.feedme)[Reeder](https://www.reederapp.com/)[Vienna RSS](http://www.vienna-rss.com/)[ReadKit](https://readkit.app/)**Authentication:** ClientLogin with username/password**Subscriptions:** List, add, edit, remove feeds**Tags/Categories:** List, rename, delete categories**Articles:** Fetch by stream, feed, or category with pagination**Mark as read/unread:** Individual articles or mark all as read**Star/unstar:** Favorite articles**Unread counts:** Per feed, category, and total\n\nContributions are welcome.\n\nTo contribute:\n\n-\nFork the repository.\n\n-\nCreate a feature branch:\n\n```\ngit switch -c feature/amazing-feature\n```\n\n-\nCommit your changes:\n\n```\ngit commit -m \"Add amazing feature\"\n```\n\n-\nPush the branch:\n\n```\ngit push origin feature/amazing-feature\n```\n\n-\nOpen a Pull Request.\n\nPlease ensure your code follows the existing style and includes appropriate tests.\n\nRSSMonster is built with the following frameworks and libraries:\n\n— JavaScript runtime[Node.js](https://nodejs.org/)— Web framework[Express](https://expressjs.com/)— Frontend framework[Vue.js 3](https://vuejs.org/)— Icon library[Bootstrap Icons](https://icons.getbootstrap.com/)— ORM and database abstraction[Sequelize](https://sequelize.org/)**SQLite**— Default database for simple self-hosted installations** MySQL**— Supported database for higher-concurrency installations— RSS/Atom feed parsing[feedsmith](https://github.com/macieklamberski/feedsmith)\n\nThis project is licensed under the MIT License. See [LICENSE.md](/pietheinstrengholt/rssmonster/blob/master/LICENSE.md) for details.", "url": "https://wpnews.pro/news/rssmonster-an-agentic-rss-reader-built-on-local-embeddings-and-small-models", "canonical_source": "https://github.com/pietheinstrengholt/rssmonster/", "published_at": "2026-08-30 13:47:45+00:00", "updated_at": "2026-08-30 14:22:08.092742+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-products", "ai-tools", "machine-learning"], "entities": ["RSSMonster", "Piethein Strengholt"], "alternates": {"html": "https://wpnews.pro/news/rssmonster-an-agentic-rss-reader-built-on-local-embeddings-and-small-models", "markdown": "https://wpnews.pro/news/rssmonster-an-agentic-rss-reader-built-on-local-embeddings-and-small-models.md", "text": "https://wpnews.pro/news/rssmonster-an-agentic-rss-reader-built-on-local-embeddings-and-small-models.txt", "jsonld": "https://wpnews.pro/news/rssmonster-an-agentic-rss-reader-built-on-local-embeddings-and-small-models.jsonld"}}