V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
JustW
V2EX  ›  程序员

探索 MCP-我的学习与实践笔记

  •  2
     
  •   JustW · 1 天前 · 1998 次点击

    👋 今天我们要一起探索 Model Context Protocol (MCP)!你可能听说过各种 AI 大模型,比如 ChatGPT 、文心一言等等,它们能聊天、写代码、甚至画画,简直无所不能!

    🤔 但是,你有没有想过,这些 AI 大模型是怎么跟现实世界交互的呢?比如,你怎么让 AI 帮你查天气、订机票、控制家里的智能灯泡?这时候,MCP 就派上用场啦!

    🌟 MCP 就像一个“万能插座”,让 AI 大模型可以安全、方便地连接各种各样的“电器”(也就是我们说的工具,比如查天气的 API 、控制灯泡的程序等等)。有了 MCP ,你的 AI 就能真正地“动起来”,而不仅仅是“说起来”!

    🧐 你是否曾梦想过,你的 AI 助手不仅能和你聊天,还能帮你完成各种实际任务?比如,当你对 AI 说“帮我预订明天早上 8 点飞往北京的航班”时,它真的能帮你订好机票,而不是仅仅回复你“好的,正在为您搜索航班信息……”?

    本文将带你从零开始,用 Python 搭建一个简单的 MCP 应用,让你亲身体验 AI 调用工具的魅力!

    💡 MCP 核心概念

    在正式开始写代码之前,我们需要先了解几个 MCP 的核心概念:

    • MCP (Model Context Protocol): 模型上下文协议。它不是一个具体的软件,而是一套“规则”或者“约定”。这套规则定义了 AI 模型(比如大型语言模型 LLM )如何与外部世界(各种工具、服务、数据)安全、高效地交互。你可以把它想象成一个“翻译官”,让 AI 听懂各种“方言”(不同的工具/服务的接口),也能让各种工具/服务听懂 AI 的“指令”。
    • 核心思想: 将 AI 模型的功能和对接到 AI 模型的工具(tool),数据(resource),提示(prompt)分离开, 独立部署, 让 AI 可以随意连接各种工具,数据以及使用各种提示!
    • MCP 主机 (MCP Host): 运行 AI 模型和 MCP 客户端的应用程序。常见的 MCP 主机有:
      • Claude Desktop: Anthropic 公司的桌面客户端,内置了 MCP 支持。
      • IDE 集成: 像 VS Code 、Cursor 等 IDE 可以通过插件支持 MCP 。
      • 自定义应用: 你自己开发的任何集成了 MCP 客户端的应用程序。
    • MCP 客户端 (MCP Client): 负责与 MCP 服务器通信的组件。它通常集成在 MCP 主机中。客户端的主要职责是:
      • 发现和连接 MCP 服务器。
      • 向 MCP 服务器请求可用的工具、资源、提示等信息。
      • 根据 AI 模型的指令,调用 MCP 服务器提供的工具。
      • 将工具的执行结果返回给 AI 模型。
    • MCP 服务器 (MCP Server): 提供具体功能(工具)和数据(资源)的程序。你可以把它想象成一个“技能包”,AI 模型可以通过 MCP 客户端“调用”这些技能。MCP 服务器可以:
      • 访问本地数据(文件、数据库等)。
      • 调用远程服务( Web API 等)。
      • 执行自定义的逻辑。
    • 本地数据源 (Local Data Source): 位于 MCP 服务器本地的数据,如文件、数据库等。
    • 远程服务 (Remote Service): MCP 服务器通过网络访问的服务,如各种 Web API 。
    • 资源 (Resource): 服务端提供的数据,比如天气信息、歌曲列表等等。
    • 工具 (Tool): 服务端提供的功能,比如查询天气、播放音乐等等。
    • Prompt: 预设的提示, 用于引导 AI 输出.

    image-20250320165955929

    🛠️ 准备工作

    在开始之前,我们需要准备一些工具:

    1. Python 环境: 确保你已经安装了 Python 3.10 或更高版本。
    2. 文本编辑器: 推荐使用 VS Code ,因为它有很多好用的插件,可以帮助我们更高效地编写代码。
    3. 终端: 在 Windows 上可以使用 PowerShell 或 CMD ,在 macOS 或 Linux 上可以使用 Terminal 。
    4. 一点点耐心和好奇心! 😉

    🏗️ 搭建 MCP 服务端

    我们的第一个任务是搭建一个 MCP 服务端。这个服务端会提供一个简单的“计算器”工具,让 AI 可以进行加法运算。下面以 windows 电脑为例,其他系统请参考: https://modelcontextprotocol.io/quickstart

    1. 创建项目目录:

      在 powershell 中执行下面的命令

      mkdir mcp-demo
      cd mcp-demo
      
    2. 创建虚拟环境 (推荐):

      用 uv 创建,更方便快捷! uv 通常指一个环境配置工具,用于简化开发环境的搭建流程。

      powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
      

      image-20250320185339119

      有的可能需要手动配置环境变量,可以参考控制台给出的提示进行配置!

      image-20250320185700725

      下面为创建目录以及激活环境,安装依赖!

      # Create a new directory for our project
      uv init calculate
      cd calculate
      
      # Create virtual environment and activate it
      uv venv
      .venv\Scripts\activate
      
      # Install dependencies
      uv add mcp[cli] httpx
      
      # Create our server file
      new-item calculate.py
      

    image-20250320185810239

    1. 打开刚刚创建的目录,并编写以下代码:

      image-20250320190113103

      from mcp.server.fastmcp import FastMCP
      
      # 创建 FastMCP 服务端实例,命名为 "add-server"
      mcp = FastMCP("add-server")
      
      # 使用 @mcp.tool() 装饰器定义一个名为 "add" 的工具
      @mcp.tool()
      def add(a: int, b: int) -> int:
          """
          计算两个整数的和。
      
          Args:
              a: 第一个整数。
              b: 第二个整数。
      
          Returns:
              两个整数的和。
          """
          return a + b
      
      # 主程序入口
      if __name__ == "__main__":
          # 启动服务端,使用 stdio 作为传输方式
          mcp.run(transport='stdio')
      
    2. 运行命令测试:

      mcp dev calculate.py
      

      如果一切正常,你应该能在终端看到类似下面的输出:

      Starting MCP inspector...
      Proxy server listening on port 3000
      
      🔍 MCP Inspector is up and running at http://localhost:5173 🚀
      

      这表示你的 MCP 服务已经成功启动了!访问终端输出的地址,即可进行调试!

      image-20250320190729603

    3. 客户端调用:

      我这里使用的是 cursor,更多支持的客户端可以查看 https://modelcontextprotocol.io/clients

      image-20250320191812621

      image-20250320191949133

      这里的路径请调整为自己的路径,注意必须使用绝对路径

      {
          "mcpServers": {
            "add-server": {
              "command": "E://mcp-demo//calculate//.venv//Scripts//python.exe",
              "args": ["E://mcp-demo//calculate//calculate.py"]
            }
          }
        }
      

      配置之后,启用刚刚添加的 mcp server, 对话框中选择 agent,然后提问即可,注意,启用时会自动启动一个控制台,请不要关闭! 这个一旦关闭,Cursor 就检测不到你的 MCP 工具

      image-20250320192141894

    Cherry Studio 中进行调用本地 mcp server,使用 uvx 始终不成功,最终使用下面方式实现! 有知道原因的可以留言指导我一下!! 参考文档: https://vaayne.com/posts/2025/how-to-use-mcp-in-cherry-studio/

    image-20250320192750523

    📱 搭建 MCP 客户端

    接下来,我们要搭建一个 MCP 客户端,参考代码见下面这个地址中的 main.py!

    代码地址: https://github.com/modelcontextprotocol/python-sdk/tree/main/examples/clients/simple-chatbot/mcp_simple_chatbot

    那么,这份代码是怎么把它们串起来,让 AI 帮你调用工具的呢?主要分三步:

    1. 🎁 把工具清单告诉 AI

    首先,我们要让 AI 知道 MCP Server 都有哪些工具可用。这一步就像是给 AI 一份“工具清单”。

    这份代码里,有一个 Tool 类,专门用来描述工具的信息,包括:

    • name(工具名称):比如 "image_generator"(图片生成器)
    • description(工具描述):告诉 AI 这个工具是干嘛的,比如“根据你的描述生成一张图片”
    • input_schema(输入格式):告诉 AI 使用这个工具需要提供哪些信息,比如“图片的描述”

    然后,format_for_llm() 方法会把这些信息整理成一段通俗易懂的文字,就像这样:

    Tool: image_generator
    Description: 根据你的描述生成一张图片
    Arguments:
    - description: 你想要生成的图片是什么样的? (required)
    

    看到了吧?这份“工具清单”是不是很清晰? AI 一看就知 道有哪些工具可以用,以及每个工具怎么用。

    ChatSession 类的 start 方法中,程序会:

    1. 从每个 MCP Server 获取工具列表。
    2. 将所有工具的信息格式化成一段文字(tools_description)。
    3. 把这段文字放到一个“系统提示”(system_message)里,告诉 AI:“你有这些工具可以用哦!”

    image-20250320194038055

    2. 🤔 AI 分析你的需求,决定用哪个工具

    现在,AI 已经知道了有哪些工具可用。接下来,当你向 AI 提问时,它就会分析你的需求,看看需不需要调用工具。

    比如,你问:“帮我画一张日落时海滩的图片。”

    AI 会想:“嗯,这个需求跟‘图片生成器’工具很匹配,我应该调用它。”

    但是,AI 怎么告诉程序它要调用哪个工具呢?这里有一个关键的约定:

    AI 必须按照特定的 JSON 格式回复!

    代码里的 system_message 特别强调了这一点:

    IMPORTANT: When you need to use a tool, you must ONLY respond with the exact JSON object format below, nothing else:

    {
    "tool": "tool-name",
    "arguments": {
      "argument-name": "value"
    }
    }
    

    也就是说,如果 AI 想调用“图片生成器”工具,它必须回复一段类似这样的 JSON:

    {
        "tool": "image_generator",
        "arguments": {
            "description": "日落时海滩的图片"
        }
    }
    

    ChatSessionprocess_llm_response方法专门处理 AI 的 JSON 回复. 检查是否包含 "tool" 和 "arguments" 键。

    image-20250320194146542

    3. 🛠️ 执行工具调用,获取结果

    最后一步,就是根据 AI 的指示,真正地去调用工具了。

    ChatSession 类的 process_llm_response 方法会:

    1. 接收到 AI 的回复。
    2. 尝试把回复解析成 JSON 格式。
    3. 如果解析成功,并且发现 AI 要调用工具:
      • 找出是哪个 MCP Server 提供了这个工具。
      • 调用 Server 类的 execute_tool 方法,执行工具。
      • 把工具的执行结果返回给 AI 。

    Server 类的 execute_tool 方法负责与 MCP Server 通信,发送工具调用请求,并获取结果。它还有重试机制,确保工具调用更可靠。

    最后,AI 会根据工具的返回结果,用自然语言给你一个最终的答复。

    image-20250320194216632

    整个过程就像这样:

    1. 你向 AI 提问。
    2. AI 分析你的问题,看看需不需要调用工具。
    3. 如果需要,AI 会按照约定的 JSON 格式回复,告诉程序要调用哪个工具,以及参数是什么。
    4. 程序解析 AI 的回复,找到对应的 MCP Server ,执行工具调用。
    5. 程序把工具的执行结果返回给 AI 。
    6. AI 根据工具的返回结果,给你一个最终的答复。

    是不是很简单?通过这种方式,AI 就可以借助 MCP Server 的各种工具,完成更复杂的任务,变得更加强大!

    演示

    image-20250320194958122

    image-20250320194804597

    启动代码通过对话就可以实现工具的调用了,然后可以自行调整上面的 API 调用地址和模型以及提示词进行测试,我个人测试可能还是 gemini 这个模型调用成功率高一些!

    ✨ 总结与展望

    通过这个简单的例子,相信你已经对 MCP 有了一个初步的了解。MCP 的强大之处在于,它可以让 AI 大模型与各种各样的工具和服务连接起来,从而实现更加复杂和强大的功能。

    • 跨平台: MCP 不仅仅支持 python, 还有 TS/JS, Java 等版本! 让你可以用自己最熟悉的语言进行开发!
    • 安全性: MCP 服务器可以控制权限, 保证你的数据安全!
    • 错误处理: 要记得在实际开发中, 对用户的输入,以及 AI 的返回做校验, 保证程序的稳定!
    • 异步处理: MCP 支持异步操作,这对于处理耗时任务(如网络请求、数据库查询)非常重要。

    未来,你可以尝试:

    • 添加更多工具: 比如查询天气、搜索新闻、控制智能家居等等。
    • 使用不同的客户端: 比如将 MCP 集成到你的 Web 应用、手机 App 中。
    • 探索更高级的 MCP 特性: 比如资源管理、Prompt 系统等等。

    MCP 的世界充满了无限可能,期待你用它创造出更多有趣、有用的 AI 应用!✨

    如果你在学习过程中遇到任何问题,或者有任何想法和建议,欢迎随时与我交流!😊

    最后

    给大家推荐一些关于 mcp server 好用的网站!

    教程

    mcp server 资源站

    17 条回复    2025-03-21 17:08:11 +08:00
    Unmurphy
        1
    Unmurphy  
       1 天前
    刚好,最近也要学习,
    tserial
        2
    tserial  
       1 天前 via iPhone
    总结的很好,也是刚接触
    kidyang
        3
    kidyang  
       1 天前 via iPhone
    🐮
    934831065ldc
        4
    934831065ldc  
       17 小时 42 分钟前
    按照你的思路,都将 mcp server 的工具都拼接到 system 里面,如果有 1 万个工具,10 万工具,那 system message 是不是要爆掉了?
    guansixu
        5
    guansixu  
       17 小时 26 分钟前
    感觉工具的调用跟 function call 有点像,只是 function call 是写在代码里面的函数
    birdhk
        6
    birdhk  
       17 小时 23 分钟前
    最近刚在学,有个疑问,比如我想让大模型使用 get 请求获取一个 url 的信息并让他分析,这应该用 resource 还是 tool 呢?
    fredweili
        7
    fredweili  
       17 小时 11 分钟前
    手工点赞,正想看看这个
    SilenceLL
        8
    SilenceLL  
       17 小时 1 分钟前
    @guansixu 不同层级的东西,function call 更定制化一些,mcp 比较通用。不过现在其他家如谷歌还没跟进,说不定谷歌也想搞一个协议,本身这玩意就是谁流传的广谁就赢了。
    JustW
        9
    JustW  
    OP
       17 小时 0 分钟前
    @934831065ldc 是的,会出现这个问题
    JustW
        10
    JustW  
    OP
       16 小时 58 分钟前
    @birdhk 按官方的写法,应该是放资源里,操作类的就是用 tool.就是个规范,不是硬性要求.
    codingKingKong
        11
    codingKingKong  
       16 小时 28 分钟前
    @JustW 如果是这样的话, 感觉就有点太怪了, 由 mcp-server 来维护这个声明, 由 client 扫描接入的 tools 说明, 支持特殊配置感觉会更正常一些
    JustW
        12
    JustW  
    OP
       16 小时 1 分钟前
    @codingKingKong 客户端的代码就是你说的这个逻辑吧.
    lpdink
        13
    lpdink  
       11 小时 26 分钟前
    @934831065ldc 对 mcp 工具的选择性召回是必要的,总归 RAG 生态现在也做的很好,接过来用在将来是必然的
    ASHYWHISPER
        14
    ASHYWHISPER  
       11 小时 12 分钟前
    🙏感谢博主的启蒙。
    HomeZane
        15
    HomeZane  
       9 小时 56 分钟前
    话说每个 mcp 都要启动一个服务的方式让我很难受,难道没有大善人提供线上 mcp 的服务吗
    JustW
        16
    JustW  
    OP
       9 小时 55 分钟前
    @HomeZane 有啊.文章末尾的资源站就是呀
    HomeZane
        17
    HomeZane  
       9 小时 23 分钟前
    @JustW #16 资源站的不都是需要本地部署吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1107 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 18:31 · PVG 02:31 · LAX 11:31 · JFK 14:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.