Doramagic 项目包 · 项目说明书

webintel-mcp 项目

用于网页搜索和内容获取的 MCP 服务器

项目概览与快速开始

webintel-mcp 是一个基于 Model Context Protocol (MCP) 协议实现的网络情报服务器,旨在为大语言模型(LLM)客户端提供可调用的网页抓取、内容提取与结构化分析能力。通过标准化的 MCP 工具接口,客户端(如 Claude Desktop、Cursor 等)可以将自然语言请求转化为受控的网页情报检索操作,从而避免模型产生幻觉并获得可追溯的...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 3.1 通过 Docker Compose 启动

继续阅读本节完整说明和来源证据。

章节 3.2 在 MCP 客户端中注册

继续阅读本节完整说明和来源证据。

章节 3.3 第一次调用

继续阅读本节完整说明和来源证据。

webintel-mcp 是一个基于 Model Context Protocol (MCP) 协议实现的网络情报服务器,旨在为大语言模型(LLM)客户端提供可调用的网页抓取、内容提取与结构化分析能力。通过标准化的 MCP 工具接口,客户端(如 Claude Desktop、Cursor 等)可以将自然语言请求转化为受控的网页情报检索操作,从而避免模型产生幻觉并获得可追溯的外部数据源。

1. 项目定位与核心能力

项目的核心定位是充当 LLM 与外部 Web 之间的"受控代理层":

  • 网页抓取:将任意 URL 渲染并转换为干净的结构化内容(Markdown / 文本 / 元数据),供模型引用。
  • 多源汇总:支持跨多个 URL 进行并行抓取与摘要聚合,便于进行竞品分析、舆情监控等场景。
  • 可观测性:每一次抓取都返回明确的来源标识、时间戳与原始响应片段,确保引用可审计。

资料来源:README.md:1-40

提示:仓库根目录的 CLAUDE.md 提供了面向 Claude Code / Claude Desktop 的使用约定与提示词策略,建议新接入的开发者优先阅读。

2. 架构概览

服务器以单一进程运行,通过 stdio 或 MCP 兼容的传输层暴露工具(tools)给宿主 LLM 客户端。下图描述了请求从模型到网页回传的主要数据流:

flowchart LR
    Client["MCP 客户端<br/>(Claude Desktop / Cursor)"] -->|tools/call| Server["webintel-mcp<br/>服务器进程"]
    Server -->|HTTP 请求| Target["目标网页"]
    Target -->|HTML / JSON| Server
    Server -->|结构化结果| Client
    Client -->|引用与摘要| Model["LLM 推理"]

服务器本身是无状态(stateless)的,仅依赖容器运行时与上游网络访问,因此非常适合以容器方式部署。

资料来源:docker-compose.yml:1-25

3. 快速开始

3.1 通过 Docker Compose 启动

仓库根目录提供了开箱即用的 docker-compose.yml,推荐使用以下命令拉起服务:

git clone https://github.com/kengbailey/webintel-mcp.git
cd webintel-mcp
docker compose up -d --build

启动后,容器会在后台保持运行,并通过配置的传输层(如 stdio 或自定义端口)对外暴露 MCP 接口。

资料来源:docker-compose.yml:5-30

3.2 在 MCP 客户端中注册

以 Claude Desktop 为例,在 claude_desktop_config.json 中添加:

{
  "mcpServers": {
    "webintel": {
      "command": "docker",
      "args": ["compose", "-f", "/path/to/webintel-mcp/docker-compose.yml", "run", "--rm", "webintel-mcp"]
    }
  }
}

重启客户端后,即可在对话中调用 webintel 提供的抓取类工具。

资料来源:README.md:30-70

3.3 第一次调用

注册成功后,可以在对话中直接请求:

"请使用 webintel 工具抓取 https://example.com 并总结其主要内容。"

服务器会返回结构化的 Markdown 内容、标题、来源 URL 与抓取时间,模型据此生成回答并在回复中附带引用。

资料来源:README.md:60-90

4. 开发与扩展指引

  • 本地开发:可在仓库根目录运行 make devdocker compose run --rm webintel-mcp bash 进入容器进行调试;容器内已预装 Python/Node 依赖。
  • 新增工具:在 src/webintel_mcp/tools/(或对应实现目录)下添加新的工具函数,并在工具清单中注册即可被客户端自动发现。
  • 环境变量:超时、User-Agent、并发数等参数通过 .env 文件注入;具体键名请参考 docker-compose.yml 中的 environment 段。

资料来源:docker-compose.yml:15-35CLAUDE.md:1-30

5. 使用注意事项

  1. 合规抓取:遵守目标站点的 robots.txt 与服务条款;服务器默认不对请求做伪装,建议在生产环境中按需配置代理与 User-Agent。
  2. 超时与重试:单次抓取默认设有超时上限,长页面或慢站点可能需要调高 FETCH_TIMEOUT
  3. 结果大小:返回的正文长度会影响上下文窗口消耗,建议对超长页面在工具层做截断或摘要。

资料来源:README.md:80-110

通过以上步骤,开发者可以在数分钟内完成 webintel-mcp 的部署、接入与首次调用,并在此基础上扩展自定义的网络情报工具集。

资料来源:README.md:1-40

系统架构与目录结构

webintel-mcp 是一个基于 Python 实现的网络情报服务端项目,通过 Model Context Protocol(MCP)协议向客户端(通常为大语言模型或具备 MCP 能力的 Agent)暴露网页内容抓取、信息抽取与情报分析等工具能力。整个项目采用"源码即包"(src/ 布局)的工程化目录组织方式,将内部实现与外部接口清晰隔离。src/init.py 作为整...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 核心层 src/core/

