[控场AI]
· 9 分钟阅读· 4,936 字

Python 实战:从零搭建 MCP 服务器,让 LLM 获取实时网页数据

Python 实战:从零搭建 MCP 服务器,让 LLM 获取实时网页数据

用 FastMCP 构建自定义 MCP 服务器,让 AI 智能体能实时抓取网页并给出有据可查的回答。

本文演示了如何从零搭建一个 MCP 服务器,使 Claude Code 等 AI 智能体能够突破训练数据截止日期的限制,主动抓取完整渲染的网页来回答实时问题。核心技术栈是 FastMCP + Oxylabs 渲染 API,工作流遵循「描述→生成→审查→优化」四步,借助 Claude Code 自动生成服务器代码。文章重点强调了几个容易忽视的细节:工具函数的 docstring 直接决定智能体是否会调用该工具;本地 STDIO 传输模式下严禁向标准输出打印内容;配置 Claude Desktop 时必须使用 UV 的绝对路径。此外文章还梳理了 STDIO 与 Streamable HTTP 两种传输方式的适用场景,并为不想自己写代码的开发者提供了官方 Oxylabs MCP 服务器和 Agent Skills 两条开箱即用的替代路径。

大模型最大的短板之一,是它只知道训练数据截止前的世界。问它一个需要实时网络信息的问题——比如某个开源项目的最新版本改了什么——它要么编造答案,要么坦白自己不知道。本教程由 Oxylabs 的 Arnaz 演示,核心思路是构建一个自定义的 MCP 服务器,让 AI 智能体能够主动抓取完整渲染的网页,再基于真实内容给出带引用来源的可靠回答。

什么是 MCP:AI 的「USB-C 接口」

MCP 全称 Model Context Protocol(模型上下文协议),是一个开放标准,规定了 AI 智能体如何连接外部工具、数据源和服务。作者给出了一个贴切的比喻:可以把它想象成 AI 的 USB-C 接口——一个标准化连接,无论两端是什么智能体、什么工具,都能通用。

理解这套体系需要分清三个角色:主机(Host) 是正在运行的 AI 客户端,比如 Claude Code、Cursor、VS Code Copilot;MCP 服务器 是一个进程,它对外暴露一个或多个工具;工具(Tool) 则是实际的能力,在本教程里就是一个「获取渲染后网页」的函数。

关键价值在于通用性。MCP 并非只服务于某一家产品,Claude Code、Claude Desktop、Cursor、VS Code 中的 GitHub Copilot,以及 OpenAI 的智能体都支持它。你只需要构建一次 MCP 服务器,它就能在所有兼容客户端中复用。

MCP 由 Anthropic 于 2024 年 11 月发布并开源,设计动机是解决 AI 工具集成的「M×N 问题」:在没有统一标准的情况下,M 个 AI 客户端要对接 N 个外部服务,就需要写 M×N 套定制集成代码。MCP 把这个问题降维成 M+N——每个客户端只需实现一次 MCP 协议,每个服务只需暴露一次 MCP 接口,双方就能自动互通。协议基于 JSON-RPC 2.0,支持工具调用(Tool)、资源读取(Resource)和提示词模板(Prompt)三种原语,服务器与客户端之间既可以通过本地进程的标准输入输出(STDIO)通信,也可以通过 HTTP 进行远程调用。

环境准备与项目搭建

开始前需要安装两样东西:Node.js(用于运行 Claude Code)以及 Claude Code 本身——后者是 Anthropic 推出的 Agent 式编程工具,运行在终端里,能理解项目、替你编写编辑和运行代码。

搭建流程相当标准:在 VS Code 里创建项目文件夹并打开终端,建立并激活 Python 虚拟环境,然后安装三个核心包:

  • FastMCP:用来构建 MCP 服务器的框架
  • requests:用于向 Oxylabs API 发起 HTTP 调用
  • python-dotenv:从 .env 文件加载凭证

