Skip to main content
Glama

FreshRSS

CLI or API | MCP

PyPI - Version MCP Server PyPI - Downloads GitHub Repo stars PyPI - License GitHub last commit (by committer)

Documentation — Installation, deployment, usage across the API, CLI, and MCP backing platform are maintained in the official documentation.


Related MCP server: freshrss-mcp-server

Table of Contents


Overview

A connector for the self-hosted FreshRSS RSS reader, wrapping its Google Reader compatible API (GReader). It exposes two action-routed MCP tool domains:

  • freshrss_reader — stream_contents (feed items + continuation), item_contents, unread_count.

  • freshrss_subscriptions — list, subscribe, unsubscribe, label, categories, mark_read, star.

This repository is actively maintained - Contributions are welcome!


Key Features

  • Consolidated Action-Routed MCP Tools: Two togglable tool domains group every GReader operation, minimizing token overhead and tool bloat in LLM contexts.

  • Google Reader Compatible: Wraps the FreshRSS GReader API — ClientLogin auth, transparent re-authentication on 401, and automatic write-token handling.

  • Enterprise-Grade Security: OIDC token delegation (RFC 8693), Eunomia policy enforcement, and per-instance credential resolution.

  • Native Telemetry & Tracing: Out-of-the-box OpenTelemetry exports and Langfuse tracing.


MCP

Install the slim [mcp] extra. All MCP examples below install freshrss-agent[mcp] — the MCP-server extra that pulls only the FastMCP / FastAPI tooling (agent-connector-sdk). It deliberately excludes the heavy agent runtime (the epistemic-graph engine, pydantic-ai, dspy, llama-index, tree-sitter), so uvx/container installs are dramatically smaller and faster. (see Installation).

Available MCP Tools

Auto-generated from the live MCP server — do not edit by hand.

Condensed action-routed tools (MCP_TOOL_MODE=condensed)

MCP Tool

Toggle Env Var

Description

freshrss_ingest_items

INGESTTOOL

Natively ingest FreshRSS feed items into epistemic-graph as :Document nodes.

freshrss_ingest_subscriptions

INGESTTOOL

Natively ingest FreshRSS subscriptions into epistemic-graph as typed nodes.

freshrss_reader

READERTOOL

Read FreshRSS streams via the Google Reader API. CONCEPT:FR-OS.identity.frss

freshrss_subscriptions

SUBSCRIPTIONSTOOL

Curate FreshRSS feeds, categories and item tags. CONCEPT:FR-OS.governance.frss

Verbose 1:1 API-mapped tools (MCP_TOOL_MODE=verbose or both)

MCP Tool

Toggle Env Var

Description

freshrss_categories

SUBSCRIPTIONS_MIXINTOOL

List categories / tags (tag/list).

freshrss_item_contents

READER_MIXINTOOL

Fetch full contents for specific item ids (GReader i parameters).

freshrss_label

SUBSCRIPTIONS_MIXINTOOL

Add a category label to an existing feed subscription.

freshrss_mark_read

SUBSCRIPTIONS_MIXINTOOL

Mark one or more items as read.

freshrss_star

SUBSCRIPTIONS_MIXINTOOL

Star or unstar an item.

freshrss_stream_contents

READER_MIXINTOOL

Fetch items for a stream.

freshrss_subscribe

SUBSCRIPTIONS_MIXINTOOL

Subscribe to a feed, optionally setting its title and category.

freshrss_subscription_list

SUBSCRIPTIONS_MIXINTOOL

List all feed subscriptions.

freshrss_unread_count

READER_MIXINTOOL

Return unread counts per stream.

freshrss_unsubscribe

SUBSCRIPTIONS_MIXINTOOL

Unsubscribe from a feed.

4 action-routed tool(s) · 10 verbose 1:1 tool(s). Each is enabled unless its <DOMAIN>TOOL toggle is set false; MCP_TOOL_MODE selects the surface (intent default — the six verb-tools, granular set loaded on demand · condensed action-routed · verbose 1:1 · both). Auto-generated — do not edit.

Detailed tool schemas, parameter shapes, and validation constraints are preserved in docs/usage.md.

Environment Variables

Package environment variables

Variable

Example

Description

HOST

0.0.0.0

PORT

8000

TRANSPORT

stdio

options: stdio, streamable-http, sse

ENABLE_OTEL

True

OTEL_EXPORTER_OTLP_ENDPOINT

http://localhost:8080/api/public/otel

OTEL_EXPORTER_OTLP_PUBLIC_KEY_REF

vault-ref-to-pk