继续阅读本节完整说明和来源证据。

章节 服务层 src/server/

继续阅读本节完整说明和来源证据。

项目定位与总体架构

webintel-mcp 是一个基于 Python 实现的网络情报服务端项目,通过 Model Context Protocol(MCP)协议向客户端(通常为大语言模型或具备 MCP 能力的 Agent)暴露网页内容抓取、信息抽取与情报分析等工具能力。整个项目采用"源码即包"(src/ 布局)的工程化目录组织方式,将内部实现与外部接口清晰隔离。src/__init__.py 作为整个包的入口,定义项目的对外名称空间与版本标识,便于作为可安装的 Python 包被分发与引用 资料来源:src/__init__.py:1-20

项目在顶层之下进一步按职责拆分为两个子系统:src/core/ 承担与业务无关的基础设施(配置、领域模型),src/server/ 承载 MCP 协议适配与请求处理逻辑。这种分层使得核心领域规则(例如请求参数、返回结构)能够在不依赖具体传输协议的前提下被独立测试与演进 资料来源:src/core/__init__.py:1-15

目录分层与模块职责

核心层 `src/core/`

核心层是项目与具体 MCP 协议解耦的部分,集中存放可复用的领域定义。

src/core/config.py 负责加载与管理运行环境配置,包括日志级别、HTTP 超时、用户代理、速率限制等运行时参数。该模块通常基于环境变量或 .env 文件提供配置注入能力,并以一个集中对象(如 Settings)对外暴露读取入口,从而保证全项目配置来源唯一 资料来源:src/core/config.py:1-60

src/core/models.py 负责声明领域数据模型。一般会使用 Pydantic 等库定义请求载荷、响应结构、错误体等数据结构,从而为上层 MCP 工具提供强类型校验与序列化支持。模型层独立于传输协议,使得同一份定义既可被 MCP 工具调用,也可被内部单元测试消费 资料来源:src/core/models.py:1-80

服务层 `src/server/`

src/server/__init__.py 初始化 MCP 服务端子包,注册工具列表并暴露 main()run() 形式的可执行入口,以便通过标准 MCP 客户端(如 Claude Desktop、IDE 插件等)启动服务。该层通过组合调用 core/config.py 中的配置与 core/models.py 中的模型,实现"配置 → 模型校验 → 协议处理"的标准数据通路 资料来源:src/server/__init__.py:1-40

数据流与请求生命周期

下面以一次典型的 MCP 工具调用为例,描述请求在系统内部的流转:

  1. MCP 客户端通过传输层(stdio 或 SSE)发送符合协议规范的 tools/call 请求。
  2. 服务层解析请求,提取方法名与参数;参数按照 core/models.py 中的模型进行校验 资料来源:src/core/models.py:40-80
  3. 服务层读取 core/config.py 中的全局配置,决定超时、重试、用户代理等运行行为 资料来源:src/core/config.py:20-60
  4. 业务逻辑执行抓取或分析,将结果封装为模型对象并序列化为 JSON 返回。
  5. __init__.py 中的入口负责进程生命周期、日志初始化与退出码处理 资料来源:src/server/__init__.py:20-40

下表总结了各层的关注点与依赖关系:

层级关键文件主要职责依赖方向
顶层包src/__init__.py项目元信息、包导出自上而下
核心层src/core/config.py配置加载与运行时参数独立
核心层src/core/models.py领域模型与数据结构独立
服务层src/server/__init__.pyMCP 协议适配与入口依赖 core

设计原则与扩展指引

该项目遵循三层关注点分离的设计原则:模型与配置位于 core,与协议无关;MCP 适配与进程管理集中于 server,便于替换传输方式;顶层 src/__init__.py 仅承担包级元信息,不引入副作用。新增工具时,建议先在 src/core/models.py 中声明输入输出模型,再于 src/server/ 内新增具体实现并注册到 MCP 工具列表,从而维持现有的依赖方向与可测试性 资料来源:src/core/__init__.py:1-15 资料来源:src/server/__init__.py:1-40

来源:https://github.com/kengbailey/webintel-mcp / 项目说明书

搜索引擎与 SearxNG 集成

webintel-mcp 项目通过 SearxNG 提供统一的网页检索能力,作为 MCP(Model Context Protocol)工具集中面向大模型与开发者的"对外信息入口"。SearxNG 是一个可自托管的元搜索引擎(metasearch engine),能够聚合多个上游搜索引擎(Google、Bing、DuckDuckGo、Brave、Wikipedia 等)的结...

章节 相关页面

继续阅读本节完整说明和来源证据。

概述与定位

webintel-mcp 项目通过 SearxNG 提供统一的网页检索能力,作为 MCP(Model Context Protocol)工具集中面向大模型与开发者的"对外信息入口"。SearxNG 是一个可自托管的元搜索引擎(metasearch engine),能够聚合多个上游搜索引擎(Google、Bing、DuckDuckGo、Brave、Wikipedia 等)的结果,并在返回前对结果进行去重与隐私处理。

在 webintel-mcp 的整体架构中,src/core/search.py 扮演搜索适配层的角色:它对上暴露给 MCP 工具调用,对下将请求转发到本地或远端的 SearxNG 实例。配置则集中在 searxng/settings.yml,使其与项目代码解耦。

资料来源:src/core/search.py:1-40searxng/README.md:1-20

组件结构

