l0ng-ai/papr: A Native RSS Reader With a CLI Built for AI Agents
A fast, native RSS reader — plus an agent-facing CLI so your AI agent can read, search and triage your feeds from the shell.
At a glance
- What is it?
- Papr pairs a Tauri desktop reader with a shell CLI over one shared SQLite database, so an agent can read, search and triage feeds without a GUI. The interesting part is the TOON output format, not the feed parser.
- Who is it for?
- Adopt Papr if you want a local RSS database that both a desktop app and a shell-driven agent can share, and if you are comfortable with a project whose last push was on 2026-09-03 and whose CLI reference lives in docs/cli.md rather than the README. Do not adopt it if you need a hosted, multi-device reader with a documented server API, or if your agent runtime cannot execute shell commands.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The Problem Papr Picks: Feeds That an Agent Cannot Reach
Most RSS readers assume a human is looking at a window. That assumption breaks the moment you want an autonomous agent to triage a feed: the agent has no window, and the reader has no interface it can call. Papr's answer is to treat the feed database as the product and the interfaces as interchangeable front-ends. The README describes it as "two front-ends over one local database": a desktop reader built with Tauri and React, and `papr`, a command-line companion the README explicitly frames as built "for autonomous agents to drive over the shell."
The intended user is narrower than "anyone who reads RSS." It is someone who already runs an agent such as Claude Code, Codex or OpenCode and wants that agent to answer questions like which articles are unread, what a specific article says, or what should be starred for later. The desktop app exists for the same person when they want to read properly. Both sides read the same database through a shared `papr-core` crate, which the README says means "the app and the CLI can never drift apart." That is a real architectural commitment, and it is the reason the project is worth a look rather than a shrug.
One Database, Two Front-Ends: How papr-core Holds It Together
The repository layout confirms the README's claim. The Cargo workspace has three members: `src-tauri`, `crates/papr-core` and `crates/papr-cli`. The root `Cargo.toml` pins shared dependencies in `[workspace.dependencies]` so both binaries inherit identical versions, and the comment above that block states the intent directly: keeping the data and ingestion stack pinned there means "the desktop app and the agent CLI link the exact same code."
The storage layer is `rusqlite` with the `bundled` and `functions` features, plus `rusqlite_migration` for schema versioning. Feed parsing is `feed-rs`; HTTP is `reqwest` with gzip, brotli and json; full-text extraction uses `scraper`, `ego-tree`, `dom_smoothie` and `lol_html`, with `ammonia` for sanitizing. Sync targets FreshRSS and Miniflux, and the dependency list includes `imap` and `mail-parser`, which suggests newsletter ingestion through a mailbox.
The CLI's output boundary is the part that differs from a normal command-line tool. Papr emits TOON, described in the README as "~40% fewer tokens than JSON" with "definitive counts and structured exit codes." The workspace pins `toon-format` with `default-features = false`, and a comment explains why: dropping the bundled TUI and CLI avoids pulling in clap, ratatui and tiktoken for what is only a library encoder. A second comment notes that `serde_json` is built with `preserve_order` so that TOON lists fields in the deliberate order each handler builds them. That is an unusual amount of care about output shape, and it tells you the author is optimizing for a machine consumer, not a human reading a table.
Installing the Desktop App and the papr CLI
The desktop app and the CLI install separately. For macOS, the README gives a Homebrew cask for the app and a different formula for the CLI:
brew install --cask l0ng-ai/papr/papr
brew install l0ng-ai/papr/papr-cliOn Windows the app ships as an `.msi` installer, while the CLI is a zip named `papr-x86_64-pc-windows-msvc.zip` that you unzip and place on your `PATH`. On Linux the app is an `.AppImage` or `.deb`. Every package is published on the project's latest release page, and the README notes that the macOS builds are Developer ID signed and notarized. If you prefer to build the CLI yourself, the README lists `cargo build --release -p papr-cli` as an option.
Once `papr` is on your `PATH`, running it bare is the first real use. The README shows that it prints an unread dashboard plus suggested next commands, so an agent can orient without being told what to do:
$ papr
unread: 206 starred: 17 later: 0 feeds: 15
articles[10]{id,feed,title,flags,date}:
3664,V2EX,[Java] 使用 kkRepo 搭建 Maven 私服,unread.star,"2026-06-25"
...
help[4]: Run `papr read <id>` to read an article's full text, ...The header line gives counts, the `articles` block gives a fixed column set, and the `help` block tells the caller what to do next. From there the README lists the verb groups: read with `feeds`, `list`, `read` and full-text `search`; triage with `mark` and `extract` and `refresh`; manage subscriptions, folders, tags, rules, highlights and OPML; and sync against FreshRSS or Miniflux. The README points to `docs/cli.md` for the full command reference, which is where you should look before scripting anything.
Wiring Papr Into an Agent: Skills and the SessionStart Hook
Papr ships a skill rather than a plugin or an MCP server. The README describes `skills/papr-rss/SKILL.md` as loading "on demand" when an agent recognizes a feed-related task, "so it costs nothing until you use it." Installation goes through Vercel's `skills` tool:
npx skills add https://github.com/l0ng-ai/papr/tree/main/skills/papr-rssThat is the lazy path: the agent learns about Papr only when a task looks feed-shaped. The eager path is `papr setup`, which the README says wires up an ambient SessionStart hook for Claude Code, Codex and OpenCode. The distinction matters more than it looks. A skill that loads on demand keeps your context small and your agent's behaviour predictable. A SessionStart hook makes the agent aware of your feeds in every conversation, which is exactly what some people want and exactly what others will find noisy. The README presents both without recommending either, so the choice is yours to make deliberately.
One thing the README does not settle: it never states which agent runtimes have been verified against the CLI beyond naming those three, and it does not describe what happens when an agent calls `papr` and the database is locked by the desktop app. Given that both processes share one SQLite file, that is the question I would want answered before putting this on a schedule.
Where Papr Is the Wrong Tool
The local-first design is the limitation as much as the feature. The README is explicit that everything stays on your machine, with no account and no cloud. That means there is no hosted sync between two computers running Papr, and no web reader you can open from a machine you do not own. FreshRSS and Miniflux sync exist, but they sync read state with a server you operate; they are not a Papr-hosted service.
The agent story has a hard dependency too. `papr` is a binary that an agent invokes over a shell. If your agent runtime cannot execute commands on the same machine as the database, the CLI is unreachable, and the skill file alone will not help. There is no documented HTTP API in the README, so you cannot point a remote agent at a Papr instance the way you might with a server-backed reader.
Maintenance is the third thing to weigh. The last push to the repository was on 2026-09-03, and the most recent release listed is v0.15.0 from 2026-07-11. That is recent enough that the project is not dormant, but the README does not document a deprecation policy, a support window, or what happens to older release artifacts. If you need a reader with a published compatibility guarantee, Papr does not offer one you can read.
How Papr Differs From FreshRSS and Miniflux
The obvious comparison is with the two servers Papr syncs against. FreshRSS and Miniflux are self-hosted web readers: you run a server, your browser is the client, and the API is the integration point. Papr inverts that. The primary client is a native desktop app, the data lives in a local SQLite file, and the second client is a shell binary. FreshRSS sync in Papr is a compatibility feature, not the architecture.
The practical difference shows up in what each can do offline. A self-hosted web reader without a network is a blank page. Papr's desktop app is described as offline-first, and the CLI reads the local database directly, so both keep working when the network does not. The trade is reach: you get one machine's worth of reader, and you give up the ability to open your feeds from a browser on a different device unless you run one of the sync servers anyway.
The second difference is the agent surface. Neither FreshRSS nor Miniflux ships a skill file for Claude Code or a SessionStart hook installer. Their APIs are general-purpose and an agent can be taught to call them, but Papr's CLI is shaped for that caller specifically: counts in the header, a fixed column set, structured exit codes, and a token-oriented encoding. If your reason for looking at Papr is the agent workflow, the comparison with a self-hosted server is not really the right one. The right comparison is with teaching your agent to call an API, and Papr's answer is that a purpose-built CLI is less work.
Licence, Upgrade Cost and What to Check Before Adopting
Papr is MIT licensed, which is permissive and imposes few obligations beyond preserving the copyright notice and licence text. That matters here because the project bundles a large dependency tree, including `imap` pinned to an exact alpha version (`=3.0.0-alpha.15`). A pinned alpha in the dependency graph is something to be aware of when you audit what you are shipping, though the MIT licence on Papr itself does not change based on its dependencies. This is not legal advice; check the licences of the transitive crates yourself if that matters to your organisation.
Upgrade cost is shaped by the migration layer. `rusqlite_migration` is in the workspace dependencies, so schema changes are handled through migrations rather than manual SQL, but the README does not describe a rollback path if an upgrade goes wrong. Back up the database file before upgrading, and note that the release history shows three releases within a single day in July 2026 (v0.13.1, v0.14.0 and v0.15.0), which suggests the project is willing to ship frequently. Frequent releases are fine; what you want to confirm is whether each one migrates cleanly. The README does not say, so test on a copy first.
Before adopting, read `docs/cli.md` rather than the README, since the README defers the full command reference to it. Confirm the exact subcommand names and flags you plan to script against, because the README only names the verb groups.
Editorial conclusion
Adopt Papr if you want a local RSS database that both a desktop app and a shell-driven agent can share, and if you are comfortable with a project whose last push was on 2026-09-03 and whose CLI reference lives in docs/cli.md rather than the README. Do not adopt it if you need a hosted, multi-device reader with a documented server API, or if your agent runtime cannot execute shell commands. Before committing, verify three things: that the TOON output parses in your agent's toolchain, that `papr setup` writes a SessionStart hook you actually want in every conversation, and that the FreshRSS or Miniflux sync path matches the server you already run.
Frequently asked questions
Does the papr CLI share data with the Papr desktop app?
Yes. The README describes both as front-ends over one local database, and the Cargo workspace has both binaries depend on the shared papr-core crate so they link the same code.
What output format does the papr CLI use?
It emits TOON, which the README says uses roughly 40 percent fewer tokens than JSON, with definitive counts and structured exit codes. The workspace pins the toon-format encoder with default features disabled.
Can Papr sync my read state across devices?
Papr itself is local-first with no account and no cloud, so it does not provide its own sync. It can sync read state with a FreshRSS server or Miniflux instance that you run.
How do I install the papr CLI on macOS or Linux?
The README gives `brew install l0ng-ai/papr/papr-cli`, which is a separate formula from the desktop app's cask. Prebuilt tarballs for specific targets are also published on the latest release page.
What licence does l0ng-ai/papr use?
Papr is MIT licensed. Note that the dependency tree includes an imap crate pinned to an exact alpha version, so review transitive licences separately if that matters to you.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/l0ng-ai-papr)