mcpField
W
Webfetch Mcp

Webfetch Mcp

ローカル
github.com/simonediromaブラウザ自動化213 週間前に更新

Webfetch Mcp について

Webfetch Mcpは、AIアシスタント向けに設定可能なHTTP取得ツールを提供するローカルのPython製MCPサーバーです。ドメイン別ヘッダー、再試行、応答形式、取得コンテンツのサニタイズに対応します。

主な機能

  1. 01ドメイン別および単一リクエストのヘッダー
  2. 02再試行、タイムアウト、プロキシの設定
  3. 03複数の応答形式
  4. 04JavaScriptレンダリング機能
  5. 05インジェクション検出と応答の切り詰め

活用シーン

  1. 01ドメイン別ヘッダーで認証が必要なページを取得
  2. 02指定要素やページ本文を抽出
  3. 03応答アサーションでエンドポイントを確認

MCP 対応

MCP対応AIアシスタントに`fetch`ツールを提供します。組み込みのWebFetchを置き換え、設定済みのリクエスト設定を適用できます。

設定

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

インストール方法は未掲載です

このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。

リポジトリ

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

webfetch-mcp

Python License MCP simonediroma/webfetch_mcp MCP server

AI アシスタントに組み込まれている WebFetch ツールを、完全に設定可能な HTTP クライアントに置き換えるローカルの Python MCP サーバーです。ドメインごとのヘッダー、リトライ、プロキシ、タイムアウト、出力形式、ボットブロック検出、プロンプトインジェクションのサニタイズに対応しており、サーバーを登録する以外にアシスタントの設定を変更する必要はありません。

導入する理由

ほとんどの AI アシスタント(Claude Code、Cursor、Continue、Zed など)で利用できる組み込みの WebFetch ツールは、カスタムヘッダーなしでリクエストを送信します。そのため、ボット保護システム(Akamai、Cloudflare、ペイウォールなど)によってブロックされたり、ドメイン固有のトークンを必要とする API に対して認証できなかったりします。

このサーバーはドロップイン置換として動作します。MCP 対応の AI アシスタントで同じ fetch ツールを利用できますが、対象ドメインに応じて適切なヘッダー、形式、リトライ戦略を各送信リクエストに自動的に適用します。リクエストのたびにヘッダーを設定する必要はありません。


機能

機能説明
ドメインごとのヘッダードメインごとに異なる認証ヘッダーを設定できます。グローバルな * フォールバックにも対応しています
呼び出しごとのヘッダークライアント(またはユーザー)が単一のリクエストに追加のヘッダーを指定できます
YAML 設定ヘッダー、タイムアウト、リトライ、プロキシ、出力形式を 1 つの読みやすいファイルで管理できます
設定可能なタイムアウトドメインごとのリクエストタイムアウト(デフォルトは 30 秒)
バックオフ付きリトライHTTP 5xx エラーまたはネットワークエラー時に、指数バックオフで自動的に再試行します
ドメインごとのプロキシドメインごとに異なるプロキシ経由でトラフィックをルーティングします
出力形式raw、markdown、trafilatura(メインコンテンツ)、json(整形表示)、lighthtml(最小限の HTML)
JSON の自動検出Content-Type が application/json のレスポンスを自動的に整形表示します
メタデータの抽出trafilatura を使用してタイトル、作成者、日付、ソースを抽出します(ドメインごとに有効化できます)
ボットブロック検出Cloudflare / CAPTCHA によるブロックを検出します。必要に応じて Chrome の User-Agent で再試行できます
プロンプトインジェクションのサニタイズ取得したコンテンツをインジェクションパターンについてスキャンします。flag または strip モードを選択できます
CSS セレクターによる抽出形式変換の前に特定の HTML 要素を抽出します。ドメインごと、または呼び出しごとに設定できます
リダイレクトの追跡必要に応じてリダイレクトの全経路を記録し、概要に表示します
レスポンスのアサーションassert_status / assert_contains は不一致時にエラーを発生させます。CI/CD のスモークテストに便利です
ヘッダーインジェクション対策制御文字(\r、\n、NUL)を含むヘッダーを検証します
レスポンスの切り詰めmax_bytes の上限を設定し、アシスタントのコンテキストウィンドウが埋まるのを防ぎます
詳細なレスポンス概要すべてのレスポンスに、構造化された概要(ステータス、経過時間(ms)、挿入されたヘッダー、形式など)が含まれます
JavaScript のレンダリング(Playwright)コンテンツ抽出の前にヘッドレス Chromium で JavaScript を多用する SPA をレンダリングします。グローバル、ドメインごと、または呼び出しごとに設定できます
lighthtml 出力形式<style>、<script>(JSON-LD を除く)、コメント、すべてのタグ属性を削除し、最小限の HTML 構造を返します
TLS フィンガープリントの偽装(curl-cffi)実際のブラウザーの TLS ClientHello/JA3 および HTTP/2 フィンガープリントを再現します。ヘッダーレベルより下のフィンガープリントを使う CDN のボット検出を回避できます。グローバル、ドメインごと、または呼び出しごとに設定できます