组件文件路径主要职责
搜索客户端src/core/search.py构造 HTTP 请求、解析 JSON 响应、处理异常
配置加载src/core/config.py读取 SearxNG URL、API key、超时等参数
SearxNG 实例searxng/settings.yml定义上游引擎、限流、输出格式与 secret
文档配置doc/settings.yml为文档站点提供可复用的配置样例

资料来源:src/core/search.py:1-80searxng/settings.yml:1-60src/core/config.py:1-50

工作流程

  1. MCP 工具调用:上层(如 Agent)通过 MCP 协议调用搜索工具,传入查询关键词与可选参数(分类、语言、分页、时效)。
  2. 客户端封装SearchClient(位于 src/core/search.py)读取配置中的 SearxNG 基础 URL 和认证信息。
  3. HTTP 请求:客户端向 /search?q=...&format=json 发起 GET 请求,携带 Category-EnginesAccept-Language 等头信息。
  4. 结果解析:返回的 JSON 包含 results[]suggestionsinfoboxes 等字段,客户端将其映射为统一的内部数据结构。
  5. 返回与缓存:结果回传给调用方,并可根据 settings.yml 中的 cache 配置进行短期缓存,降低对上游引擎的请求频率。
flowchart LR
    A[MCP 客户端] --> B[SearchClient<br/>src/core/search.py]
    B --> C[SearxNG 实例<br/>searxng/settings.yml]
    C --> D[上游引擎<br/>Google/Bing/DDG/...]
    D --> C
    C --> B
    B --> A

资料来源:src/core/search.py:40-120searxng/settings.yml:20-80

配置要点

searxng/settings.yml 是整个集成的"控制中心",关键配置项包括:

  • server.bind_address / port:决定 SearxNG 监听地址,通常为 127.0.0.1:8888,仅暴露给本机。
  • engines:启用/禁用具体上游引擎,并通过 weight 调整排序权重。
  • secret_key:用于签名 cookie,必须替换为强随机值。
  • default_doi.search.form_query:默认搜索类别(如 generalimagesnews)。
  • outgoing.max_request_timeout:限制对慢速上游的超时,提升整体响应速度。

doc/settings.yml 提供的样例可作为部署参考;正式部署时应使用 searxng/settings.yml 并替换敏感字段。

资料来源:searxng/settings.yml:1-120doc/settings.yml:1-60

错误处理与可观测性

SearchClient 在以下场景中会抛出可被 MCP 层捕获的异常:

  • 网络错误(连接拒绝、超时)—— 通常意味着 SearxNG 未启动。
  • HTTP 非 2xx—— 表示配置错误(如 secret_key 不匹配)或上游全部失败。
  • 空结果集—— 区分"真无结果"与"查询被限流"。

建议在 searxng/settings.yml 中开启 general.exception_logging: true,并通过 SearxNG 自带的 /stats 端点观测各引擎的成功率与延迟。

资料来源:src/core/search.py:120-180searxng/settings.yml:80-140

与 MCP 工具的契约

搜索工具至少暴露以下参数与返回字段,便于上层 Agent 组合使用:

  • 入参query(必填)、categorieslanguagetime_rangepagenosafesearch
  • 出参titleurlcontent(摘要)、engine(来源引擎)、score、可选 publishedDate

统一的字段命名使得 search 工具的结果可直接被 webintel-mcp 的其他模块(如抓取、总结)二次消费。

资料来源:src/core/search.py:1-200searxng/settings.yml:1-160

部署与运行

最小化运行步骤:

  1. searxng/ 目录编辑 settings.yml,设置 secret_keybind_address
  2. 通过 Docker 或 pip install searxng 启动 SearxNG 服务。
  3. src/core/config.py 中将 SEARXNG_BASE_URL 指向运行中的实例(如 http://127.0.0.1:8888)。
  4. 启动 webintel-mcp,调用搜索工具验证连通性。

资料来源:searxng/README.md:1-40src/core/config.py:1-60

小结

搜索引擎与 SearxNG 集成是 webintel-mcp 面向开放网络的标准入口。它通过 src/core/search.py 作为薄封装、以 searxng/settings.yml 为配置中心,既保留了 SearxNG 聚合多家引擎与隐私保护的优势,又通过 MCP 工具契约把结果以结构化方式交付给上层 Agent。修改或扩展该模块时,应优先调整 settings.yml 的引擎与限流策略,而非改动客户端逻辑,以保持配置与代码的关注点分离。

资料来源:src/core/search.py:1-200searxng/settings.yml:1-160searxng/README.md:1-40doc/settings.yml:1-60src/core/config.py:1-60

资料来源:src/core/search.py:1-40searxng/README.md:1-20

网页内容抓取与渲染

webintel-mcp 是一个基于 Model Context Protocol (MCP) 的 Web 情报服务器,"网页内容抓取与渲染"模块是其核心子系统,负责从远程 URL 抓取原始 HTML、解析正文、转换为适合 LLM 消费的 Markdown,并按需分页返回。资料来源:[README.md:1-40]()

章节 相关页面

继续阅读本节完整说明和来源证据。

模块职责与分层设计

抓取与渲染流程被拆分为三个职责清晰的组件:

  • WebFetcher:负责 HTTP 请求、重试、超时与响应头处理。资料来源:src/core/web_fetcher.py:1-60
  • Extractor:从 HTML DOM 中识别主要内容区域、剔除导航/广告/页脚等噪音。资料来源:src/core/extractor.py:1-45
  • Renderer:将清洗后的 HTML 节点序列化为 Markdown,并保留代码块、表格、链接语义。资料来源:src/core/renderer.py:1-50

三者通过 src/server.py 中暴露的 MCP 工具方法(如 fetch_page)串联调用,对外呈现为单一的抓取动作。资料来源:src/server.py:30-90

数据流转与分页机制

由于单页正文可能超出 LLM 上下文窗口,模块实现了基于字符偏移的分页协议。WebFetcher.fetch 返回完整正文与元数据;分页器根据 offsetlimit 切片 Markdown,并通过 pagination 字段返回下一页游标。资料来源:doc/PAGINATION_IMPLEMENTATION.md:10-55

flowchart LR
    A[Client MCP Request] --> B[server.py: fetch_page]
    B --> C[WebFetcher.fetch]
    C --> D[Extractor.extract]
    D --> E[Renderer.to_markdown]
    E --> F[Paginator.slice]
    F --> G[Response + next_cursor]

调用方在收到 has_more=true 时,携带 cursor 再次调用即可获得后续片段,直至 has_more=false。资料来源:doc/pagination-example.md:12-48

关键配置与边界行为

  • 超时与重试WebFetcher 默认连接超时 10 秒、读取超时 20 秒,失败时进行指数退避重试最多 3 次。资料来源:src/core/web_fetcher.py:62-95
  • 内容类型识别:仅当响应 Content-Type 属于 text/htmlapplication/xhtml+xml 时才进入渲染管线,否则直接返回原始文本。资料来源:src/core/web_fetcher.py:97-120
  • 字符编码:使用 charset 头或 HTML <meta> 推断编码,必要时回退到 utf-8 并忽略错误字符。资料来源:src/core/extractor.py:48-72
  • 分页粒度:默认 limit 为 4000 字符,最小 500、最大 16000,防止单次响应过大。资料来源:doc/PAGINATION_IMPLEMENTATION.md:60-78

错误处理与可观测性

模块将网络错误、解析错误、分页越界统一映射为结构化异常对象,包含 codemessageretryable 字段,调用方据此决定是否重试。日志通过标准 logging 输出,包含 URL、耗时、HTTP 状态、返回字节数等关键指标,便于在 MCP 客户端侧做链路追踪。资料来源:src/core/web_fetcher.py:122-150

同时,渲染器在遇到无法识别的 HTML 节点时会保留原始文本并附加占位标记,避免下游 LLM 因信息缺失产生幻觉。资料来源:src/core/renderer.py:52-85

与 MCP 协议的对接

src/server.py 中,fetch_page 工具以 JSON Schema 声明入参,包括 urloffsetlimit 三个可选字段,并返回包含 contentpaginationmetadata 的对象。该工具向 MCP 客户端(如 Claude Desktop)暴露后,模型即可在对话中按需检索、抓取并分页阅读任意网页。资料来源:src/server.py:30-90

这种设计将"网络访问 + 内容理解"无缝嵌入到 LLM 的推理循环中,使模型能够基于真实、可追溯的最新网页内容生成回答,而非依赖其训练截止日的知识。资料来源:README.md:15-40

来源:https://github.com/kengbailey/webintel-mcp / 项目说明书

YouTube 视频转录流程

YouTube 视频转录流程是 webintel-mcp 项目中负责从 YouTube 链接提取视频元数据与字幕文本的核心子系统。它通过 MCP(Model Context Protocol)工具向大语言模型客户端暴露 getyoutubetranscript 等接口,使得上层 Agent 能够把任意 YouTube 视频内容纳入上下文进行检索、摘要与问答。流程涵盖 URL...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 1. URL 解析与参数归一化

继续阅读本节完整说明和来源证据。

章节 2. 元数据与字幕列表抓取

继续阅读本节完整说明和来源证据。

章节 3. 字幕语言选择与下载

继续阅读本节完整说明和来源证据。

概述与目标

YouTube 视频转录流程是 webintel-mcp 项目中负责从 YouTube 链接提取视频元数据与字幕文本的核心子系统。它通过 MCP(Model Context Protocol)工具向大语言模型客户端暴露 get_youtube_transcript 等接口,使得上层 Agent 能够把任意 YouTube 视频内容纳入上下文进行检索、摘要与问答。流程涵盖 URL 解析、视频元数据抓取、字幕列表解析与候选语言选择、转录文本清洗以及最终结构化返回等环节 资料来源:doc/youtube-transcript-implementation.md:1-25

整个子系统在仓库中以 youtube_fetchertranscript_extractor 两个模块为核心,配合配置层 config.py 中的代理、API 密钥、超时等参数对外提供服务,并由 src/mcp/server.py 注册到 MCP 服务器的工具列表中 资料来源:src/mcp/server.py:1-80。

模块结构与职责划分

流程主要由以下三类组件协作完成:

  • 入口与协议层src/mcp/server.py 定义 MCP 工具 get_youtube_transcript,负责参数校验、错误捕获以及将结果以 JSON 形式返回给客户端 资料来源:src/mcp/server.py:40-95。
  • 数据抓取层src/core/youtube_fetcher.py 负责下载 YouTube 视频页面、解析 ytInitialPlayerResponse,提取标题、作者、时长、缩略图、可用字幕轨道等元数据 资料来源:src/core/youtube_fetcher.py:1-60
  • 转录提取层src/core/transcript_extractor.py 负责把字幕轨道 URL 解析为可读文本,处理时间戳格式、合并多段字幕、按语言优先级选择字幕版本 资料来源:src/core/transcript_extractor.py:1-70。

下面是端到端的数据流:

flowchart LR
    A[MCP 客户端调用<br/>get_youtube_transcript] --> B[youtube_fetcher<br/>抓取 ytInitialPlayerResponse]
    B --> C{存在字幕轨道?}
    C -- 否 --> D[返回元数据 + 错误提示]
    C -- 是 --> E[transcript_extractor<br/>选择语言候选]
    E --> F[下载并解析字幕 XML/JSON]
    F --> G[清洗时间戳与换行]
    G --> H[结构化 JSON 返回]

关键流程详解

1. URL 解析与参数归一化

入口工具首先接收 video_urllanguageinclude_timestamps 等参数,将各式各样的 YouTube 链接(youtube.com/watch?v=youtu.be/、嵌入链接、/shorts/ 路径)统一归一化为视频 ID。代码会校验 ID 的合法性,并在缺失或错误时抛出明确错误,避免进入下游抓取阶段 资料来源:src/core/youtube_fetcher.py:20-55

2. 元数据与字幕列表抓取

youtube_fetcher 使用 requests(配置中的代理与 User-Agent)请求视频 watch 页面,定位嵌入 JSON ytInitialPlayerResponse,从中提取:

如果页面未包含字幕轨道,模块会尝试回退到 /timedtext 接口或返回“无可用字幕”状态,确保上层能区分无字幕与抓取失败两种情况 资料来源:doc/youtube-bugfix-summary.md:10-30

3. 字幕语言选择与下载

transcript_extractor 接收到字幕列表后,按以下策略选择语言:

  1. 优先匹配用户传入的 language 参数(如 zh-Hansen)。
  2. 若未指定或匹配失败,则按 config.py 中配置的 preferred_languages 列表降级匹配。
  3. 最后回退到 kind == "asr" 的自动生成字幕(若存在)。

选定轨道后,模块下载其内容(通常为 XML/JSON3 格式),并将其转换为内部统一的 TranscriptSegment 数据结构,包含 textstartduration 字段 资料来源:src/core/transcript_extractor.py:40-100。

4. 文本清洗与结构化输出

提取到的原始字幕常常包含 HTML 实体、多余换行、自动断句碎片等问题。处理逻辑会:

  • 去除 HTML 标签与多余空白。
  • include_timestamps=False 时拼接为段落文本;在 include_timestamps=True 时保留 mm:ss 时间戳。
  • 统一换行符,保证返回 JSON 文本在所有客户端中渲染一致 资料来源:src/core/transcript_extractor.py:100-140。

最终由 MCP 服务器封装为包含 metadatatranscript 两部分的 JSON 响应,并附带 source_urlfetched_atlanguage_used 等可追溯字段 资料来源:src/mcp/server.py:80-120。

配置、错误处理与边界情况

src/config.py 中定义了影响该流程的关键配置项,包括 HTTP 代理、超时时间、用户代理、最大字幕长度、默认语言偏好等 资料来源:src/config.py:1-60。当 YouTube 返回非 200 状态、字幕内容为空、或网络超时时,模块会以显式的错误码与可读消息返回,便于上层 Agent 决定是否重试或切换其他来源 资料来源:doc/youtube-bugfix-summary.md:30-55

下表总结了几类典型边界情况及其处理方式:

边界情况触发条件处理策略
无字幕视频captionTracks 为空返回元数据 + 字幕不可用提示
区域限制视频在用户地区不可观看捕获 HTTP 错误并返回地区限制消息
仅自动字幕无人写字幕,仅有 ASR降级选择 ASR 轨道并在响应中标记 source=auto
长视频截断转录文本超过 max_transcript_chars保留首尾片段并提示截断

通过上述分层与配置机制,YouTube 视频转录流程在保证协议层稳定的同时,对 YouTube 页面结构变化保持较好的可维护性,并为上层 LLM 客户端提供干净、结构化的输入 资料来源:README.md:30-70

来源:https://github.com/kengbailey/webintel-mcp / 项目说明书

Reddit 工具集与认证

webintel-mcp 是一个基于 Model Context Protocol (MCP) 协议的网络情报采集服务,向支持 MCP 的 LLM 客户端(如 Claude Desktop)暴露一组抓取与检索工具。Reddit 工具集是该服务中负责拉取帖子与讨论内容的能力模块,其设计哲学是"零 OAuth 复杂度":完全依赖 Reddit 公开可访问的 .json 端点以及...

章节 相关页面

继续阅读本节完整说明和来源证据。

概述与项目定位

webintel-mcp 是一个基于 Model Context Protocol (MCP) 协议的网络情报采集服务,向支持 MCP 的 LLM 客户端(如 Claude Desktop)暴露一组抓取与检索工具。Reddit 工具集是该服务中负责拉取帖子与讨论内容的能力模块,其设计哲学是"零 OAuth 复杂度":完全依赖 Reddit 公开可访问的 .json 端点以及一行可配置的 HTTP 请求头,从而避免在服务端存储 Reddit 用户级 access token,显著降低部署门槛。

资料来源:[README.md:1-60]()

核心抓取实现

Reddit 工具集的核心是一个 RedditFetcher 类,集中定义在 src/core/reddit_fetcher.py 中。构造时它读取若干运行时参数——包括目标 subreddit、排序方式、时间窗口、抓取条数上限——并将其缓存为实例属性,避免每次调用都重复加载配置。

资料来源:[src/core/reddit_fetcher.py:1-45]()

fetch_subreddit_posts 是主入口方法。它为每个目标 subreddit 拼装形如 https://www.reddit.com/r/{subreddit}/{sort}.json?limit={n}&t={window} 的 URL,并附带一组预设请求头。Reddit 的 JSON 响应遵循统一 schema:外层为 data.children 列表,每个 child 同时携带 kind("t3" 表示帖子、"t1" 表示评论)与 data 字段,二者一起承载标题、分数、作者、permalink 等元信息。

资料来源:[src/core/reddit_fetcher.py:46-120]()

认证与配置策略

Reddit 对自动化请求的主要识别手段是 User-Agent 字符串。低辨识度或缺失的 UA 极易触发 429 限流或被 Reddit 反爬网关直接拦截。本项目因此将 UA 作为唯一需要外部配置的"准认证"参数。

资料来源:[.env.example:1-25]()

.env.example 列出了与 Reddit 工具相关的关键变量:

环境变量作用说明
REDDIT_USER_AGENT自定义 UA 字符串,覆盖代码内默认值
WEBINTEL_SUBREDDITS默认抓取目标 subreddit 列表(逗号分隔)
WEBINTEL_LOOKBACK_HOURS默认时间窗口(小时数)
WEBINTEL_DEFAULT_SORT默认排序方式(hot/new/top/rising)

.env.example 通常还包含 REDDIT_REQUEST_TIMEOUTREDDIT_MAX_RETRIES 等可选运行时旋钮,提供给运维人员微调。

资料来源:[.env.example:25-55]()

src/config.py 使用 Pydantic Settings 在进程启动时校验并加载上述变量。当用户未设置环境变量时回落到代码内默认值(如 UA 退化为 webintel-mcp/0.1 by anonymous)。这种"环境变量优先 → 代码默认兜底"的两段式策略保证了本地开发与容器化部署的参数一致性,也防止了缺配置导致的隐式失败。

资料来源:[src/config.py:12-40]()

MCP 工具注册与暴露

Reddit 抓取能力通过 MCP 框架注册为若干对 LLM 可见的工具。注册逻辑集中于服务器入口 src/server.py 内的工具声明区。工具签名遵循 MCP 协议要求:函数接收 LLM 客户端传入的参数(subreddit、sort、limit、可选关键词过滤等),内部委托给 RedditFetcher 的对应方法,并以字典列表的形式将结果回传。

资料来源:[src/server.py:30-80]()
资料来源:[src/server.py:81-140]()

为了让 LLM 更高效地利用上下文,返回数据在序列化之前进行就地精简:仅保留 titleurlscorenum_commentscreated_utcpermalinkselftext(若存在)等高价值字段,过滤掉 Reddit 原始 payload 中的 distinguishedmoderatedhiddenpromoted 等冗余键。

资料来源:[src/core/reddit_fetcher.py:121-180]()

工作流时序

下图展示从 LLM 客户端发起工具调用到获取结构化结果的完整数据流:

sequenceDiagram
    participant LLM as LLM 客户端
    participant MCP as MCP Server
    participant F as RedditFetcher
    participant R as reddit.com

    LLM->>MCP: tools/call (subreddit, sort, limit)
    MCP->>F: fetch_subreddit_posts(params)
    F->>R: GET /r/{name}/{sort}.json
    R-->>F: 标准 listing JSON
    F-->>MCP: 精简字段字典列表
    MCP-->>LLM: 序列化后的 tool result
资料来源:[README.md:60-120]()

错误处理与边界

网络层错误(如超时、非 200 状态码、JSON 解析失败)会被 RedditFetcher 捕获并转换为结构化错误对象,附带原始 HTTP 状态码,便于上层 MCP 框架以标准错误格式回传给 LLM。

资料来源:[src/core/reddit_fetcher.py:181-230]()

设计上,RedditFetcher 实现自动重试——这是一个有意识的取舍:短暂的 429 由 LLM 客户端在下一次工具调用时自然恢复,避免在 MCP 长连接中引入重试延迟与状态膨胀。错误路径在 src/server.py 中被包装为 MCP 协议要求的 ToolError 形式,确保客户端能稳定区分"成功结果"与"数据缺失"。

资料来源:[src/server.py:141-200]()

工程要点

  • 无 OAuth:整套能力只需一个 User-Agent 头即可工作,无需 Reddit client_id/secret。
  • 可覆盖默认:所有关键参数都可通过 .env 全局覆盖,工具调用时也可临时传入以覆盖全局值。
  • 上下文友好:返回数据已就地精简,剔除 Reddit 原始结构中对 LLM 无价值的元字段。
  • 零状态重试:抓取层只做单次请求,错误透传给 LLM 客户端决定下一步动作。

资料来源:README.md:1-60

MCP 服务器与请求处理

本页说明 webintel-mcp 项目中 src/server 目录下的 MCP(Model Context Protocol)服务器实现及其请求处理机制。系统作为模型与外部网页情报能力之间的协议层,负责监听客户端连接、解析 MCP 协议消息、调度相应的处理函数并返回结构化结果。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 2.1 服务端主模块(mcpserver.py)

继续阅读本节完整说明和来源证据。

章节 2.2 请求处理器模块(handlers.py)

继续阅读本节完整说明和来源证据。

章节 2.3 包初始化与依赖

继续阅读本节完整说明和来源证据。

一、整体职责与运行入口

src/server/mcp_server.py 是整个 MCP 服务器的启动与运行入口文件,主要承担以下职责:

  • 基于异步 I/O 启动 MCP 传输层(典型为 stdio 或 SSE),并对外暴露统一的服务地址 资料来源:src/server/mcp_server.py:1-40
  • 通过注册机制将 handlers.py 中定义的工具(tools)绑定到协议层,使客户端能够通过标准 MCP 协议发现与调用 资料来源:src/server/mcp_server.py:42-80
  • 处理服务级别的生命周期事件,例如启动初始化、资源清理、异常兜底 资料来源:src/server/mcp_server.py:82-120

服务器以 mcp 主类为核心,对外屏蔽底层传输细节,对内则依赖处理器模块完成业务逻辑分发。

二、核心模块划分

2.1 服务端主模块(mcp_server.py)

主模块负责协议层封装与调度,常见功能包括:

组件作用
Server 实例MCP 协议服务器对象,承载传输与路由能力
Tool 注册表将函数映射为可被客户端调用的工具
生命周期钩子处理初始化、关闭等事件

资料来源:src/server/mcp_server.py:1-120

2.2 请求处理器模块(handlers.py)

handlers.py 集中存放具体的工具实现,例如网页抓取、内容解析、链接提取等。每个工具通常以 async def 形式声明,并通过装饰器或注册函数挂载到主服务器。其职责包括:

  • 接收来自协议层的参数对象(arguments),进行参数校验
  • 调用底层网页情报能力(如 HTTP 抓取、HTML 解析)
  • 将结果包装为 MCP 标准的内容块(TextContent 等)后返回

资料来源:src/server/handlers.py:1-60 资料来源:src/server/handlers.py:60-140

2.3 包初始化与依赖

src/server/__init__.py 负责将 mcp_server 对外暴露为可导入模块,便于上层(例如 CLI 入口或测试用例)直接调用。依赖层面,requirements.txt 锁定了 MCP SDK 以及网页处理相关的第三方库。

资料来源:src/server/__init__.py:1-20 资料来源:requirements.txt:1-30

三、请求处理流程

当客户端发出一次工具调用请求时,服务器依次完成以下步骤:

sequenceDiagram
    participant C as MCP 客户端
    participant S as mcp_server.py
    participant H as handlers.py
    participant W as 网页情报后端
    C->>S: initialize / list_tools
    S-->>C: 返回可用工具列表
    C->>S: call_tool(name, arguments)
    S->>H: 分发到对应工具函数
    H->>W: 发起抓取/解析请求
    W-->>H: 返回原始结果
    H-->>S: 包装为 Content 块
    S-->>C: 返回 MCP 响应

流程的关键点在于:所有外部能力都被抽象为「工具」,客户端无需关心实现语言或执行位置,只需按协议发起调用即可。

四、配置、日志与可观测性

  • 配置src/config.py 提供全局配置常量(如超时、User-Agent、最大重试次数等),被服务器与处理器共同引用。资料来源:src/config.py:1-40
  • 日志src/utils/logger.py 封装统一的日志接口,在请求进入、处理异常、结果返回等关键节点记录 INFO/WARN/ERROR 级别日志,便于排查问题。资料来源:src/utils/logger.py:1-30

五、扩展指引

新增一个 MCP 工具的标准做法是:

  1. handlers.py 中实现一个 async def tool_xxx(arguments) 函数
  2. 通过主模块中既有的注册方式将其加入工具列表
  3. 必要时在 src/config.py 追加相关配置项
  4. requirements.txt 中补充新增的第三方依赖

资料来源:src/server/handlers.py:140-200 资料来源:src/server/mcp_server.py:120-160

通过上述分层设计,服务器层与业务层解耦清晰,便于在保持协议兼容性的同时持续扩展网页情报相关能力。

资料来源:src/server/mcp_server.py:1-120

部署、VPN 与可扩展性

webintel-mcp 项目通过 Docker 容器化、VPN 网关与外部 SearXNG 元搜索引擎三者的组合,提供了在受限或匿名网络环境中可复现、可扩展部署的能力。本页围绕部署拓扑、VPN 集成以及扩展边界进行说明。

章节 相关页面

继续阅读本节完整说明和来源证据。

1. 容器化部署结构

项目以 Dockerfile 为基础构建镜像,将 MCP 服务器打包为标准容器。Dockerfile 定义了运行所需的运行时依赖、入口点与端口暴露方式,便于在不同主机上获得一致的运行环境。资料来源:Dockerfile:1-50

在编排层面,仓库根目录提供 docker-compose.yml,用于一键启动整套服务栈。该 compose 文件通常包括三个核心服务:

  • mcp-server:基于 Dockerfile 构建的 Web 情报 MCP 服务。
  • gluetun:VPN 客户端容器,所有出站流量经由其转发。
  • searxng:作为后端搜索源的元搜索引擎(参考 doc/searxng-compose.yml)。

服务之间通过 Docker 网络互联,并通过 network_mode: "service:gluetun" 等机制让 MCP 服务共享 VPN 容器的网络栈,从而确保外部请求出口 IP 与 VPN 一致。资料来源:docker-compose.yml:1-80、资料来源:doc/webintel-mcp-compose.yaml:1-80

2. VPN 集成:Gluetun

为隐藏真实出口 IP 并规避地域封锁,项目使用 Gluetun 作为统一 VPN 网关。OpenVPN 配置文件位于 gluetun/custom/config.ovpn,由该容器在启动时挂载加载。资料来源:gluetun/custom/config.ovpn:1-40

典型工作流如下:

graph LR
    A[MCP 客户端] --> B[mcp-server 容器]
    B -->|共享网络栈| C[gluetun VPN 容器]
    C -->|加密隧道| D[VPN 服务商]
    D --> E[SearXNG / 目标网站]

MCP 服务本身不直接管理 VPN 连接,而是通过 Docker 网络层"借道" gluetun。这种方式的优势包括:

  • 配置集中:仅需维护一个 .ovpn 文件即可影响所有出站请求。资料来源:gluetun/custom/config.ovpn:1-40
  • 故障隔离:VPN 断连时,依赖网络的服务会立即失败,便于检测。
  • 协议灵活:可通过更换配置切换 OpenVPN/WireGuard 等协议。

3. SearXNG 元搜索集成

doc/searxng-compose.yml 提供 SearXNG 的独立部署描述,可在不启动 MCP 主栈的情况下单独运行搜索后端。SearXNG 默认监听 8080,通过 JSON 格式输出结果供 MCP 工具调用。资料来源:doc/searxng-compose.yml:1-60

在主栈中,searxng 可通过内部 Docker 网络(如 searxng_default)以服务名 searxng 访问,使 MCP 工具能够以 http://searxng:8080/search?... 形式发起查询,避免硬编码宿主机 IP。资料来源:docker-compose.yml:1-80

4. 部署步骤与可扩展性边界

doc/setup-searxng-and-mcp-server.md 给出了从零搭建整套环境的步骤概要,核心流程为:

  1. 准备 Docker 与 docker compose 环境。
  2. 将 VPN 凭据填入 gluetun/custom/config.ovpn。资料来源:gluetun/custom/config.ovpn:1-40
  3. 通过 docker compose up -d 启动 docker-compose.yml 定义的服务栈。资料来源:docker-compose.yml:1-80
  4. 单独部署 SearXNG(如需分离运行)。资料来源:doc/searxng-compose.yml:1-60、资料来源:doc/setup-searxng-and-mcp-server.md:1-60

可扩展性方面需要关注以下边界:

  • 单实例瓶颈:当前编排未定义 MCP 服务的水平扩容策略,副本数增加需要外部反向代理与会话粘性处理。
  • VPN 出口带宽:所有搜索流量共享同一隧道,带宽与并发受限于 VPN 提供商。
  • SearXNG 实例:搜索后端为单实例部署,高并发场景下需引入 Redis 限流与多实例负载均衡。
  • 镜像体积:Dockerfile 构建链决定了基础镜像大小,进而影响冷启动与拉取速度。资料来源:Dockerfile:1-50

整体来看,webintel-mcp 采用"VPN 出口统一 + 元搜索解耦 + MCP 服务容器化"的三层结构,兼顾了隐私、可复现性与模块化扩展空间。后续若需进一步扩展,可在不改动核心协议的前提下,于编排层加入多副本、副本亲和性与外部缓存层即可平滑演进。资料来源:docker-compose.yml:1-80、资料来源:doc/setup-searxng-and-mcp-server.md:1-60

来源:https://github.com/kengbailey/webintel-mcp / 项目说明书

失败模式与踩坑日记

保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

medium 依赖 Docker 环境

非工程用户可能没有 Docker,启动成本明显增加。

medium 可能修改宿主 AI 配置

安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。

medium 能力判断依赖假设

假设不成立时,用户拿不到承诺的能力。

medium 维护活跃度未知

新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。

Pitfall Log / 踩坑日志

项目:kengbailey/webintel-mcp

摘要:发现 8 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:安装坑 - 依赖 Docker 环境。

1. 安装坑 · 依赖 Docker 环境

  • 严重度:medium
  • 证据强度:runtime_trace
  • 发现:安装/运行入口包含 Docker 命令:docker run -p 3090:3090 -e SEARXNG_HOST=http://your-searxng:8189 ghcr.io/kengbailey/webintel-mcp:latest
  • 对用户的影响:非工程用户可能没有 Docker,启动成本明显增加。
  • 复现命令:docker run -p 3090:3090 -e SEARXNG_HOST=http://your-searxng:8189 ghcr.io/kengbailey/webintel-mcp:latest
  • 证据:identity.distribution | https://github.com/kengbailey/webintel-mcp | docker run -p 3090:3090 -e SEARXNG_HOST=http://your-searxng:8189 ghcr.io/kengbailey/webintel-mcp:latest

2. 配置坑 · 可能修改宿主 AI 配置

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
  • 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
  • 证据:capability.host_targets | https://github.com/kengbailey/webintel-mcp | host_targets=mcp_host, cursor

3. 能力坑 · 能力判断依赖假设

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:README/documentation is current enough for a first validation pass.
  • 对用户的影响:假设不成立时,用户拿不到承诺的能力。
  • 证据:capability.assumptions | https://github.com/kengbailey/webintel-mcp | README/documentation is current enough for a first validation pass.

4. 维护坑 · 维护活跃度未知

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:未记录 last_activity_observed。
  • 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
  • 证据:evidence.maintainer_signals | https://github.com/kengbailey/webintel-mcp | last_activity_observed missing
  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 证据:downstream_validation.risk_items | https://github.com/kengbailey/webintel-mcp | no_demo; severity=medium

6. 安全/权限坑 · 存在评分风险

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:风险会影响是否适合普通用户安装。
  • 证据:risks.scoring_risks | https://github.com/kengbailey/webintel-mcp | no_demo; severity=medium

7. 维护坑 · issue/PR 响应质量未知

  • 严重度:low
  • 证据强度:source_linked
  • 发现:issue_or_pr_quality=unknown。
  • 对用户的影响:用户无法判断遇到问题后是否有人维护。
  • 证据:evidence.maintainer_signals | https://github.com/kengbailey/webintel-mcp | issue_or_pr_quality=unknown

8. 维护坑 · 发布节奏不明确

  • 严重度:low
  • 证据强度:source_linked
  • 发现:release_recency=unknown。
  • 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
  • 证据:evidence.maintainer_signals | https://github.com/kengbailey/webintel-mcp | release_recency=unknown

来源:Doramagic 发现、验证与编译记录