OTEL_EXPORTER_OTLP_SECRET_KEY_REF

vault-ref-to-sk

OTEL_EXPORTER_OTLP_PROTOCOL

http/protobuf

EUNOMIA_TYPE

none

options: none, embedded, remote

EUNOMIA_POLICY_FILE

mcp_policies.json

EUNOMIA_REMOTE_URL

http://eunomia-server:8000

FRESHRSS_URL

http://localhost:8080

FRESHRSS_USER

admin

FRESHRSS_API_PASSWORD

secret-injected

FRESHRSS_TLS_PROFILE

—

Named outbound TLS policy from AgentConfig. Use a reference for runtime-only trust material; peer and hostname verification remain mandatory.

FRESHRSS_TLS_PROFILE_REF

—

READERTOOL

True

SUBSCRIPTIONSTOOL

True

INGESTTOOL

True

FRESHRSS_KG_AUTO_INGEST

True

gates opportunistic KG writeback in api_client_reader.py; default on

Inherited agent-connector-sdk variables (apply to every connector)

Variable

Example

Description

MCP_TOOL_MODE

intent

Tool surface: intent | condensed | verbose | both

MCP_ENABLED_TOOLS

—

Comma-separated tool allow-list

MCP_DISABLED_TOOLS

—

Comma-separated tool deny-list

MCP_ENABLED_TAGS

—

Comma-separated tag allow-list

MCP_DISABLED_TAGS

—

Comma-separated tag deny-list

MCP_CLIENT_AUTH

—

Outbound MCP child auth: oidc-client-credentials | basic | none

OIDC_CLIENT_ID

—

OIDC client id (service-account auth)

OIDC_CLIENT_SECRET_REF

secret://identity/oidc-client-secret

Runtime secret reference for the OIDC service account

MCP_BASIC_AUTH_USERNAME

—

HTTP Basic username (MCP_CLIENT_AUTH=basic)

MCP_BASIC_AUTH_PASSWORD_REF

secret://identity/mcp-basic-password

Runtime secret reference for HTTP Basic auth (MCP_CLIENT_AUTH=basic)

DEBUG

False

Verbose logging

PYTHONUNBUFFERED

1

Unbuffered stdout (recommended in containers)

MCP_URL

http://localhost:8000/mcp

URL of the MCP server the agent connects to

PROVIDER

—

Operator-configured LLM provider for the agent

MODEL_ID

—

Operator-configured model id for the agent

20 package + 16 inherited variable(s). Auto-generated from .env.example + the shared agent-connector-sdk set — do not edit.

Every variable the server reads. A copy-paste template lives in .env.example.

Connection & Credentials

Variable

Description

Default

FRESHRSS_URL

