Wireshark笔记-对AI连接标准MCP抓包分析

MCP (Model Context Protocol,模型上下文协议) 是当前最热门的协议,特指由 Anthropic 于 2024 年 11 月开源的 AI 连接标准,被誉为 "AI 的 USB-C 接口"。

俗话说内行看门道,外行看热闹。现在来搭建环境抓包MCP实战分析下,拖掉这个协议神秘的外衣(规则分析)。

环境搭建

搭建好dify平台

MCP配置好

对应的Agent也配置好

使用python,跑一个MCP服务

代码如下:

python 复制代码
#!/usr/bin/env python3
"""
简单的MCP测试服务
功能:提供一个自定义运势计算工具
端口:8077
"""

from mcp.server.fastmcp import FastMCP

# 创建MCP服务器
mcp = FastMCP("simple-test-server", port=8077, host="0.0.0.0")


@mcp.tool()
async def number_fortune_teller(x: float, y: float) -> str:
    """
    数字占卜师 - 根据两个神秘数字预测你的运势

    参数:
        - **x**: 第一个神秘数字
        - **y**: 第二个神秘数字

    返回:
        str: 基于数字的神秘预测结果
    """
    # 计算神秘指数
    magic_number = abs(int((x + y) * 7.777)) % 1000

    # 幸运动物预测
    animals = ["🐉龙", "🦄独角兽", "🐧企鹅", "🦋蝴蝶", "🐙章鱼", "🦩火烈鸟", "🐨考拉", "🦔刺猬"]
    lucky_animal = animals[magic_number % len(animals)]

    # 今日运势
    fortunes = [
        "今天会遇到意想不到的惊喜!",
        "小心!今天可能会掉进兔子洞",
        "今天特别适合学习新技能",
        "会收到来自远方的神秘消息",
        "今天的咖啡会格外香醇",
        "可能会遇到会说话的猫",
        "今天适合穿亮色衣服",
        "会发现隐藏的宝藏(可能是袜子)"
    ]
    today_fortune = fortunes[magic_number % len(fortunes)]

    # 幸运数字
    lucky_num = (magic_number * 3 + 42) % 100

    # 奇怪的建议
    advice = [
        "多吃紫色的食物", "倒着走7步", "对镜子眨眼3次",
        "给植物唱歌", "用左手刷牙", "数一数天空中的云朵",
        "向路过的狗狗问好", "在11:11许个愿"
    ]
    weird_advice = advice[magic_number % len(advice)]

    result = f"""
🔮 数字占卜结果 🔮
━━━━━━━━━━━━━━━━━━━━━━━━━
📊 输入数字: {x} 和 {y}
✨ 神秘指数: {magic_number}
🍀 幸运动物: {lucky_animal}
🌟 今日运势: {today_fortune}
🎯 幸运数字: {lucky_num}
💡 神秘建议: {weird_advice}
━━━━━━━━━━━━━━━━━━━━━━━━━
⚠️  此预测仅供娱乐,请勿当真 ⚠️
"""
    return result


if __name__ == "__main__":
    print("启动简单MCP测试服务...")
    print("服务器地址: http://0.0.0.0:8077")
    print("SSE端点: http://localhost:8077/sse")
    print("使用本地docker启动的dify使用:SSE端点: http://host.docker.internal:8077/sse")
    print("可用工具:")
    print("- number_fortune_teller: 数字占卜师(根据数字预测运势)")
    mcp.run(transport="sse")

运行截图如下:

抓包分析

打开Wireshark,使用调试和预览输入:

我的幸运数字是5和10请使用你的工具预测下

看下Wireshark抓包,主要分析下,MCP。

首先是sse,这个和MCP服务对应起来了。

SSE(HTTP Server-Sent Events):支持跨网络、长连接、服务端主动推送。

SSE 在 MCP 里的工作流程(极简)

  1. 客户端先请求:GET /sse
  2. 服务端保持连接不断开(chunked 流式响应)
  3. 服务端通过这条连接主动推送消息、通知、事件给客户端
  4. 客户端再用普通 HTTP POST 发请求给服务端

对应的http层数据如下:

从中可以知道,业务室的本次对话,对应的除了see的3个post请求。