要件

  • Python 3.10+
  • MCP 対応の AI アシスタント(Claude Code、Cursor、Continue、Zed など)

クイックスタート

git clone https://github.com/simonediroma/webfetch_mcp.git
cd webfetch_mcp

# Mac / Linux
python -m venv .venv && .venv/bin/pip install -r requirements.txt
# Windows
python -m venv .venv && .venv\Scripts\pip install -r requirements.txt

cp webfetch.yaml.example webfetch.yaml   # then edit with your tokens

次に、AI アシスタントの設定でサーバーを登録し、再起動します。これで完了です。


インストール

git clone https://github.com/simonediroma/webfetch_mcp.git
cd webfetch_mcp

python -m venv .venv

# Windows
.venv\Scripts\pip install -r requirements.txt

# Mac / Linux
.venv/bin/pip install -r requirements.txt

requirements.txt では以下をインストールします。

mcp[cli]>=1.0.0
httpx>=0.27.0
python-dotenv>=1.0.0
markdownify>=0.12.0
trafilatura>=1.12.0
pyyaml>=6.0
beautifulsoup4>=4.12.0

オプション — JS のレンダリングには Playwright が必要です。

pip install playwright && playwright install chromium

設定

サーバーの設定方法は 2 つあります。YAML を推奨します。すべてのオプションに対応しています。従来の環境変数を使った方法も、簡単なケースでは引き続き利用できます。

オプション A — YAML 設定ファイル(推奨)

サンプルをコピーして編集します。

cp webfetch.yaml.example webfetch.yaml

サーバーにそのファイルを指定します。

# In your shell profile, or in the MCP server env block (see Registration below)
export WEBFETCH_CONFIG=/absolute/path/to/webfetch.yaml
YAML 設定の全項目
# Global defaults — applied to every request unless overridden
global:
  headers:
    User-Agent: "MyBot/1.0"
  output_format: raw       # raw | markdown | trafilatura | json | lighthtml
  timeout: 30              # seconds
  retry:
    attempts: 1            # 1 = no retry
    backoff: 2.0           # exponential multiplier (1s → 2s → 4s …)
  proxy: null              # e.g. "http://proxy.corp:8080"
  extract_metadata: false  # true = prepend title/author/date to content
  sanitize_content: false  # false | "flag" | "strip"
  bot_block_detection: false  # false | "report" | "retry"
  css_selector: null       # CSS selector to extract element(s) before format conversion
  render_js: false           # true = render JS via headless Chromium (requires playwright)
  impersonate: null          # e.g. "chrome131" = impersonate a browser's TLS/HTTP2 fingerprint
                              # (requires curl-cffi); loses to render_js when both are set

# Per-domain overrides — only the fields you list are overridden
domains:
  example.com:
    headers:
      X-Akamai-Token: "your-token-here"
    output_format: trafilatura
    timeout: 60
    retry:
      attempts: 3
      backoff: 2.0

  news-site.com:
    output_format: markdown
    bot_block_detection: retry   # auto-retry with Chrome UA if blocked
    css_selector: "article.main-content"  # extract only the article body

  internal.corp:
    proxy: "http://proxy.corp:8080"
    headers:
      Authorization: "Bearer my-internal-token"

  api.example.com:
    output_format: json
    timeout: 10
    retry:
      attempts: 5
      backoff: 1.5

  fingerprinted-cdn.com:
    impersonate: chrome131   # bypasses TLS/JA3-fingerprint bot detection
    output_format: trafilatura

ドメインの照合にはサフィックスルールを使います。example.com は example.com と www.example.com の両方に一致します。複数のドメインが一致する場合は、より具体的な(キーが最も長い)ルールが優先されます。グローバル設定は常に最初に適用され、その後、より具体的なドメインルールで上書きされます。


オプション B — 環境変数(従来方式)

.env.example をコピーし、値を設定します。

cp .env.example .env

WEBFETCH_HEADERS — ドメインごとのリクエストヘッダー(1 行の JSON):

WEBFETCH_HEADERS={"*": {"User-Agent": "MyBot/1.0"}, "example.com": {"X-Auth-Token": "your-token"}}