Base URL of the FreshRSS instance (e.g. https://freshrss.example.invalid)

http://localhost:8080

FRESHRSS_USER

FreshRSS username (GReader Email field)

—

FRESHRSS_API_PASSWORD

FreshRSS API password (Settings → Authentication)

—

FRESHRSS_TLS_PROFILE / FRESHRSS_TLS_PROFILE_REF

Named outbound TLS policy from AgentConfig; verification is mandatory

(empty, system trust)

MCP server / transport

Variable

Description

Default

TRANSPORT

stdio, streamable-http, or sse

stdio

HOST

Bind host (HTTP transports)

0.0.0.0

PORT

Bind port (HTTP transports)

8000

MCP_TOOL_MODE

Tool surface: condensed, verbose, or both

condensed

Telemetry & governance

Variable

Description

Default

ENABLE_OTEL

Enable OpenTelemetry / Langfuse export

True

EUNOMIA_TYPE

Authorization mode: none, embedded, remote

none

EUNOMIA_POLICY_FILE

Embedded policy file

mcp_policies.json

EUNOMIA_REMOTE_URL

Remote Eunomia server URL

—

Tool toggles — each action-routed tool domain can be disabled via its toggle env var (set to false): READERTOOL, SUBSCRIPTIONSTOOL (see the Available MCP Tools table above).

MCP Configuration Examples

Install the connector-focused [mcp] extra. Examples use freshrss-agent[mcp] to add FastMCP / FastAPI through agent-connector-sdk; the required Agent Connector SDK core still carries epistemic-graph[full]. The [agent-runtime] extra additionally enables model orchestration.

stdio Transport (local IDEs — Cursor, Claude Desktop, VS Code)

{
  "mcpServers": {
    "freshrss-mcp": {
      "command": "uvx",
      "args": [
        "--from",
        "freshrss-agent[mcp]",
        "freshrss-mcp"
      ],
      "env": {
        "MCP_TOOL_MODE": "intent",
        "FRESHRSS_API_PASSWORD": "your_api_password_here",
        "FRESHRSS_KG_AUTO_INGEST": "True",
        "FRESHRSS_URL": "http://localhost:8080",
        "FRESHRSS_USER": "admin",
        "INGESTTOOL": "True",
        "READERTOOL": "True",
        "SUBSCRIPTIONSTOOL": "True"
      }
    }
  }
}

Runtime references require an alias-aware launcher such as Arbora. Other launchers must omit those entries and inject the resolved values through their own runtime secret boundary.

Streamable-HTTP Transport (networked / production)

{
  "mcpServers": {
    "freshrss-mcp": {
      "command": "uvx",
      "args": [
        "--from",
        "freshrss-agent[mcp]",
        "freshrss-mcp",
        "--transport",
        "streamable-http",
        "--port",
        "8000"
      ],
      "env": {
        "TRANSPORT": "streamable-http",
        "HOST": "127.0.0.1",
        "PORT": "8000",
        "MCP_TOOL_MODE": "intent",
        "FRESHRSS_API_PASSWORD": "your_api_password_here",
        "FRESHRSS_KG_AUTO_INGEST": "True",
        "FRESHRSS_URL": "http://localhost:8080",
        "FRESHRSS_USER": "admin",
        "INGESTTOOL": "True",
        "READERTOOL": "True",
        "SUBSCRIPTIONSTOOL": "True"
      }
    }
  }
}

Alternatively, connect to a pre-deployed Streamable-HTTP instance by url:

{
  "mcpServers": {
    "freshrss-mcp": {
      "url": "http://localhost:8000/freshrss-mcp/mcp"
    }
  }
}

Run a reviewed container image as a least-privilege stdio child (no listener or published port):

docker run -i --rm \
  --read-only \
  --cap-drop=ALL \
  --security-opt=no-new-privileges \
  --pids-limit=256 \
  --tmpfs /tmp:rw,noexec,nosuid,nodev,size=64m \
  -e TRANSPORT=stdio \
  -e MCP_TOOL_MODE=intent \
  -e FRESHRSS_API_PASSWORD=your_api_password_here \
  -e FRESHRSS_KG_AUTO_INGEST=True \
  -e FRESHRSS_URL=http://localhost:8080 \
  -e FRESHRSS_USER=admin \
  -e INGESTTOOL=True \
  -e READERTOOL=True \
  -e SUBSCRIPTIONSTOOL=True \
  registry.example.invalid/freshrss-agent@sha256:<digest> freshrss-mcp

For containerized network HTTP, supply an authenticated TLS ingress (or direct server TLS), exact MCP_ALLOWED_HOSTS, and an exact trusted-proxy CIDR policy through the operator-owned deployment profile. The generator does not emit an unauthenticated non-loopback listener.

Auto-generated from the code-read env surface (MCP_TOOL_MODE + package vars) — do not edit.

Additional Deployment Options

freshrss-agent can also run as a local container (Docker / Podman / uv) or be consumed from a remote deployment. The Deployment guide has full, copy-paste mcp_config.json for all four transports — stdio, streamable-http, local container / uv, and remote URL:

  • Local container / uv — launch the server from mcp_config.json via uvx, docker run, or podman run, or point at a local streamable-http container by url.

  • Remote URL — connect to a server deployed behind Caddy at https://freshrss-mcp.example.invalid/mcp using the "url" key.

Usage

Once configured, an LLM (or a direct caller) invokes a tool domain with an action and a JSON params_json payload. Examples:

// Fetch the 50 most recent unread items, newest first
{
  "tool": "freshrss_reader",
  "action": "stream_contents",
  "params_json": "{\"count\": 50, \"order\": \"n\"}"
}

// Subscribe to a feed and file it under a category
{
  "tool": "freshrss_subscriptions",
  "action": "subscribe",
  "params_json": "{\"feed_url\": \"http://example.com/rss\", \"category\": \"News\"}"
}

// Mark items as read
{
  "tool": "freshrss_subscriptions",
  "action": "mark_read",
  "params_json": "{\"item_ids\": [\"tag:google.com,2005:reader/item/0001\"]}"
}

Invoking a tool with an unknown or omitted action returns the discovery payload listing every valid action for that domain.

Installation

Pick the extra that matches what the operator want to run:

Extra

Installs

Use when

freshrss-agent[mcp]

Slim MCP server only (agent-connector-sdk — FastMCP/FastAPI)

The operator only run the MCP server (smallest install / image)

freshrss-agent[all]

Everything (mcp + agent + logfire)

Development / both surfaces

# MCP server only (recommended for tool hosting — slim deps)
uv pip install "freshrss-agent[mcp]"

# Everything (development)
uv pip install "freshrss-agent[all]"      # or: python -m pip install "freshrss-agent[all]"

After installation two console scripts are available:

freshrss-mcp      # run the MCP server

Container images (:mcp)

One multi-stage docker/Dockerfile builds the MCP-only image (--target mcp):

Image tag

Build target

Contents

Entrypoint

agent (:2.3.4) with a co-located :mcp sidecar.

Knowledge-graph database (epistemic-graph)

transitively via agent-connector-sdk). For production — or to share one knowledge graph across multiple agents — run epistemic-graph as its own database container and point the agent at it instead of embedding it. Deployment recipes (single-node + Raft HA), connection config, and the full database architecture (with diagrams) are documented in the epistemic-graph deployment guide. The slim [mcp] server does not require the database.

