MCP协议详解:一文读懂跨时代的模型上下文协议

本文主要介绍了 Anthropic 推出的开源协议 MCP(Model Context Protocol,模型上下文协议),能让你快速上手该协议,实现大型语言模型与外部数据源和工具的无缝集成。如果想要了解 MCP 协议可以收藏阅读!

作者:王文清
来源:腾讯云开发者

01 基本概念

MCP(Model Context Protocol,模型上下文协议)是由 Anthropic 推出的开源协议,旨在实现大型语言模型(LLM)与外部数据源和工具的无缝集成,用来在大模型和数据源之间建立安全双向的链接。

目标是成为 AI 领域的“HTTP 协议”,推动 LLM 应用的标准化和去中心化。

例如:AI 应用程序的 USB-C 端口。正如 USB-C 提供了一种将设备连接到各种外围设备和配件的标准化方式一样,MCP 也提供了一种将 AI 模型连接到不同数据源和工具的标准化方式。

MCP协议详解:一文读懂跨时代的模型上下文协议

1.1 架构

MCP 遵循客户端-服务器架构,其中:

  1. 主机是发起连接的 LLM 应用程序(Claude for Desktop或其他 AI 工具)。
  2. 客户端在主机应用程序内部与服务器保持 1:1 连接,负责协议通信。
  3. 服务器供客户端访问,向客户提供上下文、工具和提示。同时由于 MCP Server 自己控制资源,不用把 API 密钥给 MCP Host,因此更加安全。
MCP协议详解:一文读懂跨时代的模型上下文协议

1.2 资源

资源表示 MCP 服务器想要向客户端提供的任何类型的数据。这可以包括:文件内容、数据库记录、API 响应、实时系统数据、截图和图片、日志文件等更多内容。每个资源由唯一的 URI 标识,并且可以包含文本或二进制数据。

{
  uri: string;           // Unique identifier for the resource
  name: string;          // Human-readable name
  description?: string;  // Optional description
  mimeType?: string;     // Optional MIME type
}

1.3 提示

MCP 中的提示是预定义的模板,可以:接受动态参数、上下文、链接多个交互 、指导特定工作流程、表面作为 UI 元素(如斜线命令)。

{
  name: string;              // Unique identifier for the prompt
  description?: string;      // Human-readable description
  arguments?: [              // Optional list of arguments
    {
      name: string;          // Argument identifier
      description?: string;  // Argument description
      required?: boolean;    // Whether argument is required
    }
  ]
}

1.4 工具

MCP 中的工具允许服务器公开可由客户端调用并由 LLM 用来执行操作的可执行函数。工具的关键方面包括:

  1. 发现 tools/list:客户端可以通过端点列出可用的工具
  2. 调用:使用端点调用工具 tools/call,服务器执行请求的操作并返回结果
  3. 灵活性:工具范围从简单的计算到复杂的 API 交互

与资源一样,工具也由唯一名称标识,并可以包含说明来指导其使用。但是,与资源不同的是,工具表示可以修改状态或与外部系统交互的动态操作。

{
  name: string;          // Unique identifier for the tool
  description?: string;  // Human-readable description
  inputSchema: {         // JSON Schema for the tool's parameters
    type: "object",
    properties: { ... }  // Tool-specific parameters
  }
}

1.5 采样

采样是 MCP 的一项强大功能,允许服务器通过客户端请求 LLM 完成,从而实现复杂的代理行为,同时保持安全性和隐私性。这种人机交互设计确保用户可以控制 LLM 所看到和生成的内容。采样流程遵循以下步骤:

  1. sampling/createMessage 服务器向客户端发送请求。
  2. 客户审核请求并可以修改。
  3. 来自 LLM 的客户样本。
  4. 客户检查完成情况。
  5. 客户端将结果返回给服务器。
{
  messages: [
    {
      role: "user" | "assistant",
      content: {
        type: "text" | "image",

        // For text:
        text?: string,

        // For images:
        data?: string,             // base64 encoded
        mimeType?: string
      }
    }
  ],
  modelPreferences?: {
    hints?: [{
      name?: string                // Suggested model name/family
    }],
    costPriority?: number,         // 0-1, importance of minimizing cost
    speedPriority?: number,        // 0-1, importance of low latency
    intelligencePriority?: number  // 0-1, importance of capabilities
  },
  systemPrompt?: string,
  includeContext?: "none" | "thisServer" | "allServers",
  temperature?: number,
  maxTokens: number,
  stopSequences?: string[],
  metadata?: Record<string, unknown>
}

02 目标及优势

由于 LLM 难以直接访问实时数据源(如企业内部数据库、实时文档、在线服务等),开发者通常需要为每个应用场景定制专用的适配器或插件,这既耗时费力,又缺乏可扩展性。

  • 标准化:MCP 希望通过定义一个标准化的协议,使开发者在无需重复开发的情况下快速连接模型与数据源,提升模型的通用性和落地效率,降低了模型与多样化数据源之间的连接复杂度。
  • 灵活性:MCP 通过帮助 LLM 直接与数据和工具集成,保证 LLM 切换的灵活性。
  • 开放性:其作为开放协议,允许任何开发者为其产品创建 MCP 服务器。有助于快速扩展生态,形成类似 HTTP 和 REST API 的网络效应,推动模型与应用场景的融合。
  • 安全性:协议内置了严格的权限控制机制,数据源的所有者始终掌握访问权。模型在获取数据时需要经过明确授权,避免数据泄露和滥用问题。

03 示例 – 工具

MCP工具调用流程如下:

用户发送问题 -> LLM 分析可用工具 -> 客户端通过 MCP 服务器来执行所选工具 -> 将结果发送回 LLM -> LLM根据工具返回结果和用户问题进行回答。

(流程有点像检索增强生成,把检索的部分替换成了调用工具)。

这里示例包含两个,一个是结合我们当前业务初步实现的工具以及官网 github 给出的示例。

3.1 通过 mcp 构建一个获取 Path of Exile 2 游戏最新版本的工具

我们发现简单的使用 RAG 往往无法获取实时信息,因此按照官网流程初步构建了一个结合爬虫的 MCP 工具。

客户端:

1、首先导入对应的 FastMCP 类(使用 字符串自动生成工具定义,从而轻松创建和维护 MCP 工具,这里的效果后面会展示)以及我们需要获取实时信息的网址(这里是 PoE2 的官网)。

from typing import Any
from mcp.server.fastmcp import FastMCP
# Initialize FastMCP server
mcp = FastMCP("Path of Exile 2 hotfix")
target_url = "https://www.pathofexile.com/forum/view-forum/2212"

2、工具的核心功能函数 – helper 函数(实际上这里就是想要实现的功能,下面只是一个简单的爬虫函数用于示例)。

async def poe2_hotfix(url: str):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
    }
    response = requests.get(url, headers=headers)
    async with httpx.AsyncClient() as client:
        try:
            response = await client.get(url, headers=headers, timeout=30.0)
            soup = BeautifulSoup(response.text, 'html.parser')
            # 查找包含帖子内容的表格
            table = soup.find('table')
            result_text = ""
            if table:
                for row in table.find_all('tr'):
                    cells = row.find_all('td')
                    if cells:
                        for cell in cells:
                            result_text += cell.get_text(strip=True) + '\n'
                        result_text += '-' * 50 + '\n' # 分隔线
            else:
                print('未找到表格元素')
            return result_text
        except Exception:
            return None

3、添加 mcp 类中的工具函数(执行处理程序,负责实际执行每个工具的逻辑),每个工具函数对应一个特定的工具。

@mcp.tool()
async def find_poe2_hotfix() -> str:
    hotfix_data = await poe2_hotfix(target_url)
    if not hotfix_data:
        return "Unable to find any hotfix in office"
    return hotfix_data

4、最后初始化并运行服务器,到这里就可以 server 端的工作就算完成了。

if __name__ == "__main__":    
  # Initialize and run the server 
  mcp.run(transport='stdio')

5、通过 MCP host 进行测试,这里采用的是官方文档中构建 LLM client 的方法(也可以选择 Clauder for Desktop,只需要将之前的服务器添加到 key 中,相当于告诉 host 这里有一个用于 PoE2 补丁版本查询的 MCP 服务器)。

Quickstart – For Client Developers(https://modelcontextprotocol.io/quickstart/client)

实现了客户端初始化,服务器连接, 查询处理,交互式界面以及资源管理。

6、测试

安装 MCP 依赖后可以在命令行使用 MCP Inspector 对其进行测试:

pip install mcp
mcp dev server.py

在 MCP Inspector 里面的工具页面就可以看到新建立的工具,运行工具后可以看到工具返回的结果。

MCP协议详解:一文读懂跨时代的模型上下文协议

7、效果展示

在命令行将客户端连接到对应的工具

uv run client.py poe2hotfix.py
  • 询问你是谁的问题时,LLM 会根据工具开头 FastMCP 类的输入分析并回答。
MCP协议详解:一文读懂跨时代的模型上下文协议
  • 可以看到当询问最新补丁时可以准确回答 PoE2 的最新补丁版本以及时间。
MCP协议详解:一文读懂跨时代的模型上下文协议
  • 而当询问不相关问题时 LLM 会拒绝回答。

8、思考

优化 prompt 以及添加更多工具来实现更复杂的功能,比如使用更优的爬虫工具,以及通过深度爬虫爬取对应补丁的帖子,这样在回答的最新补丁版本号的同时返回具体内容。

3.2 构建一个简单的chatbot – 官方示例

完整代码详见:https://github.com/modelcontextprotocol/python-sdk/tree/main/examples/clients/simple-chatbot

逻辑流程

1、工具集成:

a. 从 MCP 服务器动态发现工具
b. 工具描述自动包含在系统提示中
c. 工具执行通过标准化 MCP 协议处理

2、运行时流程:

a. 收到用户输入
b. 输入与可用工具的上下文一起发送到 LLM
c. LLM 响应解析:
  如果是工具调用 → 执行工具并返回结果    
  如果是直接响应 → 返回给用户
d. 工具结果发送回 LLM 进行解释
e. 最终响应呈现给用户

服务器侧工具发现:服务器侧调用 list_tools 函数。

all_tools = []
for server in self.servers:
    tools = await server.list_tools()
    all_tools.extend(tools)

工具函数定义:

def format_for_llm(self) -> str:
    """Format tool information for LLM.

    Returns:
        A formatted string describing the tool.
    """
    args_desc = []
    if "properties" in self.input_schema:
        for param_name, param_info in self.input_schema["properties"].items():
            arg_desc = (
                f"- {param_name}: {param_info.get('description', 'No description')}"
            )
            if param_name in self.input_schema.get("required", []):
                arg_desc += " (required)"
            args_desc.append(arg_desc)

    return f"""
Tool: {self.name}
Description: {self.description}
Arguments:
{chr(10).join(args_desc)}
"""

chatbot prompt:

system_message = (
    "You are a helpful assistant with access to these tools:\n\n"
    f"{tools_description}\n"
    "Choose the appropriate tool based on the user's question. "
    "If no tool is needed, reply directly.\n\n"
    "IMPORTANT: When you need to use a tool, you must ONLY respond with "
    "the exact JSON object format below, nothing else:\n"
    "{\n"
    '    "tool": "tool-name",\n'
    '    "arguments": {\n'
    '        "argument-name": "value"\n'
    "    }\n"
    "}\n\n"
    "After receiving a tool's response:\n"
    "1. Transform the raw data into a natural, conversational response\n"
    "2. Keep responses concise but informative\n"
    "3. Focus on the most relevant information\n"
    "4. Use appropriate context from the user's question\n"
    "5. Avoid simply repeating the raw data\n\n"
    "Please use only the tools that are explicitly defined above."
)

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论