WEBFETCH_OUTPUT — ドメインごとの出力形式(1 行の JSON):

WEBFETCH_OUTPUT={"*": "raw", "example.com": "trafilatura", "news.com": "markdown"}

WEBFETCH_SELECTORS — ドメインごとの CSS セレクター(1 行の JSON):

WEBFETCH_SELECTORS={"example.com": "article.main-content", "news.com": "div#article-body"}

WEBFETCH_CONFIG が設定されている場合、上記の環境変数はすべて無視されます。


AI アシスタントへの登録

ほとんどの AI アシスタントは、JSON 設定ファイル内の mcpServers ブロックを使用します。形式はアシスタント間で共通で、異なるのはファイルの場所だけです。

Claude Code

~/.claude/settings.json に追加します。

{
  "mcpServers": {
    "webfetch": {
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["/absolute/path/to/server.py"],
      "env": {
        "WEBFETCH_CONFIG": "/absolute/path/to/webfetch.yaml"
      }
    }
  }
}
Cursor

~/.cursor/mcp.json(またはプロジェクトレベルの .cursor/mcp.json)に追加します。

{
  "mcpServers": {
    "webfetch": {
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["/absolute/path/to/server.py"],
      "env": {
        "WEBFETCH_CONFIG": "/absolute/path/to/webfetch.yaml"
      }
    }
  }
}
Claude Desktop(Mac / Windows)

Mac では ~/Library/Application Support/Claude/claude_desktop_config.json に、Windows では %APPDATA%\Claude\claude_desktop_config.json に追加します。

{
  "mcpServers": {
    "webfetch": {
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["/absolute/path/to/server.py"],
      "env": {
        "WEBFETCH_CONFIG": "/absolute/path/to/webfetch.yaml"
      }
    }
  }
}

Windows: command の値には .venv\Scripts\python.exe を使用してください。

その他のアシスタント(Continue、Zed など)

正確な設定ファイルの場所については、お使いのアシスタントの MCP ドキュメントを参照してください。サーバーブロックは共通で、異なるのはファイルパスだけです。

Windows: .venv/bin/python の代わりに .venv\Scripts\python.exe を使用してください。

保存後、クライアントを再起動します。ツールは mcp__webfetch__fetch として登録されます。


サーバーが有効であることの確認

登録してクライアントを再起動した後、ツールが読み込まれていることを確認します。

  • Claude Code:チャットで /mcp を実行します。webfetch がステータス connected で表示され、利用可能なツールとして fetch が一覧に表示されます。
  • Cursor:Settings → MCP を開き、webfetch が有効なサーバー一覧に表示されていることを確認します。
  • その他のクライアント:設定内の MCP ツールパネルまたはサーバー一覧を確認します。

サーバーが表示されない場合は、以下を確認してください。

  1. 設定内の Python パスと server.py のパスが絶対パスであり、正しいこと。
  2. 仮想環境にすべての依存関係がインストールされていること(pip install -r requirements.txt)。
  3. YAML または環境変数の設定にエラーがないこと。ターミナルで python server.py を直接実行すると、起動時のエラーが stderr に表示されます。

ネイティブツールではなく webfetch をクライアントに使わせる

ほとんどの AI アシスタントは、組み込みの WebFetch と登録済みの MCP ツールの両方を利用できます。mcp__webfetch__fetch が常に優先されるようにするには、次の手順に従います。

Claude Code

プロジェクトの CLAUDE.md(または、すべてのプロジェクトに適用するには ~/.claude/CLAUDE.md)に以下を追加します。

Always use the `mcp__webfetch__fetch` tool for all HTTP requests and web browsing.
Do not use the built-in WebFetch tool.

または、~/.claude/settings.json に systemPrompt エントリを追加します。

{
  "systemPrompt": "Always use mcp__webfetch__fetch for all web requests. Do not use the built-in WebFetch tool.",
  "mcpServers": { "...": "..." }
}
その他の AI アシスタント

システムプロンプトまたはカスタム指示の設定方法については、お使いのアシスタントのドキュメントを参照してください。次の指示を含めます。

すべての Web リクエストには、組み込みのフェッチツールやブラウザーツールではなく、mcp__webfetch__fetch を使用してください。


エンドツーエンドの例

インストールして登録したら、AI アシスタントを開いて、次のように試してみてください。

「https://example.com を取得し、メインコンテンツを返してください」

アシスタントは mcp__webfetch__fetch を自動的に呼び出し、そのドメインに設定したヘッダーと出力形式を適用します。次のような応答が表示されます。

--- Request Summary ---
URL:              https://example.com
Method:           GET
Injected headers: User-Agent
Status:           200 OK
Elapsed:          312ms
Output format:    trafilatura
---