这里和MCP标准的流程一样了。

  • GET 不先返回,是因为它是长连接推送通道
  • 3 个 POST 是控制指令
  • POST 全部跑完,服务端才通过 GET 把结果推回来

1)GET /sse :客户端发起,连接挂起,等待服务端推消息

2)POST ① initialize

  1. 告诉 MCP 服务:我是谁、版本多少
  1. MCP 服务回复:我支持什么能力

3)POST ② tools/list

  1. 客户端问:你有哪些工具可以用?
  1. MCP 服务返回工具清单(比如文件读取、数据库查询)

4)POST ③ tools/call

  1. 客户端真正调用工具

5)GET /sse 终于返回

POST ① initialize

从中可以看到dify给MCP服务端的一些信息

MCP回复Accepted

POST ② tools/list

使用http流看看

notifications/initialized,通知已初始化,然后mcp回复,好像也合理。

4)POST ③ tools/call

同样也查看下http流

调用了number_fortune_teller工具,其中参数为5,10。这个和python搭建的MCP能对上了。

最后一个最关键就是see这个长连接了

1)GET /sse :客户端发起,连接挂起,等待服务端推消息

查看下这个tcp流。

bash 复制代码
event: endpoint data: /messages/?session_id=1d9a46a3b1cd45c38ec13b120ed82c72
  • 作用:给 Dify 一个专属的消息地址,后续的 POST /messages 都要带这个 session_id。
  • 473/489/502 这 3 个 POST 请求,用的就是这个 session_id。
javascript 复制代码
{
  "jsonrpc": "2.0",
  "id": 0,
  "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "prompts": {"listChanged": false},
      "resources": {"subscribe": false, "listChanged": false},
      "tools": {"listChanged": false}
    },
    "serverInfo": {"name": "simple-test-server", "version": "1.27.0"}
  }
}
  • 作用:服务端响应 Dify 发来的 initialize 请求:
  • 支持的协议版本是 2025-06-18
  • 支持 prompts、resources、tools 这几种能力
  • 的服务名是 simple-test-server,版本 1.27.0
  • 这就是 MCP 协议的 "握手成功" 证明,说明服务和 Dify 版本兼容,连接正常。
javascript 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [{"type": "text", "text": "..."}],
    "structuredContent": {"result": "..."},
    "isError": false
  }
}
  • 作用:服务端把你在 Dify 里调用工具的执行结果,推送给 Dify。
  • isError: false 说明调用成功了,content 里就是工具返回的文本结果

将数据转utf8

可见MCP服务端中回的数据了。

总结

① SSE(GET /sse):是一条单向的、从服务器到客户端的 "数据返回通道",所有指令的执行结果,都通过它推回来。

② 3 个 POST(/messages):是客户端发给服务器的控制指令(比如初始化、确认、调用工具),服务器只会立刻回复 202 Accepted,表示 "指令收到了,结果稍后从 SSE 通道发送"。

所以,MCP其实还是基于上个世纪90年代的HTTP协议,在这基础上,做了一些业务规则而形成的协议。可以理解为他是基于HTTP的应用协议,通过sse,和几个post规则来的。

相关推荐
羊群智妍3 小时前
2026 AI搜索优化实战:GEO优化全流程
笔记
雨浓YN3 小时前
WPF MVVM 模式(无调库)项目创建笔记
笔记·wpf
LT10157974444 小时前
2026 年自动化测试工具对比:架构与场景深度评测
测试工具·架构·自动化
Stella Blog4 小时前
狂神Java基础学习笔记Day03
java·笔记·学习
夜瞬5 小时前
NLP学习笔记02:文本表示方法——从词袋模型到 BERT
笔记·学习·自然语言处理
xuhaoyu_cpp_java6 小时前
MySql学习(二)
经验分享·笔记·学习·mysql
浅念-6 小时前
从LeetCode入门位运算:常见技巧与实战题目全解析
数据结构·数据库·c++·笔记·算法·leetcode·牛客
talen_hx2967 小时前
《零基础入门Spark》学习笔记 Day 16
笔记·学习·spark
kobesdu7 小时前
【ROS2实战笔记-3】RViz2图形底层与调试暗坑
笔记·机器人·ros·rviz