关于 FreshRSS
FreshRSS 的 MCP 服务,让 MCP 客户端读取和管理自托管 RSS 订阅。它将 Google Reader API 转换为易用工具,并以纯文本返回文章内容。
主要功能
- 01查看订阅、分类和未读数
- 02列出并读取文章
- 03标记文章状态和标签
- 04管理订阅与分类
- 05导入和导出 OPML
适用场景
- 01汇总各订阅源的未读文章
- 02阅读指定订阅或日期范围内的文章
- 03批量标记文章为已读
- 04导入或导出订阅列表
MCP 相关
向 MCP 客户端提供 FreshRSS 订阅、分类和文章的读取及管理工具。支持只读模式、工具筛选,并为不可逆操作请求确认。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @ni-c/freshrss-mcpFRESHRSS_URLRoot URL of the FreshRSS instance, e.g. https://rss.example.comFRESHRSS_USERFreshRSS user nameFRESHRSS_API_PASSWORD密钥API password from Settings -> Profile -> API management, not the web login passwordFRESHRSS_READ_ONLYSet to true to register only the read toolsFRESHRSS_INSECURE_TLSSet to true to accept a self-signed certificate for this connection onlyFRESHRSS_ALLOW_TOOLSComma-separated tool names or list_* prefixes to register; 'essential' selects a curated preset (default: all tools)FRESHRSS_DENY_TOOLSComma-separated tool names or list_* prefixes to remove from whatever FRESHRSS_ALLOW_TOOLS left本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
16收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
freshrss-mcp
一个用于 FreshRSS 的 Model Context Protocol(MCP)服务。FreshRSS 是一款可自托管的 RSS 和 Atom 订阅源聚合器。
它让 Claude Code、Claude Desktop 或 Codex 等 MCP 客户端能够处理你的订阅源:查看未读内容、阅读文章、标记文章,以及管理订阅和分类。
16 个工具只是上限,并非最低要求:设置 FRESHRSS_ALLOW_TOOLS=essential 即可改为注册精心挑选的 7 个工具。与 16 个工具相比,模型从 7 个工具中选择正确工具的可靠性高得多——详见选择要加载的工具。
它使用 FreshRSS 在 /api/greader.php 提供的 Google Reader 兼容 API,并通过工具参数屏蔽该 API 的种种特性,让助手能够直接使用:数字订阅源 ID、分类和标签名称、ISO 日期以及十进制文章 ID,无需处理 user/-/state/com.google/… 订阅流标识符和十六进制条目标签。