[Extracted article content here]

ドメイン固有の認証ヘッダーを設定している場合、概要の Injected headers 行にヘッダーが表示され、送信されたことを確認できます。追加のプロンプトは不要です。設定はそのドメインへのすべてのリクエストに自動的に適用されます。


ツール API

url 以外のすべてのパラメーターは任意です。

パラメーター型デフォルト説明
urlstr—取得する URL
methodstr"GET"HTTP メソッド(GET、POST、PUT、DELETE、…)
bodystr | NoneNonePOST/PUT のリクエスト本文
extra_headersdict | NoneNoneドメインのヘッダーに追加される、呼び出しごとのヘッダー
extract_textboolFalseHTML タグを除去してプレーンテキストを返します(旧式。output_format より優先されます)
max_bytesint0応答を N 文字に切り詰めます(0 = 無制限)
follow_redirectsboolTrueHTTP リダイレクトに従います
output_formatstr | NoneNone呼び出しごとの形式の上書き:「"raw"」、「"markdown"」、「"trafilatura"」、「"json"」、「"lighthtml"」
css_selectorstr | NoneNone形式変換の前に HTML 要素を抽出する CSS セレクター(例:「"article"」、「"#main"」)
trace_redirectsboolFalse概要にリダイレクトの全経路を表示します
assert_statusint | NoneNone応答のステータスコードがこの値と一致しない場合、エラーを発生させます
assert_containsstr | NoneNone応答本文にこの文字列が見つからない場合、エラーを発生させます(大文字と小文字を区別します)
render_jsbool | NoneNoneヘッドレス Chromium でページをレンダリングします(JS を実行し、ネットワークがアイドル状態になるまで待機します)。playwright が必要です。
impersonatestr | NoneNoneCDN のフィンガープリントベースのボット検出を回避するため、ブラウザーの TLS/HTTP2 フィンガープリントを偽装します(例:「"chrome131"」)。curl-cffi が必要です。render_js が実質的に true の場合は無視されます。
応答形式

すべての応答は、次のような構造化された概要ブロックから始まります。

--- Request Summary ---
URL:              https://example.com/article
Method:           GET
Injected headers: User-Agent, X-Akamai-Token
Status:           200 OK
Elapsed:          843ms
Response size:    42381 bytes
Output format:    trafilatura
Text extracted:   no
JS rendering:     no
Impersonate:      no
Truncated:        no
Timeout:          60.0s
Proxy:            none
Retry:            disabled
Bot block:        none
Metadata:         extracted
Sanitization:     flag (0 pattern(s) found)
CSS selector:     "article.main-content" (applied)
---

**Title:** Example Article
**Author:** Jane Doe
**Date:** 2024-01-15
**Source:** Example News

---

[Main article content as Markdown …]

ユースケース

特定のドメインで Akamai のボット保護を回避する
# webfetch.yaml
domains:
  mysite.com:
    headers:
      X-Akamai-Token: "your-token"
      Cookie: "session=abc123"
    output_format: trafilatura

これで、サーバーはセッションを使って mysite.com のページを取得し、記事のテキストを自動的に抽出します。


ニュースサイトから記事の内容をきれいに抽出する
domains:
  theguardian.com:
    output_format: trafilatura
    extract_metadata: true

  reuters.com:
    output_format: markdown

JSON API を安定して利用する
domains:
  api.example.com:
    output_format: json
    timeout: 10
    retry:
      attempts: 5
      backoff: 1.5
    headers:
      Authorization: "Bearer my-api-key"

応答は整形済みの JSON です。エンドポイントが application/json を返すのに output_format の設定を忘れた場合、サーバーが自動的に検出します。


社内イントラネットのトラフィックをプロキシ経由でルーティングする
domains:
  internal.corp:
    proxy: "http://proxy.corp:8080"
    headers:
      Authorization: "Bearer my-internal-token"
    timeout: 60

ボットによるブロックを自動的に検出して対処する
domains:
  news-site.com:
    bot_block_detection: retry   # retry once with a Chrome User-Agent

report モードでは、概要ブロックにブロックが示されますが、再試行は行われません。retry モードでは、サーバーがリアルな Chrome User-Agent を使って2回目のリクエストを自動的に送信します。


TLS フィンガープリントベースの CDN ブロック(JA3 検出)を回避する

