Modern, self-hosted RSS reader with smart folders, powerful search, and a clean three-pane reading experience. Built with Vue and Express.
536
stars
1,861
commits
JavaScript
primary language
Sep 10, 2026
updated
Copyright (c) 2026 Piethein Strengholt, piethein@strengholt-online.nl
RSSMonster is a self-hosted, intelligent RSS reader designed to help you cut through information overload and focus on what actually matters.
Learn more about RSSMonster in the complete documentation.
Traditional 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.

At 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?
A conventional reader effectively sees:
Article
Article
Article
Article
Article
Article
RSSMonster can increasingly interpret that as:
Topic
│
Nintendo / Zelda
│
┌────────┴─────────┐
│ │
Event Related
│ content
┌───┼───┐
A B C
│
duplicates

RSSMonster 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:
Ranking 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.
Choose 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.
| Events and Topics Group related reporting into current stories and connect them to longer-running themes. | Interest Islands See the subjects your reading, favorites, and clicks keep reinforcing. |
![]() | ![]() |
| Landscape A full dark-mode reading workspace on wider mobile and tablet screens. | Portrait A focused, touch-friendly article stream that travels with you. |
![]() | ![]() |
The 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.
For the comprehensive deployment—with MySQL and local inference using Qwen and ModernBERT—use MySQL Deployment.
git clone https://github.com/pietheinstrengholt/rssmonster.git
cd rssmonster
Create a .env file in the repository root:
JWT_SECRET=replace-with-a-long-random-secret
FEVER_CREDENTIAL_SECRET=replace-with-a-long-random-secret
Generate secure values with:
openssl rand -hex 32
Run the command twice and use a different value for each secret.
docker compose up -d
The default docker-compose.yml is 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.
On first startup RSSMonster automatically:
Open:
http://localhost:3000
and create your first account.
Check the deployment:
docker compose ps
The 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.
Follow the application and crawl-worker logs:
docker compose logs -f rssmonster rssmonster-worker
SQLite data is stored in the persistent Docker volume mounted inside the container at:
/app/data
The SQLite files can include:
rssmonster.sqlite
rssmonster.sqlite-wal
rssmonster.sqlite-shm
Do not remove the Docker volume unless you intentionally want to delete your RSSMonster database.
To stop RSSMonster without deleting its data:
docker compose down
Avoid:
docker compose down -v
unless you deliberately want to remove the persistent database volume.
The 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.
It starts:
rssmonster-ai-worker background-enrichment worker;The 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 is set after configuring ASSISTANT_PROVIDER=openai and OPENAI_API_KEY, because its current inference adapter is OpenAI-only.
Add the comprehensive deployment secrets and database passwords to the repository-root .env:
JWT_SECRET=replace-with-a-long-random-secret
FEVER_CREDENTIAL_SECRET=replace-with-a-long-random-secret
DB_PASSWORD=replace-with-a-strong-database-password
MYSQL_ROOT_PASSWORD=replace-with-a-different-strong-database-password
Use the separate MySQL Compose configuration:
docker compose -f docker-compose.mysql.yml up -d --build
On the first startup, the inference container downloads Qwen and ModernBERT into the persistent inference-model-cache volume. 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.
Follow the complete deployment while it starts:
docker compose -f docker-compose.mysql.yml logs -f inference rssmonster rssmonster-worker rssmonster-ai-worker
@today unread:true sort:recommended, unread:true quality:>0.7 sort:quality, or event:true island:true eventCount:>=3 sort:recommended./rss endpoint.RSSMonster 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.
VAPID identifies your RSSMonster server to browser push services. It uses one public/private key pair for the whole RSSMonster installation:
VAPID_PUBLIC_KEY is sent to browsers when they create a push subscription. It is not secret.VAPID_PRIVATE_KEY signs outgoing push requests. Keep it secret and only provide it to the RSSMonster server.VAPID_SUBJECT supplies operator contact information. Use a mailto: address or an HTTPS URL that belongs to the server operator.Each 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.
Keep 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.
Install the server dependencies, then use the bundled web-push command:
cd server
npm install
npx web-push generate-vapid-keys
The command prints a public and private key. Copy them without adding quotes or whitespace.
For a source installation, add them to server/.env:
# Optional Web Push notification configuration (VAPID).
VAPID_PUBLIC_KEY=replace-with-the-generated-public-key
VAPID_PRIVATE_KEY=replace-with-the-generated-private-key
VAPID_SUBJECT=mailto:admin@example.com
For Docker Compose, add the same values to the repository-root .env used by Compose:
VAPID_PUBLIC_KEY=replace-with-the-generated-public-key
VAPID_PRIVATE_KEY=replace-with-the-generated-private-key
VAPID_SUBJECT=https://rss.example.com
Both included Compose configurations pass these optional values into the application container. Restart RSSMonster after changing them:
docker compose up -d
Restart a source installation after changing these values:
cd server
npm start
The 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.
If 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.
RSSMonster'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.
The semantic pipeline works in stages:
quality:>0.7, freshness:>=0.5, event:true, island:true, hot:true, tag:security, and sort:recommended.This 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.
Historical semantic rebuilding is available through npm run semantic:all. It rebuilds event, topic, and interest-island assignments for existing articles and is intended for explicit repair after large imports or algorithm changes.
The visible sort order is Newest, Oldest, Top Stories, Recommended, Quality.
0–1 signal.70% article quality with 30% FeedTrust while keeping both concepts separate.Legacy sort:attention queries remain accepted for compatibility, but Most
Engaged is no longer a visible sort option. Legacy sort:trust queries resolve
to Quality.
For the recommended Docker deployment:
No separate MySQL installation is required when using the default SQLite deployment.
For running RSSMonster directly from source:
git clone https://github.com/pietheinstrengholt/rssmonster.git
cd rssmonster
# Install server dependencies
cd server
npm install
# Install client dependencies
cd ../client
npm install
# Install inference dependencies
cd ../inference
npm install
cd ..
Copy the .env.example files to .env:
cp server/.env.example server/.env
cp client/.env.example client/.env
cp inference/.env.example inference/.env
RSSMonster sends all model requests to the standalone inference service.
Configure the server connection in server/.env:
INFERENCE_URL=http://127.0.0.1:3001
INFERENCE_TIMEOUT_MS=30000
INFERENCE_AI_ENABLED=true
INFERENCE_ASSISTANT_ENABLED=false
SKIP_ARTICLE_CLASSIFICATION_ANALYSIS=false
SKIP_ARTICLE_EMBEDDINGS=false
SKIP_SEMANTIC_LABELING=false
Set INFERENCE_AI_ENABLED=false to prevent every server and worker inference
request. This master switch overrides the feature-specific skip settings.
Leave INFERENCE_ASSISTANT_ENABLED=false to hide chat while keeping the other
intelligent features enabled. Set it to true on the server only after the
assistant provider and credentials are configured in inference.
Use a longer timeout such as 600000 when running Qwen on low-power hardware.
The inference service selects providers independently for semantic embeddings,
text generation, article scoring, and assistant responses. A complete OpenAI
configuration in inference/.env is:
# OpenAI
EMBEDDING_PROVIDER=openai
GENERATION_PROVIDER=openai
ARTICLE_SCORING_PROVIDER=openai
ASSISTANT_PROVIDER=openai
ASSISTANT_MODEL=gpt-4o-mini
OPENAI_API_KEY=your-openai-api-key
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
OPENAI_EMBEDDING_DIMENSIONS=1536
Alternatively, embeddings, article generation, and scoring can run locally while the assistant remains on OpenAI:
# Qwen and ModernBERT
EMBEDDING_PROVIDER=qwen
GENERATION_PROVIDER=qwen
ARTICLE_SCORING_PROVIDER=modernbert
EMBEDDING_MODEL=onnx-community/Qwen3-Embedding-0.6B-ONNX
EMBEDDING_DIMENSIONS=1024
GENERATION_MODEL=onnx-community/Qwen3.5-0.8B-ONNX
GENERATION_DTYPE=q4
ASSISTANT_PROVIDER=openai
ASSISTANT_MODEL=gpt-4o-mini
OPENAI_API_KEY=your-openai-api-key
INFERENCE_MODEL_CACHE_DIR=.cache/models
Run inference with cd inference && npm run dev during development. Selected
Qwen3 Embedding, Qwen3.5 generation, and ModernBERT models are downloaded and
loaded during service startup, then reused from the model cache. The service
logs when all configured models are ready and crawling can start. Development
mode also logs content-safe activity for embeddings, summaries, tags, article
scoring, assistant calls, Smart Folder recommendations, and feed rediscovery.
Assistant responses currently continue to use OpenAI.
See Model Usage and
Inference administration for production setup and
model-specific guidance.
For a simple local installation, configure server/.env with:
NODE_ENV=development
DB_DIALECT=sqlite
DB_STORAGE=./data/rssmonster.sqlite
RSSMonster creates the SQLite parent data directory when required.
SQLite installations use conservative crawl concurrency settings automatically to reduce write contention.
To use MySQL instead, configure:
NODE_ENV=development
DB_DIALECT=mysql
DB_DATABASE=rssmonster
DB_USERNAME=rssmonster
DB_PASSWORD=your_database_password
DB_HOSTNAME=localhost
DB_PORT=3306
Configure client/.env:
VITE_APP_HOSTNAME=http://localhost:3000
Create the database schema:
cd server
npm run db
If you explicitly need the project seeders:
./node_modules/.bin/sequelize db:seed:all
This section applies only to MySQL installations.
When processing or querying large numbers of articles, increasing MySQL sort memory can reduce sort-related bottlenecks.
Add the following to your MySQL configuration, for example in my.cnf:
[mysqld]
sort_buffer_size = 4M
Run a crawl manually with:
cd server
DISABLE_LISTENER=true npm run crawl
This runs a crawl of active feeds and prints the crawl and semantic-processing results to the console.
Production installations can run the dedicated crawl worker using the process-management approach appropriate to the deployment environment.
If you need to rebuild article clusters from scratch:
cd server
npm run semantic:all
This command rebuilds historical event assignments, topics, interest islands, and interest scores for every user.
Use:
npm run semantic:all -- --userId=3
to limit the rebuild to one user.
When to use this:
This is an explicit historical rebuild workflow. Normal post-crawl semantic processing only considers newly created, unfiltered articles.
Taxonomy-vector generation is not required for a normal SQLite installation or Docker Quick Start.
If you explicitly need to generate or regenerate taxonomy vectors:
cd server
npm run taxonomy:vectors
npm run seed:island-taxonomy
npm run taxonomy:vectors uses the embedding model selected by the running
inference service, so it works with either OpenAI or Qwen.
Feed trust estimates how consistently valuable a subscribed source has been as a source of articles:
cd server
npm run feedtrust
This command calculates trust scores from 0.0 to 1.0 for active feeds using:
When to use this:
Each signal has its own evidence confidence and shrinks toward the neutral score of 0.75 when evidence is sparse. Recalculating unchanged data produces the same result.
Read the conceptual FeedTrust model.
RSSMonster 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.
Example requests include:

To enable the AI assistant and other OpenAI-backed capabilities, configure:
Server (server/.env):
INFERENCE_AI_ENABLED=true
INFERENCE_ASSISTANT_ENABLED=true
INFERENCE_AGENT_TIMEOUT_MS=300000
Inference (inference/.env):
OPENAI_API_KEY=your-openai-api-key-here
ASSISTANT_PROVIDER=openai
ASSISTANT_MODEL=gpt-4o-mini
The server keeps no OpenAI credential; all provider calls go through inference. After configuration, restart the client, server, and inference processes.
The assistant provides:
RSSMonster automatically tracks article interactions and can use AI to classify content with three quality metrics:
These scores provide additional inspectable signals for filtering and ranking.
Note: All interactions are user-scoped, ensuring privacy and data isolation in multi-user environments.
Note for Developers: The MCP server is available at /mcp for programmatic integration. Authentication requires a valid JWT token passed through the Authorization: Bearer <token> header. Obtain a token by authenticating through /api/auth/login.
The 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.
Client with hot reload:
cd client
npm run dev
Server with hot reload:
cd server
npm run dev
To attach a debugger:
npm run debug
Node exposes its inspector on port 9229.
The client will typically run on:
http://localhost:8080
and the server on:
http://localhost:3000
To quickly see RSSMonster in live action, use the SQLite deployment described in Docker Quick Start:
docker compose up -d
This quick profile requires no separate database server or inference models and keeps persistent application data in a Docker volume.
For the comprehensive MySQL and local-inference deployment:
docker compose -f docker-compose.mysql.yml up -d --build
For environments where RSSMonster runs directly on the host rather than through Docker:
SQLite:
NODE_ENV=production
DB_DIALECT=sqlite
DB_STORAGE=/path/to/persistent/rssmonster.sqlite
Or MySQL:
NODE_ENV=production
DB_DIALECT=mysql
DB_HOSTNAME=localhost
DB_PORT=3306
DB_DATABASE=rssmonster
DB_USERNAME=rssmonster
DB_PASSWORD=your_database_password
cd server
npm ci
npm run db
cd ../client
npm ci
npm run build
rm -rf ../server/dist
cp -R dist ../server/dist
cd ../server
npm run start
Use a suitable process manager or service manager for long-running production installations.
For production environments, use Let's Encrypt with Certbot for SSL/TLS certificates.
certbot certonly --standalone -d yourdomain.com --agree-tos -q
For example, create a weekly cron job:
0 0 * * 0 certbot renew --quiet && cp /etc/letsencrypt/live/yourdomain.com/* /path/to/rssmonster/cert/
Add the following to server/.env:
ENABLE_HTTPS=true
RSSMonster will use certificates from:
cert/fullchain.pem
cert/privkey.pem
Restart the server after updating the configuration.
RSSMonster is compatible with the Fever API, enabling integration with third-party RSS clients.
http://your-rssmonster-url/api/fever
RSSMonster supports the Google Reader API, providing compatibility with a wide range of RSS clients.
See the Google Reader API compatibility matrix for the exact endpoint contract, authentication examples, client checklist, identifier formats, and unsupported behavior.
http://your-rssmonster-url/api/greader| App | Platform | Notes |
|---|---|---|
| News+ | Android | With Google Reader extension |
| FeedMe | Android | Full sync support |
| Reeder | iOS/macOS | Classic version |
| Vienna RSS | macOS | Open source |
| ReadKit | macOS | Multi-service reader |
Contributions are welcome.
To contribute:
Fork the repository.
Create a feature branch:
git switch -c feature/amazing-feature
Commit your changes:
git commit -m "Add amazing feature"
Push the branch:
git push origin feature/amazing-feature
Open a Pull Request.
Please ensure your code follows the existing style and includes appropriate tests.
RSSMonster is built with the following frameworks and libraries:
This project is licensed under the MIT License. See LICENSE.md for details.
JavaScript
84.8%
Vue
13.8%
Modern, self-hosted RSS reader with smart folders, powerful search, and a clean three-pane reading experience. Built with Vue and Express.
536
stars
1,861
commits
JavaScript
primary language
Sep 10, 2026
updated
Copyright (c) 2026 Piethein Strengholt, piethein@strengholt-online.nl
RSSMonster is a self-hosted, intelligent RSS reader designed to help you cut through information overload and focus on what actually matters.
Learn more about RSSMonster in the complete documentation.
Traditional 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.

At 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?
A conventional reader effectively sees:
Article
Article
Article
Article
Article
Article
RSSMonster can increasingly interpret that as:
Topic
│
Nintendo / Zelda
│
┌────────┴─────────┐
│ │
Event Related
│ content
┌───┼───┐
A B C
│
duplicates

RSSMonster 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:
Ranking 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.
Choose 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.
| Events and Topics Group related reporting into current stories and connect them to longer-running themes. | Interest Islands See the subjects your reading, favorites, and clicks keep reinforcing. |
![]() | ![]() |
| Landscape A full dark-mode reading workspace on wider mobile and tablet screens. | Portrait A focused, touch-friendly article stream that travels with you. |
![]() | ![]() |
The 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.
For the comprehensive deployment—with MySQL and local inference using Qwen and ModernBERT—use MySQL Deployment.
git clone https://github.com/pietheinstrengholt/rssmonster.git
cd rssmonster
Create a .env file in the repository root:
JWT_SECRET=replace-with-a-long-random-secret
FEVER_CREDENTIAL_SECRET=replace-with-a-long-random-secret
Generate secure values with:
openssl rand -hex 32
Run the command twice and use a different value for each secret.
docker compose up -d
The default docker-compose.yml is 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.
On first startup RSSMonster automatically:
Open:
http://localhost:3000
and create your first account.
Check the deployment:
docker compose ps
The 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.
Follow the application and crawl-worker logs:
docker compose logs -f rssmonster rssmonster-worker
SQLite data is stored in the persistent Docker volume mounted inside the container at:
/app/data
The SQLite files can include:
rssmonster.sqlite
rssmonster.sqlite-wal
rssmonster.sqlite-shm
Do not remove the Docker volume unless you intentionally want to delete your RSSMonster database.
To stop RSSMonster without deleting its data:
docker compose down
Avoid:
docker compose down -v
unless you deliberately want to remove the persistent database volume.
The 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.
It starts:
rssmonster-ai-worker background-enrichment worker;The 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 is set after configuring ASSISTANT_PROVIDER=openai and OPENAI_API_KEY, because its current inference adapter is OpenAI-only.
Add the comprehensive deployment secrets and database passwords to the repository-root .env:
JWT_SECRET=replace-with-a-long-random-secret
FEVER_CREDENTIAL_SECRET=replace-with-a-long-random-secret
DB_PASSWORD=replace-with-a-strong-database-password
MYSQL_ROOT_PASSWORD=replace-with-a-different-strong-database-password
Use the separate MySQL Compose configuration:
docker compose -f docker-compose.mysql.yml up -d --build
On the first startup, the inference container downloads Qwen and ModernBERT into the persistent inference-model-cache volume. 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.
Follow the complete deployment while it starts:
docker compose -f docker-compose.mysql.yml logs -f inference rssmonster rssmonster-worker rssmonster-ai-worker
@today unread:true sort:recommended, unread:true quality:>0.7 sort:quality, or event:true island:true eventCount:>=3 sort:recommended./rss endpoint.RSSMonster 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.
VAPID identifies your RSSMonster server to browser push services. It uses one public/private key pair for the whole RSSMonster installation:
VAPID_PUBLIC_KEY is sent to browsers when they create a push subscription. It is not secret.VAPID_PRIVATE_KEY signs outgoing push requests. Keep it secret and only provide it to the RSSMonster server.VAPID_SUBJECT supplies operator contact information. Use a mailto: address or an HTTPS URL that belongs to the server operator.Each 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.
Keep 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.
Install the server dependencies, then use the bundled web-push command:
cd server
npm install
npx web-push generate-vapid-keys
The command prints a public and private key. Copy them without adding quotes or whitespace.
For a source installation, add them to server/.env:
# Optional Web Push notification configuration (VAPID).
VAPID_PUBLIC_KEY=replace-with-the-generated-public-key
VAPID_PRIVATE_KEY=replace-with-the-generated-private-key
VAPID_SUBJECT=mailto:admin@example.com
For Docker Compose, add the same values to the repository-root .env used by Compose:
VAPID_PUBLIC_KEY=replace-with-the-generated-public-key
VAPID_PRIVATE_KEY=replace-with-the-generated-private-key
VAPID_SUBJECT=https://rss.example.com
Both included Compose configurations pass these optional values into the application container. Restart RSSMonster after changing them:
docker compose up -d
Restart a source installation after changing these values:
cd server
npm start
The 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.
If 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.
RSSMonster'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.
The semantic pipeline works in stages:
quality:>0.7, freshness:>=0.5, event:true, island:true, hot:true, tag:security, and sort:recommended.This 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.
Historical semantic rebuilding is available through npm run semantic:all. It rebuilds event, topic, and interest-island assignments for existing articles and is intended for explicit repair after large imports or algorithm changes.
The visible sort order is Newest, Oldest, Top Stories, Recommended, Quality.
0–1 signal.70% article quality with 30% FeedTrust while keeping both concepts separate.Legacy sort:attention queries remain accepted for compatibility, but Most
Engaged is no longer a visible sort option. Legacy sort:trust queries resolve
to Quality.
For the recommended Docker deployment:
No separate MySQL installation is required when using the default SQLite deployment.
For running RSSMonster directly from source:
git clone https://github.com/pietheinstrengholt/rssmonster.git
cd rssmonster
# Install server dependencies
cd server
npm install
# Install client dependencies
cd ../client
npm install
# Install inference dependencies
cd ../inference
npm install
cd ..
Copy the .env.example files to .env:
cp server/.env.example server/.env
cp client/.env.example client/.env
cp inference/.env.example inference/.env
RSSMonster sends all model requests to the standalone inference service.
Configure the server connection in server/.env:
INFERENCE_URL=http://127.0.0.1:3001
INFERENCE_TIMEOUT_MS=30000
INFERENCE_AI_ENABLED=true
INFERENCE_ASSISTANT_ENABLED=false
SKIP_ARTICLE_CLASSIFICATION_ANALYSIS=false
SKIP_ARTICLE_EMBEDDINGS=false
SKIP_SEMANTIC_LABELING=false
Set INFERENCE_AI_ENABLED=false to prevent every server and worker inference
request. This master switch overrides the feature-specific skip settings.
Leave INFERENCE_ASSISTANT_ENABLED=false to hide chat while keeping the other
intelligent features enabled. Set it to true on the server only after the
assistant provider and credentials are configured in inference.
Use a longer timeout such as 600000 when running Qwen on low-power hardware.
The inference service selects providers independently for semantic embeddings,
text generation, article scoring, and assistant responses. A complete OpenAI
configuration in inference/.env is:
# OpenAI
EMBEDDING_PROVIDER=openai
GENERATION_PROVIDER=openai
ARTICLE_SCORING_PROVIDER=openai
ASSISTANT_PROVIDER=openai
ASSISTANT_MODEL=gpt-4o-mini
OPENAI_API_KEY=your-openai-api-key
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
OPENAI_EMBEDDING_DIMENSIONS=1536
Alternatively, embeddings, article generation, and scoring can run locally while the assistant remains on OpenAI:
# Qwen and ModernBERT
EMBEDDING_PROVIDER=qwen
GENERATION_PROVIDER=qwen
ARTICLE_SCORING_PROVIDER=modernbert
EMBEDDING_MODEL=onnx-community/Qwen3-Embedding-0.6B-ONNX
EMBEDDING_DIMENSIONS=1024
GENERATION_MODEL=onnx-community/Qwen3.5-0.8B-ONNX
GENERATION_DTYPE=q4
ASSISTANT_PROVIDER=openai
ASSISTANT_MODEL=gpt-4o-mini
OPENAI_API_KEY=your-openai-api-key
INFERENCE_MODEL_CACHE_DIR=.cache/models
Run inference with cd inference && npm run dev during development. Selected
Qwen3 Embedding, Qwen3.5 generation, and ModernBERT models are downloaded and
loaded during service startup, then reused from the model cache. The service
logs when all configured models are ready and crawling can start. Development
mode also logs content-safe activity for embeddings, summaries, tags, article
scoring, assistant calls, Smart Folder recommendations, and feed rediscovery.
Assistant responses currently continue to use OpenAI.
See Model Usage and
Inference administration for production setup and
model-specific guidance.
For a simple local installation, configure server/.env with:
NODE_ENV=development
DB_DIALECT=sqlite
DB_STORAGE=./data/rssmonster.sqlite
RSSMonster creates the SQLite parent data directory when required.
SQLite installations use conservative crawl concurrency settings automatically to reduce write contention.
To use MySQL instead, configure:
NODE_ENV=development
DB_DIALECT=mysql
DB_DATABASE=rssmonster
DB_USERNAME=rssmonster
DB_PASSWORD=your_database_password
DB_HOSTNAME=localhost
DB_PORT=3306
Configure client/.env:
VITE_APP_HOSTNAME=http://localhost:3000
Create the database schema:
cd server
npm run db
If you explicitly need the project seeders:
./node_modules/.bin/sequelize db:seed:all
This section applies only to MySQL installations.
When processing or querying large numbers of articles, increasing MySQL sort memory can reduce sort-related bottlenecks.
Add the following to your MySQL configuration, for example in my.cnf:
[mysqld]
sort_buffer_size = 4M
Run a crawl manually with:
cd server
DISABLE_LISTENER=true npm run crawl
This runs a crawl of active feeds and prints the crawl and semantic-processing results to the console.
Production installations can run the dedicated crawl worker using the process-management approach appropriate to the deployment environment.
If you need to rebuild article clusters from scratch:
cd server
npm run semantic:all
This command rebuilds historical event assignments, topics, interest islands, and interest scores for every user.
Use:
npm run semantic:all -- --userId=3
to limit the rebuild to one user.
When to use this:
This is an explicit historical rebuild workflow. Normal post-crawl semantic processing only considers newly created, unfiltered articles.
Taxonomy-vector generation is not required for a normal SQLite installation or Docker Quick Start.
If you explicitly need to generate or regenerate taxonomy vectors:
cd server
npm run taxonomy:vectors
npm run seed:island-taxonomy
npm run taxonomy:vectors uses the embedding model selected by the running
inference service, so it works with either OpenAI or Qwen.
Feed trust estimates how consistently valuable a subscribed source has been as a source of articles:
cd server
npm run feedtrust
This command calculates trust scores from 0.0 to 1.0 for active feeds using:
When to use this:
Each signal has its own evidence confidence and shrinks toward the neutral score of 0.75 when evidence is sparse. Recalculating unchanged data produces the same result.
Read the conceptual FeedTrust model.
RSSMonster 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.
Example requests include:

To enable the AI assistant and other OpenAI-backed capabilities, configure:
Server (server/.env):
INFERENCE_AI_ENABLED=true
INFERENCE_ASSISTANT_ENABLED=true
INFERENCE_AGENT_TIMEOUT_MS=300000
Inference (inference/.env):
OPENAI_API_KEY=your-openai-api-key-here
ASSISTANT_PROVIDER=openai
ASSISTANT_MODEL=gpt-4o-mini
The server keeps no OpenAI credential; all provider calls go through inference. After configuration, restart the client, server, and inference processes.
The assistant provides:
RSSMonster automatically tracks article interactions and can use AI to classify content with three quality metrics:
These scores provide additional inspectable signals for filtering and ranking.
Note: All interactions are user-scoped, ensuring privacy and data isolation in multi-user environments.
Note for Developers: The MCP server is available at /mcp for programmatic integration. Authentication requires a valid JWT token passed through the Authorization: Bearer <token> header. Obtain a token by authenticating through /api/auth/login.
The 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.
Client with hot reload:
cd client
npm run dev
Server with hot reload:
cd server
npm run dev
To attach a debugger:
npm run debug
Node exposes its inspector on port 9229.
The client will typically run on:
http://localhost:8080
and the server on:
http://localhost:3000
To quickly see RSSMonster in live action, use the SQLite deployment described in Docker Quick Start:
docker compose up -d
This quick profile requires no separate database server or inference models and keeps persistent application data in a Docker volume.
For the comprehensive MySQL and local-inference deployment:
docker compose -f docker-compose.mysql.yml up -d --build
For environments where RSSMonster runs directly on the host rather than through Docker:
SQLite:
NODE_ENV=production
DB_DIALECT=sqlite
DB_STORAGE=/path/to/persistent/rssmonster.sqlite
Or MySQL:
NODE_ENV=production
DB_DIALECT=mysql
DB_HOSTNAME=localhost
DB_PORT=3306
DB_DATABASE=rssmonster
DB_USERNAME=rssmonster
DB_PASSWORD=your_database_password
cd server
npm ci
npm run db
cd ../client
npm ci
npm run build
rm -rf ../server/dist
cp -R dist ../server/dist
cd ../server
npm run start
Use a suitable process manager or service manager for long-running production installations.
For production environments, use Let's Encrypt with Certbot for SSL/TLS certificates.
certbot certonly --standalone -d yourdomain.com --agree-tos -q
For example, create a weekly cron job:
0 0 * * 0 certbot renew --quiet && cp /etc/letsencrypt/live/yourdomain.com/* /path/to/rssmonster/cert/
Add the following to server/.env:
ENABLE_HTTPS=true
RSSMonster will use certificates from:
cert/fullchain.pem
cert/privkey.pem
Restart the server after updating the configuration.
RSSMonster is compatible with the Fever API, enabling integration with third-party RSS clients.
http://your-rssmonster-url/api/fever
RSSMonster supports the Google Reader API, providing compatibility with a wide range of RSS clients.
See the Google Reader API compatibility matrix for the exact endpoint contract, authentication examples, client checklist, identifier formats, and unsupported behavior.
http://your-rssmonster-url/api/greader| App | Platform | Notes |
|---|---|---|
| News+ | Android | With Google Reader extension |
| FeedMe | Android | Full sync support |
| Reeder | iOS/macOS | Classic version |
| Vienna RSS | macOS | Open source |
| ReadKit | macOS | Multi-service reader |
Contributions are welcome.
To contribute:
Fork the repository.
Create a feature branch:
git switch -c feature/amazing-feature
Commit your changes:
git commit -m "Add amazing feature"
Push the branch:
git push origin feature/amazing-feature
Open a Pull Request.
Please ensure your code follows the existing style and includes appropriate tests.
RSSMonster is built with the following frameworks and libraries:
This project is licensed under the MIT License. See LICENSE.md for details.
JavaScript
84.8%
Vue
13.8%