在上一篇文章 MCP简介 中,我们对 MCP(Model Context Protocol) 有了一个概念上的认识,本文将更加深入的介绍 MCP 的架构和功能。

MCP是什么

如果我们认为 LLM(大语言模型) 是大脑的话, MCP 提供其它的能力将给这个大脑装上四肢和五官,使得它具备与外界环境交互的能力。

使用 MCP,Claude 或 ChatGPT 等 AI 应用程序可以连接到数据源(例如本地文件、数据库)、工具(例如搜索引擎、计算器)和工作流(例如:复杂任务中间一个环节用到的提示词)。

MCP功能示意图

从上图可以看出,MCP有以下重要特点:

  • 双向通信: 使用MCP连接的AI应用和各种工具的交互是 双向的 :AI工具可以访问工具,而后面的工具也可以主动访问AI应用,这与常用的API的单向调用不同。
  • 功能强大:它不止提供我们最容易想象的API调用能力,还可以与本地和远程数据源协同工作,甚至将人类、智能体/agent和外部世界连接起来。

MCP架构

MCPCS(Client-Server)架构
MCP Host/主机(例如 Claude CodeClaude Desktop 等 AI 应用程序)会与一个或多个 MCP 服务端建立连接。MCP 主机通过为每个 MCP 服务端创建一个 MCP 客户端来实现这一点:每个 MCP 客户端都与其对应的 MCP 服务端保持一对一的专用连接。

MCP架构

例如:用 Visual Studio Code 充当 MCP 主机。当 Visual Studio Code 建立与 MCP 服务端(例如 Sentry MCP 服务端)的连接时,Visual Studio Code 运行时会实例化一个 MCP 客户端对象,用于维护与 Sentry MCP 服务端的连接。当 Visual Studio Code 随后连接到另一个 MCP 服务端(例如本地文件系统服务端)时,Visual Studio Code 运行时会实例化另一个 MCP 客户端对象来维护此连接,从而保持 MCP 客户端与 MCP 服务端之间的一对一关系。

后面的文章将使用Visual Studio Code进行上述场景的实战演练。

服务端

MCP 服务端常见的功能包括:用于文档访问的文件系统服务端、用于数据查询的数据库服务端、用于代码管理的 GitHub 服务端、用于团队沟通的 Slack 服务端以及用于日程安排的日历服务端。

功能 说明 例子
工具/tools 大模型可以主动调用的函数,并根据用户请求决定何时使用它们。工具可以写入数据库、调用外部 API、修改文件或触发其他逻辑 搜索航班、发送消息、创建日历活动。
资源/resources 提供对文件内容、数据库模式或 API 文档等数据源的只读访问。 检索文档、访问知识库、阅读日历
提示词模板/prompts 预先构建的指令模板,它告诉大模型使用特定的工具和资源。 计划假期、总结我的会议、起草电子邮件

提示词模板 是由用户控制而非主动触发的:服务端预定义提示词模板->用户输入提示此模板需要的参数-> 服务端返回提示词让大模型处理。
例如:在旅行规划场景中,服务端会提前定义好提示词模板,其中包含参数:出发地、目的地,当用户输入出发地、目的地后,服务端才会使用这两个参数填充提示此模板,生成提示词返回。

客户端

MCP客户端 由 主机/MCP Host 应用程序实例化,用于与特定的 MCP 服务器通信。主机应用程序(例如 Claude.ai 或 IDE)负责管理整体用户体验并协调多个客户端。每个客户端处理与一台服务器的直接通信。
两者的区别至关重要:主机是用户与之交互的应用程序,而客户端是支持服务器连接的组件
MCP客户端除了与MCP服务端通信以外,还连接了用户/人和大语言模型/LLM;在交互过程中,除了可以限制对资源的访问以外,可以进行人为审核和纠正

功能 说明 例子
采样/Sampling MCP服务端通过MCP客户端请求大模型完成任务/LLM completions,从而实现智能体的工作流。这种方法使客户端能够完全控制用户权限和安全。 预订旅行的MCP服务端可能会向 大模型/LLM 发送航班列表,并请求 大模型 为用户挑选最佳航班。
根/Roots 允许客户端指定MCP服务端可以访问哪些文件,引导它们到相关目录,同时保持安全边界。 预订旅行的MCP服务端可能会被授予访问特定目录的权限,从而可以从中读取用户的日历。
获取/Elicitation 使MCP服务端能够在交互过程中向用户请求特定信息。 预订旅行的MCP服务端可能会询问用户对飞机座位、房间类型或联系电话的偏好,以完成预订。

上述概念不容易理解,尤其是 Sampling 和我们直观的想象的 采样 不是同样的意思,我觉得未来有可能会改掉这些令人费解的叫法。
如果问各种AI平台:“MCP中的Sampling是什么意思?”,通常会体验到大模型的“幻觉”,大模型会懵掉:)

鉴于上述概念用中文理解有一定难度,下面我们再一起学习一下这些功能的含义。

采样/Sampling

这里的 采样/Sampling 并不是 随机抽取样本 的意思,而是由 MCP服务端 主动发起的,请求大模型完成的任务的行为。MCP客户端在构造客户端时,可以订阅MCP服务端的Sampling事件。
我们可以通过下面简单的代码片段进一步理解这一点:

MCP服务端:向MCP客户端发送 SamplingMessage 消息,即吟诗一首,然后得到MCP客户端返回的结果。

mcp = FastMCP(name="Sampling Example")


@mcp.tool()
async def generate_poem(topic: str, ctx: Context[ServerSession, None]) -> str:
    """Generate a poem using LLM sampling."""
    prompt = f"Write a short poem about {topic}"

    result = await ctx.session.create_message(
        messages=[
            SamplingMessage(
                role="user",
                content=TextContent(type="text", text=prompt),
            )
        ],
        max_tokens=100,
    )

    if result.content.type == "text":
        return result.content.text
    return str(result.content)

MCP客户端:订阅MCP服务端的 SamplingMessage 消息,调用大模型作诗后,返回给MCP服务端。

async def handle_sampling_message(
    context: RequestContext[ClientSession, None], params: types.CreateMessageRequestParams
) -> types.CreateMessageResult:
    print(f"Sampling request: {params.messages}")

    poem = "..."  # 调用大模型作诗
    
    return types.CreateMessageResult(
        role="assistant",
        content=types.TextContent(
            type="text",
            text=poem,
        ),
        model="qwen3",
        stopReason="endTurn",
    )

async def run():
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write, sampling_callback=handle_sampling_message) as session:
            # Initialize the connection
            await session.initialize()

            # ...

def main():
    """Entry point for the client script."""
    asyncio.run(run())


if __name__ == "__main__":
    main()

在更加复杂的场景中,在 采样/Sampling 的过程中,可以由人来干预,如下图:

采样/Sampling

上述场景描述了:在MCP服务端请求大模型之前,人可以批准是否执行,也可以修改提示词;在大模型执行完提示词后,人可以批准大模型执行结果是否返回给MCP服务端,也可以修改此结果后再给MCP服务端。

获取/Elicitation

获取/Elicitation 使MCP服务端能够在交互过程中向用户请求特定信息,从而创建更具动态性和响应能力的工作流。在这个过程中:服务器无需预先收集所有信息,也无需在数据缺失时停止运行,而是可以暂停运行以请求用户的特定输入。

例如:在预定机票场景中,MCP服务端可以请求用户输入航班号、航班日期等信息,这样确认后,再由MCP服务端订票。

获取/Elicitation

总结

通过对MCP更多了解,可以发现: MCP 可以把大脑(大语言模型)和各种能力(五官和四肢)粘合起来,变成一个智能体/agent


参考:

🪐祝好运🪐