一部の CDN は User-Agent ヘッダーだけでなく、TLS ハンドシェイク自体(暗号スイートの順序、拡張機能、HTTP/2 フレームの順序 — JA3/JA4)をフィンガープリントします。その場合、偽装したヘッダーでは効果がありません。通常の httpx/Python TLS は依然として Python のものに見えるためです。impersonate はリクエストを curl-cffi 経由でルーティングし、実際のブラウザーの TLS/HTTP2 シグネチャをバイト単位で再現します。

domains:
  fingerprinted-cdn.com:
    impersonate: chrome131   # requires: pip install curl-cffi
    output_format: trafilatura

これは、フィンガープリントだけを理由にブロックし、JavaScript の実行を必要としないサイト向けの、render_js より軽量な代替手段です。ドメインで両方(JS チャレンジ と フィンガープリントの一致)が必要な場合は、代わりに render_js: true を使用してください。同じドメインで両方を設定した場合は、自動的にこちらが優先されます。


信頼できないページからのプロンプトインジェクションを防ぐ
global:
  sanitize_content: flag    # warn when suspicious patterns are found

domains:
  untrusted-forum.com:
    sanitize_content: strip  # silently remove injection attempts
CSS セレクターでページの特定のセクションを抽出する

ドメインの YAML でグローバルに設定します。

domains:
  docs.example.com:
    css_selector: "main article"   # only the article content, not nav/sidebar
    output_format: markdown

または、呼び出しごとに渡します。

fetch url="https://docs.example.com/guide" css_selector="section#quickstart"

セレクターに一致する要素がない場合は、フォールバックとして HTML 全体が使用されます。


エンドポイントのスモークテスト(CI/CD 形式)

assert_status と assert_contains を使用すると、レスポンスが期待どおりでない場合にツールでエラーを発生させることができます。ヘルスチェックやリグレッションテストに便利です。

fetch url="https://api.example.com/health" assert_status=200 assert_contains='"status":"ok"'

チェックに失敗すると、誤ったレスポンスがそのまま返される代わりに、明確な ValueError がクライアントに返されます。


URL のリダイレクトチェーンを追跡する
fetch url="https://short.ly/abc123" trace_redirects=true

概要には各ホップが表示されます。

Redirect chain:
  301  https://short.ly/abc123  →  https://example.com/landing
  200  https://example.com/landing  (final)

Cloudflare のコンテンツネゴシエーションを活用して、LLM 対応の Markdown を取得する

Cloudflare の Markdown for Agents 機能は、リクエストに Accept: text/markdown ヘッダーが含まれている場合、エッジで HTML を Markdown に変換します。生の HTML と比べてトークン使用量を約 80% 削減できます。また、変換はサーバー側で行われるため、ローカルの HTML から Markdown への変換パイプラインよりも高速で正確です。

webfetch_mcp を使用すると、このヘッダーをすべてのリクエストに自動で挿入することも、特定のドメインに限って挿入することもできます。

# Global — every request negotiates Markdown
global:
  headers:
    Accept: "text/markdown"

# Or per-domain — only for sites you know support it
domains:
  docs.example.com:
    headers:
      Accept: "text/markdown"
    output_format: raw          # Cloudflare already returns Markdown; skip local conversion

Cloudflare のレスポンスには、次の便利な追加ヘッダーが含まれます。

ヘッダー説明
x-markdown-tokensMarkdown ドキュメントの推定トークン数。コンテキストウィンドウの予算管理に便利です
Content-SignalAI の利用許可(例:ai-train=yes, search=yes, ai-input=yes)

この機能に対応していないサイトはヘッダーを無視して通常の HTML を返すため、グローバルに設定しても安全です。簡単な curl コマンドで対応状況を確認できます。

curl -sI https://example.com -H "Accept: text/markdown" | grep -i content-type
# text/markdown → supported; text/html → not supported

セキュリティ

  • シークレットはローカルに保持 — .env と webfetch.yaml は Git の対象外です。トークンがマシンの外部に送信されることはありません。
  • ドメインの分離 — ヘッダーは一致するドメインにのみ挿入されます。関係のないリクエストにはグローバルヘッダーのみが適用されます。
  • ヘッダーインジェクション対策 — サーバーは送信前に、すべてのヘッダー名と値に制御文字が含まれていないか検証します。
  • プロンプトインジェクションのサニタイズ — 取得したコンテンツを任意でスキャンし、「ignore all previous instructions」のようなパターンにフラグを付けるか、削除できます。

ローカルでの実行(開発)

# Mac / Linux
.venv/bin/python server.py

# Windows
.venv\Scripts\python.exe server.py

サーバーは stdio(標準の MCP トランスポート)で通信します。HTTP ポートは使用しません。

テストスイートを実行します。

pytest tests/ -v

ライセンス

MIT

コメント

MCP は初めてですか?

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

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