mcpField
F
Fetch MCP Server

Fetch MCP Server

ローカル
yaw.shブラウザ自動化22 週間前に更新

Fetch MCP Server について

Fetch MCP Serverは、stdioサーバーを通じてAIアシスタントがHTTPリクエストを送り、ウェブコンテンツを抽出できるようにします。HTML変換やサイトメタデータのツールに加え、リダイレクト先や解決済みアドレスも検査するSSRF対策を標準で備えています。

主な機能

  1. 01ヘッダー、認証、再試行に対応するHTTPメソッド
  2. 02HTMLをMarkdownや構造化テキストに変換
  3. 03本文、メタデータ、リンクの抽出
  4. 04サイトマップ、RSS/Atomフィード、robots.txtの解析
  5. 05リクエストとリダイレクトのSSRF検査

活用シーン

  1. 01AIアシスタントのコンテキストとしてウェブページを取得
  2. 02記事本文とページメタデータを抽出
  3. 03サイトマップ、フィード、クロール規則を確認

MCP 対応

stdioで動作するMCPサーバーとして、MCP対応クライアントにHTTPリクエストとウェブ抽出のツールを提供します。標準でSSRF対策を有効にし、リダイレクト先を逐一検査します。

設定

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

mcp.json · 共通設定
{
"mcpServers": {
"yawlabs-fetch": {
"command": "npx",
"args": [
"-y",
"@yawlabs/fetch-mcp"
]
}
}
}
起動コマンドnpx -y @yawlabs/fetch-mcp

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

パッケージ
npm@yawlabs/fetch-mcp0.8.5

ツール

15

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

