Model Context Protocol (MCP) 技术详解文档 入门案例
Model Context Protocol (MCP) 技术摘要 MCP是Anthropic推出的开放标准,旨在解决AI模型与数据源连接的兼容性问题。它采用类似USB协议的标准化设计,通过Client-Host-Server架构实现模型与数据源的解耦。核心特点包括: 标准化接口:支持本地/远程数据源统一接入 三大核心能力: Resources(只读数据访问) Prompts(预定义提示模板) T
Model Context Protocol (MCP) 技术详解文档
1. 核心概念:什么是 MCP?
Model Context Protocol (MCP) 是由 Anthropic (Claude 的母公司) 在 2024 年推出的一个开放标准。
1.1 痛点分析 (The “Why”)
在 MCP 出现之前,如果你想让 AI (如 Claude, ChatGPT) 连接你的本地数据(数据库、文件、Slack 消息),你需要为每一个 AI 模型单独写一个“插件”或“适配器”。这就像早期的硬件设备,鼠标要装鼠标驱动,键盘要装键盘驱动,且不同操作系统还不兼容。
1.2 MCP 的解决方案
MCP 相当于 AI 时代的 USB 协议。
- 标准化: 任何数据源(本地文件、Postgres、Git)只要实现了 MCP Server 标准,就可以被任何支持 MCP 的 AI 客户端(Claude Desktop, Cursor, IDEs)直接使用。
- 解耦: 模型不需要知道底层是 SQL 还是 NoSQL,它只管调用 MCP 暴露出来的
Tools(工具)或读取Resources(资源)。
2. 架构设计 (Architecture)
MCP 采用经典的 Client-Host-Server 架构(但在简单场景下,通常简化为 Client-Server)。
- MCP Host (宿主应用):
- 通常是 AI 应用程序本身,如 Claude Desktop 或 Cursor。
- 它负责运行 LLM(大模型),并将用户的自然语言转化为对 MCP Server 的调用指令。
- MCP Client (客户端):
- Host 内部实现协议通信的模块。它负责与 Server 建立连接(通常是 1:1 连接)。
- MCP Server (服务端):
- 这是我们要开发的部分。它是一个轻量级的服务,负责连接实际的数据源,并暴露功能给 Client。
3. 通信协议与传输层
3.1 协议层 (Application Layer)
基于 JSON-RPC 2.0。
- 无状态、轻量级。
- 主要消息类型:
Request(有 id,需要响应): 如tools/call。Notification(无 id,不需要响应): 如notifications/initialized,或者 Server 主动推送的日志。Result(响应): 包含执行结果。
3.2 传输层 (Transport Layer)
MCP 定义了两种主要的传输方式:
- Stdio (标准输入输出流):
- 场景: 本地运行。Host 直接启动 Server 进程(作为子进程)。
- 优势: 安全(父子进程天然信任)、简单(无需网络配置)、零延迟。
- 实现: Client 写入 Server 的
stdin,读取 Server 的stdout。stderr用于打印日志。
- SSE (Server-Sent Events) over HTTP:
- 场景: 远程运行。Server 部署在另一台服务器上。
- 优势: 支持网络调用。Client 通过 HTTP Post 发送请求,Server 通过 SSE 推送结果。
4. MCP Server 的三大核心能力
作为开发者,你在写 Server 时主要定义这三样东西:
- Resources (资源):
- 类比:
GET请求 / 文件读取。 - 作用: 被动的数据读取。例如:读取一个文本文件,读取数据库的一行记录。
- 特点: AI 只能读,不能改。
- 类比:
- Prompts (提示词模板):
- 类比: 预制菜 / 存储过程。
- 作用: Server 预定义好的 Prompt 模板。用户点击一下,就会把复杂的上下文填入 Prompt 发送给 LLM。
- Tools (工具) —— 最重要:
- 类比:
POST请求 / 函数调用 (RPC)。 - 作用: 可执行的函数。例如:
write_file,execute_sql,search_google。 - 特点: 能够改变系统状态,或执行复杂逻辑。
- 类比:
实战案例:Python 版 MCP Client & Server
为了彻底搞懂,我们不使用 Claude Desktop,而是手写一个 Python Client 来模拟 AI,去调用我们手写的一个 Python Server。
场景: 这是一个简单的“数学计算服务”。Server 提供加法和乘法工具,Client 连接并调用它。
环境准备
# 安装官方 SDK
uv pip install mcp
# 或者 pip install mcp
1. 服务端代码 (server.py)
利用 FastMCP 快速构建。
from mcp.server.fastmcp import FastMCP
# 1. 创建 Server 实例
# 这里的名字会在握手时告诉 Client
mcp = FastMCP("Math-Server")
# 2. 定义工具:加法
# 注意:类型注解 (int) 和 文档注释 (docstring) 非常重要!
# MCP 会自动把它们转换成 JSON Schema 告诉 Client。
@mcp.tool()
def add(a: int, b: int) -> int:
"""
计算两个整数的和。
"""
return a + b
# 3. 定义工具:乘法
@mcp.tool()
def multiply(a: int, b: int) -> int:
"""
计算两个整数的乘积。
"""
return a * b
# 4. 定义资源:获取服务器状态
# resources://app/status
@mcp.resource("resources://app/status")
def get_status() -> str:
"""获取服务器当前的运行状态"""
return "Running smoothly, ready for math!"
if __name__ == "__main__":
# 默认使用 Stdio 模式运行
mcp.run()
2. 客户端代码 (client.py)
这个脚本扮演了 Claude Desktop 的角色。它负责启动 Server 进程,并发送指令。
import asyncio
import sys
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
# 配置 Server 的启动参数
# 我们要启动刚才写的 server.py
# 必须使用当前环境的 python 解释器
server_params = StdioServerParameters(
command=sys.executable, # 获取当前 python 路径
args=["server.py"], # 脚本路径
env=None # 环境变量
)
async def run_client():
print("🔌 Client: 正在启动 MCP Server 子进程...")
# 使用上下文管理器建立 Stdio 连接
async with stdio_client(server_params) as (read, write):
# 创建 MCP 会话
async with ClientSession(read, write) as session:
# Step 1: 握手 (Initialize)
# SDK 会自动帮我们处理 jsonrpc 版本和 capabilities 协商
await session.initialize()
print("✅ Client: 握手成功!连接已建立。")
# Step 2: 列出可用工具 (List Tools)
# 相当于发送 tools/list
tools = await session.list_tools()
print(f"\n🛠️ Server 提供了以下工具:")
for tool in tools.tools:
print(f" - {tool.name}: {tool.description}")
# Step 3: 列出可用资源 (List Resources)
resources = await session.list_resources()
print(f"\n📂 Server 提供了以下资源:")
for res in resources.resources:
print(f" - {res.uri}")
# Step 4: 读取资源 (Read Resource)
print(f"\n📖 Client: 正在读取资源 resources://app/status ...")
resource_content = await session.read_resource("resources://app/status")
print(f" 资源内容: {resource_content.contents[0].text}")
# Step 5: 调用工具 (Call Tool)
print(f"\n🧮 Client: 正在请求计算 10 + 20 ...")
# 相当于发送 tools/call
result_add = await session.call_tool(
name="add",
arguments={"a": 10, "b": 20}
)
print(f" 计算结果: {result_add.content[0].text}")
print(f"\n✖️ Client: 正在请求计算 5 * 9 ...")
result_mul = await session.call_tool(
name="multiply",
arguments={"a": 5, "b": 9}
)
print(f" 计算结果: {result_mul.content[0].text}")
if __name__ == "__main__":
# 运行异步主程序
asyncio.run(run_client())
3. 如何运行与结果
确保 server.py 和 client.py 在同一目录下。
在终端执行:
python client.py
预期输出:
🔌 Client: 正在启动 MCP Server 子进程...
✅ Client: 握手成功!连接已建立。
🛠️ Server 提供了以下工具:
- add: 计算两个整数的和。
- multiply: 计算两个整数的乘积。
📂 Server 提供了以下资源:
- resources://app/status
📖 Client: 正在读取资源 resources://app/status ...
资源内容: Running smoothly, ready for math!
🧮 Client: 正在请求计算 10 + 20 ...
计算结果: 30
✖️ Client: 正在请求计算 5 * 9 ...
计算结果: 45
4. 深度解析:这其中发生了什么?
虽然你运行的是 client.py,但底层发生了完整的 进程间通信 (IPC):
- 启动进程:
client.py使用subprocess启动了python server.py。此时server.py在后台静默运行,监听它的stdin。 - 握手: Client 发送 JSON
{"method": "initialize", ...}给 Server。 - Schema 生成: Server 收到
list_tools请求时,Python 的mcp库利用 反射 (Reflection) 技术,读取了add函数的a: int, b: int类型提示,自动生成了如下 JSON Schema 返回给 Client:{ "name": "add", "inputSchema": { "type": "object", "properties": { "a": {"type": "integer"}, "b": {"type": "integer"} }, "required": ["a", "b"] } } - 调用: 当 Client 调用
call_tool时,Server 接收参数,执行 Python 函数add(10, 20),并将返回值30包装成 TextContent 返回。
5. 总结
对于您(后端开发者)来说,MCP 并没有引入什么“黑科技”,它只是把我们熟悉的后端技术做了一个标准化封装:
- Server 就是一个 JSON-RPC API 服务。
- Stdio 就是 API 网关(只不过走的是管道不是 TCP)。
- LLM (AI) 就是 API 调用方(它根据你提供的 API 文档/Schema,决定何时调用哪个接口)。
掌握了这个模式,您就可以用 Python 写任何逻辑(操作数据库、调用第三方 API、爬虫),封装成 MCP Server,让 Claude 瞬间拥有处理复杂业务的能力。
更多推荐


所有评论(0)