跳转至

第1章 MCP 概念

学习目标

  • 理解 Model Context Protocol(MCP)的设计动机与定位
  • 掌握 MCP 的 Host / Client / Server 三层架构
  • 了解 MCP 协议规范中的工具、资源、提示三类原语
  • 能够对比 MCP 与 Function Calling 的本质差异
  • 识别 MCP 在企业 Agent 场景中的典型应用

问题导入

假设你正在构建一个企业 Agent,需要让模型能查 Slack 消息、读 Jira 工单、操作 GitHub PR、搜索内部知识库。如果按传统 Function Calling 思路,每接入一个新工具,你都要在 Agent 代码里手写一份 Schema、写一份调用函数、再做一次权限校验——工具越多,代码越臃肿,迁移到新模型时还要重写一遍。

2024 年 11 月,Anthropic 推出了 Model Context Protocol(MCP),被业界形象地称为"AI 应用的 USB-C"。就像 USB-C 用一个统一接口取代了各种专有充电线,MCP 用一个标准协议把"模型"与"工具/数据源"解耦:工具方只需实现一次 MCP Server,任何支持 MCP 的 Host(如 Claude Desktop、Cursor、Cline)都能即插即用。从此 Agent 工程师不再重复造工具轮子,而是进入"工具市场"时代。本章将从协议动机出发,带你建立对 MCP 的整体认知。

核心概念

1. MCP 的定位:AI 应用的 USB-C

MCP 是一个开放标准,定义了"模型侧"与"外部能力侧"之间的通信规范。它的核心价值在于标准化:

  • 对模型厂商:只需支持 MCP 协议,即可获得整个工具生态。
  • 对工具开发者:实现一次 MCP Server,所有 MCP 兼容的 Host 都能调用。
  • 对 Agent 工程师:不再为每个工具手写适配代码,专注于编排逻辑。

这种"协议层"思维类似数据库领域的 ODBC/JDBC——厂商各异的数据库通过统一驱动被应用访问,MCP 让各家工具通过统一协议被模型访问。

2. MCP 三层架构:Host / Client / Server

MCP 采用经典的"宿主—客户端—服务端"三层结构:

  • Host(宿主):终端用户面对的应用,如 Claude Desktop、Cursor、自研 Agent。一个 Host 内可同时运行多个 Client 实例。
  • Client(客户端):Host 内部与单个 Server 建立连接的组件,负责协议握手、能力协商、消息路由。Client 与 Server 是 1:1 关系。
  • Server(服务端):暴露具体工具/资源/提示的进程,可独立部署。Server 不感知 Host 是谁,只响应协议请求。

这种分离让 Server 可以由工具方独立维护,甚至开源到社区供所有人使用。

3. 协议规范:三类原语

MCP 定义了三类核心原语(Primitives),由 Server 暴露、Client 发现:

原语 中文 控制方 典型用途
Tools 工具 模型决定调用 查询数据、执行操作
Resources 资源 应用决定读取 文件内容、数据库记录
Prompts 提示模板 用户主动触发 预设工作流模板

其中 Tools 最贴近 Function Calling,是 Agent 自动调用的能力;Resources 是被动数据源,由应用按需读取;Prompts 是可复用的提示模板,常用于固化最佳实践。

4. 传输层:stdio 与 Streamable HTTP

MCP 协议本身基于 JSON-RPC 2.0,传输层支持两种:

  • stdio:本地进程通信,Server 作为 Host 的子进程启动,适合本地工具(文件系统、Shell)。延迟低但不支持远程。
  • Streamable HTTP(替代早期 SSE):基于 HTTP 的流式传输,支持远程部署、负载均衡、鉴权。生产环境推荐。

5. MCP 与 Function Calling 的区别

二者并非替代关系,而是不同抽象层级:

维度 Function Calling MCP
层级 模型 API 层 协议层
工具定义 应用代码内手写 Schema Server 独立声明,Client 自动发现
复用性 每个应用各自实现 一次实现,多 Host 共用
调用方式 模型直出 JSON,应用执行 模型决策,Client 转发到 Server
适用场景 单一应用内的少量工具 跨应用、跨团队的工具生态

简言之:Function Calling 是"模型如何说出要调什么",MCP 是"工具如何被标准化地暴露给模型"。MCP Server 内部最终仍可能落到一次函数调用。

原理图

flowchart LR
    subgraph Host["Host(宿主应用,如 Claude Desktop / 自研 Agent)"]
        UI["用户界面"]
        C1["MCP Client A"]
        C2["MCP Client B"]
        C3["MCP Client C"]
    end

    subgraph S1["MCP Server A"]
        T1["Tools: 天气/搜索"]
    end
    subgraph S2["MCP Server B"]
        T2["Resources: 文件系统"]
    end
    subgraph S3["MCP Server C"]
        T3["Prompts: 代码审查模板"]
    end

    UI <--> C1
    UI <--> C2
    UI <--> C3
    C1 <-.JSON-RPC.-> T1
    C2 <-.JSON-RPC.-> T2
    C3 <-.JSON-RPC.-> T3

    classDef host fill:#e3f2fd,stroke:#1976d2
    classDef server fill:#fff3e0,stroke:#f57c00
    class Host,UI,C1,C2,C3 host
    class S1,S2,S3,T1,T2,T3 server

图:MCP 三层架构——一个 Host 通过多个 Client 连接不同的 Server,每个 Server 暴露工具/资源/提示

示例代码

下面用 mcp Python SDK 演示 MCP 的基本概念:定义一个最小化的 Server,并通过 Client 列出它暴露的能力。

# pip install "mcp[cli]"
from mcp.server.fastmcp import FastMCP

# 1. 创建一个 MCP Server(概念演示)
mcp = FastMCP("demo-server")


# 2. 暴露一个 Tool:模型可自动调用
@mcp.tool()
def get_weather(city: str) -> str:
    """查询某城市当前天气"""
    return f"{city} 今天 26℃,晴"


# 3. 暴露一个 Resource:应用按需读取
@mcp.resource("config://app")
def get_config() -> str:
    """返回应用配置"""
    return "version=1.0.0, env=production"


# 4. 暴露一个 Prompt:用户主动触发的模板
@mcp.prompt()
def code_review(code: str) -> str:
    """生成代码审查提示"""
    return f"请审查以下代码的安全性与可读性:\n```\n{code}\n```"


if __name__ == "__main__":
    # 以 stdio 方式启动,供本地 Host 连接
    mcp.run(transport="stdio")

对应的 Client 端概念示意(实际工程见第 3 章):

import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def main():
    params = StdioServerParameters(command="python", args=["server.py"])
    async with stdio_client(params) as (read, write):
        async with ClientSession(read, write) as session:
            # 协议握手
            await session.initialize()
            # 发现工具
            tools = await session.list_tools()
            print("可用工具:", [t.name for t in tools.tools])
            # 调用工具
            result = await session.call_tool("get_weather", {"city": "北京"})
            print("调用结果:", result.content[0].text)

asyncio.run(main())

企业案例

案例 1:工具标准化平台

某互联网公司内部有 30+ 业务系统(工单、监控、知识库、CRM)。过去每个 Agent 团队各自对接,重复造轮子严重。引入 MCP 后,平台团队为每个系统封装一个 MCP Server,统一发布到内部"工具市场"。Agent 团队只需在 Host 配置中勾选所需 Server,即可获得能力,工具接入成本从 2 周降到 2 小时。

案例 2:跨厂商模型适配

某金融企业同时使用 Claude 与 GPT-4。由于 MCP 是协议层标准,企业把内部工具全部封装为 MCP Server,两套模型各自的 Host 都通过 MCP 调用同一批工具,避免为每个模型重复实现工具层,工具维护成本下降 60%。

案例 3:开源生态复用

社区已有 filesystem、github、slack、postgres 等成熟 MCP Server。某初创团队构建客服 Agent 时,直接复用这些开源 Server,仅自研 1 个对接内部订单系统的 Server,2 天内完成工具集成上线。

常见问题

Q1:MCP 会取代 Function Calling 吗? 不会。MCP 是协议层,Function Calling 是模型 API 层。MCP Server 暴露的工具最终仍可能通过一次 Function Calling 被模型决策调用。二者是互补关系。

Q2:MCP 必须用 Anthropic 的模型吗? 不。MCP 是开放协议,任何模型厂商或 Agent 框架都可实现 Host 端。当前 Cursor、Cline、Zed 等都支持 MCP,OpenAI 也在 Agent SDK 中集成了 MCP 客户端。

Q3:stdio 和 HTTP 怎么选? 本地工具(文件、Shell)用 stdio,延迟低且无需端口;远程或多人共享的工具用 Streamable HTTP,便于集中部署与鉴权。

Q4:一个 Host 能连多少个 Server? 理论上无上限,每个 Server 由独立的 Client 实例管理。实际受内存与上下文限制,建议按场景分组加载,避免工具过多导致模型选择困难。

Q5:MCP 协议有版本兼容问题吗? 协议仍在演进,2024 年的 SSE 传输在 2025 年被 Streamable HTTP 取代。建议关注官方 spec 更新,使用 SDK 提供的稳定 API 而非手写协议消息。

面试题

1. 用一句话解释 MCP 是什么。 答:MCP 是一个开放协议,定义了大模型与外部工具/数据源之间的标准化通信方式,被业界比喻为"AI 应用的 USB-C"。

2. MCP 三层架构分别是什么? 答:Host(宿主应用,面向用户)、Client(与单个 Server 建立连接的组件,1:1)、Server(暴露工具/资源/提示的独立进程)。

3. MCP 的三类原语及控制方? 答:Tools(模型控制)、Resources(应用控制)、Prompts(用户控制)。

4. MCP 与 Function Calling 的核心区别? 答:Function Calling 是模型 API 层的"如何调用",MCP 是协议层的"如何标准化暴露工具"。MCP 强调一次实现多 Host 复用,Function Calling 强调模型如何输出调用意图。

5. stdio 与 Streamable HTTP 各自的适用场景? 答:stdio 适合本地进程通信、低延迟;Streamable HTTP 适合远程部署、负载均衡、需要鉴权的生产环境。

练习题

  1. 用你自己的话写一段 200 字的"MCP 价值说明",向非技术同事解释为什么企业要采用 MCP。
  2. 列出你当前工作中 3 个可封装为 MCP Server 的内部能力,并指出每个应暴露为 Tool、Resource 还是 Prompt。
  3. 对比 MCP Server 与传统 REST API 的差异,思考为什么模型场景需要专门的协议。

小结

MCP 把"工具接入"从应用代码里抽离到协议层,让 Agent 工程师从重复造轮子转向编排与组合。本章建立了对 MCP 定位、三层架构、三类原语、传输方式以及与 Function Calling 差异的整体认知。下一章我们将动手实现第一个 MCP Server,深入 Server 端的工具/资源/提示定义与生命周期管理。