接着在项目根目录创建一个 .env 文件,写入三个变量:你的 Anthropic API Key,以及 Oxylabs 的用户名和密码。把凭证放进这里有两个好处——项目分享更安全,也不会意外被提交进版本控制。

用 Claude Code 生成服务器核心逻辑

既然已经有了 Claude Code,服务器代码本身就交给它来写。工作流可以概括为四步:描述 → 生成 → 审查 → 优化。你用自然语言描述需求,Claude Code 读取请求、规划实现方案,然后把代码写入文件。

Claude Code 读取请求,规划实现方案,然后写入文件

生成后千万别直接运行,先通读 server.py。审查不仅是安全需要,也是理解 MCP 服务器结构的最好方式。代码顶部是导入语句,接着用 FastMCP 初始化服务器,核心是一个带 @mcp.tool 装饰器的函数。

这个装饰器对应 MCP 服务器能暴露的三样东西之一:工具(Tool) 是智能体调用以执行操作的功能,资源(Resource) 是智能体可访问的只读数据,提示词(Prompt) 则是可复用的指令模板。本例中我们只需要一个抓取网页的工具。

文档字符串比你想象的更重要

scrape_url 函数上的 docstring(文档字符串)看似不起眼,实则至关重要。Claude 每次决定是否调用某个工具时,都会读取它的文档字符串。如果写得太弱或根本没写,这个工具就永远不会被调用——哪怕它运行得完美无缺。

一个强有力的 docstring 应当准确告诉智能体:这个工具做什么、什么时候该用它。如果 Claude 生成的描述过于单薄,这往往是继续之前唯一值得手动打磨的地方。

另外要检查发往 Oxylabs API 的请求体:source 应设为 universal,url 需正确传入,render 设为 html。render 参数告诉 Oxylabs 在抓取前先用真实浏览器运行页面,否则 JavaScript 密集型的页面会返回空内容。

用 MCP Inspector 独立验证

接入客户端之前,先验证服务器能否独立运行。MCP Inspector 是一个基于浏览器的调试工具,可以连接任何 MCP 服务器并让你手动调用其工具。

在终端运行对应命令后,Inspector 会自动在浏览器中打开。连接时需要输入启动服务器的命令,也就是 python server.py。连接成功后就能看到服务器暴露的工具列表。

连接成功后就能看到服务器拥有的工具

选择 scrape_url,输入一个真实公开网址(教程用的是 FastMCP 文档页),运行后若一切正常,就会返回该页面的渲染 HTML。

这里有一个安全提醒:如果你新安装 MCP Inspector,务必确认版本在 0.14.1 或更高,旧版本存在一个已被修补的已知安全问题。

MCP Inspector 本质上是一个面向开发者的调试代理:它在本地启动一个轻量 Web 界面,通过 STDIO 或 HTTP 连接你指定的 MCP 服务器,然后让你在浏览器里手动构造工具调用请求并查看原始响应。这与单元测试的思路一致——在把服务器接入真实 AI 客户端之前,先用一个可控的测试环境确认每个工具的输入输出行为符合预期。Inspector 会显示完整的 JSON-RPC 请求和响应报文,方便排查参数格式错误或认证问题,比直接在 Claude 里反复触发要高效得多。

接入 Claude Code 与 Claude Desktop

验证通过后,用注册命令把服务器加入 Claude Code 配置,它会把服务器注册为 scraping-mcp 并告知如何启动。随后在项目文件夹启动 Claude Code,问它一个明显需要实时数据的问题——比如查 FastMCP 的更新日志、告诉我们最新版本改了什么。

Claude Code 会自行规划方案、搜索正确网址,当需要真实页面内容时,它会自动通过 MCP 服务器调用 scrape_url。整个过程不需要人工提示,智能体自己做出了决策。这正是 MCP 在真实智能体工作流中运作的样子:工具注册一次,需要时精准调用。

