前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >MCP协议详解:一文读懂跨时代的模型上下文协议

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

作者头像
腾讯云开发者
发布于 2025-03-27 02:07:48
发布于 2025-03-27 02:07:48
28800
代码可运行
举报
运行总次数:0
代码可运行

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

关注腾讯云开发者,一手技术干货提前解锁👇

01、基本概念

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

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

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

1.1 架构

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  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 元素(如斜线命令)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  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 交互

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  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. 客户端将结果返回给服务器。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  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 的官网)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 函数(实际上这里就是想要实现的功能,下面只是一个简单的爬虫函数用于示例)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 类中的工具函数(执行处理程序,负责实际执行每个工具的逻辑),每个工具函数对应一个特定的工具。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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 端的工作就算完成了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 对其进行测试:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install mcp
mcp dev server.py

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

7、效果展示

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
uv run client.py poe2hotfix.py
  • 询问你是谁的问题时,LLM 会根据工具开头 FastMCP 类的输入分析并回答。
  • 可以看到当询问最新补丁时可以准确回答 PoE2 的最新补丁版本以及时间。
  • 而当询问不相关问题时 LLM 会拒绝回答。

8、思考

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

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

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

逻辑流程

1、工具集成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
a.MCP 服务器动态发现工具
b. 工具描述自动包含在系统提示中
c. 工具执行通过标准化 MCP 协议处理

2、运行时流程:

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
all_tools = []
for server in self.servers:
    tools = await server.list_tools()
    all_tools.extend(tools)

工具函数定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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."
)

-End-

原创作者|王文清

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云开发者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01、基本概念
  • 02、目标及优势
  • 03、示例 - 工具
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文