Skip to main content
Glama
psg2

feedreader

by psg2

Feed Reader

A self-hosted feed reader for one person: RSS and Atom feeds plus newsletters delivered by e-mail, in a single unread queue you can read from the web, from a native macOS app, or through an AI assistant connected over MCP. One Postgres database is the source of truth; every client writes through to it.

The hosted instance at reader.sereno.dev.br is the author's and has sign-ups closed. To use Feed Reader, run your own copy: it fits in Vercel's and Neon's free tiers. See Self-host.

Features

  • Feeds and newsletters together. Subscribe by site or feed URL (the server resolves the feed), import OPML, and read newsletters as feeds: a free Kill the Newsletter inbox works out of the box, or point a subdomain's MX at Resend Receiving so the server ingests mail itself (optional).

  • Web app (TanStack Start on Vercel): mobile-first, installable PWA, keyboard-driven (shortcuts), notes, tags, starred items, categories.

  • Native macOS app (SwiftUI): signs in with OAuth in your browser, mirrors the server into a local SQLite database for instant startup and offline reading. See macos/README.md.

  • MCP for Claude and other assistants. The server is an OAuth 2.1 provider and exposes a remote MCP endpoint at /api/mcp, so an assistant can read the same inbox, mark items, star, tag, take notes and subscribe.

  • Scheduled refresh via Vercel crons, manual refresh from any client.

  • Invite-only by default. The first account bootstraps the instance; after that, new users need an invite link from Settings › Admin (or set ALLOW_SIGNUP=true to open registration). Admins can also remove accounts.

Related MCP server: FreshRSS MCP Server

Screenshots

macOS app (from the snapshot tests, light appearance):

Sidebar

Item list

Reading header

macOS sidebar

macOS item rows

macOS detail header

Command palette

First run

macOS command palette

macOS first run

Web screenshots go in docs/screenshots/web-*.png (none yet; the web UI is at apps/web).

Self-host

docs/deploy.md walks through the whole thing: Vercel project + Neon Postgres, every environment variable, Google sign-in, Resend e-mail and newsletters, crons, custom domain, the GitHub Actions deploy fallback, MCP and macOS client setup, updating and backups.

The short version: fork, import apps/web into Vercel, attach a Neon database, set BETTER_AUTH_SECRET, BETTER_AUTH_URL and CRON_SECRET, deploy, create your account. Registration is then invite-only: invite people from Settings › Admin, or set ALLOW_SIGNUP=true to open it.

Connect an MCP client

Any MCP client that supports OAuth can connect; there is no API key to mint. For Claude Code:

claude mcp add --transport http --scope user feedreader https://<your-host>/api/mcp

The browser opens once to approve the client. Tools: list_items, get_item, list_feeds, list_tags, mark_read, star, add_note, add_tags, subscribe, refresh.

Development

Requirements: Node 24, pnpm 12 (corepack enable), Docker.

pnpm install
pnpm deps:up        # Postgres + pgweb in Docker; writes .env.docker
pnpm db:migrate
pnpm dev            # → https://feedreader.localhost

pnpm dev runs Vite behind portless, which serves the app at https://feedreader.localhost (and https://<branch>.feedreader.localhost in git worktrees). On the first run it generates a local certificate authority and asks for permission to trust it and to bind port 443; both prompts are one-time. If you would rather skip that, run Vite directly:

cd apps/web && pnpm exec vite dev --port 3000   # http://localhost:3000

A fresh clone runs with no .env.local; copy .env.example to enable optional integrations (Google sign-in, Resend, observability).

Tests need the test database once (pnpm test:db:migrate), then:

pnpm test           # unit (real Postgres, rolled-back transactions) + frontend (happy-dom)
pnpm lint && pnpm format:check && pnpm type-check && pnpm knip

Layout: apps/web (TanStack Start, oRPC, BetterAuth, Drizzle), packages/db (schema + migrations), packages/api (oRPC contract), packages/query (typed client + TanStack Query hooks), macos/ (SwiftUI). Conventions live in AGENTS.md and docs/patterns.md; the macOS app defaults to production, so point it at your dev server with defaults write dev.sereno.feedreader remoteServerURL https://feedreader.localhost.

Roadmap

Rough order, no dates:

  • Pagination of long item lists (web and MCP list_items).

  • Conditional GET (ETag / Last-Modified) on feed refresh.

  • Full-text search across items and notes.

  • Keychain-backed token store in the macOS app.

  • Web screenshots and a demo video in this README.

Contributing

See CONTRIBUTING.md; security reports go through SECURITY.md. Licensed under MIT.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    An MCP server that enables AI assistants to manage Tiny Tiny RSS feeds, including reading articles, updating statuses, and searching content. It also provides tools for feed management and generating automated daily reports.
    15
    37 npm
    3
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to interact with FreshRSS feeds via the Fever API, allowing listing feeds, fetching unread items, marking items as read/unread, and managing feed subscriptions.
    8
    5 npm
    9
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Local MCP server for reading and searching RSS and Atom feeds, enabling AI assistants to fetch feed contents, search entries by keyword, and view feed metadata without any cloud intermediary.
    3
    MIT