Skip to main content
Glama

freshrss-mcp

CI npm version npm downloads node license container docs HTTP • via mcp-hub Glama sponsor

A Model Context Protocol (MCP) server for FreshRSS, the self-hosted RSS and Atom feed aggregator.

Lets MCP clients like Claude Code, Claude Desktop or Codex work through your feeds: see what is unread, read the articles, mark them, and manage subscriptions and categories.

Sixteen tools is the ceiling, not the floor: FRESHRSS_ALLOW_TOOLS=essential registers a curated seven instead, and a model picks the right tool far more reliably from seven than from sixteen — see choosing which tools load.

It speaks the Google Reader compatible API that FreshRSS exposes at /api/greader.php, and hides that API's quirks behind tool arguments an assistant can actually use: numeric feed ids, category and label names, ISO dates and decimal article ids instead of user/-/state/com.google/… stream identifiers and hexadecimal item tags.

Demo: listing the tools, the subscribed feeds and the newest article through the MCP Inspector CLI

What makes it different

Sixteen tools, no stream ids. The Google Reader API speaks in stream identifiers and hexadecimal item tags. These tools take numeric feed ids, category and label names, ISO dates and decimal article ids, and hand back plain text instead of raw HTML.

Built for untrusted feeds. Every article was written by a stranger on the internet, so responses are marked as data, feed URLs are stripped of credentials, and article text is capped per article and per response. The five irreversible tools ask a person first, through MCP elicitation.

Related MCP server: Conduit

Requirements

  • Node.js 22 or newer

  • A FreshRSS instance (developed against 1.29) with

    • the API enabled: Settings → Authentication → "Allow API access"

    • an API password set for the user: Settings → Profile → API management. This is a separate password from the web login.

Configuration

Variable

Required

Description

FRESHRSS_URL

yes

Root URL of the instance, e.g. https://rss.example.com. The API path /api/greader.php is appended automatically.

FRESHRSS_USER

yes

FreshRSS user name.

FRESHRSS_API_PASSWORD

yes

The API password from the profile page, not the web login password.

FRESHRSS_READ_ONLY

no

1, true or yes registers only the read tools.

FRESHRSS_INSECURE_TLS

no

true accepts self-signed certificates for this connection only.

FRESHRSS_ALLOW_TOOLS

no

Comma-separated tool names, list_* prefixes, or essential for a curated preset

FRESHRSS_DENY_TOOLS

no

Same syntax; removed from whatever FRESHRSS_ALLOW_TOOLS left

ELICITATION

no

false replaces the approval dialog with the two-call token. Not prefixed.

The server starts without credentials so its tools stay listable; every call then fails with these setup instructions.

Choosing which tools load

FRESHRSS_ALLOW_TOOLS and FRESHRSS_DENY_TOOLS take comma-separated tool names; a trailing * matches a whole family. essential is a curated preset of seven: list_feeds, list_categories, get_unread_counts, list_articles, get_articles, mark_articles, mark_all_as_read.

FRESHRSS_ALLOW_TOOLS=essential
FRESHRSS_ALLOW_TOOLS=list_feeds,list_articles,mark_articles
FRESHRSS_DENY_TOOLS=delete_*

An entry that matches no tool aborts startup and names it, so a typo cannot silently hide a tool — an absent tool is not something anyone traces back to an environment variable. A filtered tool is never registered, so it is absent from tools/list and unknown to tools/call alike, exactly like a write tool under FRESHRSS_READ_ONLY.

If you run several of these servers at once, mcp-hub is the other answer — its /hub endpoint replaces every server's tools with six meta-tools.

Installation

Claude Code

claude mcp add freshrss -- npx -y @ni-c/freshrss-mcp

Claude Desktop

{
  "mcpServers": {
    "freshrss": {
      "command": "npx",
      "args": ["-y", "@ni-c/freshrss-mcp"],
      "env": {
        "FRESHRSS_URL": "https://rss.example.com",
        "FRESHRSS_USER": "alice",
        "FRESHRSS_API_PASSWORD": "…"
      }
    }
  }
}

Codex

[mcp_servers.freshrss]
command = "npx"
args = ["-y", "@ni-c/freshrss-mcp"]
env = { FRESHRSS_URL = "https://rss.example.com", FRESHRSS_USER = "alice", FRESHRSS_API_PASSWORD = "…" }

Docker

docker run --rm -i \
  -e FRESHRSS_URL=https://rss.example.com \
  -e FRESHRSS_USER=alice \
  -e FRESHRSS_API_PASSWORD=... \
  ghcr.io/ni-c/freshrss-mcp:latest

The image is published for linux/amd64 and linux/arm64 with an SBOM and build provenance. It runs as the unprivileged node user and carries no npm, so the only thing in it is Node, the runtime dependencies and dist/.

