内容
# 智能RSS解析器
[](https://github.com/bluecarbons/agentic-rss-parser/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/agentic-rss-parser)
[](./SUPPORT.md)
[](./LICENSE)
[](./LICENSE)
[](https://github.com/bluecarbons/agentic-rss-parser)
[](https://github.com/bluecarbons/agentic-rss-parser/issues)
**智能RSS解析器** 是一个企业级的、**零依赖** 的Node.js库,用于解析RSS和Atom订阅源。它提供了一个熟悉的`rss-parser`兼容的API,同时添加了智能分析、去重、丰富和多SDK工具集成。
完全基于原生Node.js API构建(无`fast-xml-parser`,无`zod`,生产环境中无AI SDK)。安全部署在安全敏感的环境中。
> **版本 1.2.0** — 可配置的启发式信号、`userAgent`选项、修正的默认数据库路径,以及Anthropic、OpenAI Agents和Vercel AI SDK的完整SDK集成示例。
---
## 从`rss-parser`迁移
如果您当前正在使用npm包`rss-parser`,迁移只需要一行代码:
```javascript
// 之前
import Parser from 'rss-parser';
// 之后 — 不需要其他更改
import Parser from 'agentic-rss-parser';
```
所有现有的`parseURL`、`parseString`、`parseFile`、`customFields`、`headers`、`timeout`和回调式用法都完全保留。智能管道(`parseFeed`、`runAgenticParser`)是在此基础上的可选扩展。
---
## 为什么选择零依赖?
传统的订阅源解析器会拉入数十个嵌套依赖。`rss-parser`自2022年以来就没有收到安全更新。**智能RSS解析器**通过使用100%原生Node.js API来消除这种风险:
- **自定义XML引擎** — 非递归、逐字符扫描器。天然免疫XXE和Billion Laughs攻击。
- **原生JSON-RPC MCP服务器** — 自定义标准输入/标准输出传输,基于Node的`readline`模块。
- **原生LLM适配器** — 通过内置的`fetch()`直接连接到OpenAI和Anthropic的REST端点。
- **手动模式验证** — 零依赖模式检查(无`zod`)。
- **内置SQLite缓存** — 原生`node:sqlite`模块,用于去重。
---
## 支持的环境
- Node.js `>=22.5.0`(`node:sqlite`所需)
- 仅ESM包
- Linux、macOS、Windows
---
## 功能
- **RSS 2.0 和 Atom** — 命名空间、CDATA、HTML实体、`dc:creator`、`media:content`、`content:encoded`
- **`rss-parser` 替代品** — `parseURL`、`parseString`、`parseFile`、`customFields`、回调风格、Promise风格
- **可配置的启发式分析** — 基于信号的相关性评分,无需API密钥。可通过`signals`、`extraSignals`和`threshold`完全自定义。
- **LLM分析** — 通过原生`fetch()`支持OpenAI、Anthropic和本地(Ollama)提供商
- **文章丰富** — 从订阅源项目URL中获取并剥离完整的文章正文
- **MCP服务器** — stdio JSON-RPC 2.0服务器,暴露`fetch_rss_feed`和`fetch_full_article`工具;与Claude Desktop、Cursor、VS Code和任何MCP兼容主机一起工作
- **SQLite去重** — 跨运行的SHA-256去重
- **SDK集成** — Anthropic SDK、OpenAI Agents SDK、Vercel AI SDK和Google ADK的即用示例
- **`userAgent`选项** — 重写默认UA以避免403错误,适用于阻止机器人用户代理的订阅源
---
## 安装
```bash
npm install agentic-rss-parser
# 或
pnpm add agentic-rss-parser
```
---
## 用法
### 标准解析(rss-parser兼容)
```javascript
import Parser from 'agentic-rss-parser';
const parser = new Parser({
timeout: 10000,
headers: { 'user-agent': 'my-app/1.0' }
});
const feed = await parser.parseURL('https://news.ycombinator.com/rss');
console.log(`Feed: ${feed.title}`);
for (const item of feed.items) {
console.log(`- ${item.title} — ${item.link}`);
}
```
### 使用自定义用户代理绕过403阻止
一些订阅源(Reddit、HN、Lobste.rs)会对机器人用户代理返回403。使用`userAgent`选项:
```javascript
const parser = new Parser({
userAgent: 'Mozilla/5.0 (compatible; MyReader/1.0)'
});
const feed = await parser.parseURL('https://www.reddit.com/r/programming/.rss');
```
### 自定义字段映射
```javascript
const parser = new Parser({
customFields: {
item: [
['dc:creator', 'creator'],
['media:content', 'media', { keepArray: true }]
]
}
});
const feed = await parser.parseString(xmlString);
console.log(feed.items[0].creator);
```
---
## 智能管道
### 默认启发式分析(无API密钥)
使用可配置的信号匹配引擎分析项目。无需LLM或API密钥。
```javascript
import { runAgenticParser } from 'agentic-rss-parser';
const { results, feedErrors } = await runAgenticParser({
feedUrls: ['https://news.ycombinator.com/rss'],
dbPath: './data/rss-agent.db'
// 模型默认为 { provider: 'heuristic' }
});
for (const { item, analysis } of results) {
if (analysis.decision === 'relevant') {
console.log(`[${analysis.confidence}%] ${item.title}`);
console.log(`Summary: ${analysis.summary}`);
console.log(`Tags: ${analysis.tags.join(', ')}`);
}
}
```
### 配置启发式信号(v1.2.0+)
默认信号列表面向开发者/技术工具。 为您的领域自定义它:
```javascript
import { DEFAULT_HEURISTIC_SIGNALS, runAgenticParser } from 'agentic-rss-parser';
console.log(DEFAULT_HEURISTIC_SIGNALS);
// ['release', 'security', 'vulnerability', 'node', 'javascript', ...]
// 选项1 — 用额外信号扩展默认值
const { results } = await runAgenticParser({
feedUrls: ['https://techcrunch.com/feed'],
dbPath: './data/rss-agent.db',
model: {
provider: 'heuristic',
extraSignals: ['funding', 'acquisition', 'launch', 'series'],
threshold: 2 // 较低的阈值以获得更广泛的召回
}
});
// 选项2 — 完全替换默认值(例如,用于初创企业情报订阅源)
const { results: startupResults } = await runAgenticParser({
feedUrls: ['https://techcrunch.com/feed'],
dbPath: './data/rss-agent.db',
model: {
provider: 'heuristic',
signals: ['funding', 'series', 'yc', 'ipo', 'acquisition', 'launch', 'ai', 'b2b'],
threshold: 1
}
});
```
### LLM分析
```javascript
const { results, feedErrors } = await runAgenticParser({
feedUrls: ['https://news.ycombinator.com/rss'],
dbPath: './data/rss-agent.db',
fetchFullArticle: true,
model: {
provider: 'anthropic', // 'openai' | 'anthropic' | 'local' | 'heuristic'
model: 'claude-sonnet-4-5',
apiKey: 'sk-ant-...' // 显式传递提供者支持的分析
}
});
if (feedErrors.length) {
console.error('订阅源错误:', feedErrors);
}
```
### 直接`heuristicAnalyze`用法
```javascript
import { heuristicAnalyze, resolveSignals } from 'agentic-rss-parser';
// 检查解析的信号列表,然后运行
console.log(resolveSignals({ extraSignals: ['funding', 'launch'] }));
const analysis = heuristicAnalyze(
{ title: 'Stripe raises $1B Series H', contentSnippet: 'Fintech giant...' },
'',
{ signals: ['funding', 'series', 'raise', 'valuation'], threshold: 1 }
);
// { decision: 'relevant', confidence: 55, tags: ['funding', 'series'], ... }
```
---
## SDK集成
### Claude桌面/MCP主机
添加到您的`claude_desktop_config.json`:
```json
{
"mcpServers": {
"rss": {
"command": "npx",
"args": ["agentic-rss-parser@latest", "mcp"]
}
}
}
```
连接后,Claude(或任何MCP兼容主机)可以像调用原生工具一样调用`fetch_rss_feed`和`fetch_full_article`。
### Anthropic SDK(直接)
参见[`examples/anthropic-sdk.mjs`](./examples/anthropic-sdk.mjs) — 使用`@anthropic-ai/sdk`的多步骤`tool_use`循环的完整智能循环。
```javascript
import Anthropic from '@anthropic-ai/sdk';
import { runAgenticParser } from 'agentic-rss-parser';
// 工具定义为纯JSON模式 — 无外部模式库。
// 完整循环在examples/anthropic-sdk.mjs中
```
### OpenAI Agents SDK
参见[`examples/openai-agents-sdk.mjs`](./examples/openai-agents-sdk.mjs) — 使用`@openai/agents`的`tool()`和`Agent`。
### Vercel AI SDK
参见[`examples/vercel-ai-sdk.mjs`](./examples/vercel-ai-sdk.mjs) — 使用`ai` + `@ai-sdk/anthropic`的`generateText`和`maxSteps: 5`。
### Google ADK
参见[`examples/adk-real.mjs`](./examples/adk-real.mjs) — 将解析器包装为`LlmAgent`的`FunctionTool`。
---
## 命令行用法
```bash
npx agentic-rss --feed https://news.ycombinator.com/rss
```
多个订阅源,持久缓存:
```bash
npx agentic-rss \
--feed https://news.ycombinator.com/rss \
--feed https://hnrss.org/frontpage \
--db ./data/rss-agent.db
```
---
## MCP服务器
公开订阅源解析为模型上下文协议工具:
```bash
npx agentic-rss-mcp
```
**可用工具:**
| 工具 | 描述 |
|---|---|
| `fetch_rss_feed` | 获取并分析RSS或Atom订阅源。返回每项的`decision`、`confidence`、`summary`、`impact`、`actionItems`、`tags`。接受`url`、`limit`、`provider`。 |
| `fetch_full_article` | 获取文章URL的完整纯文本正文,剥离HTML。 |
---
## API参考
### `new Parser(options?)`
`rss-parser`的直接替代品。所有选项都兼容。
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| `timeout` | `number` | `10000` | 毫秒请求超时时间 |
| `maxRedirects` | `number` | `5` | 要遵循的最大HTTP重定向 |
| `headers` | `Record<string, string>` | — | 附加请求头 |
| `userAgent` | `string` | `agentic-rss-parser/<version>` | 重写用户代理(**v1.2.0新增**) |
| `customFields` | `CustomFieldConfig` | — | 将额外XML字段映射到项目属性 |
| `normalize` | `boolean` | `true` | 规范化输出形状 |
**方法:** `parseURL(url)`、`parseString(xml)`、`parseFile(path)`、`parseFeed(urls, config?)`
---
### `runAgenticParser(config)`
运行完整管道:获取 → 解析 → 去重 → 分析。
返回 `{ results: Array<{ item, analysis }>, feedErrors: FeedError[] }`。
| 配置键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| `feedUrls` | `string[]` | — | 要处理的订阅源URL |
| `dbPath` | `string` | `./data/rss-agent.db` | SQLite缓存路径 |
| `fetchFullArticle` | `boolean` | `false` | 每个项目获取完整文章正文 |
| `concurrency` | `number` | `1` | 最大并行订阅源工作线程(最大16) |
| `model.provider` | `string` | `'heuristic'` | `'heuristic'` \| `'openai'` \| `'anthropic'` \| `'local'` |
| `model.model` | `string` | 提供者默认值 | 模型ID字符串 |
| `model.apiKey` | `string` | `openai`/`anthropic`必填 | 重写API密钥 |
| `model.signals` | `string[]` | — | 替换默认信号(**v1.2.0新增**) |
| `model.extraSignals` | `string[]` | — | 扩展默认信号(**v1.2.0新增**) |
| `model.threshold` | `number` | `3` | 标记为“相关”的信号分数(**v1.2.0新增**) |
---
### `heuristicAnalyze(item, context?, options?)`
直接启发式分析。无异步,无API密钥。
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| `signals` | `string[]` | `DEFAULT_HEURISTIC_SIGNALS` | 完整信号替换 |
| `extraSignals` | `string[]` | — | 追加到默认值 |
| `threshold` | `number` | `3` | `'relevant'`所需分数 |
---
### `DEFAULT_HEURISTIC_SIGNALS`
内置信号列表(开发者/技术关注)。导出以供检查:
```javascript
import { DEFAULT_HEURISTIC_SIGNALS } from 'agentic-rss-parser';
// ['release', 'security', 'vulnerability', 'node', 'javascript',
// 'typescript', 'framework', 'api', 'breaking', 'performance', 'agent', 'rss']
```
---
### `resolveSignals(options?)`
根据选项对象返回有效的信号列表。用于在运行管道之前调试信号配置。
```javascript
import { resolveSignals } from 'agentic-rss-parser';
resolveSignals({ extraSignals: ['funding'] });
// [...DEFAULT_HEURISTIC_SIGNALS, 'funding']
resolveSignals({ signals: ['ai', 'launch'] });
// ['ai', 'launch']
```
---
## 开发与测试
```bash
git clone https://github.com/bluecarbons/agentic-rss-parser.git
cd agentic-rss-parser
npm install # 只安装开发依赖 — 零生产依赖
npm test # 通过Node内置测试运行器运行所有10个测试
npm run lint # 语法检查所有源文件
```
---
## 安全
- **XXE / Billion Laughs** — 忽略DOCTYPE和ENTITY声明;实体扩展从未执行
- **XSS缓解** — 从`contentSnippet`中剥离`<script>`、`<iframe>`、`<object>`、`<embed>`、`<form>`
- **提示注入** — 在LLM插值之前净化订阅源内容(控制字符剥离,新行折叠)
- **响应大小上限** — 订阅源响应上限为5 MB;LLM响应上限为1 MB
- **SSRF** — 拒绝`file://`、`javascript://`、`ftp://`和所有非HTTP(S)方案
- **堆栈溢出** — XML迭代解析(状态机),而非递归
- **供应链** — 零生产依赖;所有代码可在单个存储库中审计
参见[SECURITY.md](./SECURITY.md)获取漏洞披露政策。
---
## 许可证
MIT © Blue Carbons
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器