Documentation

Full installation, deployment, usage, and platform-provisioning guides live in the docs/ directory and are published via mkdocs + GitHub Pages at the official documentation site:

Deploy with agent-os-genesis

This package can be provisioned for you — skill-guided — by the agent-os-genesis universal skill (its single-package deploy mode): it picks your install method, seeds secrets to OpenBao/Vault (or .env), trusts your enterprise CA, registers the MCP server, and verifies it — the same machinery that stands up the whole Agent OS, narrowed to just this package. Ask your agent to "deploy freshrss-agent with agent-os-genesis".

Install mode

Command

Bare-metal, prod (PyPI)

uvx freshrss-mcp · or uv tool install freshrss-agent

Bare-metal, dev (editable)

uv pip install -e ".[all]" · or pip install -e ".[all]"

Container, dev (editable)

deploy docker/compose.dev.yml (source-mounted at /src; edits live on restart)

Secrets are read-existing + seeded via vault_sync — you are only prompted for what's missing.

Governed capability contract

This package ships a compact canonical skill surface with specialist procedures kept as referenced workflows. The current MCP tools, skill metadata, connector_manifest.yml, ontology, mappings, shapes, fixtures, migrations, tool-schema fingerprints, and certification metadata form one versioned capability contract. Validate them together; do not rely on stale tool names or historical per-task skill wrappers.

Runtime endpoints, credentials, certificate trust, tenant identity, retention, and observability policy are deployment inputs and are never packaged values. See Configuration, trust, and privacy before enabling a network transport, connector ingestion, Arbora delegation, or trace export.

Available Tools

12 tools
freshrss_categoriesCategoriesB
Read-onlyIdempotent

List categories / tags (tag/list).

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior2/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=true, fully covering the safety profile. The description adds nothing behavioral beyond naming the upstream API endpoint (tag/list); it gives no pagination, ordering, or scoping 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?

A single short sentence with the verb and resource front-loaded and zero filler. Appropriately sized for a parameterless listing tool.

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?

With no parameters and an existing output schema, the description needn't explain return values, and it correctly identifies the resource. Its only shortfall is not distinguishing this listing tool from the other list-style siblings.

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 takes zero parameters, so the baseline of 4 applies. There are no parameter semantics the description could add or omit.

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?

States a specific verb ("List") and resource ("categories / tags"), making the tool's purpose immediately clear. It does not differentiate itself from siblings like freshrss_subscription_list or freshrss_label, so it falls short of a 5.

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

Usage Guidelines2/5

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

The description contains no when-to-use guidance, no prerequisites, and no reference to alternative tools for related listing needs. The agent must infer the usage context entirely from the name.

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

freshrss_ingest_itemsFreshrss Ingest ItemsA

Natively ingest FreshRSS feed items into epistemic-graph as :Document nodes.

Fetches a stream via the GReader API and pushes the items (title + body + source_uri + originating feed) into the knowledge graph via the fast engine client. Best-effort: returns {"ingested": None} when no engine is reachable. CONCEPT:AU-KG.ingest.enterprise-source-extractor.

NameRequiredDescriptionDefault
params_jsonNoJSON string of stream_contents params (stream_id, count, order, newer_than, continuation).{}

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior4/5

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

With no annotations at all, the description carries the full burden and does disclose key traits: it is a write that creates :Document nodes, it pushes items through the 'fast engine client', and it is best-effort, returning {"ingested": None} rather than erroring when no engine is reachable — a genuinely useful failure-mode disclosure. It still omits permission/auth requirements and idempotency behavior on re-ingestion.

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

