Webfetch Mcp について
Webfetch Mcpは、AIアシスタント向けに設定可能なHTTP取得ツールを提供するローカルのPython製MCPサーバーです。ドメイン別ヘッダー、再試行、応答形式、取得コンテンツのサニタイズに対応します。
主な機能
- 01ドメイン別および単一リクエストのヘッダー
- 02再試行、タイムアウト、プロキシの設定
- 03複数の応答形式
- 04JavaScriptレンダリング機能
- 05インジェクション検出と応答の切り詰め
活用シーン
- 01ドメイン別ヘッダーで認証が必要なページを取得
- 02指定要素やページ本文を抽出
- 03応答アサーションでエンドポイントを確認
MCP 対応
MCP対応AIアシスタントに`fetch`ツールを提供します。組み込みのWebFetchを置き換え、設定済みのリクエスト設定を適用できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
webfetch-mcp
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 ツールパネルまたはサーバー一覧を確認します。
サーバーが表示されない場合は、以下を確認してください。
- 設定内の Python パスと
server.pyのパスが絶対パスであり、正しいこと。 - 仮想環境にすべての依存関係がインストールされていること(
pip install -r requirements.txt)。 - 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 以外のすべてのパラメーターは任意です。
| パラメーター | 型 | デフォルト | 説明 |
|---|---|---|---|
url | str | — | 取得する URL |
method | str | "GET" | HTTP メソッド(GET、POST、PUT、DELETE、…) |
body | str | None | None | POST/PUT のリクエスト本文 |
extra_headers | dict | None | None | ドメインのヘッダーに追加される、呼び出しごとのヘッダー |
extract_text | bool | False | HTML タグを除去してプレーンテキストを返します(旧式。output_format より優先されます) |
max_bytes | int | 0 | 応答を N 文字に切り詰めます(0 = 無制限) |
follow_redirects | bool | True | HTTP リダイレクトに従います |
output_format | str | None | None | 呼び出しごとの形式の上書き:「"raw"」、「"markdown"」、「"trafilatura"」、「"json"」、「"lighthtml"」 |
css_selector | str | None | None | 形式変換の前に HTML 要素を抽出する CSS セレクター(例:「"article"」、「"#main"」) |
trace_redirects | bool | False | 概要にリダイレクトの全経路を表示します |
assert_status | int | None | None | 応答のステータスコードがこの値と一致しない場合、エラーを発生させます |
assert_contains | str | None | None | 応答本文にこの文字列が見つからない場合、エラーを発生させます(大文字と小文字を区別します) |
render_js | bool | None | None | ヘッドレス Chromium でページをレンダリングします(JS を実行し、ネットワークがアイドル状態になるまで待機します)。playwright が必要です。 |
impersonate | str | None | None | CDN のフィンガープリントベースのボット検出を回避するため、ブラウザーの 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-tokens | Markdown ドキュメントの推定トークン数。コンテキストウィンドウの予算管理に便利です |
Content-Signal | AI の利用許可(例: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
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。