mcpField
W
web-to-markdown-mcp

web-to-markdown-mcp

本地服务
github.com/sidney浏览器自动化013 周前更新

关于 web-to-markdown-mcp

web-to-markdown-mcp 是一个将网页正文提取为 Markdown 的 MCP 服务,适合需要读取网页内容的 Agent 和 MCP 客户端。它按需结合原生 Markdown、HTTP 提取与 Chromium 渲染,并以内容稳定后提取来处理动态页面。

主要功能

  1. 01原生 Markdown 响应优先
  2. 02HTTP 页面正文提取
  3. 03Chromium 渲染动态页面
  4. 04内容稳定后再提取
  5. 05支持可见浏览器模式

适用场景

  1. 01提取网页文章供 Agent 阅读
  2. 02处理依赖 JavaScript 的网页
  3. 03读取静态 HTTP 提取无结果的网页

MCP 相关

向 MCP 客户端提供 `fetch_url_as_markdown` 工具,输入 URL 并返回 Markdown 字符串。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"sidney-web-to-markdown": {
"command": "uvx",
"args": [
"web-to-markdown-mcp"
]
}
}
}
启动命令uvx web-to-markdown-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiweb-to-markdown-mcp0.6.0

工具

1

收录的工具列表 · 更新于 2 周前

参数类型必填说明
urlstring是要获取的 URL。
headlessboolean否是否以无头模式运行 Chromium。默认值为 True。设为 False 可使用可见的浏览器窗口——速度较慢,且会在屏幕上弹出 Chromium 窗口,但能通过阻止无头模式的机器人检测挑战 (Cloudflare 等)。如果获取结果为 "ERROR: navigation timed out" 或 "ERROR: no extractable content", 且网站可能启用了机器人防护,请使用 headless=False 重试。 此模式需要显示设备,因此除非配置了 Xvfb 等虚拟 显示设备,否则在没有图形环境的服务器上使用 headless=False 会失败。
timeout_msinteger否导航超时(毫秒)。默认值为 60000。 此时限仅适用于导航步骤;内容 提取有单独的时限(poll_budget_ms)。
wait_untilenum否导航步骤何时视为完成。 "domcontentloaded"(默认值)表示 HTML 解析完成且 DOM 已构建时返回。"load" 会等待所有子资源 (图像、脚本、样式表)加载完成,速度较慢;由于之后会进行内容稳定性轮询,通常无需使用。 "networkidle" 会等待网络变为空闲,适用于单页应用,但 在存在持久连接的页面上有时会一直等待。 "commit" 会在响应开始时立即返回。load | domcontentloaded | networkidle | commit
poll_budget_msinteger否导航后等待内容提取稳定的最长时间。默认值为 5000。对于逐步渲染内容、耗时数秒的慢速 SPA,或在受机器人防护的网站上使用 headless=False、需要等待验证完成时,可适当增加此值;后一种情况建议设为 10000-15000。
poll_interval_msinteger否轮询期间重新尝试提取的频率。默认值为 250。

详细介绍

web-to-markdown-mcp

一个 MCP 服务,用于抓取 URL 并将主要内容以干净的 Markdown 格式返回。尽可能使用纯 HTTP,需要时则使用真正的 Chromium。

为什么

大多数 MCP 网页抓取工具要么:

  • 使用纯 HTTP,在需要 JS 的页面上会失败,并且会被许多网站的 Cloudflare 机器人检测拦截;要么
  • 使用真正的浏览器,但返回原始 HTML 或无障碍树快照;如果你只想阅读文章,这些内容就会很冗杂,也很耗 Token。