Through mcp-hub

A client that cannot spawn a local process — ChatGPT connectors, Claude on the web, Cursor, LibreChat — reaches freshrss-mcp through mcp-hub: one container serves many stdio MCP servers over Streamable HTTP, with an OAuth 2.1 login behind a single password and long-lived tokens for the clients that cannot do OAuth. Its /hub endpoint puts every server behind six meta-tools, so one connector reaches all of them without N×tool schemas in the model's context, and it speaks both protocol revisions — a question this server asks travels through it to the person at the far end.

Its /config/mcp.json uses Claude Code's format, so the entry is the one you already have:

{
  "mcpServers": {
    "freshrss": {
      "command": "npx",
      "args": ["-y", "@ni-c/freshrss-mcp"],
      "env": { "FRESHRSS_ALLOW_TOOLS": "essential" },
      "denyTools": ["delete_*"]
    }
  }
}

allowTools and denyTools there are the hub's own per-server filter, which is not the same thing as *_ALLOW_TOOLS in env — the difference, and the mistake it invites, are in the client guide.

Tools

Reading

Tool

Description

get_user_info

The authenticated account — a quick credential check.

list_feeds

Every subscription with its category and unread count.

list_categories

Categories (folders of feeds) and user labels (tags on articles).

get_unread_counts

Total and per-feed/category unread counts, sorted.

list_articles

Articles of a feed, category, label or built-in stream, with excerpts or bounded full text.

get_articles

Full text of specific articles by id.

list_article_ids

Ids only — the cheap way to collect a set for mark_articles.

export_opml

All subscriptions as an OPML document.

Writing

Not registered when FRESHRSS_READ_ONLY=true.

Tool

Description

Confirmation

mark_articles

Set read state, star and labels on specific articles.

mark_all_as_read

Mark a whole feed, category, label or stream as read.

yes

subscribe_feed

Subscribe to a feed or website URL.

update_feed

Rename a feed or move it to another category.

unsubscribe_feed

Delete a feed and all of its stored articles.

yes

rename_category_or_label

Rename a category or a user label.

delete_category_or_label

Delete a category or a user label.

yes

import_opml

Subscribe to every feed in an OPML document.

yes

Structured output

Every tool declares an outputSchema and answers with structuredContent alongside the text block, so a client can use the result without parsing prose:

{
  "untrusted": true,
  "source": "freshrss",
  "articles": [{ "id": "1234", "title": "…", "read": false, "starred": false }],
  "continuation": "1699999999",
  "notes": ["…"],
}

Every tool that reports feed content carries untrusted: true and source: "freshrss" as fields. This server has always said so in notes — prose in a list, which a client can read but not check — and the field is what makes it checkable. Eight tools are without it, because their answer is entirely this server's own words: ids it was given, a sentence built from the arguments, the account it authenticates as.

Six tools used to answer with a sentence ("Feed 9 deleted."); they now answer with the fields as well, and the sentence stays in the text block. export_opml returns {opml} rather than the document as the whole result: a schema whose root is a string is served to a 2025-era client rewritten as {result: …}, and truncated needs somewhere to live either way.

FreshRSS does not offer full-text search over its API — the Google Reader endpoints filter by stream, read state and date only. list_articles therefore has no query parameter; narrow the result with feed_id/category and since/until and filter the returned articles yourself.

Not exposed, on purpose

No full-text search, because FreshRSS offers none over the Google Reader API: its endpoints filter by stream, read state and date only. Narrow with feed_id, category, since and until, then filter the returned articles yourself. The search in the FreshRSS web interface has no API endpoint behind it.

No raw HTML. Article bodies are converted to plain text and capped per article and per response, so one listing cannot bury everything else in the context.

Safety

  • Article text is untrusted input. Everything this server returns from FreshRSS was written by a third party on the internet, so responses that carry article text, titles or feed names are explicitly marked as data, never as instructions.

  • A person is asked, not just told. Where the client supports MCP elicitation, the five irreversible tools raise a real dialog that the model cannot answer on its behalf. A plain boolean could be set on the very first call, or be talked into it by text hidden in a feed. Where the client cannot show a dialog they fall back to a single-use token bound to the exact target, and say so rather than implying somebody approved. The messages deliberately never quote titles or names coming from the API. See Asking a person.

  • Response budgets. FreshRSS returns up to 500 000 characters of HTML per article. Article text is converted to plain text, capped per article and against a per-response budget, and is opt-in in listings. The budget is charged for the markup that was read rather than for the text that came out, so it bounds the conversion work and not only the resulting context — markup that strips away to nothing is the expensive case, and it used to be free. The conversion itself is a single left-to-right scan, linear in the length of the article whatever the article contains.

  • Credentials are read once, removed from process.env afterwards and never written to disk. Requests never follow redirects, which would resend the authorization header to another host, and relaxed TLS validation is scoped to this connection instead of the whole process.

  • Feed URLs are redacted. FreshRSS stores HTTP-auth feeds as https://user:password@host/feed. The userinfo part is stripped before a feed URL reaches a tool result or the OPML export, so list_feeds cannot print the password of a paid or private feed into the transcript.

  • subscribe_feed and import_opml refuse internal targets. FreshRSS fetches those URLs server-side, which makes both tools an SSRF primitive reachable from text inside an article. Loopback and link-local addresses — including cloud metadata endpoints — are rejected, for the feed URL and for every xmlUrl/htmlUrl in an OPML document. Addresses are compared numerically, so an IPv4-mapped IPv6 literal such as [::ffff:169.254.169.254] is caught too, and a hostname is resolved before it is accepted. An OPML document is read the way an XML parser reads it, and what reaches FreshRSS is the document as checked — so the URL that was inspected is the URL that gets fetched. Private LAN addresses stay allowed, because self-hosted setups legitimately subscribe to feeds on their own network.

  • import_opml refuses a <!DOCTYPE>. No XML is parsed in this process, but the document is handed to FreshRSS, where a document type declaration is the carrier for entity-expansion and external-entity attacks. OPML never needs one.

  • FRESHRSS_READ_ONLY=true does not register the write tools at all rather than refusing them at call time.

Which tools ask a person: mark_all_as_read, unsubscribe_feed, delete_category_or_label, import_opml — and mark_articles, but only when it is about to mark something read. Starring, unstarring and labelling can all be set back; which of those articles were unread cannot, and FreshRSS keeps no record of it.

Documentation

The full guide, tool reference and security notes live at freshrss-mcp.ni-c.de (source in docs/).

Development

npm install
npm run lint && npm run build && npm test
npm run test:coverage

See CONTRIBUTING.md for a throwaway FreshRSS to develop against. The full documentation lives at freshrss-mcp.ni-c.de.

Releasing

  1. Move the [Unreleased] entries in CHANGELOG.md under the new version and bump version in package.json.

  2. npm run lint && npm run build && npm run test:coverage.

  3. Commit, then tag: git tag -s vX.Y.Z -m vX.Y.Z && git push origin main vX.Y.Z.

The tag triggers release.yml, which verifies the tag matches package.json, publishes to npm via Trusted Publishing with provenance (no token involved), creates the GitHub release from the CHANGELOG section, and publishes the entry to the MCP Registry. If only the registry step fails, fix it on main and re-run mcp-registry.yml by hand — never re-run the tagged job, which would check out the old tree.

Contributing

Issues, discussions and pull requests are welcome — see CONTRIBUTING.md. For vulnerabilities please use private reporting rather than a public issue; the policy is in SECURITY.md.

License

MIT © Willi Thiel

Available Tools

16 tools
delete_category_or_labelDelete a category or labelA
Destructive

Deletes a category (its feeds move to the default category, no articles are lost) or a user label (it is detached from every article). FreshRSS matches categories first, so a category and a label of the same name cannot be told apart here. Two-step: the first call returns a confirmation token, the second call with that token performs the deletion.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesName, exactly as in list_categories
confirm_tokenNoToken from the first call of this tool

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotation already provides destructiveHint=true, so the agent knows deletion is destructive. The description adds critical behavioral detail: categories moves feeds to default (no data loss), labels are detached only, the two-step confirmation flow, and the matching order between categories and labels. This goes well beyond the annotation, scoring high.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, front-loads the core action, and each sentence adds unique value (behavior for category vs label, naming collision, confirmation flow). No wasted words; could be slightly more compact but is well within reasonable length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 2 parameters, destructiveHint annotation, and no output schema, the description covers the key behaviors: what happens to associated data, the two-step confirmation, and the naming ambiguity. For complexity level, this is nearly complete; only missing details like error cases or permissions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters (name, confirm_token) are documented in the input schema. The description adds context that 'name' must match exactly from list_categories, and that 'confirm_token' comes from a first call. This adds value beyond schema, but not enough to raise above baseline 3 given good schema already.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool deletes a category or label, and it distinguishes the behavior between categories (feeds move to default, no articles lost) and labels (detached from articles). However, it does not explicitly differentiate from siblings like rename_category_or_label or other deletion tools, though the scope is specific enough.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains when to use this tool (to delete categories or labels), mentions a naming collision caveat (categories matched first), and describes a two-step process with confirmation token. It does not explicitly state when not to use it or list alternatives, but the two-step guidance helps the agent select and invoke correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

export_opmlExport OPMLA
Read-only

Exports all subscriptions as an OPML document — the portable backup format for feed readers. For a readable overview of the subscriptions use list_feeds instead.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, indicating a safe read operation. The description confirms an export (read-only) but adds no further behavioral details like size limits or response format. It is consistent but does not add substantial context beyond the annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences: first sentence states purpose, second provides a clear alternative. No redundant or extraneous information. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has no parameters, no output schema, and annotations already cover safety, the description is complete. It explains what is exported (all subscriptions) and in what format (OPML), and offers a sibling alternative. No gaps remain for this simple tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters (100% schema coverage). With no parameters to describe, the description does not need to add parameter meaning. Per guidelines, 0 parameters yields a baseline score of 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool exports all subscriptions as an OPML document, a portable backup format. It distinguishes itself from the sibling list_feeds by directing users to that tool for a readable overview, ensuring no ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance: use this tool to export a backup OPML, and for a readable overview use list_feeds instead. This directly addresses when to use and when not to use, naming a specific alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_articlesGet articlesA
Read-only

Fetches the full text of specific articles by id, as plain text. At most 20 ids per call.

ParametersJSON Schema
NameRequiredDescriptionDefault
article_idsYesArticle ids as returned by list_articles
max_content_charsNoCharacters of article text per article, default 2000

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide readOnlyHint=true, so the description doesn't contradict that. However, the description adds no extra behavioral context beyond the schema (e.g., whether content is truncated, if there's rate limiting, or what happens for invalid/private article IDs). With annotations already indicating safety, the bar is lower, but still minimal added value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise at two sentences, with key information front-loaded. The first sentence covers purpose and format, the second adds a crucial constraint. No wasted text, though slightly more structure (e.g., mentioning the optional parameter) could improve readability for an agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there's no output schema, the description doesn't explain what the returned plain text looks like (e.g., HTML stripped? metadata included?). With 14 sibling tools and moderate complexity (2 params, no nested objects), the description is adequate but could be more self-contained by noting that article IDs come from list_articles or elaborating on the output format.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description does not add meaning beyond what the schema already documents for 'article_ids' and 'max_content_chars' – it merely restates the id limit from the schema. No additional context about parameter behavior is provided.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('Fetches') and resource ('full text of specific articles by id'), and distinguishes itself from sibling tools like 'list_articles' which likely return summaries. The constraint 'as plain text' adds precision, and the 20-id limit is unique to this tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is for retrieving article content after identifying articles via 'list_articles' (referenced in input schema), and the sibling context shows it's one of many article-related tools. However, it doesn't explicitly state when to use this versus 'mark_articles' or 'get_unread_counts', leaving some ambiguity for an agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_unread_countsGet unread countsA
Read-only

Returns how many unread articles are waiting, in total and per feed and category, sorted by count. Only entries with unread articles are listed.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide readOnlyHint=true. Description adds that results are sorted by count and only include entries with unread articles, which are useful behavioral details. No mention of scope (e.g., user-specific) or performance characteristics, but sufficient given the tool's simplicity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero wasted words. The first sentence immediately states the core purpose (returns unread counts) and the second adds ordering and filtering. Perfectly front-loaded and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description covers total, per-feed, and per-category breakdowns, sorting, and filtering. It does not specify whether feed/category identifiers are names or IDs, but the information is sufficient for an agent to decide when to call this tool. Sibling context (list_feeds, list_categories) can fill the gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist, so schema coverage is trivially 100%. The description adds meaning by explaining that the output includes total counts and per-feed/category breakdowns sorted by count, which compensates for the lack of output schema and clarifies the tool's value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool returns unread article counts in total and per feed/category, sorted by count. It distinguishes from siblings like get_articles (which returns article content) and list_articles (which lists articles) by focusing on counts and aggregations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus alternatives. The purpose is clear, but the description does not mention that this tool is best for quick counts before fetching articles, nor does it contrast with list_feeds or list_categories. Usage context is implied but not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_user_infoGet user infoA
Read-only

Returns the FreshRSS account the server is authenticated as. Useful as a connection and credential check before anything else.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the description's additional context about returning account info is consistent but not extensive. It adds value by explaining the purpose but does not reveal new behavioral traits beyond the annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the action and purpose. Every word earns its place; no unnecessary information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no parameters and no output schema, the description fully covers what the tool does, why it is useful, and when to use it. It is complete for its simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are no parameters, so schema coverage is trivially 100%. The description adds meaning by explaining what the tool returns, which is useful even with zero parameters. Baseline 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Returns') and identifies the exact resource ('the FreshRSS account the server is authenticated as'). It clearly distinguishes from sibling tools, none of which concern authentication or account info.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states it is useful as a connection and credential check before anything else, providing clear context for when to invoke this tool. It does not exclude alternatives, but the guidance is strong enough for an agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

