Skip to content

Tools

Sixteen tools: eight read, eight write. With FRESHRSS_READ_ONLY=true only the read tools are registered.

Tools marked two-step return a single-use confirmation token on the first call and perform the operation only when called again with that token — see Security.

Stream selectors

Six tools address "where to read from" with the same four mutually exclusive parameters. Set exactly one; the default is the whole reading list.

ParameterTypeMeaning
feed_idintegerNumeric feedId from list_feeds
categorystringCategory (folder) name, exactly as in list_categories
labelstringUser label name, exactly as in list_categories
streamenumreading-list (default), starred, main, important

main and important are FreshRSS extensions: feeds shown on the main stream, and feeds marked as important.

A wrong name looks like "nothing new"

Names are matched literally, including case — copy them from list_categories. A category, label or feed id that does not exist returns an empty list rather than an error (verified against FreshRSS 1.29.1); only a malformed built-in stream id produces HTTP 400. The listing tools add a hint field when they return nothing for one of these selectors, precisely so a typo is not reported as an empty inbox.

Categories and user labels also share one namespace in this API, so category and label resolve identically — the two parameters exist only so tool descriptions can stay readable.

Read tools

get_user_info

No parameters. Returns userId, userName and userEmail. The cheapest way to check that the credentials work.

list_feeds

No parameters. Every subscribed feed with feedId, title, category, feedUrl, siteUrl, priority and unreadCount, plus feedCount and totalUnread.

Feed URLs have any embedded credentials redacted. If /unread-count is unavailable the feed list is still returned, with a note and no unreadCount.

list_categories

No parameters. Returns categories and labels separately — FreshRSS distinguishes them by the tag type even though they share a namespace — each with an unreadCount, plus the names of the built-in streams.

get_unread_counts

No parameters. Unread totals per feed and per category, sorted by count, with totalUnread. Only entries that actually have unread articles are listed.

list_articles

Stream selector, plus:

ParameterTypeDefaultMeaning
filterenumunreadunread, read, starred, all
limit1–10020Maximum articles
orderenumnewestnewest or oldest by publication date
sinceISO dateOnly articles published after this
untilISO dateOnly articles published before this
continuationstringValue from a previous call, for the next page
include_contentbooleanfalseFull article text instead of an excerpt
max_content_chars100–200002000Characters of text per article

Each article carries id, title, author, published, url, feed, read, starred, priority, labels, any enclosures, and either excerpt (300 characters) or content. since/until also accept a bare unix timestamp.

There is no keyword search — FreshRSS does not offer one over this API. Narrow with the selector and the date range, then filter what comes back.

get_articles

ParameterTypeDefaultMeaning
article_idsstring[] (1–20)Ids from list_articles
max_content_chars100–200002000Characters of text per article

Full text for specific articles. Ids that returned nothing are reported as a count — FreshRSS retention settings may have purged them.

list_article_ids

Same parameters as list_articles minus the content options. Returns just articleIds, count and continuation — the cheap way to collect a set for mark_articles.

export_opml

No parameters. All subscriptions as an OPML document, the portable backup format. Credentials in xmlUrl attributes are redacted; the document is truncated at 200 000 characters. For a readable overview use list_feeds.

Write tools

mark_articles

ParameterTypeMeaning
article_idsstring[] (1–100)Ids from list_articles
readbooleantrue marks read, false unread
starredbooleantrue adds the star, false removes it
add_labelsstring[]Labels to attach; unknown ones are created
remove_labelsstring[]Labels to detach

At least one change is required; each is applied to every given article. Not confirmation-gated — see why.

mark_all_as_read — two-step

Stream selector, plus older_than (ISO date, default: all) and confirm_token.

Marks an entire feed, category, label or stream as read. Which articles were unread before cannot be recovered, which is why it is gated.

subscribe_feed

ParameterTypeMeaning
urlstringFeed URL or website URL (http/https)
titlestringTitle to use instead of the feed's own
categorystringCategory to file it under; created if unknown

FreshRSS discovers the feed from a website URL and then downloads it, so this can take a while — the timeout is 120 s. Loopback and link-local URLs are refused: FreshRSS fetches the URL itself, which would make this an SSRF primitive.

update_feed

feed_id (integer, required), plus title and/or category. At least one of the two. Fields not given stay unchanged; an unknown category is created.

unsubscribe_feed — two-step

feed_id (integer) and confirm_token.

Deletes the feed and all of its stored articles, read state and stars. Not reversible: re-subscribing starts from whatever the feed currently offers.

rename_category_or_label

name and new_name. FreshRSS resolves the name against categories first and falls back to labels, so one tool covers both. Feeds and articles keep their assignment.

delete_category_or_label — two-step

name and confirm_token.

For a category, its feeds move to the default category and no articles are lost. For a label, it is detached from every article. Because FreshRSS matches categories first, a category and a label of the same name cannot be told apart here.

import_opml — two-step

opml (the document, up to 900 000 characters) and confirm_token.

Subscribes to every feed in the document, creates the categories it names, then refreshes everything — minutes, on a large file. There is no bulk undo. Documents with a <!DOCTYPE> or <!ENTITY> declaration are refused.

The token is bound to a fingerprint of the exact document, so confirming one OPML cannot authorise importing another.

Released under the MIT License.