AI に要約させずに Web 情報の原典を読む CLI を作った
外部のドキュメントや GitHub のソースを原典のままコンテキストに取り込むための CLI、scout を作りました。
結論
- Claude Code の WebFetch は内部で Haiku が要約した結果しかメインモデルに渡さない
- 表示される
Receivedはダウンロード量で、AI が読んだ量ではない - scout は要約を介さず Web 情報の原典を Markdown に変換して返すことで、この問題を解決する
なぜ作ったか
Claude Code の WebFetch は要約された結果しか返さない
詳しい挙動は zhizhiarv さんの記事 にありますが、原文が 18,000 文字あってもメインモデルには数百文字の要約しか届かない、ということが普通に起こります。ドキュメントを AI に読ませて仕様を取り込みたい場合に取りこぼしが発生するため、この構造は実装の精度に直結します。
この問題を解決するために 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_KEY(search / research に必須)と GITHUB_TOKEN(任意、レート制限緩和用)を設定します。GEMINI_API_KEY は Google AI Studio で取得できます。
特に触れてほしいのは research
基本機能はもちろん、特におすすめなのが research です。
scout research "Next.js App Router authentication best practices" --depth 5
これで、Gemini Grounding による検索 → 上位 5 ページの fetch → Markdown 変換が走り、レポートが出力されます。各ページの本文がそのまま含まれるので、AI に要約させずにコンテキストに取り込めます。
search と research の違いは、ソース全文を含むかどうかです。
| コマンド | 出力 |
|---|---|
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/repo、https://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 を使っていただいてフィードバックなどいただけたら嬉しいです。
Discussion