Model Context Protocol(模型上下文协议) —— 打通大模型与外部世界的标准化桥梁


一、什么是 MCP —— 大模型的 “USB-C 接口”

背景:大模型的能力边界

LLM(大语言模型)在文本生成、代码编写、逻辑推理方面已经非常强大。但它们有一个天生的短板:无法直接访问外部数据、调用外部工具、或与真实世界交互。模型的知识截止于训练数据,缺少实时信息,也无法执行"发一封邮件"、"查一下数据库"这样的操作。

MCP 要解决的问题

此前,开发者若想让 AI 连接外部系统,需要为每个模型、每个平台单独写一套适配层。这就像每种设备都需要一个专属充电口 —— 直到 USB-C 出现。

MCP 就是 AI 世界的 “USB-C 协议”。 它定义了一套标准化的接口规范,让任何 AI 应用(Host)都能以统一的方式与任何外部工具/数据源(Server)通信,彻底告别 N×M 的适配困境。

MCP 由 Anthropic 于 2024 年底开源发布,目前已经成为 AI 生态中增长最快的协议标准之一,被 OpenAI、Google、Microsoft 等主流厂商广泛采纳。

没有 MCP 之前:

模型A --自定义适配层1--> 工具/数据
模型B --自定义适配层2--> 工具/数据
... (M x N 种组合,每次都要重写适配层)

有了 MCP 之后:

任何 Host --[ MCP 协议 / JSON-RPC 2.0 ]--> 任何 Server
(只需实现一次协议,即可无限组合)

二、核心架构:三大角色与通信模型

三大角色

角色 说明
MCP Host AI 应用本身(如 Claude Desktop、WorkBuddy、VS Code 插件)。负责发起连接请求,将 Server 提供的能力注入 LLM 的上下文。
MCP Client 协议客户端,嵌入在 Host 内部。负责与 Server 建立通信通道、发送请求、接收响应,管理连接生命周期。
MCP Server 轻量级服务程序,暴露具体的工具/数据/提示词能力。每个 Server 专注一个领域,通过标准协议对外提供服务。

架构全貌

+-------------------------------------------+
|        LLM(大语言模型)                     |
|        Claude / GPT / DeepSeek             |
+--------------------+----------------------+
                     |
+--------------------+----------------------+
|        MCP Host                            |
|        Claude Desktop / WorkBuddy          |
+--------------------+----------------------+
                     |
+--------------------+----------------------+
|        MCP Client                          |
|        协议编解码 & 连接管理                  |
+--------+-----------+----------+-----------+
         |           |          |  JSON-RPC 2.0
    +----+---+  +----+---+  +---+----+
    | File   |  | DB    |  | API    |  ... 更多 Server
    | Server |  | Server|  | Server |
    +--------+  +-------+  +--------+

通信传输层

MCP 支持两种传输方式:

传输方式 说明 适用场景
stdio 通过标准输入/输出进行 JSON-RPC 消息交换,Client 作为子进程启动 Server 本地工具、CLI 应用
SSE (HTTP) 基于 HTTP + Server-Sent Events,支持远程通信 远程服务、云端部署

设计哲学: 每个 MCP Server 应该是"小而美"的,专注于一个领域。不是一个大而全的巨型 Server,而是像微服务一样,按领域拆分成多个独立的 Server。这样既便于维护,也符合安全最小权限原则。


三、协议细节:JSON-RPC 消息格式与生命周期

消息格式

MCP 使用 JSON-RPC 2.0 作为消息编码协议。所有通信都是 JSON 对象,通过 Request / Response / Notification 三种模式交互。

请求(Request)
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": { "city": "北京" }
  }
}
响应(Response)
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      { "type": "text", "text": "北京当前天气:晴,26°C" }
    ]
  }
}
通知(Notification)—— 无 id,不期待响应
{
  "jsonrpc": "2.0",
  "method": "notifications/initialized"
}

连接生命周期

1. Initialize  -->  2. List Capabilities  -->  3. Invoke  -->  4. Shutdown
   (握手协商)         (能力发现)                 (调用工具)       (优雅关闭)

关键阶段说明:

  • Initialize:Client 发送 initialize 请求,Server 返回自身的能力清单(protocol version、capabilities)
  • Initialized:Client 发送 notifications/initialized 通知,表示握手完成
  • 正常工作:Client 可调用 tools/listtools/callresources/read 等方法
  • 关闭:在 stdio 模式下,关闭进程的 stdin;在 HTTP 模式下,发送 DELETE 或关闭 SSE 流

提示: 在 stdio 模式下,MCP Server 的标准输出完全被 JSON-RPC 消息占用。任何 print() 或日志输出都会破坏协议。调试日志必须输出到 stderr


四、核心概念:Tools / Resources / Prompts 三剑客

MCP Server 通过三种原语向 Host 暴露能力:

1. Tools(工具)—— “让 AI 动手做事”

Tools 是 MCP 最核心的概念。每个 Tool 是一个可由 LLM 调用的函数,有明确的名称、描述和参数 schema。当用户问"帮我查一下北京天气",LLM 会识别出需要调用 get_weather 工具,Host 通过 MCP Client 调用 Server 执行该函数,并把结果返回给 LLM。

# 定义一个 Tool
@server.tool()
async def get_weather(city: str) -> str:
    """获取指定城市的实时天气信息"""
    # ... 调用天气 API
    return f"{city}当前天气:晴,26°C"

2. Resources(资源)—— “让 AI 读取数据”

Resources 是只读的数据源,用 URI 标识。LLM 可以像"打开文件"一样读取资源内容。例如:file://docs/readme.mddb://users/list

3. Prompts(提示词模板)—— “让用户快速上手”

Prompts 是预定义的对话模板,带有参数占位符。用户在 Host 中选择一个 Prompt,填入参数,即可生成结构化的对话。例如:"代码审查"模板,参数为文件路径。

三者对比

概念 类比 方向 典型场景
Tool 函数调用 AI -> Server(读写) 发送邮件、查询天气、操作数据库
Resource 文件读取 AI <- Server(只读) 读取文档、获取配置、查看日志
Prompt 对话模板 User -> AI(输入) 代码审查模板、翻译模板、摘要模板

五、环境准备与工具链

安装 MCP SDK

Anthropic 提供了官方的 Python SDK,一行命令即可安装:

pip install mcp

如果你使用 uv(推荐,更快的包管理器):

uv pip install mcp

# 或者创建独立项目
uv init my-mcp-server
cd my-mcp-server
uv add mcp

推荐的工具链

  • mcp —— Anthropic 官方 Python SDK,提供 ServerToolResource 等装饰器
  • Claude Desktop —— 现成的 MCP Host,用于测试你的 Server
  • MCP Inspector —— 官方调试工具:npx @anthropic-ai/mcp-inspector
  • WorkBuddy / Cursor / Windsurf —— 支持 MCP 的 IDE,直接在编程环境中使用

版本说明: MCP 协议正在快速迭代中,截至 2025 年 7 月,最新稳定版支持 mcp >= 1.0.0。本文代码基于 Python SDK 1.x 版本,建议使用 pip install "mcp>=1.0" 确保兼容性。


六、实战一:从零编写一个 MCP Server

我们来创建一个完整的 MCP Server —— 天气助手,提供两个 Tool:查询天气和获取城市建议。

项目结构

weather-server/
├── server.py          # MCP Server 主程序
├── .env               # API Key 等配置(可选)
└── pyproject.toml     # 项目依赖

编写 Server 代码

#!/usr/bin/env python3
"""
天气查询 MCP Server
提供实时天气查询和城市建议功能
"""
import asyncio
import json
from mcp.server import Server, NotificationOptions
from mcp.server.models import InitializationCapabilities
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent, ImageContent, EmbeddedResource

# 1. 创建 Server 实例
server = Server("weather-server")

# 2. 注册工具列表
@server.list_tools()
async def list_tools() -> list[Tool]:
    """返回此 Server 提供的所有工具列表"""
    return [
        Tool(
            name="get_weather",
            description="获取指定城市的实时天气信息,包括温度、湿度、天气状况",
            inputSchema={
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名称,如 '北京'、'上海'、'深圳'"
                    }
                },
                "required": ["city"]
            }
        ),
        Tool(
            name="suggest_city",
            description="根据用户的偏好推荐适合旅游的城市",
            inputSchema={
                "type": "object",
                "properties": {
                    "preference": {
                        "type": "string",
                        "description": "用户偏好,如 '海滨'、'山景'、'美食'、'历史文化'",
                        "enum": ["海滨", "山景", "美食", "历史文化"]
                    }
                },
                "required": ["preference"]
            }
        )
    ]