Conciseness3/5

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

The core content is front-loaded and efficient in three sentences. The trailing 'CONCEPT:AU-KG.ingest.enterprise-source-extractor' is internal jargon that adds no selection or invocation value and dilutes an otherwise tight description.

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?

An output schema exists, so return shape need not be explained, and the description still usefully pins down the no-engine case. For a single-parameter best-effort ingest tool it is nearly complete; the missing pieces are what permissions the write requires and what happens to duplicate items.

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?

Only one parameter exists and schema description coverage is 100%, so the schema already documents params_json and its stream_contents keys. The description adds context (stream is fetched via the GReader API) but no parameter-level meaning beyond the schema, so baseline 3 applies.

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?

States a specific verb and resource: ingesting FreshRSS feed items into epistemic-graph as :Document nodes, via the GReader API and fast engine client. It is clearly distinct from read-oriented siblings like freshrss_stream_contents, though it never explicitly names the alternative it is not (e.g. freshrss_ingest_subscriptions), so it stops short of full sibling differentiation.

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?

Implied usage is reasonably clear: this is the tool that moves stream items into the knowledge graph, whereas freshrss_stream_contents merely reads them. However, there is no explicit when-to-use or when-not statement, no prerequisites (does the stream need to exist first?), and no named alternative, so an agent must infer the routing.

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

freshrss_ingest_subscriptionsFreshrss Ingest SubscriptionsB

Natively ingest FreshRSS subscriptions into epistemic-graph as typed nodes.

Lists feed subscriptions via the GReader API and pushes them as :FeedSubscription nodes with their :FeedCategory folders and :inCategory links. Best-effort: returns {"ingested": None} when no engine is reachable. CONCEPT:AU-KG.ingest.enterprise-source-extractor.

NameRequiredDescriptionDefault
params_jsonNoJSON string of options (currently none; reserved).{}

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

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

With no annotations, the description carries the full burden, and it does usefully disclose best-effort semantics and the exact degenerate return shape ({"ingested": None}) when no engine is reachable. However, for a graph-mutating tool it says nothing about idempotency, duplicate handling, overwrite vs append behavior, or required auth/engine state, leaving significant gaps.

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 core behavior and the best-effort caveat are front-loaded in three tight sentences with no filler. The trailing concept tag 'CONCEPT:AU-KG.ingest.enterprise-source-extractor' reads as internal jargon that adds little for an invoking agent, which slightly dilutes an otherwise efficient description.

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?

An output schema exists so return-value documentation is not required, and the description does explain the one unusual return case. Still, for an unannotated ingest/mutation tool it omits behaviors an agent needs (idempotency, re-run effects, prerequisites), so it is adequate but not 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 description coverage is 100% and the single param is documented in the schema as a reserved, currently empty JSON options string, so the description adds nothing but loses nothing by omitting it. Baseline 3 applies when the schema fully documents the parameters.

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?

States a specific verb ('ingest') and resource ('FreshRSS subscriptions'), and details the target graph structure (:FeedSubscription nodes, :FeedCategory folders, :inCategory links). The plural resource noun makes it distinguishable from the sibling freshrss_ingest_items, though that distinction is left implicit rather than called out.

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?

Usage is implied by the purpose statement (ingest subscriptions into the graph), but there is no explicit when-to-use or when-not-to-use guidance, and no mention of the alternative freshrss_ingest_items or freshrss_subscription_list. The agent must infer which ingest tool applies from the resource noun alone.

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

freshrss_item_contentsItem contentsB

Fetch full contents for specific item ids (GReader i parameters).

NameRequiredDescriptionDefault
item_idsYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior3/5

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

Annotations state readOnlyHint=false, openWorldHint=true, idempotentHint=false and destructiveHint=false, so the safety profile is already covered. The description usefully signals that 'full' contents (as opposed to stream summaries) are returned, but adds nothing on whether fetching has side effects (consistent with the non-read-only hint) or on output format. There is tension between the word 'Fetch' and readOnlyHint=false, but this mirrors GReader's POST-based item-contents endpoint rather than a clear claim of mutation, so it is not treated as a hard contradiction.

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?

One short sentence with the operation front-loaded and no filler; the GReader parenthetical is the only extra detail and it is immediately useful.

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?

An output schema exists, so return values need no explanation, and one param with no nesting keeps the surface small. Missing is the upstream step for obtaining item ids and any note on cost/batching when passing many ids.

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

Parameters2/5

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