import_opmlImport OPMLA
Destructive

Subscribes to every feed in an OPML document, creating the categories it names, and then refreshes all feeds — which can take minutes on a large file. There is no bulk undo; every feed would have to be removed individually. Two-step: the first call returns a confirmation token, the second call with that token performs the import.

ParametersJSON Schema
NameRequiredDescriptionDefault
opmlYesOPML document
confirm_tokenNoToken from the first call of this tool

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description reveals significant behavioral traits beyond the annotations: it refreshes all feeds (potentially minutes), has no bulk undo, and requires a two-step process with a confirmation token. These details are critical for the agent and are not present in the annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three concise sentences, each serving a distinct purpose: core action and side effects, warning about undo, and the two-step process. No redundant or unnecessary information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (two-step, destructive, no output schema), the description covers the key aspects: what it does, the delay, lack of undo, and the confirmation token flow. It is slightly incomplete in not mentioning the return type of the second call (e.g., success/failure), but this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds meaning beyond the input schema: it explains the two-step process and the role of confirm_token. While the schema describes both parameters, the description contextualizes their usage. Baseline 3 because schema coverage is 100%, but the extra context about the two-step justifies a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific verb 'subscribes to every feed' and resource 'OPML document', along with creating categories and refreshing feeds. This distinguishes it from sibling tools like subscribe_feed (single feed) and export_opml (export).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: it is for bulk importing an OPML file, warns about the time cost and lack of bulk undo, and explains the two-step confirmation process. However, it does not explicitly contrast with alternatives like subscribe_feed for single feeds, leaving some interpretation to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_article_idsList article idsA
Read-only

Lists only the ids of matching articles — the cheap way to collect a set for mark_articles. Same selectors and filters as list_articles.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelNoUser label name exactly as returned by list_categories
limitNoMaximum number of articles, default 20
orderNoSort order by publication date, default newest
sinceNoOnly articles published after this ISO-8601 date
untilNoOnly articles published before this ISO-8601 date
filterNoRead state to return, default unread
streamNoBuilt-in stream: reading-list = everything (default), starred = favourites, main = feeds shown on the main stream, important = feeds marked important
feed_idNoNumeric feedId from list_feeds
categoryNoCategory (folder) name exactly as returned by list_categories
continuationNoContinuation value from a previous call, to fetch the next page

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description correctly aligns with the readOnlyHint annotation, being a read operation. It adds value by noting the tool returns only IDs and is efficient, which annotations alone don't convey. It doesn't mention pagination via continuation, but since the parameter is self-explanatory, this is a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short, front-loaded sentences convey purpose, usage guidance, and efficiency. Every word serves a purpose with no redundancy. Excellent conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 10 optional parameters with full schema coverage, no output schema, and annotations confirm read-only. The description effectively covers the core behavioral aspect (only IDs, cheap) and usage context (same filters). A very brief note about the response being just IDs might help, yet the purpose is clear enough.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description doesn't add parameter semantics beyond what the schema already provides; it merely states that same selectors and filters apply. No additional value over the rich schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool lists only IDs of matching articles, explicitly positioning it as a cheap alternative to list_articles. It specifies the purpose and resource precisely, distinguishing it well from its siblings, particularly list_articles.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the tool is a cheap way to collect a set for mark_articles, and states it uses the same selectors and filters as list_articles. This provides clear when-to-use guidance and implicitly indicates when not to use it (when full article details are needed).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_articlesList articlesA
Read-only

