mcpField
C
codearia-sieve

codearia-sieve

本地服务
github.com/AntonG87浏览器自动化55 周前更新

关于 codearia-sieve

codearia-sieve 是供 Agent 开发者使用的网页解析 MCP 服务,将网页整理为带来源锚点的日期、数值事实和预算内文本块。它用普通代码处理,不调用模型,并提供用量与警告信息。

主要功能

  1. 01提取并规范化日期
  2. 02识别带单位的数值事实
  3. 03按预算切分文本块
  4. 04记录来源区块与页面锚点
  5. 05提供用量、警告和清理追踪

适用场景

  1. 01为决策模型准备网页输入
  2. 02核验提取事实在页面中的出处
  3. 03按需读取特定网页文本块

MCP 相关

通过 `sieve_page` 接收 URL 或 HTML 并返回结构化页面状态;`sieve_chunk` 可读取上次结果中的单个文本块。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"antong87-codearia-sieve": {
"command": "npx",
"args": [
"-y",
"codearia-sieve"
]
}
}
}
启动命令npx -y codearia-sieve

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmcodearia-sieve0.2.2

工具

2

收录的工具列表 · 更新于 2 周前

参数类型必填说明
urlstring否要获取的页面。必须提供 url 或 html 之一。
htmlstring否要处理的原始 HTML,不通过抓取获取。为生成锚点,请同时提供 url。
modeenum否summary:不含分块文本的状态数据(开销低,默认值)。full:包含分块文本。markdown:返回易读文本,而非状态数据。summary | full | markdown
taskstring否你打算做出什么决策;配置了选择器时,此项可启用相关性筛选。
traceboolean否包含被丢弃的内容以及日期的来源。
maxCharsinteger否分块的字符数预算。
maxTokensinteger否分块的令牌数预算。

详细介绍

codearia-sieve — 将网页转化为可直接用于决策的状态

codearia-sieve

将网页解析为决策模型所需的精确格式。
日期就是日期。数字附带单位。文本拆分为适合模型上下文窗口的块,每块都指向其来源。
一次调用——调用前后的令牌开销一目了然。

MCP 服务 TypeScript 库 MCP 注册表 npm MIT 测试 无需模型或密钥

npx codearia-sieve          # MCP server for Claude Code, Cursor and any agent
npm i codearia-sieve        # or the library

令牌中位数节省 98.5%。页面中位数:处理前 53 718 个令牌,处理后 1 106 个。每页耗时 1.1 秒。56 个随机页面中有 50 个可用,涵盖 9 种语言。

实测所得,绝非承诺。 我们在同一天随机选取网页进行了实时测试——包括来自多种语言 RSS 源的最新新闻、随机维基百科词条、文档、博客、政府网站、食谱和商店。每条结果都记录在 bench/analytics/ 中,运行 npm run analytics 即可重做全部测试。随后,我们将输出交给决策模型进行评估:请参阅 由评审验证。


它的作用

需要网页的 Agent 会获取整个页面:导航栏、Cookie 横幅、页脚、广告位,以及一兆字节的框架标记。然后,按令牌付费的大模型还得从这一大堆内容中找出一段文字。

codearia-sieve 会在模型看到任何内容之前完成这项筛选——并将页面作为状态而非散文返回:

日期变成标准日期

"Published September 15, 2026" → "2026-09-15"。 优先从 JSON-LD、元标签和 <time> 中读取;只有标记中没有信息时才从署名行读取,绝不猜测。

数字变成事实

"$42 per billion tokens" → { value: 42, unit: "USD_per_billion" }。 支持九种语言;小数逗号遵循页面语言。没有单位的数字不是事实。年份永远不是事实。

文本拆分为合适的块

每个块都记录其令牌数和字符数、生成它所依据的内容块,以及用于核查决策的页面 #anchor。

其余内容——菜单、页脚、横幅、标签行、“阅读更多”——都会被移除;启用 trace: true 后,还会返回已移除内容的列表及移除原因。


如今:Agent 获取页面,大模型负责清理。使用 codearia-sieve:一次调用即可获得就绪状态,大模型只需做决策。

## 适用人群

构建 Agent、也见过账单的人。 每抓取一个页面,Agent 还没读到一个字,就要耗费数万个 token。样本中的页面 token 中位数:输入 53 718 个,输出 1 106 个。

运行低成本决策模型的人。 分类器、排序器,以及像 Jev 这样的 System One 模型:它们负责判断,而非写作。它们几乎免费,速度也很快,但能力有明显局限:不会计数,会把日期当作文本读取,而且上下文中无关内容越多,准确率就越低。每款“网页转 Markdown”工具都在为阅读者准备输入,而这款工具为判断者准备输入。

需要可核查答案的人。 如果抓取文本中的每一项都不能追溯到来源,那么基于这些文本给出的结论就无法证实。在这里,每条事实都注明其所在区块,每个分块都带有锚点。


处理流程:抓取;解析;从未经改动的树中提取日期和 ID;清理;提取区块、事实和锚点;分块;组装。选择步骤为可选,默认不运行任何模型。

工作原理

八个常规代码步骤。除非你接入模型,否则不会运行任何模型。相同的 HTML 会生成完全一致的 JSON,逐字节相同。

  1. 抓取 — 先检查 robots.txt;如果被拒绝,会报告拒绝结果,而不是绕过限制。使用普通 HTTP 和如实的用户代理。
  2. 解析 — 使用 linkedom 将 HTML 解析为 DOM。不使用浏览器。
  3. 从未经改动的树中提取日期和 ID — 清理过程会移除 <head>、署名和属性,因此会在清理之前读取日期和 ID。
  4. 清理 — Defuddle 移除页面杂项;如果结果为空,则改用 Readability。内联元素之间会先插入空格,因此 <span>20 Sept</span><span>10 min</span> 不会变成 202610 min。
  5. 提取区块 — 按顺序提取标题、段落、列表、表格、代码和引文,并分配位置 ID。使用 <br><br> 排版的旧页面也会转换为段落;表格行会保留其列标题。
  6. 提取事实和锚点 — 恢复 ID;仅在数字旁边有单位时才将其提取为事实;范围会保留两端。
  7. 分块 — 按顺序贪心分块,同时遵守两个预算:默认上限为 20 000 个 token 和 50 000 个字符。
  8. 组装 — 按需返回 state、markdown、usage、warnings 和追踪信息。
结果示例
const r = await sieve({ kind: 'url', url: 'https://docs.typesafe.ai/models' });

r.state.title         // "Models"
r.state.facts[0]      // { value: 42, unit: "USD_per_billion", label: "price_btok_mtok",
                      //   context: "Price (per Btok / per Mtok) | jev-1.13.0: $42 / $0.042", from: "b3" }
r.state.facts[1]      // { value: 0.042, unit: "USD_per_million", … }   — paired by position
r.state.chunks[0]     // { id: "c1", tokens: 1210, chars: 5357, anchor: "Current models",
                      //   headings: ["Current models", "Pricing", …], blocks: ["b1", …, "b36"], text: "…" }
r.usage               // { rawTokens: 127413, stateTokens: 1211,
                      //   visibleChars: 4939, stateChars: 5357, chunks: 1, ms: 1503 }
r.warnings            // []
r.markdown            // the same article, for a human or a generative model

预期情况不会导致异常,而是以警告形式返回,每种警告都有名称:

警告含义
robots-disallowed网站要求爬虫不要访问;我们没有抓取
blocked遇到机器人验证或拒绝访问(403、405、429、“Just a moment…”),并附带状态码
http-error404 或 500 错误页面仍成功渲染;这不是你请求的页面
paywall页面标明文章并非免费;你拿到的是预览内容
empty-without-js文章容器为空,需要脚本填充内容
thin-content页面很大,但提取到的文本很少——例如首页或列表页
block-split某个区块超出预算,因此按句子边界切分
facts-capped页面中的事实超过了所列的 500 条——例如一份很长的费用表

你用通俗语言为 Claude Code 设定规则。Claude 调用 sieve_page,获取状态,然后通过 jev-mcp 向 Jev 提出带类型的问题,获取带概率的评分,排序并撰写结果。Sieve 负责准备。Jev 负责判断。Claude 负责写作。

## 在 Agent 中使用

用通俗的语言说出你的需求。Agent 会找到相关页面,对每个页面调用 sieve_page,将状态交给一个带类型问题的决策模型,然后整理结果。Sieve 负责准备。裁判负责评判。Agent 负责撰写。

{ "mcpServers": { "sieve": { "command": "npx", "args": ["-y", "codearia-sieve"] } } }

已列入官方 MCP Registry,条目为 io.github.AntonG87/codearia-sieve;能够读取该注册表的客户端可以按名称安装。

sieve_page — url 或 html

返回带有输出架构的类型化 structuredContent:source、state、usage、warnings。在默认的 summary 模式下,分块会包含大小、锚点及其标题,但不包含文本——Agent 可以看到现有内容的提纲,而无需为此付费。需要完整内容时,使用 mode: "full" 或 mode: "markdown"。

sieve_chunk — url、id

返回该 URL 上次结果中的一个分块文本,不会重新抓取。先看概览,再获取所需内容——这个工具把自己的理念也应用到了自身。

它与 jev-mcp 配合使用:分块大小经过调整,适合放入其字段,因此状态可以直接传入类型化问题。

经裁判验证

我们的主张是:与原始文本相比,决策模型从 Sieve 获得的输入质量更好。因此,我们将输出交给了一个决策模型。 examples/jev.ts 使用官方客户端驱动这两个 MCP 服务——codearia-sieve 准备了 6 个页面(API 文档、发布说明、两种语言的两篇 Wikipedia 文章、两个定价页面),Jev 则通过 jev-mcp 对其进行评判。运行时间相同:2026 年 9 月 21 日:

向 Jev 提出的问题Sieve 提供的输入结果
jev_classify — 这是哪种类型的页面?标题 + 第一个分块的开头,未超过工具的 2 000 字符限制6 个全部正确;5 个自动判定,1 个标记待审核——该页面既是文档,也是费率表
jev_verify — 提取的每条事实是否确实出现在页面上?每条事实作为一项主张,其分块作为证据11 条全部核实,且全部自动完成,置信度为 0.86–1.0
jev_extract — 页面何时发布?第一个分块、日期正则表达式、描述页面注明日期时,结果与 Sieve 一致;Sieve 还会读取 JSON-LD 和 <meta>,而 Jev 看不到这些内容

这项测试的第一轮结果恰好相反:Jev 提交了 3 条事实供审核,并对其中 1 条提出异议。这 4 个问题都追溯到了 Sieve——一行表格被列标题而非行标题标注,一个表头中的两个费率没有正确配对,还有俄语参考文献中的“256 с.”被误读为秒。修复、测试、重跑:11 条全部通过。裁判能指出解析器何时出错,这正是两者配合的意义所在。

TYPESAFE_API_KEY=… node --experimental-strip-types examples/jev.ts

作为库使用

import { sieve } from 'codearia-sieve';

await sieve({ kind: 'url', url });                    // fetch it
await sieve({ kind: 'html', html, url });             // already have it; url only for anchors

await sieve(input, {
  budget:    { maxTokens: 8000, maxChars: 30000 },    // chunk limits
  trace:     true,                                    // everything discarded, and why
  tokenizer: myTokenizer,                             // o200k by default; swap for your model's
  fetcher:   myFetcher,                               // your transport, or a file reader in tests
  now:       () => fixedDate,                         // injected clock: identical output on identical input
  selector:  mySelector, task: 'is this about pricing?', // relevance judge; nothing runs without one
});

parseDate、findDates 和供应商限制项(JEV、JEV_MCP、DEFAULT_BUDGET)也已导出。

能力边界

  • 首页、列表页和产品页面没有可供查找的文章。你会得到标题和 thin-content 警告,而不是虚假的成功结果。
  • 由 JavaScript 渲染的文章在容器为空时会返回 empty-without-js。无法区分只提供摘要、其余内容再流式传输的网站和其他情况;若不使用浏览器,你只能得到摘要。
  • 文本密集型页面节省较少。 一整本小说只能节省 22%,而一份 RFC 可节省 84%:没有可移除的包装,文本也会完整保留。这正是该工具应有的表现。
  • 定价网格不是表格。 一条事实会记录它来自哪个区块,却不会记录它位于哪个套餐列之下;Sieve 不会猜测两者如何配对。发送整个分块——清理后的定价页面约有一千个 token——让裁判来阅读:examples/pricing-watch.ts。
  • Token 数量使用 o200k 进行近似估算。 超过一兆字节的页面会进行抽样计数,并设置 usage.rawTokensEstimated: true。

Develop

npm install
npm test                    # 71 tests, offline, a few seconds
npm run demo -- <url>       # the token bill for one page
npm run bench               # the 20-page benchmark set
npm run analytics           # the 56-page random sample: rows, CSV, summary

Design notes — vision and architecture — are in docs/.

MIT © 2026 Anton Evelson · Codearia Academy

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。