The single parameter has 0% schema description coverage, so the description must carry the load. It clarifies that the values are item ids and correspond to GReader 'i' parameters, but not accepted form (single string vs array), nor where the ids come from (e.g., freshrss_stream_contents).

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?

States a concrete verb and resource ('Fetch full contents') scoped to 'specific item ids', which implicitly separates it from freshrss_stream_contents (whole-stream listing). It never names a sibling directly, so the differentiation is inferable rather than explicit.

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

Usage Guidelines2/5

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

There is no when-to-use or when-not-to-use guidance and no named alternative. The agent must guess that this is the follow-up call after stream_contents when full text is needed rather than summaries.

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

freshrss_labelLabelC

Add a category label to an existing feed subscription.

NameRequiredDescriptionDefault
categoryYes
feed_urlYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=false, destructiveHint=false, and idempotentHint=false, so the safety profile is covered. The description adds the 'existing feed subscription' precondition, but says nothing about whether re-adding the same label duplicates it, errors, or is a no-op — a real gap given the non-idempotent hint.

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?

A single sentence with no filler, front-loaded with the action. It is efficient, though arguably too terse for a mutation tool with undocumented parameters.

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

Completeness2/5

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

An output schema exists so return values need not be explained, but with 0% parameter coverage, no usage guidance, and no behavioral detail beyond the annotations, the definition leaves an agent guessing about preconditions and duplicate-label behavior.

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

Parameters2/5

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

Schema description coverage is 0% with two required parameters, so the description must carry the burden. It loosely maps 'category' and 'feed subscription' to the parameters but gives no format guidance for feed_url (URL? feed ID?) and no clarification on whether the category value must match an existing category name.

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?

States a specific verb and resource: adding a category label to an existing feed subscription. It is reasonably distinguishable from freshrss_subscribe (creates subscriptions) and freshrss_categories (manages categories), though the phrase 'category label' leaves some ambiguity about whether the category is created or must already exist.

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

Usage Guidelines2/5

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

No guidance on when to use this versus freshrss_categories or freshrss_subscribe, and no prerequisites stated (e.g., whether the category must already exist, or whether the feed must already be subscribed). The word 'existing' hints at a precondition but never spells it out.

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

freshrss_mark_readMark readC

Mark one or more items as read.

NameRequiredDescriptionDefault
item_idsYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior2/5

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

Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false and openWorldHint=true, so the safety profile is covered by structured data. The description adds nothing beyond them — it does not say whether the change is reversible, whether it is persisted server-side, or what happens for invalid IDs.

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?

One short, front-loaded sentence with no filler or redundancy. It is efficient, though its brevity borders on under-specification rather than true concision.

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?

An output schema exists so return values need not be explained, and the operation itself is simple (one required ID parameter). Still, for a state-mutating tool the description omits any note on persistence, failure handling, or interaction with unread counts, leaving it only minimally adequate.

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 0%, and the single parameter accepts either a bare string or an array of strings. The phrase "one or more items" is the only signal that both forms are accepted (multiplicity), which partially compensates for the undocumented anyOf shape, but it gives no format for the IDs.

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 names a specific verb and resource ("Mark ... items as read"), so the agent knows exactly what state change occurs. It does not, however, distinguish this from siblings such as freshrss_star or freshrss_label, which are also per-item state mutations, leaving sibling selection to inference.

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

Usage Guidelines2/5

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

There is no statement of when to use this tool versus alternatives (freshrss_star, freshrss_label, freshrss_unread_count) and no prerequisites or exclusions. "One or more items" hints at batching but is not framed as usage guidance.

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

freshrss_starStarC

Star or unstar an item.

NameRequiredDescriptionDefault
item_idYes
starredNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

C2.7/5.0
Behavior2/5

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

Annotations already declare the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=true), so the bar is lower, but the description adds nothing on top: it doesn't say the state persists, what permissions are needed, or what happens when item_id doesn't exist.

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?

A single short sentence with no filler and the operation front-loaded. It is efficient, though the brevity comes at the cost of the detail noted elsewhere.

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

Completeness2/5

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

An output schema exists so return values need not be explained, but for a 2-parameter mutation tool with zero schema coverage the description leaves the parameter meaning and usage context entirely undocumented.

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

Parameters2/5

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

Schema description coverage is 0% for both parameters, so the description must carry the load. 'Star or unstar' vaguely maps to the starred boolean, but it never explains that starred=true stars and false unstars, that it defaults to true, or what format item_id takes.

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?

States a specific verb pair (star/unstar) and resource (item), so an agent knows exactly what operation it performs. It does not, however, distinguish itself from similar siblings such as freshrss_label or freshrss_mark_read, which also mutate item state.

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

