深入理解 MCP (模型上下文协议):从原理到实践

AI前沿5天前更新 yizz
3,291 0 0
广告也精彩

1. 什么是 MCP (模型上下文协议)? #模型上下文协议

MCP,全称 Model Context Protocol,即模型上下文协议,是 Claude 公司于 2024 年 11 月 25 日发布的一项协议。虽然名字听起来有些“故弄玄虚”,但它实际上是一个旨在让大模型更好地使用各类工具的协议。

  • 为什么需要 MCP?

    大模型本身只具备问答能力,不具备使用外部工具的能力。MCP 的出现,相当于赋予了大模型使用各种外部工具的能力,例如:

    • 使用浏览器上网查询信息
    • 操作 Unity 编写游戏
    • 查询实时路况

2. MCP Host 是什么?如何使用 Kline? #VSCode

MCP Host 是一个支持 MCP 协议的软件。常见的 MCP Host 包括 Claude DesktopCursorKlineCherry Studio 等。

  • 本教程以 Kline 为例,讲解 MCP 的使用方法:
    1. 安装 VS Code:首先,你需要安装 VS Code
    2. 安装 Kline 插件:打开 VS Code,搜索 Kline 插件并安装。
    3. 配置模型:安装完成后,点击 Kline 插件图标,进入配置页面。
    • 选择 API 接入方和模型Kline 支持不同的 API 接入方和模型。目前对 MCP 支持最好的模型是 Claude 3.7,但价格较高。如果预算有限,可以选择 DeepSeek V30324,效果也不错,价格更低。
    • 配置 API Key
      • DeepSeek:到 DeepSeek 官方网站注册登录并充值,获取 API Key
      • OpenRouter
        • 登录 OpenRouter 页面。
        • 点击 Sign In 进行登录。
        • 将鼠标移到右上角,点击 Keys
        • 点击 Create API Key
        • 输入 API Key 的名称(例如:defaults)和金额上限(可选,建议填写)。
        • 点击 Create 创建 Key,并妥善保存。

        注意:创建后无法在 OpenRouter 页面找回 Key

        如果只使用免费模型,OpenRouter 的操作到此结束。如果使用付费模型,需要点击 Credits 进行充值。

    • 回到 Kline
      • 点击配置图标。
      • API Provider 选择 OpenRouter,填写 API Key
      • Model 选择 DeepSeek V30324(建议选择收费版本,免费版本可能不稳定)。
      • X-Mode 中配置相同的信息。
      • 点击 Save
      1. 测试Kline 会引导你进入聊天页面,随便问一个问题,看是否能正常回复。

3. MCP Server 是什么?如何配置? #Client配置

MCP Server,即模型上下文服务器,听起来像一个远程服务器,但实际上它只是一个符合 MCP 协议的程序。

  • MCP Server 的特点:
    • 通常在本地通过 NodePython 启动。
    • 使用过程中可能联网,也可能不联网。
    • 本质上是一个程序,类似于手机上的应用。
  • Tool 的概念:

    ToolMCP Server 内置的功能模块,类似于编程语言中的函数。一个 Tool 就是一个执行特定任务的机器或工具箱。

    • 例子:一个处理天气的 MCP Server 可能包含两个 Tool

    • get_forecast​:传入经纬度,返回未来几天的天气。

    • get_alerts​:传入地区,返回未来几天的气象预警。
  • 在 Kline 中配置 MCP Server:

    1. 自动安装Kline 支持自动安装 MCP Server,但这种方式不够灵活,且可能安装失败。
    2. 手动配置(推荐):
    • Kline 中点击 Install -> Configure MCP Services
    • Kline 会打开一个 JSON 格式的文件。
    • 在文件中填入 MCP Server 的启动命令。
      {
      "weather": {  // MCP Server 的名字
        "disabled": false, // 是否禁用,false 表示启用
        "timeout": 60, // 超时时间,单位秒
        "command": "uv", // 运行程序的命令
        "args": [  // 命令参数
          "venv/bin/python",
          "weather.py"
        ],
        "transport_type": "stdio" // 通信方式,stdio 表示标准输入输出
      }
      }
      
    • command​:指定运行 MCP Server 的程序。

    • args​:程序的参数。
    • transport_type​:KlineMCP Server 的沟通方式。

      • stdio​:使用标准输入和标准输出进行沟通(常用)。
      • service-sent-events​:暂不介绍。
    • 保存文件后,Kline 会自动识别并加载 MCP Server

4. MCP Server 内部写了什么? #Tool函数

MCP Server 本质上是一个程序,其运行符合 MCP 规范

  • 代码示例(Python):
    import asyncio
    import json
    import logging
    import os
    from typing import Any, Dict, List, Optional
    
    import httpx
    from mcp import fast_mcp, mcpmethod
    
    logging.basicConfig(level=logging.INFO)
    
    MCP = fast_mcp(
      "weather",
      description="A weather tool that can get weather forecasts and alerts.",
      log_level=logging.ERROR # 添加了log_level参数,避免输出过多日志
    )
    
    NWS_API_URL = "https://api.weather.gov"
    USER_AGENT = "weather-app/1.0"
    
    async def make_nws_request(url: str) -> Any:
      """Make a request to the NWS API."""
      async with httpx.AsyncClient(headers={"User-Agent": USER_AGENT}) as client:
          response = await client.get(url)
          response.raise_for_status()
          return response.json()
    
    
    def format_alerts(alerts: List[Dict[str, Any]]) -> str:
      """Format alerts into a string."""
      if not alerts:
          return "No alerts for this area."
      return "\n".join(
          [
              f"  - {alert['properties']['severity']}: {alert['properties']['event']} - {alert['properties']['instruction']}"
              for alert in alerts
          ]
      )
    
    
    @MCP.tool(
      description="Get weather alerts for a US state.",
      states="The US state to get alerts for. e.g. CA",
    )
    async def get_alerts(states: str) -> str:
      """Get weather alerts for a US state."""
      url = f"{NWS_API_URL}/alerts/active?area={states}"
      data = await make_nws_request(url)
      if not data["features"]:
          return f"No alerts found for {states}."
      return format_alerts(data["features"])
    
    
    @MCP.tool(
      description="Get the weather forecast for a location.",
      latitude="The latitude of the location.",
      longitude="The longitude of the location.",
    )
    async def get_forecast(latitude: float, longitude: float) -> str:
      """Get the weather forecast for a location."""
      url = f"{NWS_API_URL}/points/{latitude},{longitude}"
      point_data = await make_nws_request(url)
      forecast_url = point_data["properties"]["forecast"]
      forecast_data = await make_nws_request(forecast_url)
      return forecast_data["properties"]["periods"][0]["detailedForecast"]
    
    
    async def main():
      """Main function to start the MCP server."""
      logging.info("Starting weather MCP server...")
      await MCP.start(transports=["stdio"])
    
    
    if __name__ == "__main__":
      asyncio.run(main())
    
    • 代码解释:

    • 导入必要的包和变量。

    • 调用 fast_mcp​ 函数,快速构建 MCP Server
    • 定义 make_nws_request​ 函数,用于请求天气数据。
    • 定义 format_alerts​ 函数,用于格式化告警数据。
    • 使用 @MCP.tool​ 装饰器注册 get_alerts​ 和 get_forecast​ 函数为 Tool
    • transports=["stdio"]​:指定 MCP ServerKline 的沟通方式为标准输入输出。
  • @MCP.tool装饰器的作用:

    • 将函数注册为 Tool
    • 从函数的注释中提取函数的用途和每个参数的含义,以便模型选择最佳时机调用该函数。

5. MCP Server 的工作流程 #数据流转

  1. 使用 JSON 配置 MCP Server
  2. Kline 使用配置中的命令执行该程序。
  3. 程序等待 Kline 的指令。
  4. KlineMCP Server 进行“寒暄”(打招呼)。
  5. Kline 询问 MCP Server 有哪些 Tool 可用。
  6. MCP Server 回答包含的 Tool 列表。
  7. 用户提问。
  8. Kline 将问题和 MCP ServerTool 列表传递给模型。
  9. 模型选择合适的 Tool,并告知 Kline
  10. Kline 调用 MCP Server 上的 Tool,并传递参数。
  11. MCP Server 执行 Tool,并将结果返回给 Kline
  12. Kline 将结果传递给模型。
  13. 模型根据结果回答用户问题。
  14. Kline 将结果返回给用户。

6. 如何找到别人写的 MCP Server? #MCPServer市场

目前有很多 MCP Server 市场,例如:

  • mcp.so
  • MCP Market .com
  • Smedera .AI

MCP Server 大多使用 PythonNode 进行编写,对应的启动程序一般是 UVXNPX

7. UVX 和 NPX 如何使用? #包管理器

UVXNPX 类似于 PythonpipNodenpm,可以自动下载并安装程序。

  • UVX:用于启动 Python 程序。
    1. 安装 UV
    • 访问 UVGitHub 仓库,找到对应的安装命令。
    • 在命令行中执行安装命令。
      1. 使用 UVX 启动 MCP Server
    • 复制 MCP Server 配置中的 UVX 命令。

    • 在终端中执行该命令,等待程序下载和安装完成。
    • 回到 VS Code,点击 Retry Connection
  • NPX:用于启动 Node 程序。

    1. 安装 Node.js
    • 访问 Node.js 官方网站,下载并安装 Node.js
      1. 使用 NPX 启动 MCP Server
    • 复制 MCP Server 配置中的 NPX 命令。

    • 在终端中执行该命令,等待程序下载和安装完成。
    • 回到 VS Code,点击 Retry Connection

8. 进阶:如何编写自己的 MCP Server? (进阶篇内容概要) #MCP协议分析

进阶篇将包含以下内容:

  1. 动手编写 MCP Server:使用 Python 从零开始构建一个 MCP Server
  2. 截获 MCP Server 的输入输出:通过截获并分析 MCP Server 的输入输出,深入理解 MCP 协议是如何运作的。
  3. 直接与 MCP Server 沟通:在不借助 MCP Host 和任何编程语言的情况下,根据 MCP 协议的规范,直接与 MCP Server 沟通。
  4. 重新思考 MCP 的含义:在掌握了协议细节的基础上,重新思考 MCP 的本质及其在大模型应用中的角色。

代码仓库:本视频涉及到的代码都放到了 GitHub 仓库中,方便大家自行尝试。


我认为:这 MCP 协议,看似高深莫测,实则亦不过是披着技术外衣的“纸老虎”。那些“模型上下文”、“工具箱”之类的词汇,不过是用来唬人的障眼法。真正理解了其本质,便会发现,它不过是规定了一套函数注册与调用的规范罢了。然而,这规范虽简单,却能让大模型拥有了无限可能,这便是其价值所在。正如那黑暗中的一丝光亮,虽微弱,却能照亮前行的道路。

© 版权声明
chatgpt4.0

相关文章

error: Content is protected !!