本服务采用三级策略,根据每个 URL 选择最快的可行方式:

  1. 原生 Markdown 快速通道。 每次请求都会先尝试使用带有 Accept: text/markdown 请求头的纯 HTTP GET。支持内容协商的服务(例如启用了 Markdown for Agents 的 Cloudflare 托管网站)会返回 Content-Type: text/markdown,随后立即返回正文,无需启动浏览器。

  2. 纯 HTTP + 内容提取。 如果服务返回 HTML,则使用 trafilatura 直接从静态响应中提取文章正文,并转换为干净的 Markdown。启发式检测会识别 JS 外壳,即静态 HTML 中只返回“需要 JavaScript”提示的页面,并将这些页面交由第 3 级处理。

  3. 无头浏览器。 如果第 1 级和第 2 级都无法得到可用内容,则由 patchright(一个带有反检测补丁的 Playwright 分支)驱动真正的 Chromium,并由 trafilatura 提取渲染后的内容。单个无头浏览器实例会在多次调用间保持运行:首次使用浏览器级抓取时才启动,并在整个会话期间持续运行,因此后续抓取只需等待页面导航,无需再次承担 Chromium 的启动耗时(约 2–5 秒)。

对于连无头 patchright 都会拦截的网站(机器人检测十分激进),请传入 headless=False。这会使用可见的 Chromium 窗口,速度较慢且会干扰视觉操作,但能绕过大多数剩余的验证挑战。每次需要时都会启动并关闭一个有头浏览器;它不会持续运行,因为有头抓取只是偶尔使用的备用方案,并非常规情况。

浏览器完成导航后,服务会轮询 DOM 并运行 trafilatura;当连续两次轮询提取结果相同时,就会立即返回。对于典型页面,这意味着只需几百毫秒即可返回,而不必等待分析脚本、广告及其他延迟加载的资源全部完成;同时也能为加载较慢的 SPA 和机器人验证挑战留出稳定完成的时间,避免过早超时。

对于典型文章,与原始 HTML 相比,Token 数量预计可减少约 80%;与完整的无障碍树快照相比,预计可减少约 90%。

安装

需要 Python 3.10+,并且只需一次性下载 Chromium(约 300 MB)。

# Run directly with uv (no install step)
uvx web-to-markdown-mcp

# Or install with pip
pip install web-to-markdown-mcp

# One-time browser download
patchright install chromium

MCP 客户端配置

Claude Desktop

编辑配置文件:

  • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows:%APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "web-to-markdown": {
      "command": "uvx",
      "args": ["web-to-markdown-mcp"]
    }
  }
}

重启 Claude Desktop。

LM Studio

编辑 ~/.lmstudio/mcp.json(Developer 选项卡 → Edit mcp.json)——使用与上文相同的 JSON 代码块。然后在 Developer 选项卡的 Server Settings 中启用 Allow calling servers from mcp.json。该服务会显示在所有新聊天的 Integrations 选项卡中。

Cursor / Windsurf / VS Code

在各客户端的 MCP 配置位置使用相同的 JSON 代码块。

Claude Code
claude mcp add web-to-markdown -- uvx web-to-markdown-mcp

用法

该服务提供一个工具:

fetch_url_as_markdown
参数类型默认值描述
urlstring必填要抓取的 URL
wait_untilstring"domcontentloaded"导航完成时机:"load"、"domcontentloaded"、"networkidle"、"commit"
timeout_msint60000导航步骤超时时间,单位为毫秒
headlessbooltruefalse 会使用可见的浏览器窗口——速度较慢,但能绕过更多机器人检测
poll_budget_msint5000导航后等待内容稳定的最长时间
poll_interval_msint250轮询期间重新尝试提取的间隔

返回值:以字符串形式返回 Markdown;遇到预期内的失败(超时、没有可提取的内容、导航错误)时,返回以 "ERROR:" 开头的字符串。

调用示例(在任意 MCP 客户端的工具调用界面中):

fetch_url_as_markdown(url="https://example.com/long-article")

wait_until 选项:

  • "domcontentloaded"(默认)——DOM 构建完成时返回;之后由内容稳定性轮询处理其余工作
  • "load"——等待所有子资源(图像、脚本、样式表)加载完成;由于之后会进行轮询,因此很少需要此选项
  • "networkidle"——等待网络活动停止;对于存在持久后台连接的页面,有时会一直等待
  • "commit"——响应一开始就返回;很少有用