Lists articles from a feed, category, label or built-in stream, newest first. Returns short plain-text excerpts by default; set include_content=true for the article text, or fetch single articles with get_articles. FreshRSS has no full-text search over its API, so there is no way to query by keyword — narrow the result with feed_id/category and since/until instead and filter the returned articles yourself.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelNoUser label name exactly as returned by list_categories
limitNoMaximum number of articles, default 20
orderNoSort order by publication date, default newest
sinceNoOnly articles published after this ISO-8601 date
untilNoOnly articles published before this ISO-8601 date
filterNoRead state to return, default unread
streamNoBuilt-in stream: reading-list = everything (default), starred = favourites, main = feeds shown on the main stream, important = feeds marked important
feed_idNoNumeric feedId from list_feeds
categoryNoCategory (folder) name exactly as returned by list_categories
continuationNoContinuation value from a previous call, to fetch the next page
include_contentNoReturn the article text instead of a short excerpt
max_content_charsNoCharacters of article text per article, default 2000

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses several behavioral traits beyond the readOnlyHint annotation: default returns excerpts, can return full text with include_content=true, newer-first ordering, pagination via continuation, and critical platform limitation 'FreshRSS has no full-text search over its API.' This provides rich context for safe and effective invocation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, each carrying distinct and essential information: function, key options, and limitation/strategy. It is front-loaded with the core purpose, with no redundant or extraneous text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 12 parameters and no output schema, the description covers the main filtering strategy, default behavior, and a critical limitation (no full-text search). It mentions the alternative get_articles. However, it does not explain the response structure beyond 'short plain-text excerpts' or how multiple filters interact, leaving some ambiguity for complex queries.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value by explaining the overall strategy (narrow with feed_id/category and date range, then filter) and the default response format (short plain-text excerpts). This synthesizes multiple parameters, going beyond individual schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Lists articles from a feed, category, label or built-in stream, newest first.' This specifies the action (list), resource (articles), and sources (feed, category, label, stream), and distinguishes it from sibling tools like get_articles for fetching single articles.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides guidance by mentioning an alternative ('fetch single articles with get_articles') and advising to narrow results with 'feed_id/category and since/until instead and filter the returned articles yourself.' It implies when to use this tool (listing multiple articles) and when not to (keyword search not possible), but it lacks explicit exclusions or precise when-to-use scenarios.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_categoriesList categories and labelsA
Read-only

Lists the categories (folders that hold feeds) and the user labels (tags that are attached to individual articles), each with its unread count. Both are addressed by name in the other tools.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint=true. The description adds that each entry includes an unread count, which is behavioral context beyond the annotation. However, it does not mention ordering, pagination, or any limits, but given zero parameters and simplicity, this level is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core action after the verb 'Lists', and every sentence adds distinct value. No redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and zero parameters, the description explains what is returned (categories, labels, unread counts) and a practical note about addressing by name. It is complete enough for a simple list tool, though it could mention if there is any default ordering or maximum items.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are no parameters, so the baseline is 4. The description does not need to add parameter information, and it correctly uses the space to explain the return content rather than inventing param guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists categories and user labels with unread counts, and clarifies the difference between categories (folders for feeds) and labels (tags for articles). It also notes they are addressed by name in other tools, fully distinguishing its purpose from sibling tools like list_feeds or get_unread_counts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use for retrieving category and label names with unread counts, and mentions they are used by name elsewhere, but does not explicitly state when to use this tool versus alternatives such as list_feeds (for feeds) or get_unread_counts (which might focus on aggregate counts). No direct when-not or alternative guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_feedsList feedsA
Read-only

Lists every subscribed feed with its category and unread count. The numeric feedId is what all other tools take as feed_id. Start here to find out what is subscribed before listing articles.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true. The description adds value by specifying the returned data (category and unread count), which is not present in the schema or annotations. No contradictions observed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core action, then additional context. Every sentence adds value with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with no parameters and no output schema, the description fully explains the purpose, output fields, and usage context. It is complete and actionable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has zero parameters, so baseline is 4. The description adds no parameter detail because none are needed. Schema coverage is 100% trivially.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists every subscribed feed with category and unread count. It distinguishes itself from siblings like list_articles by recommending starting here before listing articles, and it explains the feedId's role in other tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says 'Start here to find out what is subscribed before listing articles', establishing a clear use case and ordering relative to other tools. This provides strong guidance on when to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mark_all_as_readMark all as readA
Destructive

Marks every article of a feed, category, label or built-in stream as read. Two-step: the first call returns a confirmation token, the second call with that token performs the change. Which articles were unread before cannot be recovered afterwards.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelNoUser label name exactly as returned by list_categories
streamNoBuilt-in stream: reading-list = everything (default), starred = favourites, main = feeds shown on the main stream, important = feeds marked important
feed_idNoNumeric feedId from list_feeds
categoryNoCategory (folder) name exactly as returned by list_categories
older_thanNoOnly articles published before this ISO-8601 date; default: all of them
confirm_tokenNoToken from the first call of this tool

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint annotation, the description reveals the critical two-step process (confirmation token required) and irreversibility of the action. This adds significant behavioral context that annotations alone do not provide, such as the recovery impossibility.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no superfluous content. It front-loads the core purpose, then concisely explains the two-step process and the irreversible consequence. Every sentence is essential.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the main points: purpose, two-step mechanism, and irreversibility. However, it omits the 'older_than' date filter parameter, which modifies the scope of articles marked. Given the tool's complexity (6 parameters, no output schema), this is a minor but notable gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema coverage, the baseline is 3. The description does not add new meaning beyond the schema's parameter descriptions; it merely mentions the scope types (feed, category, label, stream) without clarifying exclusivity or the optional 'older_than' parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool marks all articles in a feed, category, label, or built-in stream as read, using specific verbs and resources. It distinguishes itself from the sibling 'mark_articles' tool by indicating bulk operations, and the two-step process is explicitly mentioned.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for bulk marking but does not explicitly state when to use it over alternatives like 'mark_articles'. It lacks clear guidance on when not to use it or which scope parameter to choose, leaving the agent to infer usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mark_articlesMark articlesA
DestructiveIdempotent

