文档抓取服务

一个基于Bun的模型上下文协议(MCP)服务器,用于抓取和爬取文档页面,支持静态抓取和可选Puppeteer渲染。

  • by wolfyy970
  • TypeScript
  • 本地部署
  • 7 星标
  • 更新于
在 GitHub 查看 wolfyy970/docs-fetch-mcp

使用说明

文档提取MCP服务器

一个基于Bun的模型上下文协议(MCP)服务器,用于获取文档页面和有界文档抓取。

服务器公开了一个MCP工具, fetch_doc_content。它获取根URL,提取可读的Markdown,对链接进行排名,并可以在明确的深度、页面、超时和范围限制内抓取链接页面。结果以结构化JSON形式返回,其中包含爬网元数据、页面内容、排名链接、截断标志和每页错误。

特性

  • 快速静态获取路径 axios
  • 客户端渲染或精简页面的可选Puppeter渲染
  • Markdown提取,包括标题、列表、代码块、表格、区块引用和链接
  • 实际爬行深度语义:
    • depth: 1 仅返回根页面
    • depth: 2 包括直接子链接
    • depth: 3 包括孙子孙女,最多为 5
  • 重复数据消除前的URL规范化:删除片段、跟踪参数、默认端口和尾随斜线重复项
  • 按相同来源和可选条件进行爬网范围界定 pathPrefix
  • 有界的 maxPages, maxConcurrency、全局超时、每页超时和每页内容截断
  • 具有显式每页失败的部分结果
  • 与播发的工具架构共享运行时参数验证

需求

  • 包子 >=1.3.0
  • Puppeteer的浏览器安装如果 render 是 auto 或 always

此项目使用Bun进行依赖关系管理、运行时执行、构建和测试。

安装

bun install
bun run build

配置您的MCP客户端:

{
  "mcpServers": {
    "docs-fetch": {
      "command": "bun",
      "args": ["/path/to/docs-fetch-mcp/build/index.js"]
    }
  }
}

对于没有建设的当地发展:

{
  "mcpServers": {
    "docs-fetch": {
      "command": "bun",
      "args": ["/path/to/docs-fetch-mcp/src/index.ts"]
    }
  }
}

工具

fetch_doc_content

获取一个URL,并可选择抓取链接的页面。

参数:

名称 类型 默认值 限制 描述
url string 必需 仅限HTTP/HTTPS 要获取的根URL。
depth 编号 1 1 到 5 链接到根的距离。
maxPages 编号 10 1 到 50 爬网过程中返回的最大页面数。
maxConcurrency 编号 3 1 到 8 一次获取的最大页数。
timeoutMs 编号 45000 5000 到 120000 全局爬网超时。
perPageTimeoutMs 编号 10000 1000 到 60000 每页获取超时。
render 字符串 auto auto, always, never 浏览器渲染策略。
sameOrigin 布尔值 true n/a 将已爬网链接限制在同一来源。
pathPrefix string 省略 n/a 可选路径前缀爬网范围,例如 /docs.
contentLimit 编号 12000 1000 到 50000 截断前每页的Markdown字符数。
includeLinks 布尔值 true n/a 在返回的页面对象中包含排名链接。

请求示例:

{
  "url": "https://example.com/docs",
  "depth": 2,
  "maxPages": 8,
  "pathPrefix": "/docs",
  "render": "auto"
}

响应形状:

{
  "rootUrl": "https://example.com/docs",
  "normalizedRootUrl": "https://example.com/docs",
  "explorationDepth": 2,
  "maxPages": 8,
  "pagesExplored": 3,
  "pagesFailed": 1,
  "timedOut": false,
  "durationMs": 1234,
  "crawl": {
    "sameOrigin": true,
    "pathPrefix": "/docs",
    "maxConcurrency": 3,
    "render": "auto",
    "perPageTimeoutMs": 10000
  },
  "content": [
    {
      "url": "https://example.com/docs",
      "finalUrl": "https://example.com/docs",
      "depth": 0,
      "status": 200,
      "title": "Documentation",
      "description": "Example documentation",
      "canonicalUrl": "https://example.com/docs",
      "headings": ["Documentation"],
      "content": "# Documentation\n\n...",
      "contentLength": 2400,
      "truncated": false,
      "fetchedWith": "http",
      "links": [
        {
          "url": "https://example.com/docs/api",
          "text": "API reference",
          "score": 18.5,
          "internal": true
        }
      ]
    }
  ],
  "errors": [
    {
      "url": "https://example.com/docs/missing",
      "depth": 1,
      "error": "Request failed with status code 404",
      "status": 404
    }
  ]
}

爬行行为

  • 爬行是广度优先的。
  • 在重复数据消除和排队之前,URL会被规范化。
  • sameOrigin: true 拒绝来源与规范化根URL不同的链接。
  • pathPrefix 进一步将链接限制为根原点上的路径前缀。
  • includeLinks: false 隐藏返回页面对象中的链接,但不禁用爬行的链接发现。
  • render: "never" 仅使用HTTP获取路径。
  • render: "always" 对每个提取的页面使用Puppeter。
  • render: "auto" 首先尝试HTTP,然后在HTTP失败或提取的内容非常薄时使用Puppeteer。
  • 浏览器回退目前保留了渲染的响应状态,并提取了页面正文,即使对于非2xx页面也是如此。

建筑

src/index.ts                         CLI entrypoint
src/server.ts                        MCP server wiring and tool registration
src/config/tool-options.ts           Shared tool schema/default/range metadata
src/tool/fetch-doc-content-args.ts   Runtime argument validation
src/crawler/docs-crawler.ts          Crawl orchestration and queue management
src/crawler/page-fetcher.ts          HTTP fetch, browser fallback, extraction coordination
src/browser/browser-manager.ts       Reusable Puppeteer browser/page handling
src/content/content-extractor.ts     Page metadata/content extraction facade
src/content/main-content-selector.ts Main content selection
src/content/link-extractor.ts        Link normalization, dedupe, and ranking
src/content/markdown-renderer.ts     HTML-to-Markdown rendering
src/content/text-cleanup.ts          Shared text normalization helpers
src/utils/url.ts                     URL normalization and scope utilities
src/types/index.ts                   Shared TypeScript types

MCP模式和运行时选项规范化在中共享相同的元数据源 src/config/tool-options.ts。首先保留新选项,然后通过验证和爬虫选项连接行为。

发展

bun install
bun run dev
bun run test
bun run typecheck
bun run build

脚本:

  • bun run dev:从TypeScript源代码运行MCP服务器。
  • bun run test:在以下条件下运行Bun测试 src.
  • bun run typecheck:使用以下命令运行TypeScript --noEmit.
  • bun run build:发射 build/index.js 与Bun shebang。
  • bun run start:运行内置的MCP服务器。

测试

测试与它们所涵盖的模块托管在一起:

  • src/crawler/docs-crawler.test.ts:爬网深度、范围、失败和链接可见性。
  • src/crawler/page-fetcher.test.ts:获取/呈现回退特性。
  • src/content/content-extractor.test.ts:Markdown提取和截断。
  • src/tool/fetch-doc-content-args.test.ts:边界验证和模式/默认同步。
  • src/utils/url.test.ts:URL规范化和作用域帮助器。

更改行为时,请先添加或更新特征测试。对于重构器,请保持 bun run test, bun run typecheck,以及 bun run build 绿色。

备注

  • 使用 render: "never" 用于快速静态文档抓取和测试。
  • 使用 pathPrefix 用于与营销页面、博客或应用程序共享域的文档网站。
  • 只有当呼叫者使用时,才能跳过Puppeter浏览器安装 render: "never".
  • 自定义Markdown渲染器有意被特征测试覆盖;除非进行明确的行为更改,否则请保持输出兼容性。

许可证

麻省理工学院