# 3. 实现工具调用逻辑
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
    """处理工具调用请求"""

    if name == "get_weather":
        city = arguments["city"]
        # 实际场景中应调用真实的天气 API
        weather_data = await fetch_weather(city)
        return [TextContent(
            type="text",
            text=f"坐标城市: {city}\n"
                 f"温度: {weather_data['temp']}°C\n"
                 f"湿度: {weather_data['humidity']}%\n"
                 f"天气: {weather_data['condition']}\n"
                 f"风速: {weather_data['wind']} m/s"
        )]

    elif name == "suggest_city":
        suggestions = {
            "海滨":     ["三亚", "青岛", "厦门", "大连"],
            "山景":     ["丽江", "张家界", "黄山", "桂林"],
            "美食":     ["成都", "广州", "西安", "重庆"],
            "历史文化": ["西安", "南京", "洛阳", "开封"]
        }
        cities = suggestions.get(arguments["preference"], ["暂无推荐"])
        return [TextContent(
            type="text",
            text=f"偏好: {arguments['preference']}\n"
                 f"推荐城市:\n" + "\n".join(f"  * {c}" for c in cities)
        )]

    raise ValueError(f"Unknown tool: {name}")

# 4. 模拟天气数据(实际项目应接入真实 API)
async def fetch_weather(city: str) -> dict:
    """模拟天气数据获取"""
    # 实际项目中替换为: requests.get(f"https://api.weather.com/...")
    import random
    conditions = ["晴", "多云", "阴", "小雨", "阵雨"]
    return {
        "temp": random.randint(15, 35),
        "humidity": random.randint(30, 90),
        "condition": random.choice(conditions),
        "wind": round(random.uniform(1, 10), 1)
    }

# 5. 启动 Server(stdio 模式)
async def main():
    async with stdio_server() as (read_stream, write_stream):
        await server.run(
            read_stream,
            write_stream,
            InitializationCapabilities(
                sampling={},
                experimental={},
                roots={"listChanged": True}
            ),
            notification_options=NotificationOptions(),
        )

if __name__ == "__main__":
    asyncio.run(main())

本地测试 Server

你可以直接用命令行测试 Server 是否能正常启动:

python server.py
# Server 会阻塞在 stdio,等待 JSON-RPC 消息
# 按 Ctrl+C 退出

提示: 如果遇到 ModuleNotFoundError: No module named 'mcp',请先执行 pip install mcp 安装 SDK。


七、实战二:让 Claude Desktop / WorkBuddy 连接你的 Server

配置 Claude Desktop

Claude Desktop 是目前最成熟的 MCP Host。配置非常简单 —— 编辑它的配置文件:

配置文件路径:

  • macOS~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows%APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "weather": {
      "command": "python",
      "args": ["D:/projects/weather-server/server.py"]
    }
  }
}

重启 Claude Desktop,在聊天框输入**“帮我查一下北京的天气”**,Claude 会自动识别并调用你的 MCP Server!

配置 WorkBuddy

WorkBuddy 的 MCP 配置位于 ~/.workbuddy/mcp.json

{
  "mcpServers": {
    "weather": {
      "command": "python",
      "args": ["D:/projects/weather-server/server.py"]
    }
  }
}

配置完成后,在 WorkBuddy 的"连接器管理"中找到新注册的 Server,点击"信任"即可启用。

调试技巧

使用 MCP Inspector 可以在不依赖 Host 的情况下独立测试 Server:

npx @anthropic-ai/mcp-inspector python server.py

这会启动一个 Web 界面(默认 http://localhost:5173),你可以在其中:

  • 查看 Server 暴露的所有 Tool / Resource / Prompt
  • 手动构造 JSON-RPC 请求并查看响应
  • 模拟 LLM 的工具调用流程

八、总结与展望

核心要点

要点 说明
标准化协议 MCP 用 JSON-RPC 2.0 统一了 AI 与外部工具的通信,像 USB-C 一样"插上即用"。
三大能力原语 Tools(执行动作)、Resources(读取数据)、Prompts(对话模板),覆盖几乎所有交互场景。
清晰的架构 Host -> Client -> Server 三层分离,职责清晰,支持 stdio 和 HTTP 两种传输。
生态繁荣 官方已有数百个开源 Server,覆盖文件系统、数据库、API、搜索引擎等各个领域。

下一步学习建议

  1. 阅读官方规范modelcontextprotocol.io —— 协议的最新权威文档
  2. 浏览官方 Server 仓库:GitHub 上的 modelcontextprotocol/servers 有大量生产级的 MCP Server 参考实现
  3. 动手写一个:从你最熟悉的领域开始 —— 封装一个你每天都在用的 API 或工具
  4. 关注 SDK 更新:Python SDK 和 TypeScript SDK 都在快速迭代,定期升级关注新特性
  5. 参与社区:MCP 有着非常活跃的开发者社区,讨论设计和最佳实践

MCP 正在重新定义 AI 与世界的交互方式。 它让大模型不再是"纸上谈兵"的思考者,而是能真正"动手做事"的行动者。学完这篇教程,你已经具备了从零搭建 MCP 应用的能力——现在就去写你的第一个 MCP Server 吧!

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