mcpField
N
NetLens

NetLens

ローカル
github.com/pzalutski-pixelブラウザ自動化03 週間前に更新

NetLens について

NetLensは、ウェブページと検索結果を必要とするエージェント向けのMCPサーバーです。ページ全体を整形済みMarkdownに変換し、検索リンクを返すほか、セクションやページ概要を指定できます。

主な機能

  1. 01ページ全体を整形済みMarkdownで取得
  2. 02検索エンジンを選んで検索
  3. 03ページのセクションや概要を選択
  4. 04広告やページの定型部分を除去
  5. 05要約ではなく検索リンクを返却

活用シーン

  1. 01標準ツールで取得できない記事を読む
  2. 02ページを検索して内容を確認
  3. 03長いページから指定セクションを抽出

MCP 対応

MCPクライアントにweb_searchとweb_fetchツールを提供し、検索エンジン、ページ形式、セクションを指定できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"pzalutski-pixel-netlens": {
"command": "npx",
"args": [
"-y",
"netlens-mcp"
],
"env": {
"NETLENS_SEARCH_ENGINE": "<NETLENS_SEARCH_ENGINE>",
"NETLENS_SEARXNG_URL": "<NETLENS_SEARXNG_URL>"
}
}
}
}
起動コマンドnpx -y netlens-mcp
設定が必要な環境変数
NETLENS_SEARCH_ENGINEDefault search backend: auto, duckduckgo, bing, mojeek, or searxng
NETLENS_SEARXNG_URLBase URL of a SearXNG instance to use when engine=searxng (e.g. https://searx.example.org)

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmnetlens-mcp0.2.3
pypinetlens-mcp0.2.3

ツール

2

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
pageintegerいいえ結果ページ番号(1 始まり)。SearXNG のみ対応。スクレイピング対象のエンジンは 1 ページのみを提供するため、この機能は無視されず、非対応として報告されます。
limitintegerいいえ結果数の上限(省略可)。デフォルトでは最初のページの全結果(約 10 件)を返します。
querystringはい検索クエリ
engineenumいいえ検索バックエンド。'auto'(デフォルト)は、設定されている場合にまず SearXNG を試し、その後 DuckDuckGo、Mojeek、Bing を試します。'searxng' には NETLENS_SEARXNG_URL が必要です。auto | duckduckgo | bing | mojeek | searxng
categoriesstringいいえSearXNG のカテゴリーフィルター。例:'it'、'science'、'news'。SearXNG のみ対応。
time_rangeenumいいえ最近の結果に限定します。SearXNG のみ対応。day | week | month | year

詳細

NetLens

npm PyPI CI License: Apache 2.0 Python 3.10+

制限のないウェブ閲覧を実現する MCP サーバーです。ブラウザーのようなヘッダーを使って任意の URL を直接取得し、 robots.txt や単純なボットブロックを回避して、要約ではなく広告を除去したクリーンな Markdown として ページ全体を返します。実際のリンクを返すウェブ検索機能も備えています。依存関係はゼロで、Python 標準ライブラリのみを使用します。

AI エージェント向けに構築

AI エージェントは、組み込みツールでは読み取れないページに頻繁に遭遇します。NetLens は、取得結果が空または役に立たない状態になる主な 3 つの原因を解決します。

ネイティブのウェブツールNetLens
robots.txt に従うため、クローラーが許可されていないページは何も返さない自分で開くブラウザーと同じように読み取ります。robots.txt は参照しません
ヘッダーや User-Agent によるボットフィルターでブロックされる(ブラウザー以外のクライアントには 403/202 が返る)システムの curl を使って実際のブラウザーヘッダーを送信します。一般に 403 → 200 に変わります
ページの要約を返すMarkdown でページの全コンテンツを返します
広告、Cookie バナー、ナビゲーション、関連リンクなどが出力に残る定型要素をローカルで取り除き、コンテンツのみをコンテキストに渡します

JavaScript/Cloudflare のチャレンジページや CAPTCHA の突破は試みません。これは意図的に対象外としています。ページが強固にブロックされている場合は、HTTP ステータスを偽らず、そのまま提示します。

インストール

npm(npx 経由):

{
  "mcpServers": {
    "netlens": {
      "command": "npx",
      "args": ["-y", "netlens-mcp"]
    }
  }
}

PyPI(uvx 経由):

{
  "mcpServers": {
    "netlens": {
      "command": "uvx",
      "args": ["netlens-mcp"]
    }
  }
}

いずれかを MCP クライアントの設定(Claude Code の .mcp.json など)に追加し、 ツールを読み込むためにセッションを再起動してください。

ツール

web_search

ウェブを検索し、実際の検索結果リンク(タイトル、URL、スニペット)をローカルで解析して返します。 返すのはリンクであり、要約ではありません。検索結果を読むには、続けて web_fetch を使用してください。

引数型説明
querystring(必須)検索クエリ
limitinteger任意の上限。デフォルトでは最初のページ全体(約 10 件)を返します
enginestringauto(デフォルト)、duckduckgo、bing、mojeek、searxng
pageinteger検索結果のページ番号(1 から開始)。SearXNG のみ
time_rangestringday、week、month、year。SearXNG のみ
categoriesstring例:it、science、news。SearXNG のみ

結果には、応答した検索エンジンと、スキップされた検索エンジンで発生した内容が示されます。そのため、別のバックエンドへのフォールバックも隠されずに確認できます。

{
  "query": "…",
  "engine": "mojeek",
  "results": [ … ],
  "engines_skipped": [ { "engine": "duckduckgo", "outcome": "HTTP 202" } ]
}

結果は観測された内容であり、結論ではありません。HTTP 202 はサーバーが送信したものであり、それがスロットリング、マークアップの変更、または本当に一致する結果がないことを意味するかは、応答から判断できません。SearXNG を設定すると、直接の answers、infoboxes、suggestions も検索結果とともに表示されます。

検索では単一の検索結果ページ(約 10 件)を取得し、位置 9/10 の結果も漏れないよう、デフォルトですべて返します。ページをまたぐ詳細なページネーションには対応していません。答えが最初のページにない場合は、クエリを絞り込んでください。

web_fetch

任意のページを取得し、クリーンな Markdown として全コンテンツを返します。

引数型説明
urlstring(必須)取得する URL(スキームは省略可能。省略時は https を使用)
modestringarticle(メインコンテンツのみ。デフォルト)、full(本文全体)、raw(変換前の HTML)、outline(見出し構造)
sectionstringこの見出しの内容のみを返します。配下にネストされた内容も含みます
linksstringinline(デフォルト)ではリンク先を保持します。none ではリンクテキストを保持し、URL を除外します
max_charsinteger返す文字数の任意の上限(上限を超えた場合は注記とともに切り詰めます)
長いページの一部を読む

ページの一部だけを読みたい場合でも、大きな記事は数万文字に及ぶことがあります。mode="outline" は記事の構成を返し、section はその部分だけを返します。たとえば、大きな百科事典の記事は全文で153,000文字、アウトラインで1,000文字、目的のセクションだけなら7,400文字です。

web_fetch(url=…, mode="outline")      → headings with each section's size
web_fetch(url=…, section="Gameplay")  → that section and its subsections

リンクの多いページでは、URL自体が出力の大きな割合を占めます。大きな百科事典の記事では約40%に達するため、本文だけが必要な場合は links="none" で出力をおよそ半分にできます。同じページ内を指すリンクは、常にプレーンテキストとして表示されます。

ページがクライアント側でレンダリングされるシェルだと判明した場合、web_fetch は空の結果を成功として返すのではなく、そのことを通知します。

(注:6,856文字のHTML内で、読み取り可能なテキストは10文字しか見つかりませんでした。 このページはJavaScriptによってクライアント側でレンダリングされているようです……)

ワークフロー: web_search でページを見つけてから、web_fetch で読み取ります。

検索エンジン

検索エンジンは、プラグインとして追加でき、選択可能なレジストリになっています。auto モードでは、NetLens は順番に検索エンジンを試し、結果が得られた最初のエンジンの結果を返します。そのため、あるエンジンでレート制限やチャレンジページが発生しても、次のエンジンに切り替わります。

エンジン説明
duckduckgoデフォルト。html.duckduckgo.com エンドポイント
bing自動フォールバック
mojeek独立したインデックス。自動フォールバック
searxngセルフホスト可能/公開SearXNG JSON API — NETLENS_SEARXNG_URL を設定

呼び出しごとに engine 引数で選択するか、NETLENS_SEARCH_ENGINE でデフォルトを設定します。

設定

環境変数デフォルト説明
NETLENS_SEARCH_ENGINEautoデフォルトの検索バックエンド
NETLENS_SEARXNG_URL—SearXNG のベースURL。例:http://192.168.1.10:8888
NETLENS_SEARXNG_TIMEOUT8到達不能なSearXNGをスキップするまでの秒数
NETLENS_USER_AGENTChrome UAリクエストのUser-Agentを上書き
NETLENS_MAX_BYTES104857601回のレスポンスの上限。超過分は切り捨て
NETLENS_CACHE_TTL300取得したページを再利用する秒数。0 にするとキャッシュを無効化
NETLENS_HOST_DELAY0.5同じホストへのリクエスト間に設ける最小間隔(秒)
NETLENS_REQUEST_TIMEOUT1201回のツール呼び出しの最大時間
SearXNG のセルフホスト

JSON API が有効になっているインスタンスを NETLENS_SEARXNG_URL に指定します(settings.yml の search.formats に json を含める必要があります)。設定すると、auto モードで最初に試されるため、一般的な処理経路からHTMLスクレイピングと、それに伴うレート制限をなくせます。

最初に試されるため、インスタンスが停止している場合はすぐに失敗する必要があります。到達不能なインスタンスが毎回の検索を停滞させることなく数秒でスキップされるよう、接続タイムアウトは個別に制限されており、スキップされたことは結果に報告されます。

仕組み

  • 直接取得。 システムの curl を使って、リクエストを対象サイトへ直接送信します (TLS/HTTP-2/圧縮の処理に優れているため、実際のブラウザーのように見えます)。利用できない場合は urllib にフォールバックします。サードパーティのプロキシやリーダーは使用しません。
  • ローカル変換。 HTML から Markdown への変換は、独自実装の html.parser コンバーターを使ってプロセス内で行います。見出し、リスト、リンク(相対 URL は解決)、 コードブロック、colspan/rowspan に対応した GFM テーブルを処理します。
  • 削除ではなくコンテンツ選択。 NetLens はページのメインコンテンツ領域を選択します。HTML5 のランドマーク (<main>/<article>/[role=main])があればそれを使い、なければリンク密度に対する文章量が最も多いサブツリーを選び、 その部分だけを変換します。名前のパターンに一致する要素を削除するのではなく、候補から最適なものを 選択 するため、抽出結果が気付かないうちに空のページになることはありません。何をコンテンツとするかの判定に、 CSS クラス名や id 名を調べることはありません。
  • 測定に基づく刈り込み。 その領域内では、リンク密度に基づいて、ほとんどがリンクアンカーで構成されるブロック (ナビゲーションボックス、タグクラウド、「このサイトのその他の記事」のグリッド)を除外します。描画されない要素 (<script>、<style> など)、明示的に非表示にされた要素、サードパーティの広告ネットワーク枠 (実際の文章と衝突しない adsbygoogle などのベンダー名で識別)も完全に削除します。
  • レスポンスの文字セット を尊重します(Content-Type または <meta> から取得)。そのため、UTF-8 以外の ページも文字化けせずに返されます。

CLI からの使い方

このサーバーは通常のスクリプトとしても実行できます。クライアントから読み込む前のテストに便利です。

python -m netlens_mcp.server search "http caching best practices"
python -m netlens_mcp.server fetch  https://example.com/article
python -m netlens_mcp.server full   https://example.com   # whole body
python -m netlens_mcp.server raw    https://example.com   # unconverted HTML

python -m netlens_mcp は stdio MCP サーバーを実行し、python -m netlens_mcp.server <cmd> は CLI を実行します。

開発

pip install -e ".[dev]"
python -m pytest        # run the test suite
ruff check .            # lint

要件

  • Python 3.10 以降、およびシステムの curl(最新の Windows/macOS/Linux に付属しています。 存在しない場合は urllib にフォールバックします)

ライセンス

Apache License 2.0 — LICENSE と NOTICE を参照してください。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。