パラメーター型必須説明
urlstringはい対象 URL(http:// または https://)
headersobjectいいえ追加のリクエストヘッダーをキーと値のオブジェクトで指定します
retriesintegerいいえ408/425/429/500/502/503/504 の場合に指数バックオフで再試行します(デフォルト 0)
max_bytesintegerいいえレスポンス本文を切り詰める前の最大サイズ(バイト)(デフォルト 5MiB、上限 100MiB)
basic_authobjectいいえHTTP Basic 認証情報
basic_auth.passwordstringはい
basic_auth.usernamestringはい
timeout_msintegerいいえ各試行のタイムアウト(ミリ秒)。DNS、各リダイレクトホップ、本文を対象とします(デフォルト 10000、最大 120000)。再試行には新しい時間枠が割り当てられ、呼び出し全体の上限は 5 分です。
user_agentstringいいえUser-Agent を上書きします(デフォルトでは @yawlabs/fetch-mcp として識別)
decode_textbooleanいいえテキストデコード(true)またはバイナリ base64(false)を強制します。デフォルトは自動で、text/*、json、xml などはテキスト、それ以外はバイナリです。
bearer_tokenstringいいえAuthorization: Bearer <token> として送信する Bearer トークン
max_redirectsintegerいいえ追跡するリダイレクトの最大ホップ数(デフォルト 5)
allow_private_hostsbooleanいいえこの呼び出しでループバック/プライベート/リンクローカルの宛先を許可します(デフォルト false)。サーバーオペレーターが FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 を指定して fetch-mcp を起動していない場合は拒否されます。いずれの場合も、SSRF 保護はデフォルトで有効です。

詳細

@yawlabs/fetch-mcp

Yaw MCP に追加

ワンクリックでローカルの Yaw MCP 設定に追加でき、すべての Yaw Terminal セッションで利用できます。手動でインストールする場合は、以下をご覧ください。

AI アシスタント向けの包括的な HTTP フェッチ MCP サーバーです。クライアントは自由に選べます。stdio MCP サーバーとして動作するため、MCP 対応クライアント(Claude Code、Claude Desktop、Cursor、mcph など)で安全にウェブコンテンツを取得できます。

モデルに提供する機能

ツール機能
http_get / http_head / http_optionsヘッダー、認証、タイムアウト、サイズ上限、再試行に対応した基本的な HTTP リクエスト
http_post / http_put / http_patch / http_deleteJSON または生のボディを使った書き込み用 HTTP リクエスト
fetch_html_to_markdownページを GET し、クリーンな Markdown に変換します(生の HTML より 3~8 倍小さくなります)
fetch_html_to_textページを GET し、ブロック構造を保持したプレーンテキストに変換します
fetch_readerリーダーモードで抽出し、記事本文を切り出してタイトルと Markdown を返します
fetch_meta<head> のメタデータを抽出します:タイトル、説明、OpenGraph、Twitter カード、JSON-LD、フィード、アイコン
fetch_linksすべての外部リンクを抽出し、絶対 URL に解決して、内部/外部に分類します
fetch_sitemapsitemap.xml を解析します(gzip 圧縮とサイトマップインデックスの連鎖にも対応)
fetch_feedRSS 2.0 または Atom 1.0 フィードを解析してエントリーにします
fetch_robotsサイトの robots.txt を解析し、指定されたパスとユーザーエージェントに対する判定を返します

安全性

SSRF 保護はデフォルトで有効です。サーバーは次の宛先へのリクエストを拒否します。

  • ループバック(127.0.0.0/8、::1)
  • RFC1918 プライベート範囲(10/8、172.16/12、192.168/16)
  • リンクローカル(169.254/16、fe80::/10)— クラウドのメタデータエンドポイント 169.254.169.254 も含みます
  • CGNAT(100.64/10)
  • IPv6 ユニークローカル(fc00::/7)
  • マルチキャスト/ブロードキャスト
  • IPv4 マップ IPv6(::ffff:0:0/96)は IPv4 のルールに照らして再確認されます。同様に、IPv4 互換(::/96)、IPv4 変換(::ffff:0:0:0/96)、6to4(2002::/16)アドレス内に埋め込まれた IPv4 も再確認されます
  • Teredo(2001::/32)、NAT64(64:ff9b::/96、64:ff9b:1::/48)、サイトローカル(fec0::/10)、破棄専用(100::/64)の IPv6
  • グローバルユニキャスト(2000::/3)以外のその他すべての IPv6 と、その範囲内にある非グローバルブロック(3fff::/20、2001:2::/48、2001:10::/28)
  • Azure WireServer アドレス 168.63.129.16
  • http/https 以外のスキーム(file://、gopher://、javascript: など)
  • ホスト名 localhost およびすべての *.localhost

リダイレクトの各段階では、接続前に上記すべて(スキーム、リテラル IP、localhost*)を再検証するため、公開ホストから http://127.0.0.1、http://169.254.169.254、ftp://… へリダイレクトする 302 も検出されます。ホスト名については、各段階で DNS を一度だけ解決し、返されたすべてのアドレスを確認します。検証済みの IP は HTTP ディスパッチャーに固定されるため、その後の TCP 接続は必ずそのアドレスに接続され、DNS リバインディングによる TOCTOU の隙間を塞ぎます。オリジンをまたぐリダイレクトでは、Authorization、Cookie、Proxy-Authorization ヘッダーが削除されます。

プライベートホストへの接続(開発時)

モデルはツール引数を選択しますが、モデルは信頼できません。取得したページに埋め込まれたプロンプトインジェクションによって、モデルが何でも要求する可能性があります。そのため、呼び出しごとの allow_private_hosts: true オプトインは、FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 を設定してサーバーを起動し、オペレーターが有効にしない限り拒否されます(true/yes/on も使用できます。認識されない値はオフとして扱われ、stderr に値が表示されます)。この変数を設定しても、呼び出し側でオプトインする必要があります。allow_private_hosts を指定しないリクエストは引き続き保護されます。

{
  "mcpServers": {
    "fetch": {
      "command": "npx",
      "args": ["-y", "@yawlabs/fetch-mcp@latest"],
      "env": { "FETCH_MCP_ALLOW_PRIVATE_HOSTS": "1" }
    }
  }
}

モデルが内部ネットワークに正当に接続できる環境でのみ設定してください。たとえばローカルの開発マシンでは設定できますが、メタデータエンドポイントのあるクラウド VM では設定しないでください。

インストールと実行

# One-off (auto-updates each spawn via @latest)
npx -y @yawlabs/fetch-mcp@latest

# Or globally
npm i -g @yawlabs/fetch-mcp
fetch-mcp

Node で実行する場合は、Node 22.19 以降が必要です(HTTP クライアントである undici 8 が要求する最低バージョンです。ランチャーは古いバージョンの Node ではクラッシュせず、明確なメッセージを表示して起動を拒否します)。インストール済みの場合にランチャーが優先して使用する oam の下では、Node のバージョンは問いません。

Claude Code/Claude Desktop での設定

クライアントの MCP 設定(通常は claude_desktop_config.json または ~/.claude.json)に追加します。

{
  "mcpServers": {
    "fetch": {
      "command": "npx",
      "args": ["-y", "@yawlabs/fetch-mcp@latest"]
    }
  }
}

または、mcph を使用します。

mcph add fetch

ツールリファレンス

http_get、http_post、http_put、http_patch、http_delete、http_head、http_options

共通パラメーター:

フィールド型デフォルト意味
urlstring—絶対 URL
headersobject—カスタムリクエストヘッダー
timeout_msint10000各試行のタイムアウト。DNS、すべてのリダイレクト先、本文を対象とします。再試行ごとに新しい時間枠が設けられ、呼び出し全体は 5 分で打ち切られます。ツール呼び出しをキャンセルすると、リクエストも停止します
max_bytesint5242880(5 MiB)本文がこれを超える場合に切り詰めます
max_redirectsint5許可されるリダイレクトの回数
retriesint0408/425/429/5xx の場合の再試行回数(バックオフあり。Retry-After を尊重します)
user_agentstring@yawlabs/fetch-mcp/<v>User-Agent の上書き値
basic_auth{username,password}—Authorization: Basic … を付与します
bearer_tokenstring—Authorization: Bearer … を付与します
allow_private_hostsboolfalseこの呼び出しでループバック/プライベート/リンクローカルの宛先を許可します。オペレーターが FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 を設定していない場合は拒否されます(詳細)
decode_textbool自動未設定の場合、レスポンスの Content-Type に基づいて自動判定します(text/*、JSON、XML、JS、form-urlencoded はテキスト、それ以外はバイナリ)。テキストデコードを強制するには true、body_base64 での Base64 出力を強制するには false を明示的に設定します。

本文を扱うツール(POST/PUT/PATCH/DELETE)では、次のパラメーターも使用できます。

フィールド型意味
bodystring生のリクエスト本文
body_jsonany構造化された本文。JSON としてエンコードされ、Content-Type: application/json が自動設定されます
content_typestringContent-Type を上書きします

レスポンスの形式:

{
  ok: boolean;
  status: number;
  statusText: string;
  url: string;              // final URL after redirects
  headers: Record<string,string>;
  body_text?: string;
  body_base64?: string;     // when decode_text=false
  json?: unknown;           // auto-parsed when response is application/json
  truncated?: boolean;      // set when max_bytes hit
  redirects?: string[];     // chain of intermediate URLs
  duration_ms: number;
  error?: string;
}
fetch_html_to_markdown

URL に GET リクエストを行い、スクリプト/スタイル/iframe/svg/canvas に加えて <nav>、<footer>、<aside> を除去し、ATX 形式の見出し、フェンス付きコードブロック、ダッシュ形式の箇条書きを使用した Markdown に変換します。コンテキストの上限を超えずにページを LLM に入力することを目的としています。

fetch_html_to_text

同じリクエストを行いますが、ブロックレベルの構造を改行で保持したプレーンテキストを出力します。モデルに Markdown の書式が不要な場合に便利です。

fetch_reader

本文を、次の順で抽出します。<article>、<main>、itemprop="articleBody"、一般的な CMS のクラス名(post-content、entry-content など)、最後にフォールバックとして <body>。返される内容:

{
  url: string;          // final URL after redirects
  title?: string;       // og:title, then <title>, then <h1>
  byline?: string;      // meta[name=author] / article:author
  wordCount: number;
  markdown: string;     // main content converted to markdown
}
fetch_meta

URL に GET リクエストを行い、本文全体をダウンロードせずに head のメタデータを返します(デフォルトでは 2 MiB で上限を設定):

{
  url: string;
  title?: string;
  description?: string;
  canonical?: string;
  language?: string;
  robots?: string;
  og:      Record<string, string>;       // first value per key (og:title, og:image, og:type, ...)
  twitter: Record<string, string>;       // first value per key
  article: Record<string, string>;       // first value per key
  ogAll:      Record<string, string[]>;  // only keys that appear > once (e.g. multiple og:image)
  twitterAll: Record<string, string[]>;
  articleAll: Record<string, string[]>;
  icons:   Array<{ rel: string; href: string; sizes?: string }>;
  feeds:   Array<{ href: string; title?: string; type?: string }>;   // RSS/Atom
  jsonLd:  unknown[];                    // parsed application/ld+json blocks
}
fetch_links

ページに GET リクエストを行い、すべての <a href> をテキストとともに絶対 URL に解決して返します。<base href> を尊重します。#、javascript:、mailto:、tel:、data:、file: は除外します。各リンクを、ページのホストと比較して internal または external に分類します。filter/dedupe/limit は任意です。

fetch_sitemap

sitemap.xml またはサイトマップインデックスを取得し、URL リストを返します:

{
  sitemaps: string[];       // indexes followed, in order
  urlCount: number;
  truncated: boolean;       // hit max_urls
  childSitemaps: string[];  // listed but not fetched (past max_depth or max_sitemaps)
  warnings: Array<{ url: string; error: string }>;
  urls: Array<{
    loc: string;
    lastmod?: string;
    changefreq?: string;
    priority?: number;
  }>;
}

.xml.gz 形式の gzip 圧縮されたサイトマップは自動的に展開されます。max_depth は、たどるサイトマップインデックスの階層数を制御します(デフォルトは 1 です)。サイトマップインデックスで max_depth: 0 を設定すると、子を取得せずにインデックスの childSitemaps リストを返します(構造を手軽に確認するのに便利です)。一部で失敗した場合(ある子サイトマップが 500 を返し、ほかは成功した場合など)、呼び出し全体を中断せず、失敗は warnings に返されます。max_sitemaps(デフォルトは 50、最大 1000)は、インデックスを含め、1 回の呼び出しで取得するサイトマップドキュメント数の上限です。上限を超える子は、警告とともに childSitemaps に記載されます。呼び出し全体のタイムアウトは 5 分です。max_bytes(デフォルトは 20 MiB)は各サイトマップに適用され、gzip 圧縮されたサイトマップの場合は展開後のサイズに適用されます。このサイズを超えるサイトマップはエラーとなり(子の場合は警告となり)、URL リストが黙って不完全な状態で返されることはありません。

fetch_feed

RSS 2.0 または Atom 1.0 フィードを解析します:

{
  kind: "rss" | "atom" | "unknown";
  title?: string;
  description?: string;
  link?: string;
  updated?: string;
  entryCount: number;
  truncated: boolean;       // hit limit
  entries: Array<{
    title?: string;
    link?: string;
    id?: string;
    published?: string;
    updated?: string;
    author?: string;
    summary?: string;
    content?: string;
    categories?: string[];
  }>;
}
fetch_robots

<origin>/robots.txt を取得して解析し、次を返します:

{
  robotsUrl: string;
  status: number;
  userAgent: string;
  path: string;
  allowed: boolean;
  matchedRule: string | null;  // the longest-match Allow/Disallow that decided it
  crawlDelay: number | null;   // from the matched group
  sitemaps: string[];          // top-level Sitemap: declarations
  rawRobotsText: string;       // first 512KB
  note?: string;               // only when robots.txt 404s
}

/robots.txt が 404 を返す場合、ルールは存在しないものとみなされるため、判定結果は allowed: true になります。レスポンスは同じ形式を保ちます:status: 404、matchedRule: null、crawlDelay: null、sitemaps: []、rawRobotsText: "" に加えて、note が含まれます。その他の 2xx 以外のステータスはエラーとして返されます。

パーサーは Google のルールに従います。最長一致が優先され、* はワイルドカードセグメント、$ はパスの末尾を示します。UA が一致する場合は、特定のユーザーエージェントのグループが * ワイルドカードグループより優先されます(一致したグループの先頭のエージェントではなく、実際に一致したエージェントトークンの長さで比較します)。同じ長さで競合する場合は、Allow が Disallow より優先されます。

開発

npm install
npm run build
npm test         # vitest
npm run lint     # biome
npm run typecheck

テストでは 127.0.0.1:0 でローカルのループバック HTTP サーバーを起動し、実際のリクエスト/レスポンス経路を検証します。HTTP のモックは使用しません。SSRF テストでは、オペレーター用ゲートが有効で、リクエストに allow_private_hosts が指定されていない限り、ローカルサーバーに対してもデフォルトの拒否設定が適用されることを確認します。

ライセンス

MIT © Yaw Labs

リンク

X で @YawLabs をフォロー

コメント

MCP は初めてですか?

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

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