Skip to main content
Glama
JohnnyFoulds

markdown-for-agents-mcp

markdown-for-agents-mcp

npm version npm downloads Node.js codecov License: MIT

一个 MCP (Model Context Protocol) 服务器,它通过 完整的 JavaScript 渲染 抓取 URL,并将其转换为适合 AI 智能体的整洁、节省 Token 的 Markdown。

大多数 MCP 抓取工具使用普通的 HTTP —— 它们只能看到服务器发送的内容,而不会运行任何 JavaScript。这对于静态网站有效,但对于 React、Vue、Angular、SPA 以及任何动态加载数据的页面,它们只会静默地返回空内容或损坏的内容。此服务器通过 Playwright 运行真实的 Chromium 浏览器,因此它会在提取前渲染整个页面 —— 这与人类用户看到的内容完全一致。

Playwrightmarkdown-for-agents 库提供支持。它会剔除广告、导航和样板代码 —— 相比原始 HTML,Token 消耗减少高达 80%。


为什么选择 Playwright?

功能

普通 HTTP 抓取工具

markdown-for-agents-mcp

静态 HTML 页面

React / Vue / Angular 应用

JavaScript 渲染内容

单页应用路由

懒加载 / 无限滚动

相比原始 HTML 的 Token 效率

中等

减少高达 80%

反爬虫规避

UA 轮换、webdriver 伪装

Token 缩减示例: 一个典型的网页新闻文章原始 HTML 大约为 150 KB(约 40,000 个 Token)。经过 Playwright 渲染、DOM 修剪和 Markdown 转换后,同一篇文章仅需约 2,000 个 Token —— 减少了 95%。


目录


功能特性

  • JavaScript 渲染 —— 由 Playwright 驱动的 Chromium 在提取前渲染 React、Vue、Angular 及任何重度依赖 JS 的页面

  • 结构化输出 —— 工具返回类型化的 structuredContent(url、title、markdown、fetchedAt、contentSize)以及文本响应,兼容 MCP SDK 1.11+

  • 智能内容提取 —— 对内容块进行评分并选择主要内容(main > article > #content > body),自动丢弃侧边栏、导航和广告

  • Token 效率 —— 生成紧凑的、适合 LLM 的 Markdown;基准测试显示相比原始 HTML 减少高达 80% 的 Token

  • 网页搜索 —— DuckDuckGo 搜索,并可选择抓取并转换搜索结果页面

  • LRU 缓存 —— 50 MB 内存缓存,TTL 为 15 分钟,避免重复抓取

  • 域名过滤 —— 内置追踪器/社交域名黑名单;支持按请求设置允许/阻止列表,以及服务器级允许列表模式

  • 批量抓取 —— 支持可配置并发的多 URL 抓取

  • HTTP 服务器模式 —— 可作为 HTTP 服务器运行(--http [port]HTTP_PORT 环境变量),支持可选的 Bearer Token 认证

  • 代理支持 —— 传入 PLAYWRIGHT_PROXY 可通过代理路由 Playwright 流量

  • 健康监控 —— health_check 工具可查看缓存和抓取指标

  • 零配置 —— Chromium 在首次运行时自动安装


安装

npm install -g markdown-for-agents-mcp

Chromium 会通过 postinstall 脚本自动下载。如果失败,请参阅 故障排除

您也可以不进行全局安装,直接使用 npx 运行:

npx markdown-for-agents-mcp

MCP 客户端设置

将服务器添加到您的 MCP 客户端配置中。

Claude Desktop

编辑 ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) 或 %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "markdown": {
      "command": "markdown-mcp"
    }
  }
}

VS Code (Copilot / Continue)

添加到您的工作区或用户 settings.json 中相关的 MCP 扩展键下,例如:

{
  "mcpServers": {
    "markdown": {
      "command": "markdown-mcp"
    }
  }
}

Cursor / Windsurf / Zed

任何实现了 MCP 规范 的客户端都可以使用此服务器。命令入口点是 markdown-mcp(全局安装后可在 PATH 中找到),或者使用本地构建的 dist/index.js 的完整路径。

使用环境变量覆盖

{
  "mcpServers": {
    "markdown": {
      "command": "markdown-mcp",
      "env": {
        "FETCH_TIMEOUT_MS": "60000",
        "LOG_LEVEL": "DEBUG"
      }
    }
  }
}

HTTP 服务器模式

除了 stdio,您还可以将服务器作为标准 HTTP 端点运行 —— 这对于共享部署、Docker 或任何偏好 Streamable HTTP 传输的客户端非常有用:

# Start on port 3456
markdown-mcp --http 3456

# Or use the env var
HTTP_PORT=3456 markdown-mcp

所有 MCP 流量均在 POST|GET|DELETE /mcp 处理。若要要求 Bearer Token,请设置 MCP_AUTH_TOKEN

