MCP Model Context Protocol

💡 本文核心:在 AI Agent 和大语言模型(LLM)应用飞速发展的今天,我们正面临一个“巴别塔”困境:每个应用、每个数据源都在用自己独特的方式与模型交互,导致了巨大的集成成本和生态碎片化。模型上下文协议(Model Context Protocol, MCP) 正是为解决这一问题而生。本文将从零开始,带你深入理解 MCP 的核心设计理念,并通过一个完整的实战案例,手把手教你构建自己的 MCP 服务器,并将其接入 Claude 生态,真正体验到“一次构建,处处可用”的魅力。


一、为什么我们需要 MCP?AI 应用的“连接器”危机

想象一下,你正在开发一个强大的 AI 编程助手。你希望它能:

  • 读取你本地项目的文件结构和代码;
  • 连接到你的 GitHub 仓库,查看最新的 Issues 和 PR;
  • 访问公司的 Jira,了解当前的任务进度;
  • 查询内部的数据库,获取相关的业务数据。

在没有统一标准的情况下,你需要为每一个外部系统编写专门的适配器(Adapter)。每个适配器都要处理不同的认证方式、数据格式和 API 风格。这不仅工作量巨大,而且极度脆弱——任何一个外部系统的 API 变更都可能导致你的 Agent “失忆”或“失能”。

MCP 的出现,就是为了终结这种混乱。

Anthropic 将其比作 AI 应用的“USB-C”端口 [1]。正如 USB-C 用一个标准化的接口统一了充电、数据传输和视频输出,MCP 也旨在用一个开放、统一的协议,来标准化 AI 应用与外部世界(数据源、工具、工作流)的连接方式。

MCP 的核心价值

  • 对于开发者:极大降低了构建和集成 AI 应用的复杂度和时间成本。
  • 对于 AI 应用:可以轻松接入一个不断增长的、由第三方提供的工具和数据生态系统,从而增强自身能力。
  • 对于最终用户:可以获得更强大、更个性化的 AI 体验,因为 Agent 能够安全、可靠地访问用户授权的数据并代表用户执行操作。

二、MCP 核心概念拆解

要理解 MCP,我们需要从它的架构、分层和三大核心“原语”入手。

1. 客户端-服务器架构

MCP 遵循一个清晰的客户端-服务器模型,其中包含三个关键角色 [2]:

  • MCP Host (主机):通常是 AI 应用本身,例如 Claude Desktop、VS Code 插件或你自己的聊天机器人应用。主机负责管理一个或多个 MCP 客户端。
  • MCP Client (客户端):由主机为每一个要连接的服务器所创建的实例。它负责维护与特定服务器的连接,并为上层的主机获取上下文信息。
  • MCP Server (服务器):一个独立的程序,它将外部系统(如文件系统、数据库、SaaS API)的能力通过 MCP 协议暴露出来。

MCP 架构图

这种架构的优势在于解耦。AI 应用(Host)本身无需关心如何与五花八门的外部系统打交道,它只需要与标准化的 MCP Client 对话。而 MCP Server 则将特定系统的复杂性封装起来,对外提供统一的 MCP 接口。

2. 数据层与传输层

MCP 的协议设计分为两层,实现了内容与通道的分离:

层级 作用 协议/技术
数据层 (Data Layer) 定义“聊什么”。它规定了客户端和服务器之间通信的消息结构和语义,基于 JSON-RPC 2.0。这包括连接的生命周期管理(初始化、能力协商、关闭)以及核心原语的交互。 JSON-RPC 2.0
传输层 (Transport Layer) 定义“怎么聊”。它负责管理实际的通信通道和认证。MCP 目前支持两种主要的传输方式。 stdio (本地), HTTP+SSE (远程)

两种传输方式

  • Stdio (标准输入/输出):用于本地进程间通信。当 MCP Server 和 Client 在同一台机器上运行时,这是最高效的方式,没有网络开销。例如,VS Code 插件启动一个本地的 MCP Server 进程。
  • Streamable HTTP (HTTP + SSE):用于远程通信。客户端通过 HTTP POST 发送请求,服务器可以通过 Server-Sent Events (SSE) 推送实时通知。这种方式使得 AI 应用可以连接到云端的 MCP 服务器,并支持 OAuth、API Key 等标准认证方法。

3. 三大核心原语 (Primitives)

MCP Server 通过三种核心能力(或称“原语”)向外提供上下文和功能 [3]:

原语 作用 类比 示例
Tools (工具) 可执行的动作。允许 LLM 在用户批准后调用外部函数或 API。 一个函数库 github/create_issue, jira/get_ticket_status
Resources (资源) 可供读取的数据。为 LLM 提供类似文件的上下文信息,可以是静态的,也可以是动态更新的。 一个文件系统 file:///path/to/code.py, db://sales/quarterly_report
Prompts (提示) 预定义的工作流。为用户提供结构化的、可复用的任务模板,引导用户与模型进行更高效的交互。 一个快捷指令 “帮我总结这篇 PDF 的核心观点”、“起草一封项目周报”

这三者共同构成了 MCP 的能力基石。一个设计良好的 MCP Server 会根据其所代理的外部系统的特点,合理地将功能暴露为这三种原语的组合。


三、实战:从零构建一个天气查询 MCP Server

理论讲完了,让我们动手实践。我们将使用 Python 和官方的 fastmcp 库,构建一个简单的天气查询服务器。这个服务器将暴露两个工具:get_forecast(获取天气预报)和 get_alerts(获取天气警报)。

1. 环境准备

首先,确保你安装了 Python 3.9+,然后安装必要的库:

# 安装 FastMCP 服务器框架和 HTTP 客户端
pip install fastmcp httpx

2. 编写 Server 代码

创建一个名为 weather_server.py 的文件,并填入以下代码。我们这里将使用免费的美国国家气象局 (NWS) API 作为数据源。

# weather_server.py

from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP

# 1. 初始化 FastMCP 服务器,并给它一个唯一的名字
mcp = FastMCP(
    name="weather_server",
    title="实时天气查询服务",
    description="一个提供实时天气预报和警报的 MCP 服务器。"
)

# --- API 常量和辅助函数 ---
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "mcp-weather-server/1.0 (my-contact@example.com)" # 使用 NWS API 需要一个 User-Agent

async def make_nws_request(url: str) -> dict[str, Any] | None:
    """一个带错误处理的 NWS API 请求函数"""
    headers = {"User-Agent": USER_AGENT, "Accept": "application/geo+json"}
    async with httpx.AsyncClient() as client:
        try:
            response = await client.get(url, headers=headers, timeout=10.0)
            response.raise_for_status() # 如果请求失败 (如 404, 500) 则抛出异常
            return response.json()
        except httpx.HTTPStatusError as e:
            # 可以选择在这里记录更详细的日志
            print(f"API request failed: {e}")
            return None
        except Exception as e:
            print(f"An unexpected error occurred: {e}")
            return None

# --- 工具定义 ---

# 2. 使用 @mcp.tool() 装饰器来定义一个工具
#    函数名、文档字符串和类型注解会被自动解析为 MCP 的 Tool 定义
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
    """根据经纬度获取未来的天气预报。

    Args:
        latitude: 地点的纬度
        longitude: 地点的经度
    """
    # NWS API 需要先通过经纬度获取预报的 URL
    points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
    points_data = await make_nws_request(points_url)
    if not points_data or "properties" not in points_data or "forecast" not in points_data["properties"]:
        return "无法获取该地点的预报信息。请检查经纬度是否正确。"

    forecast_url = points_data["properties"]["forecast"]
    forecast_data = await make_nws_request(forecast_url)
    if not forecast_data or "properties" not in forecast_data or "periods" not in forecast_data["properties"]:
        return "无法获取详细的预报数据。"

    # 格式化输出,使其更易于 LLM 理解
    periods = forecast_data["properties"]["periods"]
    forecasts = []
    for period in periods[:4]: # 只返回最近的几个预报
        forecast = f"""- **{period['name']}**: {period['detailedForecast']}
  - 温度: {period['temperature']}°{period['temperatureUnit']}
  - 风速: {period['windSpeed']} {period['windDirection']}"""
        forecasts.append(forecast)

    return "\n".join(forecasts)

@mcp.tool()
async def get_alerts(state_code: str) -> str:
    """获取美国某个州当前生效的恶劣天气警报。

    Args:
        state_code: 美国的两字母州代码 (例如: CA, NY, TX)
    """
    url = f"{NWS_API_BASE}/alerts/active/area/{state_code.upper()}"
    data = await make_nws_request(url)
    if not data or "features" not in data:
        return f"无法获取 {state_code} 的天气警报。"

    if not data["features"]:
        return f"{state_code} 当前没有生效的恶劣天气警报。"

    alerts = []
    for feature in data["features"][:3]: # 最多返回3个警报
        props = feature["properties"]
        alert = f"""- **事件**: {props.get('event', 'N/A')}
  - **区域**: {props.get('areaDesc', 'N/A')}
  - **严重性**: {props.get('severity', 'N/A')}
  - **描述**: {props.get('description', 'N/A')}"""
        alerts.append(alert)

    return "\n---\n".join(alerts)


# 3. 定义主函数,用于启动服务器
if __name__ == "__main__":
    # 使用 stdio 传输层,适合本地测试
    mcp.run(transport="stdio")

