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.

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 10 (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.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/psg2/feed-reader'

If you have feedback or need assistance with the MCP directory API, please join our Discord server