Sets the read state, the star and user labels of specific articles. All changes are reversible by calling this tool again with the opposite value. At most 100 articles per call; every given change is applied to all of them.

ParametersJSON Schema
NameRequiredDescriptionDefault
readNotrue marks as read, false marks as unread
starredNotrue adds the star (favourite), false removes it
add_labelsNoUser labels to attach; unknown labels are created
article_idsYesArticle ids as returned by list_articles
remove_labelsNoUser labels to detach

TDQS

A3.6/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description claims changes are reversible ('All changes are reversible'), which contradicts the annotation 'destructiveHint: true' that implies irreversible or destructive behavior. This is a serious inconsistency. The description also adds useful context (max 100, batch application) but the contradiction undermines trust.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences cover the tool's purpose, reversibility, and constraints. Every word contributes value; no fluff. Front-loaded with the core action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 5 parameters with 100% schema coverage and no output schema, the description explains the key behavioral aspects (reversibility, batch limit, application to all articles). It is sufficient for a straightforward mutation tool, though it could mention that labels are user-created per the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds that all changes are applied to all given articles and that at most 100 articles are allowed per call, which is already in the schema (maxItems). No additional parameter-level meaning is provided beyond what the schema gives.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool sets read state, star, and user labels on specific articles. It distinguishes from sibling tools like 'mark_all_as_read' which operates on all articles, while 'mark_articles' targets specific ones.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains that changes are reversible by calling with opposite values, and enforces a 100-article limit per call. It does not explicitly contrast with sibling tools like 'mark_all_as_read' or 'list_articles', but the context is clear enough for typical use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rename_category_or_labelRename a category or labelA

Renames a category (folder) or a user label. FreshRSS resolves the name against its categories first and falls back to labels, so one tool covers both. Feeds and articles keep their assignment.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesCurrent name, exactly as in list_categories
new_nameYesNew name

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses that feeds and articles keep their assignment (non-destructive behavior) and the resolution order, which are important behavioral traits beyond the basic purpose. It does not mention permissions, idempotency, or error states, but for a rename tool these are adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, starting with the primary action and then adding nuance and behavioral assurance. Every sentence adds unique information, and there is no redundancy or fluff. It is front-loaded with the most important information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the main behavioral aspects (resolution, preservation of assignments) but does not mention return values or error cases. Since there is no output schema, the agent is left wondering what the tool returns on success or failure. For a simple mutation tool, this is a moderate gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with descriptive parameter comments. The description adds value by explaining how the 'name' parameter is resolved against categories and labels, which is not in the schema. This additional context helps the agent understand the lookup behavior beyond the schema's mention of 'exactly as in list_categories'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action (rename) and the two resources (category or label). It explicitly covers both types, which is more specific than a vague 'rename something'. The sibling distinction is implicitly handled by covering both categories and labels in one tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the resolution order (categories first, then labels), which helps the agent understand how the tool works. However, it does not explicitly contrast with the sibling 'delete_category_or_label' or provide guidance on when to use this tool over alternatives. It also omits prerequisites like listing categories first, though the schema parameter description hints at that.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

subscribe_feedSubscribe to a feedA

Subscribes to a feed. The URL may point at the feed itself or at a website — FreshRSS discovers the feed and then downloads it, so this call can take a while. A category that does not exist yet is created.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesFeed URL or website URL (http/https)
titleNoTitle to use instead of the feed's own title
categoryNoCategory to file the feed under; created if unknown

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses the auto-discovery and download process, plus duration, which adds value beyond the annotations (idempotentHint=false, destructiveHint=false). However, it does not clarify whether subscribing to an already-subscribed feed creates a duplicate or returns an error, leaving an important behavioral gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the primary action, and every phrase contributes essential context. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's modest complexity (3 params, no output schema, minimal annotations), the description adequately covers the core behaviors and side effects. Missing details like return value or error conditions, but acceptable for a straightforward subscribe operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description reinforces the schema's meaning (e.g., website-to-feed discovery, category auto-creation) but does not add new semantic information beyond what the param descriptions already provide.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the verb 'Subscribes to a feed' and distinguishes the resource. The description adds specificity by noting that the URL can be a feed or website, and contrasts with sibling tools like update_feed and unsubscribe_feed through the distinct action of subscribing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies usage context (add a new feed) and provides helpful notes about URL flexibility and potential delay, but does not explicitly state when to use this tool versus alternatives (e.g., update_feed for modifying existing feeds) or when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unsubscribe_feedUnsubscribe from a feedA
Destructive

