> ## Content Index
> Fetch the complete content index at: https://www.hubwiz.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# 抓包理解MCP模型上下文协议
- URL: https://www.hubwiz.com/blog/understanding-model-context-protocol-through-packet-capture/
- Published: 2025-05-03T14:05:15.000Z
- Updated: 2025-05-03T14:05:15.000Z
- Description: 通过抓包分析，我们清晰地了解了 MCP 的完整通信流程：从建立 SSE 连接、三步初始化、工具调用操作，到最终的连接终止
- Author: admin
- Tags: APPLICATION, MCP, PROXYMAN, #Import 2026-10-14 14:41

通过抓包分析，我们清晰地了解了 MCP 的完整通信流程：从建立 SSE 连接、三步初始化、工具调用操作，到最终的连接终止。显而易见，MCP 基于简单的 SSE 协议构建了一个强大的工具调用框架，使 AI 代理能够便捷地调用外部工具完成复杂的任务。

相比传统的 API 调用方式，MCP 更加灵活，能够自动适配不同的工具集，使 AI 代理能够“即插即用”地使用各种服务能力，这正是其设计的巧妙之处。

当然，MCP 并非完美无缺，作为一个新兴协议，它仍在不断发展。未来可能会添加更多特性和功能，以满足日益复杂的需求。

## 1、背景

