🔍

AI に要約させずに Web 情報の原典を読む CLI を作った

に公開

外部のドキュメントや GitHub のソースを原典のままコンテキストに取り込むための CLI、scout を作りました。

結論

  • Claude Code の WebFetch は内部で Haiku が要約した結果しかメインモデルに渡さない
  • 表示される Received はダウンロード量で、AI が読んだ量ではない
  • scout は要約を介さず Web 情報の原典を Markdown に変換して返すことで、この問題を解決する

なぜ作ったか

Claude Code の WebFetch は要約された結果しか返さない

詳しい挙動は zhizhiarv さんの記事 にありますが、原文が 18,000 文字あってもメインモデルには数百文字の要約しか届かない、ということが普通に起こります。ドキュメントを AI に読ませて仕様を取り込みたい場合に取りこぼしが発生するため、この構造は実装の精度に直結します。

https://zenn.dev/zhizhiarv/articles/claude-code-webfetch-haiku-summary

この問題を解決するために CLI として scout を作成しました。

なにができるか

WebFetch 問題の解決が出発点ですが、ついでに SPA 対応・GitHub のソース読み取り・Google 検索による複数ソース調査も詰め込みました。

カテゴリ コマンド 用途
Web 系 scout search Gemini Grounding + Google 検索によるグラウンドされた回答
Web 系 scout fetch URL → clean Markdown 変換
Web 系 scout research 検索 → 上位 N 件 fetch → レポート化
GitHub 系 scout repo-tree リモートリポのファイル一覧
GitHub 系 scout repo-read リモートリポのファイル読み込み
GitHub 系 scout repo-overview リポメタデータ + README + Issue / PR / Releases

インストール

brew install thkt/tap/scout

GEMINI_API_KEYsearch / research に必須)と GITHUB_TOKEN(任意、レート制限緩和用)を設定します。GEMINI_API_KEYGoogle AI Studio で取得できます。

特に触れてほしいのは research

基本機能はもちろん、特におすすめなのが research です。

scout research "Next.js App Router authentication best practices" --depth 5

これで、Gemini Grounding による検索 → 上位 5 ページの fetch → Markdown 変換が走り、レポートが出力されます。各ページの本文がそのまま含まれるので、AI に要約させずにコンテキストに取り込めます。

searchresearch の違いは、ソース全文を含むかどうかです。

コマンド 出力
scout search "query" Gemini Grounding の回答 + ソース URL リスト
scout research "query" 上記 + 各ソースページの Markdown 全文
scout fetch URL 単一 URL の Markdown 化

fetch は Mozilla Reader View 由来の Readability アルゴリズムで本文要素だけを抽出し、ナビ・サイドバー・広告・フッターを除外して Markdown に変換します。SPA は自動検出で headless Chrome(CDP)にフォールバックします。

--raw を付ければ Readability をスキップして HTML 全体を Markdown 化することもできます。

GitHub の読み取り機能

scout repo-tree denoland/deno --path cli/ --pattern "*.rs"
scout repo-read facebook/react src/ReactElement.js --lines 1-50
scout repo-overview rust-lang/rust

repo-tree でファイルを探し、repo-read で範囲指定で読み、repo-overview で全体像(README + 直近の Issue / PR / Releases)を一覧します。owner/repohttps://github.com/....git 付きの URL すべてに対応しています。

日本語クエリは ASCII を抽出して併用検索

ライブラリの公式ドキュメントなど技術系の一次情報は英語で書かれていることが多く、英語クエリのほうが直接届きやすいです。scout は日本語クエリから ASCII 技術用語を抜き出して英語クエリを自動生成し、元のクエリと両方を検索した結果を併合します。

入力 抽出されるクエリ
Next.js 認証 ベストプラクティス Next.js
Next.js 19 の Server Actions Next.js 19 Server Actions
React.useState の罠 React.useState
型安全とは (ASCII 無し → 元クエリ 1 本のみ)

ライブラリ名やバージョン番号は元から英語で書かれているという前提に賭けて、翻訳ではなく ASCII 抽出に限定しています。明示制御は --lang ja / --lang en / --lang auto(デフォルト)です。

SSRF への多層防御

fetch は URL を受け取って HTTP リクエストを投げるため、http://169.254.169.254/http://localhost:8080/ を渡されると、外から見えないはずの内部リソースに到達できる SSRF(Server-Side Request Forgery)のリスクがあります。

ローカル CLI でも、AI エージェント経由で外部ページに混入したプロンプトから scout fetch の URL が任意に差し替えられる可能性があるので、念のため多層防御をかけています。

内容
URL validation パース時にプライベート / ループバック / リンクローカル系を reject
DNS pre-check 名前解決した IP がプライベート系なら reject
Per-hop redirect check リダイレクト先 URL を毎回再チェック
Post-redirect recheck 最終接続先の IP を再確認

ちなみに、DNS チェック時点と接続時点の間で IP が変わる TOCTOU ギャップは原理的に残るので、場合によっては DNS pinning などの追加対策が必要になります。

出力は Markdown と JSON

--json を付けるとどのコマンドも 1 行 JSON で出力します。

場面 推奨 理由
ターミナルで自分が読む Markdown 視認性
Claude / Codex などの AI から叩く Markdown AI は自然言語のほうが扱いやすい
jq でフィールドを抜き出す JSON パースが確定的
エラー時のリトライをスクリプト化 JSON retryable フラグが取れる
degraded(部分劣化)を見逃したくない JSON フラグが明示的
CI で結果を後続ステップに渡す JSON スキーマが安定

フィードバックなどいただければと思います

AI を使うと、自分用の細かいツールをある程度のスピード感で形にできて楽しいですよね。(とはいえ、このツールは形にするまで数ヶ月かかっていますが)

よかったらこのアイデアをもとにツールを作成したり、あるいは scout を使っていただいてフィードバックなどいただけたら嬉しいです。

https://github.com/thkt/scout

GitHubで編集を提案

Discussion