mcpField
F
Fetch MCP Server

Fetch MCP Server

本地服务
yaw.sh浏览器自动化22 周前更新

关于 Fetch MCP Server

Fetch MCP Server 让 AI 助手通过 stdio 服务发送 HTTP 请求并提取网页内容。它提供 HTML 转换和站点元数据工具,并默认启用 SSRF 防护,包括检查重定向目标和解析出的地址。

主要功能

  1. 01支持带请求头、认证和重试的 HTTP 方法
  2. 02将 HTML 转为 Markdown 或结构化文本
  3. 03提取正文、元数据和链接
  4. 04解析站点地图、RSS/Atom 源和 robots.txt
  5. 05检查请求及重定向以防 SSRF

适用场景

  1. 01获取网页内容供 AI 助手参考
  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 会话中使用。也可以按照下方说明手动安装。

这是一款功能全面的 HTTP 抓取 MCP 服务,适用于 AI 助手。客户端由你选择:它以 stdio MCP 服务的形式运行,因此任何兼容 MCP 的客户端(Claude Code、Claude Desktop、Cursor、mcph 等)都可以安全地抓取网页内容。

它能为模型提供什么

工具功能
http_get / http_head / http_options基础 HTTP 请求,支持请求头、身份验证、超时、大小限制和重试
http_post / http_put / http_patch / http_delete写入类 HTTP 请求,支持 JSON 或原始请求体
fetch_html_to_markdownGET 页面并转换为简洁的 Markdown(比原始 HTML 小 3–8 倍)
fetch_html_to_textGET 页面并转换为纯文本,同时保留区块结构
fetch_reader阅读模式提取——分离文章正文并返回标题和 Markdown
fetch_meta提取 <head> 元数据:标题、描述、OpenGraph、Twitter 卡片、JSON-LD、订阅源、图标
fetch_links提取所有外链,将其解析为绝对 URL,并分类为站内或站外链接
fetch_sitemap解析 sitemap.xml(包括 gzip 压缩文件和 sitemap 索引链)
fetch_feed将 RSS 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)
  • 全局单播范围(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 请求头。

连接到私有主机(开发)

模型会选择工具参数,而模型并不可信:通过抓取的页面注入的提示词可以要求执行任何操作。因此,除非操作人员通过使用 FETCH_MCP_ALLOW_PRIVATE_HOSTS=1 启动服务来启用,否则每次调用中的 allow_private_hosts: true 选项都会被拒绝(true/yes/on 也有效;任何无法识别的值都会按关闭处理,并在 stderr 中说明)。设置该变量后,调用仍须主动请求此权限:未设置 allow_private_hosts 的请求仍会受到防护。

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

仅在模型确实需要访问内部网络的环境中设置此项——例如本地开发机,而不是带有元数据端点的云虚拟机。

安装并运行

# 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 下运行时(启动器优先使用已安装的 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允许的重定向跳转次数
retriesint0遇到 408/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 可强制解码为文本,设为 false 则强制将正文以 base64 格式放入 body_base64。

支持正文的工具(POST/PUT/PATCH/DELETE)还接受:

字段类型含义
bodystring原始请求正文
body_jsonany结构化正文,以 JSON 编码,并自动设置 Content-Type: application/json
content_typestring覆盖 Content-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。适用于将网页内容提供给大模型,同时避免超出上下文预算。

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 请求并返回页面头部元数据,不下载完整正文(默认上限为 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

抓取页面并返回每个 <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)限制单次调用获取的站点地图文档数量,索引也计入其中;超出限制的子项会列在 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

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。