返回学习路线/阶段 05 · 编排可控的工作流
LESSON 14 / 18

理解 MCP:统一工具连接方式

认识 Host、Client 和 Server,读懂工具发现与调用过程。

30 分钟 · 含动手练习进阶MCP协议

学完这一课,你将能够

  • 说清 MCP 的三个角色
  • 区分 tools、resources 和 prompts
  • 校验工具调用并处理协议错误

学习目标

  • 解释 Host、Client、Server 各自承担的角色。
  • 区分工具、资源和提示词三类能力。
  • 读懂工具发现与调用中的消息结构。

前置要求:HTTP、JSON 和工具分发器。 本节演示离线消息处理,不声称实现完整 MCP 服务端。

MCP 解决什么问题

如果每个 AI 应用都为每个数据源写一套私有连接方式,维护成本会快速增加。 Model Context Protocol 为应用与能力提供方定义共同的连接与消息约定。 它帮助应用发现和调用工具、访问资源、获取可复用提示词。

MCP 不是模型,也不是 Agent 的完整控制循环。 应用仍要决定调用哪些能力、如何管理上下文以及何时需要用户确认。 协议一致不代表任何服务端都可信或拥有相同质量。

三个角色

角色职责例子
Host组织 AI 体验,管理权限与多个连接你的 Agent 应用
Client与一个 Server 建立协议连接应用内的 MCP 客户端
Server暴露工具、资源或提示词文档搜索服务

Host 可以管理多个 Client;每个连接对接一个 Server。 Server 可以连接数据库或外部 API,但应用不应因此直接继承它全部权限。

三类能力分别是什么

Tools 表达可执行操作,如搜索文档或查询库存。 Resources 表达可读取的上下文数据,如文件内容或数据库结构。 Prompts 表达可复用的交互模板,由应用或用户选择使用。

协议还包含生命周期、能力协商和其他机制。 建立连接时应先初始化并协商版本与能力,再使用支持的方法。 本地常见传输是标准输入输出;远程服务可使用规范定义的 HTTP 传输。

离线观察发现和调用

保存为 mcp_messages.py 并运行。 下面只演示 JSON-RPC 请求的两个方法,省略初始化、传输、通知和完整规范校验。 不要直接把它作为生产 MCP Server。

import json

TOOL = {
    "name": "lookup_stock",
    "description": "按商品 ID 查询库存,只读。",
    "inputSchema": {
        "type": "object",
        "properties": {"product_id": {"type": "string"}},
        "required": ["product_id"], "additionalProperties": False,
    },
}

def handle(request):
    response = {"jsonrpc": "2.0", "id": request["id"]}
    if request["method"] == "tools/list":
        response["result"] = {"tools": [TOOL]}
    elif request["method"] == "tools/call":
        params = request.get("params", {})
        if params.get("name") != TOOL["name"]:
            response["error"] = {"code": -32602, "message": "Unknown tool"}
        else:
            args = params.get("arguments", {})
            valid = args == {"product_id": "python-book"}
            text = '{"stock":3}' if valid else "商品不存在或参数无效"
            response["result"] = {
                "content": [{"type": "text", "text": text}],
                "isError": not valid,
            }
    else:
        response["error"] = {"code": -32601, "message": "Method not found"}
    return response

requests = [
    {"jsonrpc": "2.0", "id": 1, "method": "tools/list"},
    {"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {
        "name": "lookup_stock", "arguments": {"product_id": "python-book"},
    }},
    {"jsonrpc": "2.0", "id": 3, "method": "missing_method"},
]
for request in requests:
    print(json.dumps(handle(request), ensure_ascii=False, indent=2))

观察响应 ID 如何对应请求 ID。 未知协议方法返回 JSON-RPC 错误;已知工具中的执行问题可以通过工具结果的 isError 表达。 两者代表不同层面的失败,客户端应按规范区分处理。

接入一个真实 Server 前

先读它暴露哪些能力、如何认证、访问哪些数据,以及如何更新版本。 只启用任务需要的工具,并在 Host 侧检查输入和操作影响。 外部服务返回的文本依旧是数据,不会因为通过 MCP 传输就自动成为可信指令。

如果工具清单发生变化,应刷新发现结果并重新检查权限。 对连接失败、工具超时和服务端错误分别记录,避免全部显示为“模型出错”。

练习与验收

新增一个未知工具请求和一个无效商品请求,比较两类响应。 画出你的应用连接文档服务时的三个角色。

  • 能指出例子省略了哪些生产协议步骤。
  • 能通过 ID 把响应映射回请求。
  • 能区分协议错误和工具执行错误。
  • 能解释 MCP 为什么不能代替执行层权限检查。

延伸阅读

下一课把人工确认嵌入工作流,并讨论多 Agent 何时值得使用。

让这一课,真正成为你的收获

完成练习后标记完成,也可以随时回来复习。

笔记与进度保存在当前浏览器,无需登录

AgentStudy · Learn by building.以理解为起点,以作品为答案