大模型开发_基础002 mcp
MCP(Model Context Protocol)框架新课程教案
课程名称:MCP 框架精讲与实践
适用对象:AI 应用开发者、LLM 集成工程师
目标:全面掌握 MCP 协议架构、核心概念、开发方式与使用规范,能够构建标准 MCP 服务器与客户端。
格式:可直接导出 PDF 的 Markdown 教案
目录
-
MCP 概述与架构
-
传输机制与生命周期
-
核心概念:Resources
-
核心概念:Prompts
-
核心概念:Tools
-
高级特性:Sampling、Roots、Logging
-
使用规范与功能表达
-
开发实战:构建天气 MCP Server
-
配置与部署示例
-
附录:知识点速查表
1. MCP 概述与架构
1.1 什么是 MCP?
-
定义:模型上下文协议(Model Context Protocol),由 Anthropic 提出并开源的开放协议,用于标准化应用向大语言模型(LLM)提供上下文的方式。
-
类比:就像 USB-C 统一了设备连接,MCP 统一了 AI 模型与外部数据源、工具的连接方式。
-
目标:
-
消除各 LLM 客户端/插件生态的碎片化。
-
让数据、工具、提示模板可一次构建,多处复用。
-
实现安全、双向的上下文交换。
-
1.2 核心架构
架构采用 客户端-服务器 模型,包含三个关键角色:
| 角色 | 描述 | 示例 |
|---|---|---|
| MCP Host | 运行 LLM 的应用,负责连接并管理多个 MCP Client | Claude Desktop、VSCode 插件、自研 APP |
| MCP Client | 与 MCP Server 维持 1:1 连接的组件,由 Host 管理 | Host 内建的协议客户端 |
| MCP Server | 提供上下文能力的轻量服务,实现 Resources/Prompts/Tools | 文件系统服务器、数据库服务器、天气API服务器 |
通信拓扑:Host (内含多个 Client) ↔ Client ↔ Server
一个 Host 可连接多个 Server,每个 Server 对应一个 Client。
1.3 能力协商
初始化时,客户端与服务器交换各自的能力(Capabilities),如:
-
resources: 是否支持资源与订阅 -
prompts: 是否支持提示模板 -
tools: 是否支持工具调用 -
sampling: 服务器是否可反向请求 LLM 生成(仅客户端声明) -
roots: 是否支持文件根路径列表(客户端声明) -
logging: 是否支持日志
2. 传输机制与生命周期
2.1 传输方式
MCP 使用 JSON-RPC 2.0 作为消息格式,目前定义两种底层传输:
| 传输 | 适用场景 | 启动方式 | 连接地址格式 |
|---|---|---|---|
| stdio | 本地子进程通信,无需网络 | Client 直接 spawn Server 进程 | 命令(如 python server.py) |
| Streamable HTTP | 远程服务器,支持流式响应 | Client 通过 HTTP 连接到 Server | http://host:port/mcp |
-
stdio:通过标准输入/输出传递 JSON-RPC,无加密,仅本机。
-
Streamable HTTP(前身为 SSE):Client 发送 HTTP POST 请求,Server 通过分块传输响应流。需处理会话 ID 和重连。
2.2 协议生命周期
-
连接建立:启动传输通道。
-
初始化 (Initialize):
-
Client 发
initialize请求,携带自身能力与客户端信息。 -
Server 返回其能力与服务器信息。
-
Client 发送
initialized通知,表示准备就绪。
-
-
能力交换与协商:基于双方声明的能力确定可用功能。
-
正常运行:交换资源读取、工具执行、提示获取等请求/通知。
-
断开:进程终止或 HTTP 会话超时。
2.3 心跳与健康检查
-
可通过
ping请求/回复检测连接活性。
3. 核心概念:Resources
3.1 定义
资源(Resources)是将数据或文件内容以可寻址的 URI 暴露给 LLM 的接口。模型可像读取文件一样读取资源,无需提前复制。
3.2 资源类型
-
文本资源:返回文本内容,带 MIME 类型
text/*。 -
二进制资源:返回 base64 编码的 blob,MIME 为
image/png等。 -
资源模板:含参数的 URI 模板(如
weather://{city}/current),支持动态匹配。
3.3 资源交互
| 方法 | 方向 | 描述 |
|---|---|---|
resources/list |
Client→Server | 列出所有可用资源及模板 |
resources/read |
Client→Server | 读取指定 URI 的内容 |
resources/subscribe |
Client→Server | 订阅某资源的变更通知 |
notifications/resources/updated |
Server→Client | 资源更新时推送通知 |
notifications/resources/list_changed |
Server→Client | 资源列表发生变化时通知 |
3.4 使用规范
-
资源 URI 应具有唯一性、描述性,如
file:///path/to/doc.md,db://users/table -
优先使用资源模板处理动态参数,避免无限列表。
-
大文件建议分页或使用资源内容内嵌(Embedded Resource)。
4. 核心概念:Prompts
4.1 定义
提示(Prompts)是参数化的提示模板,由 Server 预定义,支持多轮消息(System/User/Assistant),并可包含资源引用。
4.2 功能表达
-
模板可接受参数(可选必填),动态生成完整提示。
-
消息可引用资源:在
content中嵌入resource类型,指向某个资源 URI 或内容块。
4.3 交互方法
| 方法 | 方向 | 描述 |
|---|---|---|
prompts/list |
Client→Server | 获取所有提示模板的清单 |
prompts/get |
Client→Server | 根据名称和参数获取具体提示消息 |
4.4 示例结构
json
{
"name": "summarize_report",
"description": "总结季度报告",
"arguments": [
{ "name": "quarter", "required": true }
]
}
// 调用 prompts/get 返回 messages:
{
"messages": [
{ "role": "user", "content": { "type": "text", "text": "请总结以下报告..." } },
{ "role": "user", "content": { "type": "resource", "resource": { "uri": "report://2024/Q1" } } }
]
}
4.5 使用规范
-
提示名称简洁、语义化。
-
描述应清晰说明用途,便于 Host 自动发现。
-
参数说明需完整,最好给出示例值。
5. 核心概念:Tools
5.1 定义
工具(Tools)是可由模型调用的函数,用于执行计算、查询 API、修改数据等操作。MCP 将工具发现与执行标准化。
5.2 工具 Schema
每个工具包含:
-
name: 唯一名称(如get_weather) -
description: 详细功能说明(直接影响模型调用准确度) -
inputSchema: JSON Schema 定义输入参数
5.3 交互方法
| 方法 | 方向 | 描述 |
|---|---|---|
tools/list |
Client→Server | 列出可用工具及其 Schema |
tools/call |
Client→Server | 调用指定工具并传参,返回结果 |
notifications/tools/list_changed |
Server→Client | 工具列表变更时通知 |
5.4 调用结果
返回 content 数组,可以是文本、图像、嵌入式资源等。错误使用 isError: true 标记。
5.5 使用规范
-
描述应极尽详细,说明何时使用、参数含义、返回格式,因为 LLM 依赖描述进行函数选择。
-
工具应是幂等的(如果可能),避免副作用歧义。
-
复杂结果可使用结构化文本(Markdown)或资源引用。
6. 高级特性:Sampling、Roots、Logging
6.1 Sampling(服务器采样)
-
允许 Server 向 Client 发起 LLM 生成请求,实现“服务器主动要求模型思考”。
-
典型场景:工具内部需要智能总结、翻译或决策。
-
方法:
sampling/createMessage,由 Server 发送至 Client。 -
安全性:Client 必须明确声明支持
sampling,且可限制使用。
6.2 Roots(根目录)
-
Client 可向 Server 声明一组文件系统“根”路径(如
/home/user/project)。 -
Server 使用
roots/list请求获取根列表(Client→Server 方向有通知notifications/roots/list_changed)。 -
用于文件型 Server 确定可操作范围,增强安全性。
6.3 Logging(日志)
-
Server 可通过
notifications/logging/message向 Client 发送结构化日志。 -
等级:
debug,info,warning,error。 -
须在初始化时声明
logging能力。
6.4 错误处理
-
基于 JSON-RPC 错误码,预定义标准错误类型:
-
-32700解析错误,-32600无效请求,-32601方法未找到,-32602无效参数,-32603内部错误。
-
-
业务逻辑错误在
result中通过isError: true返回。
7. 使用规范与功能表达
7.1 设计原则
-
单一职责:一个 Server 聚焦一类能力(如只有文件操作,或只有数据库查询)。
-
描述即接口:Tools/Prompts 的描述质量直接影响 LLM 调用的正确率。
-
渐进式暴露:通过资源模板、参数化提示避免一次性暴露海量数据。
-
安全第一:明确读写权限,工具应校验输入,遵循最小权限原则。
7.2 功能表达检查清单
-
Resources 是否覆盖静态数据和动态数据(模板)?
-
Prompts 是否封装了常用任务流?是否包含参数说明?
-
Tools 的
inputSchema是否精确且约束合理? -
所有文本均用 Markdown 优化可读性?
-
是否注册了列表变更通知以支持动态更新?
-
传输选择:本地用 stdio,远程用 Streamable HTTP。
7.3 开发方式
推荐使用官方 SDK:
-
Python:
mcp[cli](pip install mcp) -
TypeScript:
@modelcontextprotocol/sdk -
Go/Java 社区 SDK
构建 Server 的核心步骤:
-
创建服务器实例并声明能力。
-
注册
resources/list、resources/read等处理器。 -
使用
@server.list_prompts()@server.call_tool()装饰器定义功能。 -
选择传输并启动
server.run()。
调试工具:MCP Inspector (npx @modelcontextprotocol/inspector) 可可视化测试 Server。
8. 开发实战:构建天气 MCP Server
示例使用 Python SDK,展示 Resources、Prompts、Tools 的综合运用。
python
import json
from mcp.server import Server, NotificationOptions
from mcp.server.stdio import stdio_server
import mcp.types as types
# 创建服务器实例
server = Server("weather-server")
# --- Resources ---
@server.list_resources()
async def list_resources() -> list[types.Resource]:
return [
types.Resource(
uri="weather://current/Beijing",
name="北京当前天气",
mimeType="text/plain",
description="实时天气数据"
)
]
@server.read_resource()
async def read_resource(uri: str) -> str:
if uri == "weather://current/Beijing":
# 模拟获取数据
data = {"city": "北京", "temp": 28, "condition": "晴"}
return json.dumps(data, ensure_ascii=False)
raise ValueError("未知资源")
# --- Prompts ---
@server.list_prompts()
async def list_prompts() -> list[types.Prompt]:
return [
types.Prompt(
name="weather_advice",
description="根据天气给出穿衣建议",
arguments=[
types.PromptArgument(name="city", required=True)
]
)
]
@server.get_prompt()
async def get_prompt(name: str, arguments: dict) -> types.GetPromptResult:
if name == "weather_advice":
city = arguments.get("city", "北京")
return types.GetPromptResult(
messages=[
types.PromptMessage(
role="user",
content=types.TextContent(
type="text",
text=f"请根据 {city} 的当前天气(从资源读取),给出具体的穿衣建议。"
)
)
]
)
raise ValueError("未知提示")
# --- Tools ---
@server.list_tools()
async def list_tools() -> list[types.Tool]:
return [
types.Tool(
name="get_forecast",
description="获取指定城市未来3天天气预报,输入城市中文名,返回摘要",
inputSchema={
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名,如 上海"}
},
"required": ["city"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[types.TextContent]:
if name == "get_forecast":
city = arguments["city"]
# 模拟预报
forecast = f"{city}未来三天:25-30°C,多云转晴"
return [types.TextContent(type="text", text=forecast)]
raise ValueError("未知工具")
# 启动
async def main():
async with stdio_server() as (read, write):
await server.run(read, write, server.create_initialization_options())
if __name__ == "__main__":
import asyncio
asyncio.run(main())
9. 配置与部署示例
9.1 在 Claude Desktop 中配置 stdio Server
编辑 claude_desktop_config.json:
json
{
"mcpServers": {
"weather": {
"command": "python",
"args": ["path/to/weather_server.py"]
}
}
}
重启 Claude Desktop,即可通过对话调用 weather 工具和资源。
9.2 Streamable HTTP 部署
使用 mcp 包提供的 ASGI/WSGI 集成,或直接使用 FastAPI 包装:
python
from mcp.server.streamable_http import StreamableHTTPServerTransport
# ... 定义 server 后
transport = StreamableHTTPServerTransport("/mcp")
app = transport.get_asgi_app()
Client 端配置连接 URL。
10. 附录:知识点速查表
| 分类 | 知识点 | 关键方法/事项 |
|---|---|---|
| 协议基础 | JSON-RPC 2.0、请求/响应/通知 | initialize, ping, 错误码 |
| 传输 | stdio | 子进程标准输入输出,无网络 |
| 传输 | Streamable HTTP | HTTP POST + 流式响应,会话管理 |
| 能力 | resources, prompts, tools, sampling, roots, logging | 初始化协商 |
| 资源 | 静态资源、资源模板、内容类型 | resources/list, resources/read, 订阅更新 |
| 提示 | 参数化模板、多轮消息、嵌入资源 | prompts/list, prompts/get |
| 工具 | JSON Schema 输入、结构化输出 | tools/list, tools/call |
| 反向 | Server→Client 生成请求 | sampling/createMessage |
| 根 | 文件系统作用域 | roots/list,安全限制 |
| 日志 | Server→Client 日志 | logging/message,级别控制 |
| 开发 | Python/TS SDK,装饰器注册 | @server.call_tool 等 |
| 调试 | MCP Inspector | 可视化测试工具 |
| 部署 | Claude Desktop 配置、HTTP 部署 | 配置 mcpServers 字段 |
| 设计规范 | 描述即接口、单一职责、安全校验 | Tools 描述详细化,资源 URI 唯一 |
更多推荐


所有评论(0)