同一个服务器也能配合 Claude Desktop 使用,只需改一个配置文件。你需要先拿到机器上 UV 可执行文件的绝对路径——在 macOS 或 Linux 上运行 which uv,Windows 上运行 where uv,复制输出结果。

在 macOS/Linux 上运行 which uv,Windows 上运行 where uv

配置文件必须用精确的绝对路径,相对路径会导致服务器加载失败。随后在 Claude Desktop 的「设置 → 开发者 → 编辑配置」中打开 claude_desktop_config.json,在 mcpServers 下新增一个条目,命令使用 UV 的绝对路径,参数指向 server.py,并在 env 块中填入 Oxylabs 凭据。

保存后必须完全退出 Claude Desktop(不是关窗口):Windows 上右键系统托盘图标选退出,macOS 上按 Command+Q。重启后在聊天界面看到加号图标,即说明服务器已正确加载。

一个容易踩的坑:不要向标准输出打印

本教程构建的服务器使用 STDIO 传输方式,作为本地进程运行,通过标准输入输出与客户端通信。Claude Desktop 与服务器之间走的是 JSON-RPC 协议,因此绝不要在代码里使用 print() 向标准输出写内容——那会破坏数据流并中断连接。需要调试时,请改用日志文件或标准错误(stderr)。

本地 vs 远程:传输方式的选择

STDIO 适合在本地机器运行,是 Claude Desktop 和 Claude Code 调用本地服务器的最优选择。但如果你想远程部署 MCP 服务器、与团队共享或在云端运行,则应考虑改用 Streamable HTTP:服务器监听一个 URL,任何兼容客户端都能通过网络连接。

作者特别指出,Streamable HTTP 是官方推荐的远程传输方式,因为旧的 SSE 传输正在被逐步淘汰。

旧的 SSE 传输正在被逐步淘汰

Streamable HTTP 是 MCP 规范在 2025 年修订版中引入的新传输方式,用来取代早期的 SSE(Server-Sent Events)方案。SSE 的问题在于它是单向推送协议,MCP 需要双向通信时不得不维护两条独立连接,增加了实现复杂度和状态管理负担。Streamable HTTP 改为在单个 HTTP 连接上通过流式响应实现双向交互,既兼容标准的反向代理和负载均衡基础设施,也更容易做横向扩展。如果你的 MCP 服务器需要给多人或多个自动化流程共享,Streamable HTTP 是目前唯一被官方规范持续维护的远程传输选项。

不想自己写代码?三条路径对应三种场景

教程收尾时提醒:如果你的目标专门是网页抓取,可能根本不需要从零构建。作者给出了三条清晰路径:

  1. 构建自定义工具(本教程做法):适合想理解其工作原理、需要完全掌控实现的场景。
  2. 官方 Oxylabs MCP 服务器:只需一个配置块就能接入 Claude Desktop 或 Claude Code,无需 Python 文件、无需 FastMCP、无需自定义代码。适合现在就要在智能体中获取实时数据、且不需要定制实现的用户。
  3. 智能体技能(Agent Skills):这是完全不同的格式——轻量级 Markdown 指令文件,智能体真正需要时才加载。相比会占用上下文窗口的 MCP 工具架构,技能能完全避免这一开销。适合经常在 Claude Code 中做抓取、又想保持上下文精简的场景。GitHub 上的 Oxylabs Agent Skills 仓库覆盖了网页抓取 API、代理和无头浏览器等完整能力。

小结

这篇教程的价值不只在于「跑通一个抓取工具」,更在于把 MCP 的完整工作流讲清楚了:从协议概念、框架选型、docstring 的隐性重要性,到独立调试、多客户端接入,再到传输方式的权衡。对想要给自己的 AI 智能体加上「实时上网」能力的开发者来说,这是一条可直接复用的实践路径。

#MCP服务器#模型上下文协议#FastMCP#Claude Code#网页抓取#Python LLM 实时数据#Oxylabs#AI 智能体工具
分享:

相关推荐