FreshRSS Agent
This MCP server connects to FreshRSS via the Google Reader API and exposes tools to read feeds, manage subscriptions, and ingest content into an epistemic knowledge graph.
Read stream contents, including pagination/continuation, ordering, and newer-than filtering.
Fetch full contents for specific feed items.
Get unread counts and list subscriptions/categories.
Subscribe to or unsubscribe from feeds, optionally setting title/category.
Add category labels to subscriptions.
Mark items as read and star/unstar items.
Ingest FreshRSS items or subscriptions into epistemic-graph as typed nodes, best-effort when the graph engine is reachable.
Allows interaction with FreshRSS, a self-hosted RSS reader, via its Google Reader compatible API. Provides tools for managing subscriptions, categories, feeds, and items, including reading streams, marking as read, starring, and unsubscribing.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@FreshRSS Agentlist my subscriptions and unread counts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
FreshRSS
CLI or API | MCP
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 —
ClientLoginauth, transparent re-authentication on401, 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 installfreshrss-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), souvx/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 |
|
| Natively ingest FreshRSS feed items into epistemic-graph as :Document nodes. |
|
| Natively ingest FreshRSS subscriptions into epistemic-graph as typed nodes. |
|
| Read FreshRSS streams via the Google Reader API. CONCEPT:FR-OS.identity.frss |
|
| 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 |
|
| List categories / tags ( |
|
| Fetch full contents for specific item ids (GReader |
|
| Add a category label to an existing feed subscription. |
|
| Mark one or more items as read. |
|
| Star or unstar an item. |
|
| Fetch items for a stream. |
|
| Subscribe to a feed, optionally setting its title and category. |
|
| List all feed subscriptions. |
|
| Return unread counts per stream. |
|
| 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 |
|
| |
|
| |
|
| options: stdio, streamable-http, sse |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| options: none, embedded, remote |
|
| |
|
| |
|
| |
|
| |
| secret-injected | |
| — | Named outbound TLS policy from AgentConfig. Use a reference for runtime-only trust material; peer and hostname verification remain mandatory. |
| — | |
|
| |
|
| |
|
| |
|
| gates opportunistic KG writeback in api_client_reader.py; default on |
Inherited agent-connector-sdk variables (apply to every connector)
Variable | Example | Description |
|
| Tool surface: |
| — | Comma-separated tool allow-list |
| — | Comma-separated tool deny-list |
| — | Comma-separated tag allow-list |
| — | Comma-separated tag deny-list |
| — | Outbound MCP child auth: |
| — | OIDC client id (service-account auth) |
|
| Runtime secret reference for the OIDC service account |
| — | HTTP Basic username ( |
|
| Runtime secret reference for HTTP Basic auth ( |
|
| Verbose logging |
|
| Unbuffered stdout (recommended in containers) |
|
| URL of the MCP server the agent connects to |
| — | Operator-configured LLM provider for the agent |
| — | 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 |
| Base URL of the FreshRSS instance (e.g. |
|
| FreshRSS username (GReader | — |
| FreshRSS API password (Settings → Authentication) | — |
| Named outbound TLS policy from AgentConfig; verification is mandatory | (empty, system trust) |
MCP server / transport
Variable | Description | Default |
|
|
|
| Bind host (HTTP transports) |
|
| Bind port (HTTP transports) |
|
| Tool surface: |
|
Telemetry & governance
Variable | Description | Default |
| Enable OpenTelemetry / Langfuse export |
|
| Authorization mode: |
|
| Embedded policy file |
|
| 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 usefreshrss-agent[mcp]to add FastMCP / FastAPI throughagent-connector-sdk; the required Agent Connector SDK core still carriesepistemic-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-mcpFor 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.jsonviauvx,docker run, orpodman run, or point at a local streamable-http container byurl.Remote URL — connect to a server deployed behind Caddy at
https://freshrss-mcp.example.invalid/mcpusing 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 |
| Slim MCP server only ( | The operator only run the MCP server (smallest install / image) |
| Everything ( | 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 serverContainer 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:
Overview · Installation · Usage · Deployment · Platform · Concepts
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) |
|
Bare-metal, dev (editable) |
|
Container, dev (editable) | deploy |
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 toolsfreshrss_categoriesCategoriesBRead-onlyIdempotent
List categories / tags (tag/list).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| params_json | No | JSON string of stream_contents params (stream_id, count, order, newer_than, continuation). | {} |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| params_json | No | JSON string of options (currently none; reserved). | {} |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| item_ids | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| category | Yes | ||
| feed_url | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| item_ids | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| item_id | Yes | ||
| starred | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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 contentsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | ||
| order | No | o | |
| stream_id | No | user/-/state/com.google/reading-list | |
| newer_than | No | ||
| continuation | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| category | No | ||
| feed_url | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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 listBRead-onlyIdempotent
List all feed subscriptions.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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 countBRead-onlyIdempotent
Return unread counts per stream.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| feed_url | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
12 tool updates
v2.3.0- First observed
freshrss_categories - First observed
freshrss_ingest_items - First observed
freshrss_ingest_subscriptions - First observed
freshrss_item_contents - First observed
freshrss_label - First observed
freshrss_mark_read - First observed
freshrss_star - First observed
freshrss_stream_contents - First observed
freshrss_subscribe - First observed
freshrss_subscription_list - First observed
freshrss_unread_count - First observed
freshrss_unsubscribe
TDQS
Scored across 12 tools
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.
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.
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.
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
Related MCP Connectors
A MCP server that works with Google Calendar to manage event listing, reading, and updates.
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
Reddit MCP — public Reddit data via the Atom/RSS feeds.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP RSS is a Model Context Protocol (MCP) server for interacting with RSS feeds4 npm27MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for interacting with FreshRSS via the Google Reader API, enabling subscription management, content reading, and item operations.2MIT
- AlicenseAqualityCmaintenanceAn MCP server for managing and querying RSS/news feeds, enabling real-time fetching, searching, and retrieval of feed items.56 npm1MIT
- AlicenseBqualityAmaintenanceSecure MCP server for RSS/Atom feed reading with SQLite backend. Enables feed management, entry search, and OPML import/export.17AGPL 3.0