有何不同
16 个工具,无需订阅流 ID。 Google Reader API 使用订阅流标识符和十六进制条目标签。这些工具使用数字订阅源 ID、分类和标签名称、ISO 日期以及十进制文章 ID,并返回纯文本,而非原始 HTML。
专为不可信订阅源打造。 每篇文章都来自互联网上的陌生人,因此响应会标记为数据,订阅源 URL 会移除凭据,文章文本也会按单篇文章和单次响应限制长度。5 个不可逆工具会先通过 MCP elicitation 征求用户确认。
要求
- Node.js 22 或更高版本
- FreshRSS 实例(基于 1.29 开发),并满足以下条件:
- 已启用 API:设置 → 身份验证 → “允许 API 访问”
- 已为用户设置 API 密码:设置 → 个人资料 → API 管理。 该密码与 Web 登录密码不同。
配置
| 变量 | 必填 | 说明 |
|---|---|---|
FRESHRSS_URL | 是 | 实例的根 URL,例如 https://rss.example.com。系统会自动追加 API 路径 /api/greader.php。 |
FRESHRSS_USER | 是 | FreshRSS 用户名。 |
FRESHRSS_API_PASSWORD | 是 | 个人资料页面中的 API 密码,而非网页登录密码。 |
FRESHRSS_READ_ONLY | 否 | 设置为 1、true 或 yes 时,仅注册读取工具。 |
FRESHRSS_INSECURE_TLS | 否 | 设置为 true 时,仅对此连接接受自签名证书。 |
FRESHRSS_ALLOW_TOOLS | 否 | 以逗号分隔的工具名称、list_* 前缀,或精选预设 essential |
FRESHRSS_DENY_TOOLS | 否 | 语法相同;从 FRESHRSS_ALLOW_TOOLS 筛选后的结果中移除指定工具 |
ELICITATION | 否 | 设置为 false 时,以双调用令牌取代审批对话框。不带前缀。 |
服务器无需凭据即可启动,因此其工具仍可列出;但每次调用都会失败,并显示这些设置说明。
选择要加载的工具
FRESHRSS_ALLOW_TOOLS 和 FRESHRSS_DENY_TOOLS 接受以逗号分隔的工具名称;末尾的 * 可匹配整个工具系列。essential 是包含以下七个工具的精选预设:list_feeds、list_categories、get_unread_counts、list_articles、get_articles、mark_articles、mark_all_as_read。
FRESHRSS_ALLOW_TOOLS=essential
FRESHRSS_ALLOW_TOOLS=list_feeds,list_articles,mark_articles
FRESHRSS_DENY_TOOLS=delete_*
如果某个条目与任何工具都不匹配,启动就会中止并指出该条目,因此拼写错误不会悄悄隐藏工具——没人会想到要从环境变量中排查某个缺失的工具。经过筛选的工具不会被注册,因此它既不会出现在 tools/list 中,也无法通过 tools/call 调用,这与 FRESHRSS_READ_ONLY 下的写入工具完全一样。
如果你同时运行多个此类服务器,mcp-hub 是另一种解决方案——它的 /hub 端点会将每个服务器的工具替换为六个元工具。
安装
Claude Code
claude mcp add freshrss -- npx -y @ni-c/freshrss-mcp
Claude Desktop
{
"mcpServers": {
"freshrss": {
"command": "npx",
"args": ["-y", "@ni-c/freshrss-mcp"],
"env": {
"FRESHRSS_URL": "https://rss.example.com",
"FRESHRSS_USER": "alice",
"FRESHRSS_API_PASSWORD": "…"
}
}
}
}
Codex
[mcp_servers.freshrss]
command = "npx"
args = ["-y", "@ni-c/freshrss-mcp"]
env = { FRESHRSS_URL = "https://rss.example.com", FRESHRSS_USER = "alice", FRESHRSS_API_PASSWORD = "…" }
Docker
docker run --rm -i \
-e FRESHRSS_URL=https://rss.example.com \
-e FRESHRSS_USER=alice \
-e FRESHRSS_API_PASSWORD=... \
ghcr.io/ni-c/freshrss-mcp:latest
此镜像面向 linux/amd64 和 linux/arm64 发布,并附带 SBOM 和构建来源证明。它以非特权用户 node 运行,且不包含 npm,因此镜像中只有 Node、运行时依赖项和 dist/。
通过 mcp-hub
无法启动本地进程的客户端——ChatGPT connectors、Claude on the web、Cursor、LibreChat——可通过 mcp-hub 访问 freshrss-mcp:一个容器通过 Streamable HTTP 为许多 stdio MCP 服务器提供服务,并使用单一密码进行 OAuth 2.1 登录,同时为无法使用 OAuth 的客户端提供长期有效的令牌。它的 /hub 端点会将每个服务器置于六个元工具之后,因此一个连接器即可访问所有服务器,无需在模型上下文中加入 N×tool 模式;它还支持两个协议修订版本——本服务器提出的问题会经由它传递给另一端的人。
它的 /config/mcp.json 使用 Claude Code 的格式,因此配置项就是你已有的那一项:
{
"mcpServers": {
"freshrss": {
"command": "npx",
"args": ["-y", "@ni-c/freshrss-mcp"],
"env": { "FRESHRSS_ALLOW_TOOLS": "essential" },
"denyTools": ["delete_*"]
}
}
}
其中的 allowTools 和 denyTools 是 hub 自身针对每个服务器的筛选项,不同于 env 中的 *_ALLOW_TOOLS——两者的区别及其可能导致的误用,详见客户端指南。
工具
阅读
| 工具 | 说明 |
|---|---|
get_user_info | 已通过身份验证的账户——快速检查凭据。 |
list_feeds | 所有订阅及其分类和未读数量。 |
list_categories | 分类(订阅源文件夹)和用户标签(文章标签)。 |
get_unread_counts | 按排序列出的未读总数,以及各订阅源/分类的未读数量。 |
list_articles | 订阅源、分类、标签或内置信息流中的文章,可提供摘要或有长度限制的全文。 |
get_articles | 按 ID 获取指定文章的全文。 |
list_article_ids | 仅返回 ID——这是为 mark_articles 收集一组 ID 的简便方法。 |
export_opml | 将所有订阅导出为 OPML 文档。 |
写入
当 FRESHRSS_READ_ONLY=true 时不会注册。
| 工具 | 说明 | 确认 |
|---|---|---|
mark_articles | 设置指定文章的已读状态、星标和标签。 | — |
mark_all_as_read | 将整个订阅源、分类、标签或信息流标记为已读。 | 是 |
subscribe_feed | 订阅订阅源或网站 URL。 | — |
update_feed | 重命名订阅源或将其移至其他分类。 | — |
unsubscribe_feed | 删除订阅源及其所有已存储文章。 | 是 |
rename_category_or_label | 重命名分类或用户标签。 | — |
delete_category_or_label | 删除分类或用户标签。 | 是 |
import_opml | 订阅 OPML 文档中的所有订阅源。 | 是 |
结构化输出
每个工具都声明了 outputSchema,并在文本块之外通过 structuredContent
返回结果,因此客户端无需解析散文即可使用结果:
{
"untrusted": true,
"source": "freshrss",
"articles": [{ "id": "1234", "title": "…", "read": false, "starred": false }],
"continuation": "1699999999",
"notes": ["…"],
}
每个报告订阅源内容的工具都会带有 untrusted: true 和
source: "freshrss" 字段。该服务一直在 notes 中说明这一点——以列表形式呈现的散文,客户端可以读取但无法验证;而这些字段则让它可以验证。另有八个工具不带这些字段,因为它们的回答完全是该服务自己的内容:传入的 ID、根据参数生成的句子,以及它通过身份验证的账户。
以前有六个工具会用一句话作答(“Feed 9 deleted.”);现在它们也会返回字段,而这句话仍保留在文本块中。
export_opml 返回 {opml},而不是将文档作为整个结果返回:如果根节点为字符串的架构提供给 2025 年代的客户端,就会被改写为 {result: …};无论如何,truncated 都需要一个存放位置。
不支持搜索
FreshRSS 的 API 不提供全文搜索——Google Reader 端点只能按信息流、已读状态和日期筛选。因此,list_articles 没有查询参数;请使用 feed_id/category 和 since/until 缩小结果范围,然后自行筛选返回的文章。
有意不提供的功能
不提供全文搜索,因为 FreshRSS 的 Google Reader API 不支持全文搜索:
其端点只能按信息流、已读状态和日期筛选。请使用 feed_id、
category、since 和 until 缩小范围,然后自行筛选返回的文章。
FreshRSS 网页界面中的搜索没有对应的 API 端点。
不提供原始 HTML。 文章正文会转换为纯文本,并限制每篇文章和每次响应的长度, 以免单次列表响应中的内容占满整个上下文。
安全
- 文章文本是不可信输入。 此服务从 FreshRSS 返回的所有内容都由互联网上的第三方撰写,因此,包含文章文本、标题或订阅源名称的响应都会明确标记为数据,而非指令。
- 需要征得用户同意,而不只是告知。 如果客户端支持 MCP 征询,五个不可逆工具会弹出一个真正的对话框,模型无法代替用户作答。布尔值可能在首次调用时就被设为真,也可能被订阅源中隐藏的文本诱导为真。如果客户端无法显示对话框,这些工具会改用绑定到确切目标的一次性令牌,并明确说明这一点,而不会暗示有人已批准。消息会刻意避免引用来自 API 的标题或名称。请参阅征求用户同意。
- 响应预算。 FreshRSS 为每篇文章最多返回 500 000 个字符的 HTML。文章文本会转换为纯文本,并受到单篇文章上限和单次响应预算的限制;在列表中,只有明确选择后才会包含文章文本。预算按读取的标记语言计费,而不是按转换后的文本计费,因此它限制的是转换工作量,而不仅仅是最终上下文——剥离后几乎不剩内容的标记语言最耗资源,而过去这类情况不计费。转换过程本身是一次从左到右的扫描,耗时与文章长度呈线性关系,与文章内容无关。
- 凭据只读取一次,之后会从
process.env中移除,并且绝不会写入磁盘。请求绝不跟随重定向,以免将授权标头重新发送到其他主机;放宽的 TLS 验证仅作用于此连接,而非整个进程。 - 订阅源 URL 会进行脱敏。 FreshRSS 会以
https://user:password@host/feed的形式存储使用 HTTP 身份验证的订阅源。在订阅源 URL 到达工具结果或 OPML 导出之前,userinfo 部分会被剥除,因此list_feeds不会将付费或私人订阅源的密码打印到对话记录中。 subscribe_feed和import_opml会拒绝指向内部网络的目标。 FreshRSS 会在服务端获取这些 URL,因此,这两个工具都可能成为一种 SSRF 原语,可通过文章中的文本触发。环回地址和链路本地地址(包括云元数据端点)都会被拒绝;这既适用于订阅源 URL,也适用于 OPML 文档中的每个xmlUrl/htmlUrl。地址会以数值形式比较,因此像[::ffff:169.254.169.254]这样的 IPv4 映射 IPv6 字面地址也会被拦截;主机名则会先解析再接受。读取 OPML 文档的方式与 XML 解析器一致,传给 FreshRSS 的就是经过检查的文档——因此,检查的 URL 就是实际获取的 URL。私有局域网地址仍然允许使用,因为可自托管的设置通常需要订阅自己网络上的订阅源。import_opml会拒绝<!DOCTYPE>。 此进程不会解析 XML,但文档会交给 FreshRSS 处理,而文档类型声明可能被用于实体扩展攻击和外部实体攻击。OPML 根本不需要它。FRESHRSS_READ_ONLY=true不会注册写入工具,而不是等到调用时才拒绝它们。
会征求用户同意的工具:mark_all_as_read、unsubscribe_feed、delete_category_or_label、import_opml,以及 mark_articles,但仅限即将将文章标记为已读时。加星标、取消星标和添加标签都可以恢复;但哪些文章原先未读则无法恢复,而且 FreshRSS 不会记录这一状态。
文档
完整指南、工具参考和安全说明见 freshrss-mcp.ni-c.de(源文件位于 docs/)。
开发
npm install
npm run lint && npm run build && npm test
npm run test:coverage
请参阅 CONTRIBUTING.md,了解如何使用临时 FreshRSS 实例进行开发。完整文档见 freshrss-mcp.ni-c.de。
发布
- 将 CHANGELOG.md 中的
[Unreleased]条目移到新版本下方,并更新package.json中的version。 npm run lint && npm run build && npm run test:coverage。- 提交,然后打标签:
git tag -s vX.Y.Z -m vX.Y.Z && git push origin main vX.Y.Z。
该标签会触发 release.yml,验证标签与 package.json 中的版本是否一致,通过 Trusted Publishing 发布到 npm 并附带来源证明(无需使用令牌),根据 CHANGELOG 对应章节创建 GitHub 发布,并将条目发布到 MCP Registry。如果只有 Registry 步骤失败,请在 main 上修复,然后手动重新运行 mcp-registry.yml——切勿重新运行已打标签的任务,因为它会检出旧代码树。
贡献
欢迎提交问题、参与讨论和发起拉取请求——请参阅 CONTRIBUTING.md。如需报告漏洞,请使用私密报告渠道,而非公开提交问题;相关政策见 SECURITY.md。
许可证
MIT © Willi Thiel
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。