3. 运行与测试

现在,在你的终端中运行这个 Python 脚本:

python weather_server.py

你会看到服务器启动并打印出一些 JSON-RPC 消息。它正在通过标准输入/输出等待客户端的连接和指令。这表明你的 MCP Server 已经成功运行了!


四、接入 AI 应用:以 Claude Desktop 为例

光有服务器还不够,我们需要一个 MCP Host 来消费它的能力。这里我们以 Anthropic 官方的 Claude Desktop 应用为例,演示如何将我们自制的 weather_server 连接进去。

1. 找到 Claude Desktop 的配置文件

Claude Desktop 通过一个 JSON 文件来管理和发现 MCP 服务器。这个文件的位置取决于你的操作系统:

  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

2. 添加本地 Server 配置

打开这个 JSON 文件(如果不存在,就创建一个),并添加以下内容。这段配置告诉 Claude Desktop 如何找到并启动我们的 weather_server.py

{
  "mcp_servers": [
    {
      "name": "local_weather_server",
      "type": "process",
      "enabled": true,
      "command": [
        "python",
        "/path/to/your/weather_server.py" // ‼️ 重要:替换成你的 weather_server.py 的绝对路径
      ]
    }
  ]
}

关键字段解释

  • name: 服务器的唯一标识符。
  • type: process 表示这是一个本地进程服务器。
  • enabled: true 表示启用这个服务器。
  • command: 一个数组,定义了如何启动服务器进程。第一个元素是可执行程序(python),后续是它的参数(脚本路径)。

3. 重启 Claude Desktop 并开始对话

完全退出并重新启动 Claude Desktop 应用。它只在启动时读取配置文件。

现在,你可以开始向 Claude 提问了!试试下面的问题:

“你好,帮我查一下加州(CA)有什么天气警报吗?”

如果一切配置正确,Claude 会识别出这个任务需要使用工具。它会发现我们通过 MCP 提供的 get_alerts 工具,并向你请求授权调用。在你点击“允许”后,Claude Desktop 会在后台执行 tools/call 请求,我们的 weather_server.py 脚本会接收到请求,调用 NWS API,然后将结果返回给 Claude。最终,Claude 会用自然语言向你总结查询到的天气警报。

你还可以继续提问:

“再帮我看看加州山景城(纬度 37.3861, 经度 -122.0839)未来的天气怎么样?”

这次,Claude 会调用我们的 get_forecast 工具,为你带来精准的天气预报。

恭喜你!你已经成功构建了一个完整的 MCP 应用,打通了从外部数据源到 AI Agent 的端到端链路!


五、MCP 的生态与未来

MCP 不仅仅是一个协议,更是一个正在快速成长的生态系统。目前,社区已经涌现出许多开源的 MCP 服务器,覆盖了从开发工具到日常应用的方方面面:

  • 开发与 DevOps: GitHub, GitLab, Sentry, Datadog, Terraform…
  • 生产力工具: Notion, Slack, Google Calendar, Jira…
  • 数据库: PostgreSQL, MySQL, SQLite…
  • 本地能力: Filesystem, Shell…

你可以在 Awesome MCP ServersMCP Market 等社区资源中发现更多有趣的服务器。

MCP 协议本身也在快速演进。未来的路线图包括了对更复杂工作流的编排、更细粒度的安全控制、以及对多模态数据的更好支持 [4]。

总结

模型上下文协议(MCP)为我们提供了一个强大而优雅的框架,用以解决 AI Agent 与外部世界连接的难题。它通过标准化的客户端-服务器架构、分层协议设计以及“工具、资源、提示”三大核心原语,实现了 AI 应用与外部能力的彻底解耦。

通过本文的实战演练,我们看到,构建一个 MCP 服务器并将其接入现有 AI 应用的门槛其实非常低。这为广大开发者打开了一扇新的大门:我们可以将任何想得到的数据或 API,封装成一个标准的“上下文插件”,即插即用地赋能给强大的语言模型。

AI Agent 的未来,必然是一个互联互通的未来。而 MCP,正是铺设这条信息高速公路的关键基石。


参考文献

[1] Anthropic. (2024, November 25). Introducing the Model Context Protocol. https://www.anthropic.com/news/model-context-protocol
[2] Model Context Protocol. (2025, June 18). Architecture overview. https://modelcontextprotocol.io/docs/learn/architecture
[3] Model Context Protocol. (2025, June 18). Tools Specification. https://modelcontextprotocol.io/specification/2025-06-18/server/tools
[4] Model Context Protocol. (2025, October 31). Roadmap. https://modelcontextprotocol.io/development/roadmap

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