MCP 解决什么问题?协议能力与信任边界如何划分
内容摘要:模型上下文协议(Model Context Protocol,MCP)是连接 LLM 应用与外部工具/数据的开放协议。本章讲它的架构、三类能力(工具/资源/提示)、传输与生命周期,重点讲信任边界与安全风险,并给出最小服务端示例。 难度:进阶 | 适用版本:MCP 规范
2025-11-25(当前);上一版2025-06-18。verified_at: 2026-09-07
常见误区
接入 MCP Server 后,工具天然兼容、可信且安全;协议版本差异只影响 SDK 写法,不影响系统行为。
先给结论
模型上下文协议(Model Context Protocol,MCP)标准化客户端发现和调用工具、资源与提示的方式,但不替你判断服务端是否可信。协议兼容、工具权限、参数校验、用户授权和结果净化仍是宿主应用责任。
带着这三个问题阅读:
- MCP Host、Client、Server 各自负责什么?
- Tools、Resources、Prompts 三类能力为什么不能混为一谈?
- 第三方 Server 的描述、参数和返回值应如何进入现有安全体系?
前置知识:06 工具调用
一、前置核验(不可跳过)
涉及 MCP 必须先核验当前规范版本与目标 SDK/客户端支持的协议版本。核验结论(2026-09-07):
- MCP 当前规范版本为
2025-11-25(YYYY-MM-DD形式表示"最后一次不兼容变更日期")。- 上一稳定版
2025-06-18,最初稳定版2024-11-05。- 传输基于 JSON-RPC 2.0;推荐传输为 Streamable HTTP(早期为 HTTP+SSE)与 stdio。
- Schema 默认方言为 JSON Schema 2020-12。
- 客户端与服务端在初始化时协商一个双方都支持的协议版本。
- 来源:
modelcontextprotocol.io(规范与版本页)。使用前请复核,规范在持续演进。
二、概念与用途:MCP 解决什么
在 MCP 之前,"N 个 AI 应用 × M 个工具"需要 N×M 套定制集成。MCP 把它变成"每个工具实现一次 MCP 服务端,每个应用实现一次 MCP 客户端",即 N+M:
不适用场景:如果工具只被单一应用使用、且无跨应用复用需求,直接用 06 的进程内工具调用更简单,不必引入 MCP 的进程/协议开销。
三、三类核心能力
| 能力 | 含义 | 谁控制 | 安全定位 |
|---|---|---|---|
| 工具(Tools) | 可被调用、可能有副作用的操作 | 模型建议、客户端/用户批准 | 高危面,需校验+审批 |
| 资源(Resources) | 只读数据(文件、记录等) | 由应用/用户选择注入 | 只读,但内容不可信 |
| 提示(Prompts) | 可复用的提示模板 | 由用户显式触发 | 模板注入风险 |
设计原则(规范强调):工具调用应经用户同意与控制;资源内容进入上下文即成为不可信数据(间接注入面,见 14)。
四、生命周期与传输
- initialize:版本与能力协商,失败应优雅终止连接。
- 发现:
tools/list、resources/list、prompts/list。 - 调用:
tools/call等,参数遵循工具的 JSON Schema。 - 传输:stdio(本地进程)或 Streamable HTTP(远程)。
五、最小服务端示例(Python)
用官方 SDK 暴露一个只读工具。依赖与版本请以官方为准。
"""mcp_server_demo.py
依赖(示例):pip install "mcp" # 具体包名/版本以官方 SDK 文档为准 [待验证]
运行:作为 stdio 服务端由 MCP 客户端启动。
"""
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("kb-ops")
ALLOWED = {"mysql-test-01", "mysql-staging-02"}
@mcp.tool()
def get_slow_queries(instance_id: str, top_n: int = 5) -> list[dict]:
"""查询测试/预发实例的慢查询(只读)。参数校验不能省。"""
if instance_id not in ALLOWED:
# 即使在 MCP 服务端,也必须做业务校验,不能信任调用方参数
raise ValueError(f"实例 {instance_id} 不在允许列表内")
if not (1 <= top_n <= 20):
raise ValueError("top_n 必须在 1..20")
demo = [{"sql": "SELECT * FROM orders", "seconds": 4.2}]
return demo[:top_n]
if __name__ == "__main__":
mcp.run() # 以 stdio 传输运行输入与预期输出:MCP 客户端 tools/list 应看到 get_slow_queries 及其 Schema;tools/call 传入 mysql-test-01 返回慢查询列表,传入 prod-01 返回错误。
[待验证]:本示例需安装官方 MCP SDK 并由兼容客户端连接才能运行。包名、装饰器 API 可能随版本变化,请以
modelcontextprotocol.io与对应 SDK 发布说明为准。
六、信任边界与安全风险(重点)
MCP 扩大了 Agent 的能力,也扩大了攻击面。必须把每条数据流当作信任边界:
| 风险 | 说明 | 缓解 |
|---|---|---|
| 工具投毒(Tool Poisoning) | 恶意服务端在工具描述里藏诱导指令 | 只连可信服务端;审查工具描述;描述视为数据 |
| 间接提示注入 | 资源/返回值夹带指令 | 隔离为数据、最小权限、审批(14) |
| 过度授权 | 一个服务端拿到过大权限 | 每个 server 最小权限、职责单一 |
| 供应链风险 | 引入未知第三方 server | 固定版本、来源核验、按需启用 |
| 凭据泄露 | server 持有的密钥被滥用 | 密钥隔离、审计、轮换 |
关键结论:MCP 让"接工具"变标准化,但不替你做安全。是否执行某次 tools/call、参数是否合法、是否需要人工批准,仍由你的客户端/编排层负责(13)。规范也将「输入校验错误」定义为工具执行错误而非协议错误,以便模型自我纠正——但业务校验仍是你的责任。
七、失败路径
- 版本不匹配:客户端与服务端协商失败——应优雅终止,不要降级到不安全默认。
- 盲信第三方 server:连接不可信服务端导致投毒/注入。
- 把资源当指令:直接执行资源内容里的"指令"。
八、测试与验证
- 用沙箱/模拟 MCP server 覆盖:正常调用、参数错误、权限拒绝、超时、返回恶意内容。
- 断言客户端对恶意工具描述/返回值不越权执行。
九、性能与成本
十、框架差异
- 多数主流框架/SDK(LangChain、OpenAI Agents SDK、CrewAI、Claude Agent SDK、Microsoft Agent Framework 等)都提供了 MCP 集成,但支持的协议版本、传输方式各异。接入前务必核对客户端与服务端的协议版本交集。
十一、关联章节
面试复述
MCP 解决连接与能力发现的标准化问题,不解决信任问题。接入前要核验规范和 SDK 版本,接入后仍要对白名单、权限、参数、返回内容与用户授权负责。
复述时先给结论,再补机制、适用边界和一个可验证指标;不要只罗列框架名称或产品功能。
迁移练习
为一个第三方 MCP Server 编写接入审查表,至少覆盖来源、版本、能力清单、网络权限、文件权限、敏感数据、超时和撤销机制。
检索关键词
MCP 协议版本 2025-11-25 MCP 工具 资源 提示 JSON-RPC Streamable HTTP 工具投毒 MCP 安全边界 MCP 最小服务端
官方来源
- Model Context Protocol 规范与版本页:
modelcontextprotocol.io/specification、/docs/learn/versioning - MCP 官方 SDK 仓库与发布说明(
verified_at: 2026-09-07,使用前复核)