Usage Guidelines2/5

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

There is no statement of when to use this versus freshrss_label or freshrss_mark_read, nor any prerequisite or context. 'Star or unstar' only hints that the operation is a toggle; the caller must infer the rest.

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

freshrss_stream_contentsStream contentsA
Read-onlyIdempotent

Fetch items for a stream.

stream_id is a GReader stream id (e.g. user/-/state/com.google/reading-list for all items, feed/<feedUrl> for one feed, or user/-/label/<category>). order is o (oldest first) or n (newest first). newer_than is a unix-seconds watermark mapped to the GReader ot parameter (exclude items older than this). continuation resumes a previous page. Returns the raw {"items": [...], "continuation": "..."} payload.

NameRequiredDescriptionDefault
countNo
orderNoo
stream_idNouser/-/state/com.google/reading-list
newer_thanNo
continuationNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is covered. The description adds genuine context beyond that: continuation resumes a previous page (pagination semantics), newer_than is a unix-seconds watermark mapped to the GReader ot parameter, and the raw return payload shape is spelled out.

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 purpose is front-loaded in one short sentence, followed by compact per-parameter notes and a final statement of the return shape. Every sentence carries information an agent needs; there is no filler or repetition.

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?

With an output schema present, the description need not enumerate return fields, yet it still notes the {"items": [...], "continuation": "..."} shape, and it covers pagination, ordering, and id construction. The only meaningful omission is the count parameter's semantics and default, which leaves a small hole in an otherwise complete definition.

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 description coverage is 0%, so the description carries the burden and largely does: it documents stream_id formats, the meaning of order ('o' vs 'n'), the newer_than-to-ot mapping, and the role of continuation. It omits the count parameter entirely, which is the one remaining gap in a five-parameter schema.

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 first sentence states a specific verb and resource: 'Fetch items for a stream.' That is clear and unambiguous, and the subsequent detail about stream ids confirms the resource type. It does not, however, differentiate itself from siblings such as freshrss_item_contents or freshrss_unread_count, which an agent might otherwise confuse with a general item-fetch.

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?

Usage is implied rather than stated: it is a read tool for listing stream items, and the description explains the id shapes needed to target a stream. There is no explicit when-to-use guidance, no mention of when to prefer freshrss_item_contents (full body) or freshrss_unread_count (counts only), and no stated prerequisites.

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

freshrss_subscribeSubscribeB

Subscribe to a feed, optionally setting its title and category.

NameRequiredDescriptionDefault
titleNo
categoryNo
feed_urlYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior2/5

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

Annotations already declare the key traits (write, non-idempotent, open-world, non-destructive), and the description adds no behavioral context beyond them. It does not mention duplicate handling, authentication, or rate limits, though the annotations cover the safety profile.

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?

A single, front-loaded sentence with no wasted words; every part (feed, optional title/category) earns its place.

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?

For a simple 3-parameter write tool with output schema and annotations, the description covers purpose and optional fields, but it omits required-parameter emphasis and duplicate-subscription behavior. It is minimally adequate but leaves clear gaps.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate, but it only names title and category as optional and never mentions feed_url or parameter formats. This adds marginal meaning beyond the schema.

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?

States a specific verb 'Subscribe' and resource 'feed,' and the optional title/category scope is clear. The action is inherently distinct from sibling unsubscribe, so an agent can route correctly.

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

Usage Guidelines2/5

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

Provides no explicit when/when-not guidance or alternatives (e.g., freshrss_ingest_subscriptions). Usage is only implied by the tool name, which is insufficient for distinguishing ingestion vs manual subscription.

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

freshrss_subscription_listSubscription listB
Read-onlyIdempotent

List all feed subscriptions.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior2/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=true and destructiveHint=false, so the safety profile is fully covered elsewhere. The description adds nothing beyond that - no note on scope, pagination, or whether it returns all accounts' feeds - so it contributes no new 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.

Conciseness4/5

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

A single short, front-loaded sentence with no filler or redundancy. It is tight and readable, though its very brevity is what leaves the other dimensions thin.

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 no-argument, read-only list tool with a full annotation set and an output schema that documents the return shape, the definition is essentially adequate. Only a brief note on scope (all subscriptions across categories/accounts) would round it out.

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 takes zero parameters, which is the baseline-4 case per the rubric, and the empty object schema with additionalProperties:false is unambiguous. There is nothing for the description to clarify about inputs.

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?