MCP_AUTH_TOKEN=mysecrettoken HTTP_PORT=3456 markdown-mcp

客户端必须在每个请求中传递 Authorization: Bearer mysecrettoken


可用工具

fetch_url

抓取单个 URL 并进行完整的 JavaScript 渲染,返回整洁的 Markdown。

参数:

名称

类型

必需

描述

url

string

要抓取并转换的 URL

timeout

number

请求超时时间(毫秒,覆盖 FETCH_TIMEOUT_MS

示例:

fetch_url(url="https://example.com/blog/post")

文本输出(始终存在,向后兼容):

# Blog Post Title

Source: https://example.com/blog/post

This is the main content of the article, stripped of navigation, ads, and boilerplate.

## Related Section

More content here...

---
*Converted by markdown-for-agents-mcp*

结构化输出(MCP SDK 1.11+ 客户端可通过 structuredContent 获取):

{
  "url": "https://example.com/blog/post",
  "title": "Blog Post Title",
  "markdown": "# Blog Post Title\n\nSource: ...",
  "fetchedAt": "2026-04-06T17:00:00.000Z",
  "contentSize": 2048
}

fetch_urls

并发抓取多个 URL 并返回合并后的 Markdown,每个 URL 对应一个部分。

参数:

名称

类型

必需

描述

urls

string[]

要抓取的 URL 列表

timeout

number

每个请求的超时时间(毫秒)

示例:

fetch_urls(urls=[
  "https://example.com/post1",
  "https://example.com/post2"
])

文本输出:

# Post 1 Title

Source: https://example.com/post1

...

---

# Post 2 Title

Source: https://example.com/post2

...

---

结构化输出(通过 structuredContent):

{
  "results": [
    {
      "url": "https://example.com/post1",
      "title": "Post 1 Title",
      "markdown": "...",
      "fetchedAt": "2026-04-06T17:00:00.000Z",
      "contentSize": 1820,
      "success": true
    },
    {
      "url": "https://example.com/post2",
      "title": "Post 2 Title",
      "markdown": "...",
      "fetchedAt": "2026-04-06T17:00:00.000Z",
      "contentSize": 2104,
      "success": true
    }
  ],
  "summary": { "total": 2, "succeeded": 2, "failed": 0 }
}

并发性由 MAX_CONCURRENT_FETCHES 控制(默认:5)。


搜索 DuckDuckGo,并可选择将搜索结果抓取为 Markdown。使用普通 HTTP 端点以避免反爬虫检测 —— 搜索本身不使用 Playwright。

参数:

名称

类型

必需

描述

query

string

搜索查询

maxResults

number

返回的最大结果数(默认:10)

allowedDomains

string[]

仅包含来自这些域名的结果

blockedDomains

string[]

排除来自这些域名的结果

fetchResults

boolean

抓取并将顶部结果页面转换为 Markdown

timeout

number

请求超时时间(毫秒)

示例 —— 仅搜索:

web_search(
  query="typescript tutorials",
  maxResults=5,
  allowedDomains=["typescriptlang.org", "github.com"]
)

示例 —— 搜索并抓取:

web_search(
  query="react hooks guide",
  fetchResults=true,
  maxResults=3
)

文本输出:

# Web Search Results

## Query: typescript tutorials
**Found 5 results in 1234ms**

### Results:

1. [TypeScript Handbook](https://www.typescriptlang.org/docs/)
   The TypeScript Handbook provides comprehensive documentation...

2. [Best TypeScript Tutorials](https://github.com/danistefanovic/build-your-own-typescript)
   Learn TypeScript by building your own compiler...

结构化输出(通过 structuredContent):

{
  "query": "typescript tutorials",
  "results": [
    { "title": "TypeScript Handbook", "url": "https://www.typescriptlang.org/docs/", "snippet": "...", "domain": "typescriptlang.org" }
  ],
  "fetchedContent": [
    { "url": "https://www.typescriptlang.org/docs/", "markdown": "..." }
  ],
  "durationMs": 1234
}

注意: allowedDomainsblockedDomains 参数仅适用于搜索结果过滤。当随后抓取这些结果时,服务器级的 BLOCKLIST_DOMAINS / USE_ALLOWLIST_MODE 设置仍然适用。


download_file

从 URL 下载二进制文件(PDF、图像、ZIP 等)并保存到本地路径。使用普通 HTTP 客户端 —— 无需 Playwright。强制执行 SSRF 防护和域名黑名单。

参数:

名称

类型

必需

描述

url

string

要下载的文件 URL

outputPath

string

保存文件的绝对本地路径(父目录必须存在)

示例:

download_file(
  url="https://example.com/report.pdf",
  outputPath="/tmp/report.pdf"
)

输出:

{
  "savedPath": "/tmp/report.pdf",
  "sizeBytes": 204800,
  "mimeType": "application/pdf",
  "filename": "report.pdf"
}

注意: 即使 fetch_url 阻止了路径如 /download/... 的 URL(以避免二进制下载链),此工具仍允许下载。请使用 fetch_url 处理 HTML 页面 —— download_file 将拒绝 text/html 响应。


health_check

返回当前服务器状态、缓存指标和抓取统计信息。对监控和调试非常有用。

参数:

输出示例:

{
  "status": "healthy",
  "cache": {
    "hits": 47,
    "misses": 15,
    "currentSize": 12,
    "totalBytes": 4194304,
    "maxBytes": 52428800
  },
  "metrics": {
    "totalFetches": 62,
    "successCount": 59,
    "errorCount": 3,
    "avgDuration": 1840,
    "cacheUtilization": 76
  }
}

CLI 使用

包含一个独立的 CLI (markdown-cli),供 MCP 协议之外使用。

单个 URL

markdown-cli https://example.com

多个 URL(批量模式)

markdown-cli -b https://example.com https://example.org https://example.net

保存到文件

markdown-cli https://example.com/article > article.md

下载二进制文件

markdown-cli -d -o /tmp/report.pdf https://example.com/report.pdf

命令参考

命令

描述

markdown-cli <url>

抓取单个 URL 并打印 Markdown

markdown-cli -b <url1> <url2> ...

批量模式抓取多个 URL

markdown-cli -d -o <path> <url>

将二进制文件下载到本地路径

markdown-cli --help

显示帮助


配置

所有设置在启动时从环境变量读取,并使用 Zod 进行验证。无效值会导致非零退出并显示描述性错误。

.env.example 复制到 .env 即可开始:

cp .env.example .env

参考

变量

默认值

描述

FETCH_TIMEOUT_MS

30000

每个抓取请求的超时时间(毫秒)

MAX_CONCURRENT_FETCHES

5

批量操作中的最大并行抓取数

MAX_REDIRECTS

10

报错前的最大重定向跳转次数

MAX_CONTENT_LENGTH

100000

截断前的最大内容大小(字符)

LOG_LEVEL

INFO

DEBUG, INFO, WARNERROR

LOG_FORMAT

text

text(人类可读)或 json(结构化)

CACHE_MAX_BYTES

52428800

最大 LRU 缓存大小(50 MB)

CACHE_TTL_MS

900000

缓存条目 TTL(15 分钟)

USE_ALLOWLIST_MODE

false

若为 true,则仅允许 BLOCKLIST_DOMAINS 中的域名

BLOCKLIST_DOMAINS

(空)

以逗号分隔的要阻止的域名(或在允许列表模式下要允许的域名)

BLOCKLIST_URL_PATTERNS

(空)

以逗号分隔的要按 URL 路径阻止的正则表达式

WEB_SEARCH_DEFAULT_TIMEOUT_MS

30000

搜索请求的默认超时时间(毫秒)

DOWNLOAD_TIMEOUT_MS

60000

二进制文件下载的超时时间(毫秒)

HTTP_PORT

(未设置)

设置后,在此端口启动 HTTP 服务器而不是 stdio

MCP_AUTH_TOKEN

(未设置)

所有 HTTP 请求所需的 Bearer Token(仅限 HTTP 模式)

PLAYWRIGHT_PROXY

(未设置)

Playwright 的代理服务器 URL(例如 http://proxy.example.com:8080

PLAYWRIGHT_PROXY_BYPASS

(未设置)

以逗号分隔的绕过代理的域名

所有日志均写入 stderr,以保持 stdout 的整洁,供 MCP 协议使用。


安全性

默认域名黑名单

默认阻止以下域名,以防止意外抓取追踪器、广告网络和社交平台,这些平台通常会积极阻止机器人或提供低质量内容:

doubleclick.net, facebook.com, twitter.com, tiktok.com, hotjar.com, mixpanel.com, bit.ly 以及其他约 20 个域名(完整列表请参阅 src/utils/domainBlacklist.ts)。

如果您需要抓取被阻止的域名,请将 USE_ALLOWLIST_MODE=false 并将其添加到 BLOCKLIST_DOMAINS —— 这会增加到黑名单中,而不会删除现有条目。要允许默认被阻止的域名,您需要 fork 并修改 domainBlacklist.ts

URL 路径阻止

某些 URL 路径模式无论域名如何都会被阻止(例如 OAuth 回调、二进制文件下载、支付/结账路径、管理面板)。这些可以防止意外抓取敏感或非内容 URL。

允许列表模式

设置 USE_ALLOWLIST_MODE=trueBLOCKLIST_DOMAINS=yourdomain.com,trusted.org 可将服务器限制为仅从明确列出的域名抓取。建议用于生产部署。

重定向策略

跨域重定向被阻止。服务器仅遵循同源

-
security - not tested
A
license - permissive license
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JohnnyFoulds/markdown-for-agents-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server