codearia-sieve について
codearia-sieveは、エージェント開発者向けのMCPサーバーです。Webページから日付、単位付き数値、予算内のテキストチャンクを抽出し、出典アンカーを付けます。通常のコードで処理し、モデルを実行せず、使用量や警告も返します。
主な機能
- 01日付の抽出と標準化
- 02単位付き数値の識別
- 03予算内でのテキスト分割
- 04出典ブロックとページアンカーの記録
- 05使用量・警告・削除履歴の返却
活用シーン
- 01判定モデル向けのWeb入力準備
- 02抽出した事実の出典確認
- 03ページ内の必要なチャンクの取得
MCP 対応
`sieve_page`はURLまたはHTMLを受け取り、構造化されたページ状態を返します。`sieve_chunk`で、URLの前回結果から個別のテキストチャンクを取得できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
2掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| url | string | いいえ | 取得するページ。url または html のいずれかが必須です。 |
| html | string | いいえ | 取得せずに処理する生の HTML です。アンカーを付けるには url も指定してください。 |
| mode | enum | いいえ | summary:チャンクテキストを含まない状態データ(低コスト、デフォルト)。full:チャンクテキストを含みます。markdown:状態データの代わりに読みやすいテキストを返します。summary | full | markdown |
| task | string | いいえ | 判断したい内容です。セレクターが設定されている場合、関連性による選択が有効になります。 |
| trace | boolean | いいえ | 破棄された内容と、日付の出所を含めます。 |
| maxChars | integer | いいえ | チャンクの文字数予算です。 |
| maxTokens | integer | いいえ | チャンクのトークン数予算です。 |
詳細
codearia-sieve
Webページを、意思決定モデルに必要な正確な形式に解析します。
日付は日付として。数値には単位を付けます。テキストはモデルのコンテキストウィンドウに収まるチャンクに分け、それぞれに出典を示します。
1回の呼び出しで、前後のトークン料金もわかります。
npx codearia-sieve # MCP server for Claude Code, Cursor and any agent
npm i codearia-sieve # or the library
約束ではなく、実測値です。 同じ日に選んだランダムなページを実際に処理しました。複数言語のRSSフィードからの最新ニュース、ランダムなWikipedia記事、ドキュメント、ブログ、政府サイト、レシピ、ショップが対象です。すべての結果はbench/analytics/にあり、npm run analyticsで全体を再実行できます。出力を意思決定モデルに評価させた結果については、評価者による検証をご覧ください。
機能
Webページを必要とするエージェントは、ナビゲーション、Cookieバナー、フッター、広告枠、そしてメガバイト単位のフレームワークのマークアップまで、ページ全体を取得します。次に、トークンごとに課金されるモデルが、その山の中から必要な段落を探します。
codearia-sieveは、モデルが何かを見る前にその作業を行います — ページを文章ではなく、状態として返します。
|
日付は日付に
|
数値は事実に
|
テキストは収まるチャンクに 各チャンクには、トークン数と文字数、元になったブロック、そして意思決定を確認できるページ上の |
それ以外のメニュー、フッター、バナー、タグの行、「続きを読む」などはすべて削除されます。trace: trueを指定すると、削除したものとその理由の一覧も取得できます。
エージェントを構築していて、請求額を見たことがある方。 ページを取得するたびに、エージェントが一言も読む前に数万トークンが消費されます。サンプルのページの中央値は、入力が53 718トークン、出力が1 106トークンです。
低コストの判断モデルを運用する方。 分類器やランキングモデル、文章を書くのではなく判断するJeVのようなSystem Oneモデルです。ほぼ無料で非常に高速ですが、苦手なこともあります。数を数えられず、日付をテキストとして読み、無関係な情報がコンテキストに増えるほど精度が低下します。「ページをMarkdownに変換する」ツールはどれも、読み手に渡す入力を準備します。このツールが準備するのは、判断するモデルへの入力です。
確認できる回答が必要な方。 スクレイピングしたテキストから得た判定は、各要素が出典を示していなければ検証できません。ここでは、すべての事実がブロックを示し、すべてのチャンクがアンカーを持ちます。
仕組み
通常のコードによる8つのステップです。モデルを組み込まない限り、モデルは実行されません。同じHTMLからは、バイト単位で同じJSONが生成されます。
- 取得 — 最初に
robots.txtを確認します。拒否された場合は報告し、回避しません。通常のHTTPを使い、ユーザーエージェントを偽りません。 - 解析 —
linkedomでHTMLをDOMに変換します。ブラウザーは使いません。 - 未加工のツリーからの日付とIDの抽出 — クリーニングで
<head>、署名欄、属性が取り除かれるため、実行前に両方を読み取ります。 - クリーニング — Defuddleで不要な要素を取り除き、結果が空の場合はReadabilityに切り替えます。インライン要素の前にはスペースを挿入するため、
<span>20 Sept</span><span>10 min</span>が202610 minになることはありません。 - ブロック — 見出し、段落、リスト、表、コード、引用を順序どおりに、位置を示すID付きで処理します。
<br><br>で構成された古いページも段落として扱い、表の行には列見出しを保持します。 - 事実とアンカー — IDを復元し、単位を伴う数値のみを事実に変換します。範囲は両端を保持します。
- チャンク化 — 順序を保ったまま、デフォルトでは20 000トークンと50 000文字という2つの上限を同時に超えないよう、貪欲法で分割します。
- 組み立て —
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-error | 404または500が返されたものの、エラーページが表示されました。要求したページではありません |
paywall | ページが記事を無料公開していないことを示しています。取得できたのは導入部分のみです |
empty-without-js | 記事のコンテナーが空で、スクリプトによる読み込みが必要です |
thin-content | ページのサイズに対して本文が少量しか得られませんでした。トップページや一覧ページなどが該当します |
block-split | 1つのブロックが上限を超えたため、文の区切りで分割されました |
facts-capped | 500件の上限を超える事実がページに含まれています。たとえば、長大な料金表などです |
欲しいものを普通の言葉で伝えます。エージェントはページを見つけ、それぞれに対して sieve_page を呼び出し、状態を型付きの質問とともに判定モデルに渡して、結果をまとめます。Sieve が準備し、判定モデルが判定し、エージェントが書きます。
{ "mcpServers": { "sieve": { "command": "npx", "args": ["-y", "codearia-sieve"] } } }
公式 MCP Registry に io.github.AntonG87/codearia-sieve として登録されています。レジストリを読み取るクライアントは、名前を指定してインストールできます。
|
出力スキーマとして |
その URL の直近の結果から、再取得せずにチャンクひとつ分のテキストを返します。まず概要を確認し、必要なものだけを取得します。ツール自身が、自分にもその考え方を適用しています。 |
jev-mcp と組み合わせて使えます。チャンクはそのフィールドに収まるようにサイズが調整されているため、状態をそのまま型付きの質問に渡せます。
判定モデルによる検証
主張は、判定モデルに生のテキストよりも 優れた 入力を Sieve が提供する、というものです。そこで、出力を判定モデルに渡しました。examples/jev.ts は公式クライアントを使って両方の MCP サーバーを実行します。codearia-sieve が6ページ(API ドキュメント、リリースノート、2言語の Wikipedia 記事2件、料金ページ2件)を準備し、Jev が jev-mcp を通じて判定します。同じ実行での結果です。2026年9月21日:
| Jev への質問 | Sieve からの入力 | 結果 |
|---|---|---|
jev_classify — このページはどのような種類ですか? | 最初のチャンクのタイトルと冒頭部分。ツールの上限である2 000文字以内 | 6件中6件正解。5件は自動判定、1件は要確認としてフラグ付け — ドキュメントと料金表の両方に該当するページ |
jev_verify — 抽出した各事実は本当にページに記載されていますか? | 各事実を主張として、そのチャンクを根拠として入力 | 11件中11件を検証、すべて自動判定。信頼度は0.86~1.0 |
jev_extract — いつ公開されましたか? | 最初のチャンク、日付の正規表現、説明 | ページに日付が記載されている場合は Sieve と一致。Sieve は JSON-LD と <meta> も読み取りますが、Jev はそれらを見ません |
このテストの最初の実行では、逆のことが起きました。Jev は3件の事実を要確認として返し、そのうち1件に異議を唱えました。4件とも原因は Sieve にありました。表の行見出しではなく列見出しを付けた行、ひとつの見出しに含まれたまま対応付けられていない2つの料金、そしてロシア語の書誌表記「256 с.」を秒数と読み取ったことです。修正し、テストし、再実行した結果は11件中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 は対応関係を推測しません。チャンクを渡してください。料金ページはクリーニング後で約1000トークンです。判定モデルに読み取らせましょう。
examples/pricing-watch.ts。 - トークン数は近似値として o200k で計算されます。 1メガバイトを超えるページはサンプリングして数え、
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
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。