Deletes a feed together with all of its stored articles, read state and stars. Two-step: the first call returns a confirmation token, the second call with that token performs the deletion. This cannot be undone — re-subscribing starts from whatever the feed currently offers.

ParametersJSON Schema
NameRequiredDescriptionDefault
feed_idYesNumeric feedId from list_feeds
confirm_tokenNoToken from the first call of this tool

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, but the description goes beyond by detailing the two-step token mechanism and what is lost (articles, read state, stars). It also notes that re-subscribing starts fresh, adding valuable behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, each adding essential information: what is deleted, the two-step process, and irreversibility. No fluff, front-loaded with core action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description sufficiently covers behavior, prerequisites, and consequences. For a destructive two-step operation with good annotations, this is complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the description adds minimal value over the schema for parameters. However, it clarifies that feed_id comes from list_feeds and confirm_token is from the first call, which is helpful but not essential given the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific verbs ('Deletes') and resources ('feed', 'stored articles, read state and stars'), clearly distinguishing it from sibling tools like subscribe_feed or update_feed. The purpose is uniquely defined.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the two-step process (first call for token, second call for deletion) and warns about irreversibility, guiding the agent on correct invocation. It does not explicitly mention when not to use it or alternatives, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_feedUpdate a feedA
Idempotent

Renames a feed and/or moves it to another category. A category that does not exist yet is created. Fields that are not given stay unchanged.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoNew title
feed_idYesNumeric feedId from list_feeds
categoryNoCategory to move the feed to

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide idempotentHint=true and destructiveHint=false. The description adds that a non-existent category is created and that omitted fields remain unchanged, which clarifies the partial update behavior beyond what annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences long, front-loaded with the purpose, and includes necessary caveats. Every sentence earns its place with no redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple update tool with 3 parameters and no output schema, the description covers the core behavior (rename, move, category creation, partial updates). It does not mention return values or prerequisites (e.g., feed must exist), but these are implied by the required feed_id parameter and the tool's purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so each parameter has a description. The description adds value by tying the parameters together: 'Renames a feed and/or moves it to another category' explains the two actions, and 'Fields that are not given stay unchanged' clarifies the partial update semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Renames a feed and/or moves it to another category,' which is a specific verb (rename/move) and resource (feed). It clearly distinguishes from sibling tools like subscribe_feed, unsubscribe_feed, and rename_category_or_label.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains that categories are created on the fly and fields not provided stay unchanged, giving some usage context. However, it does not explicitly state when to use this tool versus alternatives (e.g., rename_category_or_label) or when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 16 tool updatesv0.1.1
    • First observeddelete_category_or_label
    • First observedexport_opml
    • First observedget_articles
    • First observedget_unread_counts
    • First observedget_user_info
    • First observedimport_opml
    • First observedlist_article_ids
    • First observedlist_articles
    • First observedlist_categories
    • First observedlist_feeds
    • First observedmark_all_as_read
    • First observedmark_articles
    • First observedrename_category_or_label
    • First observedsubscribe_feed
    • First observedunsubscribe_feed
    • First observedupdate_feed

TDQS

A4.1/5.0
Disambiguation5/5

Each tool targets a distinct operation or resource: user info, feeds, articles, categories, counts, import/export, etc. Even where tools are related (e.g., list_articles vs get_articles), their purposes are clearly separated by filters vs. ID-based retrieval, so no ambiguity exists.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern in snake_case (e.g., list_feeds, mark_articles, export_opml). The verbs are descriptive and uniform, making it easy for an agent to predict tool names.

Tool Count4/5

With 16 tools, the set is slightly above the ideal 3-15 range but still well-scoped for a full-featured feed reader. Each tool serves a clear purpose, and no tool feels redundant or excessive.

Completeness4/5

The tool set covers the core lifecycle for feeds, articles, categories, labels, and import/export. A minor gap is the lack of an explicit tool to create a label without marking an article, but the overall coverage is strong and the platform's API limitations (no full-text search) are acknowledged.

Maintenance

ActivityMaintained
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    An MCP server for RSS feed aggregation and article content extraction, allowing users to subscribe to feeds and extract full article content as Markdown.
    2
    183
    5
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A self-hosted RSS reader MCP server that manages RSS subscriptions and fetches live feed content, deployable on AWS.
    -
  • A
    license
    B
    quality
    D
    maintenance
    An MCP server that provides RSS feed tools for Claude Desktop, enabling fetching and parsing RSS feeds with configurable feeds and blocklists.
    6
    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/ni-c/freshrss-mcp'

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