何时调高 poll_budget_ms: 对于典型页面,默认的 5 秒已足够;但对于需要数秒才能渲染完内容的慢速 SPA,可能只返回部分提取结果;在有头模式下,也可能在机器人检测挑战解除前超时。对于抓取受机器人防护的网站,有头模式下将预算设为 10000-30000 是合理的。

局限性

  • 每个会话的首次浏览器层抓取。 无头浏览器会在首次需要浏览器的抓取时延迟启动(约 2–5 秒)。同一会话中后续的浏览器层抓取会复用正在运行的实例,只需等待页面导航。
  • 难以访问的网站会检测机器人。 patchright 无头模式可以绕过许多网站的默认 Cloudflare 配置,但启用了激进 Bot Fight Mode、Turnstile 交互式验证或商业机器人管理产品(PerimeterX、DataDome、Kasada)的页面,以及 Cloudflare 自己的营销网站,仍会检测到无头 Chromium。传入 headless=False 可使用有头浏览器窗口,大多数情况下都能通过验证。代价是每次抓取时 Chromium 窗口会在屏幕上闪现几秒。
  • 有头模式下的机器人验证需要更充足的轮询预算。 在受机器人防护的网站上使用 headless=False 时,验证可能需要 5–15 秒才能通过。此类情况下请将 poll_budget_ms 设为 10000–15000;默认值 5000 可能会在验证仍在进行时提前返回。
  • 有头模式需要显示设备。 在没有图形环境的服务器(云 VM、容器、CI)上,headless=False 会失败。若要在这些环境中使用有头模式,请使用 Xvfb 等虚拟显示设备。
  • 数据中心 IP。 无论浏览器指纹或有头/无头模式如何,Cloudflare 更严格的验证仍会拦截来自数据中心 IP(Oracle Cloud、AWS 等)的请求。在住宅网络上运行效果最佳。
  • SPA 渲染较慢。 对于内容在数秒内逐步渲染的页面,请增大 poll_budget_ms。达到预算上限时会返回最近一次提取的结果;如果 SPA 仍在渲染,该结果可能不完整。
  • 需要身份验证的内容。 此服务使用不带 Cookie 或已存储身份验证信息的干净浏览器上下文。需要登录才能访问的页面无法使用。

与相关工具的比较

  • @playwright/mcp(Microsoft)——通用交互式浏览器自动化:导航、点击、填写表单、运行 JS、获取无障碍快照。需要与页面交互时使用它;需要读取页面时使用此服务。
  • mcp-server-fetch 和类似的基于 HTTP 的服务——也会先尝试纯 HTTP,因此处理静态网站时行为相似。区别在于 JS 渲染的页面和受机器人防护的网站:这些工具没有浏览器回退方案,因此在此服务可以成功的情况下,它们会失败。
  • LM Studio Hub 插件,例如 vadimfedenko/visit-website-reworked 和 npacker/web-tools——在 LM Studio 插件系统中实现了相同的功能。此服务可在任何 MCP 客户端中运行。

路线图

  • 持久化无头浏览器实例,摊销冷启动开销
  • 为 Cloudflare's Markdown for Agents 提供 Accept: text/markdown 快速通道
  • 添加可选的 selector 参数,以限定提取范围
  • 添加可选的视口、user-agent 和区域设置覆盖项
  • 添加可选的持久化浏览器上下文,以保留 Cookie/WAF 信任状态
  • 添加 channel="chrome" 选项,以使用已安装的 Google Chrome 代替捆绑的 Chromium(进一步提升对最难访问网站的隐蔽性)

贡献

欢迎提交问题和 PR。对于较大的改动,请先提交问题,讨论实施方案。

许可证

MIT——请参阅 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

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

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