MCP 支持两种标准传输实现：标准输入/输出 (stdio) 和服务器发送事件 ([SSE)](https://en.wikipedia.org/wiki/Server-sent%5Fevents?ref=hubwiz.com)。stdio 基于命令行工具，通常用于通过进程通信进行本地集成；SSE 基于客户端-服务器网络通信，用于跨设备联网场景。

由于我们通过抓包进行分析，因此需要选择一个采用 SSE 传输的 MCP 服务器，然后使用工具进行网络数据包分析。在深入研究数据包分析之前，有必要简要了解 SSE 协议。

## 2、SSE 协议

SSE 协议是一种服务器推送技术，允许客户端通过 HTTP 连接自动从服务器接收更新，通常用于服务器到客户端的消息更新或连续数据流（流式信息）。

本质上，除非服务器“通知”客户端它正在发送流信息，否则 HTTP 协议无法实现主动消息推送。这可以防止客户端断开连接，并允许其通过该连接持续接收数据流。

你可能想到的是 WebSocket 协议，因为两者都涉及在客户端和服务器之间建立连接，然后服务器将数据推送到客户端。虽然看似相似，但两者之间存在显著差异：

- SSE 是基于 HTTP 的轻量级协议；WebSocket 是一个独立的协议。
- SSE 基于 HTTP 请求，使用 `Accept: text/event-stream` ；WebSocket 利用 HTTP 协议升级，使用 `Upgrade: websocket` ，然后使用独立的协议。
- SSE 是伪双工的，仅支持从服务器到客户端的单向通信；客户端到服务器的通信需要发送单独的 HTTP 请求。WebSocket 是全双工的，支持双向通信。
- SSE 简单、轻量，适用于单向低频推送；WebSocket 更复杂，实时性更强，适用于双向高频交互。

通过以上比较，不难理解 MCP 选择 SSE 作为网络传输协议的原因。

了解了 SSE 协议后，我们就可以开始分析了。

## 3、环境

- 抓包工具：Proxyman，已安装 CA 证书以处理 HTTPS 请求。
- AI 应用：VSCode Insiders，已安装 Github Copilot 插件并启用 Agent 模式。
- MCP 服务器：使用[上一篇文章](https://atbug.com/one-command-to-convert-legacy-spring-rest-services-to-mcp-services/?ref=hubwiz.com)中的 [Spring REST API 示例](https://github.com/addozhang/spring-boot-3-rest-api-sample/tree/spring-api-mcp?ref=hubwiz.com)。

![](http://defiplot.com/blog/content/images/2025/05/image-56.png)

## 4、配置 MCP 服务器

在 `settings.json` 中添加 MCP 服务器配置。要使用 Proxyman 的 HTTP 代理，请在 `/etc/hosts` 中添加 `127.0.0.1 nio.local`。

```
{
  "mcp": {
    "servers": {
      "spring-ai-mcp-sample": {
        "type": "sse",
        "url": "http://nio.local:8080/sse"
      }
    }
  }
}
```

添加配置后，我们就可以启动 MCP 客户端连接到服务器了。

![](http://defiplot.com/blog/content/images/2025/05/image-57.png)

## 5、MCP 通信

下面我们将通过抓包来分析 MCP 通信的完整生命周期，包括连接建立、初始化、运行和终止四个阶段。

当我们的 VSCode 成功连接到 MCP 服务器后，我们已经可以在 Proxyman 中看到多个通信。

![](http://defiplot.com/blog/content/images/2025/05/image-58.png)

## 6、建立连接

由于不确定服务器支持哪种方法，MCP 客户端会向我们配置的服务器地址发送 GET 和 POST 请求，尝试建立连接。请求中的 Accept 标头为 text/event-stream，表示尝试与服务器建立 SSE 通信。

配置的服务器仅支持通过 GET 方法建立 SSE 通信；POST 请求会收到 404 响应。在 GET 请求响应中，服务器返回以下信息：

- Session id： `3e19fbcd-51f4-4784-9f63-538c9a203859`
- Event event: `endpoint` 表示内容类型，它是客户端与服务器后续单向通信的端点。
- Data data： `/mcp/messages?sessionId=3e19fbcd-51f4–4784–9f63–538c9a203859`，其中 `/mcp/messages` 由服务端配置为 `spring.ai.mcp.server.sse-message-endpoint: /mcp/messages` 。

```
id:3e19fbcd-51f4-4784-9f63-538c9a203859
event:endpoint
data:/mcp/messages?sessionId=3e19fbcd-51f4-4784-9f63-538c9a203859
```

此 HTTP 连接作为后续服务端到客户端流信息推送的通道，这也是我们在截图中看到其他流信息的原因。此时，MCP 客户端-服务器连接的生命周期开始：

- 初始化
- 操作
- 终止

![](http://defiplot.com/blog/content/images/2025/05/image-59.png)

> 初始化

初始化阶段必须是客户端与服务器之间的首次交互，这个过程有点类似于 TCP 的三次握手。

> 客户端发起初始化请求

在收到服务器发送的后续通信端点后，客户端发送初始化请求以执行初始化、报告信息并协商功能。

- protocolVersion：协议版本
- capabilities：功能支持：listChanged 表示支持列表变更通知
- clientInfo：客户端信息

```
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-03-26",
    "capabilities": {
      "roots": {
        "listChanged": true
      }
    },
    "clientInfo": {
      "name": "Visual Studio Code - Insiders",
      "version": "1.100.0-insider"
    }
  }
}
```

> 服务器响应初始化请求

类似地，服务器也会返回流信息：

- 相同的会话 ID
- 事件类型：消息
- 事件数据

```
id:3e19fbcd-51f4-4784-9f63-538c9a203859
event:message
data:{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"logging":{},"tools":{"listChanged":true}},"serverInfo":{"name":"webmvc-mcp-server","version":"1.0.0"}}}
```

在事件的数据部分，服务器也提供了与请求类似的内容（下文中，我们将直接展示流信息的数据部分）：

```
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "logging": {},
      "tools": {
        "listChanged": true
      }
    },
    "serverInfo": {
      "name": "webmvc-mcp-server",
      "version": "1.0.0"
    }
  }
}
```

> 初始化完成

客户端与服务器完成信息交互并协商成功后（例如版本兼容性、功能支持），发送请求完成初始化。

```
{
  "method": "notifications/initialized",
  "jsonrpc": "2.0"
}
```

此时服务器不会提供任何响应，类似于客户端在 TCP 握手过程中发送 ACK 后服务器不进行任何处理。

## 7、操作

### 7.1 获取工具列表

初始化完成后，客户端发送请求获取服务器支持的工具列表。

```
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list",
  "params": {}
}
```

服务器通过 SSE 连接返回工具列表。我们的示例服务器包含 4 个工具。响应包含工具名称、输入架构参数描述等信息。客户端收到此响应后，会将工具列表缓存到本地，以避免频繁请求。缓存内容仅在服务器更新列表并通知客户端时更新。

由于篇幅限制，列表内容并未全部显示。

```
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "addUser",
        "description": "Add a new user",
        "inputSchema": {
          "type": "object",
          "properties": {
            "arg0": {
              "type": "object",
              "properties": {
                "email": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              },
              "required": [
                "email",
                "name"
              ],
              "description": "user to add"
            }
          },
          "required": [
            "arg0"
          ],
          "additionalProperties": false
        }
      },
     //...
    ]
  }
}
```

有了工具列表，我们可以尝试让 Copilot 执行任务。在 Copilot Agent 模式下，输入与上次相同的任务：

> 首先，帮我检查用户列表，看看是否有名为 Carson 的用户。如果没有，则添加一个新用户：Carson, carson@gmail.com；然后再次检查列表，看看新用户是否添加成功。最后，向 Carson 打个招呼。

我们先来看看执行结果。

我发出任务请求后，VSCode 对其进行了分析，并决定执行多个工具来完成任务。我这里使用的是 GPT-4o 模型，它没有显示推理过程。如果我没有展开工具执行结果，我只能看到最终的响应。

![](http://defiplot.com/blog/content/images/2025/05/image-60.png)

如果切换到 Claude 3.7 Sonnet 模型，执行过程将包含推理过程，使整个过程更加清晰。

![](http://defiplot.com/blog/content/images/2025/05/image-61.png)

### 7.2 执行

回到 Proxyman 查看捕获的请求：

当 VSCode首先请求 Copilot 服务器，请求内容相当长。以 GPT-4o 模型为例，请求大小为 49.7 KB，响应大小为 1.34 KB。

该请求包含：

- 一个非常长的系统提示。有兴趣的可以参考开发者编写的 GitHub Copilot Agent 官方提示
- 可用工具列表，包括 VSCode 提供的系统工具和配置的 MCP 服务器提供的工具

![](http://defiplot.com/blog/content/images/2025/05/image-62.png)

响应中包含了分析任务后决定调用的工具：

```
{
 "choices": [
   {
     "index": 0,
     "delta": {
       "content": null,
       "role": "assistant",
       "tool_calls": [
         {
           "function": {
             "arguments": "",
             "name": "bb7_getUsers"
           },
           "id": "call_nL7ToTNvrfLwUPYoqtUH8Yx3",
           "index": 0,
           "type": "function"
         }
       ]
     }
   }
 ],
 "created": 1745649196,
 "id": "chatcmpl-BQTO863fJsOBHD4tU1LN3AEk5Uuo2",
 "model": "gpt-4o-2024-11-20",
 "system_fingerprint": "fp_ee1d74bde0"
}
```

VSCode 根据响应内容调用 MCP Tool。

```
 //http://nio.local:8080/mcp/messages?sessionId=3e19fbcd-51f4-4784-9f63-538c9a203859
   {
     "jsonrpc": "2.0",
     "id": 3,
     "method": "tools/call",
     "params": {
       "name": "getUsers",
       "arguments": {}
     }
   }
```

MCP Server 通过 SSE 连接返回工具调用结果。

```
{
 "jsonrpc": "2.0",
 "id": 3,
 "result": {
   "content": [
     {
       "type": "text",
       "text": "[{\"name\":\"John\",\"email\":\"john@example.com\"},{\"name\":\"Jane\",\"email\":\"jane@example.com\"}]"
     }
   ],
   "isError": false
 }
}
```

VSCode 随后将调用结果发送到 Copilot Server 进行处理，并接收另一个工具及其所需参数进行调用。

![](http://defiplot.com/blog/content/images/2025/05/image-63.png)

此循环重复，直到任务执行完成。在最右侧发送给 Copilot Server 的请求中，我们可以看到本次任务执行期间调用的所有工具请求和响应的列表。这意味着每次调用该模型时，它都会携带所有先前调用的工具请求和响应，这就是请求大小逐渐增加的原因。

![](http://defiplot.com/blog/content/images/2025/05/image-64.png)

### 7.3 终止

终止操作很简单——对于 SSE 传输类型的 MCP 交互，只需断开相关的 HTTP 连接即可。

---

原文链接：[Understanding MCP Through Packet Capture: The Communication Mechanism Behind AI Tool Invocation](https://addozhang.medium.com/understanding-mcp-through-packet-capture-the-communication-mechanism-behind-ai-tool-invocation-83ff0ea8855d?source=home%5Ffor%5Fyou---------69-59--------------------17b0c03a%5Ff82b%5F4d6a%5Fab9b%5F6d94e33b740a-------15-------)

汇智网翻译整理，转载请标明出处