States a specific verb ('List') and resource ('feed subscriptions'), so an agent immediately knows what the tool returns. It does not, however, differentiate itself from adjacent siblings such as freshrss_stream_contents or freshrss_ingest_subscriptions, which also deal with subscriptions/feeds.

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

Usage Guidelines2/5

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

The description offers no when-to-use context, no prerequisites, and no mention of alternatives even though several siblings (freshrss_ingest_subscriptions, freshrss_subscribe, freshrss_unsubscribe) operate on the same subscription domain. Usage is left entirely to inference.

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

freshrss_unread_countUnread countB
Read-onlyIdempotent

Return unread counts per stream.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds the per-stream granularity, which is meaningful context beyond the annotations, but says nothing about freshness, caching, or whether counts are affected by read state changes.

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?

A single short sentence, front-loaded with the verb and result. It is efficient with no wasted words, though it borders on under-specification rather than fully optimized brevity.

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?

An output schema exists, so return value details need not be explained, and the description correctly scopes the result to per-stream counts. It is adequate for a simple 0-param read tool, though it omits any note about which streams are included or authentication expectations.

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 takes zero parameters, so there are no parameter semantics to document; the baseline for a 0-param tool is 4. Nothing in the description is needed or missing here.

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?

States a specific verb (Return) and resource (unread counts) with a scope qualifier (per stream). It is clearly distinguishable from sibling tools like freshrss_stream_contents (returns items, not counts) and freshrss_subscription_list, though it does not explicitly name those alternatives.

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

Usage Guidelines2/5

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

There is no guidance on when to call this versus the many other read-oriented siblings (stream_contents, categories, subscription_list). No exclusions, prerequisites, or context is implied beyond the resource name.

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

freshrss_unsubscribeUnsubscribeC

Unsubscribe from a feed.

NameRequiredDescriptionDefault
feed_urlYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

C2.7/5.0
Behavior2/5

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

Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false, and openWorldHint=true, so the safety profile is partly covered. However, the description adds nothing: it does not say whether the feed's items are removed, whether calling twice errors (relevant given idempotentHint=false), or whether authentication is required for this mutation.

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?

A single short sentence with zero filler and the action front-loaded. It is appropriately sized, though the brevity reflects under-specification rather than disciplined economy.

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

Completeness2/5

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

An output schema exists, so return values need not be explained. But for a mutation tool with an undocumented required parameter and no annotations covering consequences, the description omits what an agent needs: what state changes on success and what error conditions exist.

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

Parameters2/5

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

Schema description coverage is 0% and the single required feed_url parameter is typed only as a string. The description's phrase 'from a feed' implies feed_url identifies the target but gives no format guidance (URL vs. feed ID, case sensitivity), so it fails to compensate for the undocumented parameter.

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 states a specific verb (unsubscribe) and resource (a feed), clearly distinguishing it from the sibling freshrss_subscribe. It stops short of naming alternatives or scope, but the action is unambiguous.

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

Usage Guidelines2/5

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

There is no guidance on when to use this versus alternatives, no prerequisites, and no mention of what happens if the feed is not subscribed. The agent must infer all usage context from the name alone.

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.

  1. 12 tool updatesv2.3.0
    • First observedfreshrss_categories
    • First observedfreshrss_ingest_items
    • First observedfreshrss_ingest_subscriptions
    • First observedfreshrss_item_contents
    • First observedfreshrss_label
    • First observedfreshrss_mark_read
    • First observedfreshrss_star
    • First observedfreshrss_stream_contents
    • First observedfreshrss_subscribe
    • First observedfreshrss_subscription_list
    • First observedfreshrss_unread_count
    • First observedfreshrss_unsubscribe

TDQS

B3.4/5.0

Scored across 12 tools

Disambiguation4/5

Most tools target distinct resources/actions, but there is mild overlap between freshrss_stream_contents and freshrss_item_contents (both retrieve item data) and between the two ingest_* tools. Descriptions clarify these boundaries, so misselection risk is low.

Naming Consistency4/5

All names use a consistent freshrss_ prefix and snake_case, which is good. There is minor verb/noun mixing (verb-first like mark_read/subscribe vs noun-first like categories/subscription_list), but it remains readable and predictable.

Tool Count5/5

12 tools is well-scoped for a FreshRSS integration, covering reading, subscription management, and graph ingestion without bloating. Each tool appears to earn its place.

Completeness4/5

Coverage is solid: subscribe/unsubscribe/list, read fetches, mark_read, star, label, categories, unread counts, and ingestion. Minor gaps like mark-unread, delete, or search operations exist but are workaroundable.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers