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

173 天前
 JustW

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

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

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

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

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

💡 MCP 核心概念

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

🛠️ 准备工作

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

  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"
    

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

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

    # 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
    

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

    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 服务已经成功启动了!访问终端输出的地址,即可进行调试!

  3. 客户端调用:

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

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

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

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

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

📱 搭建 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 类,专门用来描述工具的信息,包括:

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

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

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

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

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

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" 键。

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

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

ChatSession 类的 process_llm_response 方法会:

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

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

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

整个过程就像这样:

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

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

演示

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

✨ 总结与展望

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

未来,你可以尝试:

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

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

最后

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

教程

mcp server 资源站

9293 次点击
所在节点    程序员
45 条回复
Unmurphy
173 天前
刚好,最近也要学习,
tserial
172 天前
总结的很好,也是刚接触
kidyang
172 天前
🐮
934831065ldc
172 天前
按照你的思路,都将 mcp server 的工具都拼接到 system 里面,如果有 1 万个工具,10 万工具,那 system message 是不是要爆掉了?
guansixu
172 天前
感觉工具的调用跟 function call 有点像,只是 function call 是写在代码里面的函数
birdhk
172 天前
最近刚在学,有个疑问,比如我想让大模型使用 get 请求获取一个 url 的信息并让他分析,这应该用 resource 还是 tool 呢?
fredweili
172 天前
手工点赞,正想看看这个
SilenceLL
172 天前
@guansixu 不同层级的东西,function call 更定制化一些,mcp 比较通用。不过现在其他家如谷歌还没跟进,说不定谷歌也想搞一个协议,本身这玩意就是谁流传的广谁就赢了。
JustW
172 天前
@934831065ldc 是的,会出现这个问题
JustW
172 天前
@birdhk 按官方的写法,应该是放资源里,操作类的就是用 tool.就是个规范,不是硬性要求.
codingKingKong
172 天前
@JustW 如果是这样的话, 感觉就有点太怪了, 由 mcp-server 来维护这个声明, 由 client 扫描接入的 tools 说明, 支持特殊配置感觉会更正常一些
JustW
172 天前
@codingKingKong 客户端的代码就是你说的这个逻辑吧.
lpdink
172 天前
@934831065ldc 对 mcp 工具的选择性召回是必要的,总归 RAG 生态现在也做的很好,接过来用在将来是必然的
ASHYWHISPER
172 天前
🙏感谢博主的启蒙。
HomeZane
172 天前
话说每个 mcp 都要启动一个服务的方式让我很难受,难道没有大善人提供线上 mcp 的服务吗
JustW
172 天前
@HomeZane 有啊.文章末尾的资源站就是呀
HomeZane
172 天前
@JustW #16 资源站的不都是需要本地部署吗?
ppddtt
171 天前
uvx 不成功的 可以先在 terminal 中安装一遍
zhaoxj58
171 天前
写的很好,赞一个
ChristopherY
170 天前
没太理解,为什么你的例子中服务端实现了一个简单的加法工具,客户端又是一个 chatbot

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1119962

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX