alex-ilgayev/MCPSpy
GitHub: alex-ilgayev/MCPSpy
基于 eBPF 的 MCP 协议实时监控工具,提供安全审计、调试诊断和性能分析能力。
Stars: 499 | Forks: 73
# MCPSpy - 基于 eBPF 的 MCP 监控工具 🕵️✨
[](https://github.com/alex-ilgayev/mcpspy/actions/workflows/ci.yml)
[](https://golang.org)
[](LICENSE)
## 概述
MCPSpy 是一款功能强大的命令行工具,它利用 [eBPF(扩展伯克利包过滤器)](https://ebpf.io/)技术在内核层面监控[模型上下文协议 (MCP)](https://modelcontextprotocol.io/)通信。通过挂钩底层系统调用,它提供了对 MCP 客户端与服务器之间交换的 JSON-RPC 2.0 消息的实时可见性。
模型上下文协议支持三种传输协议进行通信:
- **Stdio**:通过标准输入/输出流进行通信
- **可流式 HTTP**:带有服务器发送事件的直接 HTTP 请求/响应通信
- **SSE(服务器发送事件)**:基于 HTTP 的流式通信(_已弃用_)
**MCPSpy 支持监控 Stdio 和 HTTP/HTTPS 传输**(包括服务器发送事件),全面覆盖 MCP 通信通道。

## 为什么选择 MCPSpy?
模型上下文协议正成为 AI 工具集成的标准,但了解底层发生的情况可能具有挑战性。MCPSpy 通过以下功能解决了这个问题:
- **🔒 安全分析**:监控正在传输的数据,检测 PII 泄露,并审计工具执行情况
- **🛡️ 提示词注入检测**:使用 ML 模型实时检测提示词注入和越狱尝试
- **🐛 调试**:通过查看实际的消息流来排查 MCP 集成问题
- **📊 性能监控**:跟踪消息模式并识别瓶颈
- **🔍 合规性**:确保 MCP 通信符合监管要求
- **🎓 学习**:通过观察实际通信来了解 MCP 的工作原理
## 安装
### 前置条件
- Linux 内核版本 5.15 或更高版本
- Root 权限(eBPF 需要)
### 下载预构建二进制文件(自动检测操作系统 + 架构)
从[发布页面](https://github.com/alex-ilgayev/mcpspy/releases)下载最新版本:
```
# 设置平台相关的二进制文件名
BIN="mcpspy-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/')"
# 下载正确的二进制文件
wget "https://github.com/alex-ilgayev/mcpspy/releases/latest/download/${BIN}"
# 添加执行权限并移动到 PATH 目录中
chmod +x "${BIN}"
sudo mv "${BIN}" /usr/local/bin/mcpspy
```
### 从源代码构建
#### 安装依赖
首先,安装所需的系统依赖:
```
sudo apt-get update
# 安装构建基础工具和 eBPF 依赖
sudo apt-get install -y clang clang-format llvm make libbpf-dev build-essential
# 安装 Python 3 和 pip(用于端到端测试)
sudo apt-get install -y python3 python3-pip python3-venv
# 安装 docker 和 buildx(如果尚未安装)
sudo apt-get install -y docker.io docker-buildx
```
#### 安装 Go
MCPSpy 需要 Go 1.24 或更高版本。使用以下方法之一安装 Go:
选项 1:从 Go 官方网站安装(推荐)
```
# 下载并安装 Go 1.24.1(根据需要调整版本)
wget https://go.dev/dl/go1.24.1.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.24.1.linux-amd64.tar.gz
# 将 Go 添加到 PATH(将其添加到 ~/.bashrc 或 ~/.profile 以持久化)
export PATH=$PATH:/usr/local/go/bin
```
选项 2:通过 snap 安装
```
sudo snap install go --classic
```
#### 构建 MCPSpy
克隆仓库并构建 MCPSpy:
```
# 克隆仓库
git clone https://github.com/alex-ilgayev/mcpspy.git
cd mcpspy
# 构建项目
make all
```
### Docker
```
# 构建 Docker 镜像
make image
# 或者拉取最新镜像
docker pull ghcr.io/alex-ilgayev/mcpspy:latest
# 或者拉取特定版本的镜像
docker pull ghcr.io/alex-ilgayev/mcpspy:v0.1.0
# 运行容器
docker run --rm -it --privileged ghcr.io/alex-ilgayev/mcpspy:latest
```
### Kubernetes
MCPSpy 可以部署在 Kubernetes 集群中,用于监控来自 LangFlow、LangGraph 等 AI/LLM 服务以及其他使用模型上下文协议的应用程序的 MCP 流量。
```
# 将 MCPSpy 部署为 DaemonSet
kubectl apply -f https://raw.githubusercontent.com/alex-ilgayev/mcpspy/main/deploy/kubernetes/mcpspy.yaml
```
#### Kubernetes 中的实际用例
1. **监控 LangFlow/LangGraph 部署**
- 观察 LangFlow/LangGraph 与 AI 服务之间的 MCP 流量
- 调试复杂 AI 工作流中的集成问题
- 出于安全和合规目的审计 AI 交互
2. **AI 服务监控**
- 跟踪与远程和本地 MCP 服务器的交互
- 识别 AI 服务调用中的性能瓶颈
- 检测 AI 通信中潜在的数据泄露
3. **开发与测试**
- 在容器化环境中测试 MCP 实现
- 在生产部署前验证 AI 服务集成
- 确保不同环境中行为的一致性
有关在 Kubernetes 中监控 AI 服务的详细说明和实际示例,请参阅 [Kubernetes 使用指南](docs/kubernetes-usage.md)。
## 使用方法
### 基本用法
```
# 开始监控 MCP 通信(默认为 TUI 模式)
sudo mcpspy
# 开始监控并输出到静态控制台(禁用 TUI)
sudo mcpspy --tui=false
# 开始监控并将输出保存到 JSONL 文件
sudo mcpspy -o output.jsonl
# 按 Ctrl+C 停止监控(或在 TUI 模式下按 'q')
```
### 提示词注入检测
MCPSpy 包含使用 HuggingFace Inference API 的可选实时提示词注入检测功能。启用后,它会分析 MCP 工具调用是否存在潜在的注入攻击和越狱尝试。
**检测范围:**
1. **基于请求的注入**:检测工具调用参数中的恶意提示词
2. **基于响应的注入**:检测工具响应中可能操纵 Agent 的恶意内容
```
# 使用 HuggingFace 令牌启用安全扫描
sudo mcpspy --security --hf-token=hf_xxxxx
# 使用自定义检测模型
sudo mcpspy --security --hf-token=hf_xxxxx --security-model=protectai/deberta-v3-base-prompt-injection-v2
# 调整检测阈值(默认值:0.5)
sudo mcpspy --security --hf-token=hf_xxxxx --security-threshold=0.7
# 同步运行分析(阻塞直到分析完成)
sudo mcpspy --security --hf-token=hf_xxxxx --security-async=false
```
**安全 CLI 标志:**
| 标志 | 描述 | 默认值 |
| ---------------------- | --------------------------------------------------------- | ------------------------------------- |
| `--security` | 启用提示词注入检测 | `false` |
| `--hf-token` | HuggingFace API 令牌(启用安全功能时必需) | - |
| `--security-model` | 用于检测的 HuggingFace 模型 | `protectai/deberta-v3-base-prompt-injection-v2` |
| `--security-threshold` | 检测阈值 (0.0-1.0) | `0.5` |
| `--security-async` | 异步运行分析 | `true` |
**支持的模型:**
- `protectai/deberta-v3-base-prompt-injection-v2`(默认,公开可访问)
- `meta-llama/Llama-Prompt-Guard-2-86M`(在 HF Inference API 上已弃用)
当检测到潜在注入时,MCPSpy 会显示安全警报,包含风险等级(低/中/高/严重)、类别和分析的内容。
### 输出格式
#### TUI 模式(默认)
MCPSpy 默认在交互式终端 UI 模式下运行。TUI 提供:
- 带滚动功能的交互式表格视图
- 详细的消息检查(按 Enter 键)
- 按传输方式、类型和参与者过滤
- 适用于不同屏幕尺寸的多种密度模式
- 实时统计
#### 静态控制台输出
使用 `--tui=false` 运行时:
```
12:34:56.789 python[12345] → python[12346] REQ tools/call (get_weather) Execute a tool
12:34:56.890 python[12346] → python[12345] RESP OK
```
#### JSONL 输出
**Stdio 传输 - 请求:**
```
{
"timestamp": "2024-01-15T12:34:56.789Z",
"transport_type": "stdio",
"stdio_transport": {
"from_pid": 12345,
"from_comm": "python",
"to_pid": 12346,
"to_comm": "python"
},
"type": "request",
"id": 7,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": { "city": "New York" }
},
"error": {},
"raw": "{...}"
}
```
**Stdio 传输 - 响应:**
```
{
"timestamp": "2024-01-15T12:34:56.890Z",
"transport_type": "stdio",
"stdio_transport": {
"from_pid": 12346,
"from_comm": "python",
"to_pid": 12345,
"to_comm": "python"
},
"type": "response",
"id": 7,
"result": {
"content": [
{
"type": "text",
"text": "Weather in New York: 20°C"
}
],
"isError": false
},
"error": {},
"request": {
"type": "request",
"id": 7,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": { "city": "New York" }
},
"error": {}
},
"raw": "{...}"
}
```
**HTTP/HTTPS 传输 - 请求:**
```
{
"timestamp": "2024-01-15T12:34:56.789Z",
"transport_type": "http",
"http_transport": {
"pid": 47837,
"comm": "python",
"host": "127.0.0.1:12345",
"is_request": true
},
"type": "request",
"id": 7,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": { "city": "New York" }
},
"error": {},
"raw": "{...}"
}
```
**HTTP/HTTPS 传输 - 响应:**
```
{
"timestamp": "2024-01-15T12:34:56.890Z",
"transport_type": "http",
"http_transport": {
"pid": 47837,
"comm": "python",
"host": "127.0.0.1:12345"
},
"type": "response",
"id": 7,
"result": {
"content": [
{
"type": "text",
"text": "Weather in New York: 20°C"
}
],
"isError": false
},
"error": {},
"request": {
"type": "request",
"id": 7,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": { "city": "New York" }
},
"error": {}
},
"raw": "{...}"
}
```
## 架构
MCPSpy 采用事件驱动架构和发布-订阅模式来解耦组件并实现可扩展性。该系统由多个通过中央事件总线通信的组件组成:
### 1. 事件总线 (`pkg/bus/`)
- 使用发布-订阅模式的中央通信枢纽
- 支持异步事件处理
- 使用 `github.com/asaskevich/EventBus` 库
### 2. eBPF 程序 (`bpf/`)
- 挂钩 `vfs_read` 和 `vfs_write` 内核函数以处理 stdio 传输
- 挂钩 TLS 库函数(`SSL_read`、`SSL_write`)以处理 HTTP/HTTPS 传输
- 通过检测 JSON 模式过滤潜在的 MCP 流量
- 通过环形缓冲区向用户空间发送事件
- 早期过滤带来的性能影响极小
### 3. eBPF 加载器 (`pkg/ebpf/`)
- 管理 eBPF 程序和资源的生命周期
- 使用 cilium/ebpf 库将预编译的 eBPF 对象加载到内核中
- 将来自内核空间的原始二进制事件转换为结构化的 Go 数据类型
- 将事件发布到事件总线以供下游处理
### 4. HTTP 会话管理器 (`pkg/http/`)
- 订阅来自事件总线的 TLS 相关事件
- 管理 HTTP/HTTPS 会话并关联请求/响应对
- 处理 TLS 负载拦截和解析
- 支持分块传输编码和服务器发送事件 (SSE)
- 从碎片化的 TLS 数据重建完整的 HTTP 消息
- 将重建的 HTTP 正文发布到事件总线以进行 MCP 解析
### 5. MCP 协议解析器 (`pkg/mcp/`)
- 订阅来自事件总线的数据事件(stdio 和 HTTP TLS 负载)
- 验证 JSON-RPC 2.0 消息格式
- 解析 MCP 特定的方法和参数
- 将读取操作和写入操作关联为单个 MCP 消息(与 stdio 传输相关)
- 支持 stdio 和 HTTP/HTTPS 传输(包括 SSE)
- 将解析后的 MCP 消息发布到事件总线
### 6. 输出处理器 (`pkg/output/`)
- 订阅来自事件总线的 MCP 消息事件
- 带有彩色、格式化输出的控制台显示
- 用于程序化分析的 JSONL 输出
- 实时统计跟踪
### 7. 事件记录器 (`pkg/eventlogger/`)
- 订阅事件总线上的所有事件以进行调试
- 提供系统中事件流的详细日志记录
- 可配置不同事件类型的日志级别
### 8. 安全分析器 (`pkg/security/`)
- 用于实时提示词注入检测的可选组件
- 订阅来自事件总线的 MCP 消息事件
- 分析高风险方法(`tools/call`、`resources/read`、`prompts/get`)
- 使用 HuggingFace Inference API 和可配置的 ML 模型
- 检测到注入时发布安全警报
- 支持异步和同步分析模式
## 开发
### 构建
```
# 生成 eBPF 绑定并构建
make all
# 构建 Docker 镜像
make image
```
### 测试
MCPSpy 包含全面的端到端测试,可模拟不同传输方式下的真实 MCP 通信:
```
# (可选)设置测试环境
make test-e2e-setup
# 运行所有测试(需要 root 权限)
make test-e2e
# 运行单个传输测试
make test-e2e-stdio # Test stdio transport
make test-e2e-https # Test HTTP/HTTPS transport
```
测试套件包括:
- 用于 stdio 和 HTTP 传输的 MCP 服务器和客户端模拟器
- 根据预期输出进行消息验证
- 多种消息类型覆盖
- SSL/TLS 加密 HTTP 通信测试
## 限制
- **FS 事件缓冲区大小**:每条消息限制为 16KB。这意味着**缓冲区大小**超过 16KB 的 MCP 消息将被遗漏/忽略。
- **由多条消息组成的 FS 事件**:MCPSpy 目前不支持重建跨多个 `read` 或 `write` 系统调用分割的 MCP 消息。这意味着如果 MCP 消息大于单个系统调用中使用的缓冲区大小,它可能会被遗漏或忽略。
- **Stdio 传输的 Inode 冲突**:Inode 编号仅在文件系统内唯一。如果跨多个文件系统或挂载命名空间监控进程,理论上可能发生 inode 冲突,但在基于管道的 stdio 通信实践中很少见。
- **平台**:仅限 Linux(内核 5.15+)。
## Agentic 工作流设置
MCPSpy 支持使用 Claude Code 等 AI 编码助手进行开发。由于 mcpspy 需要 root 权限才能执行 eBPF 操作,您需要配置无密码 sudo 以启用自主测试执行。
### 配置 Sudoers 以实现无密码执行
创建一个 sudoers 规则,允许您的用户无需密码即可运行 mcpspy。E2E 测试使用位于 `build/mcpspy-linux-amd64`(或在 ARM 上为 `build/mcpspy-linux-arm64`)的二进制文件:
```
# 选项 1:使用 visudo(打开编辑器)
sudo visudo -f /etc/sudoers.d/mcpspy
# 添加此行(替换 YOUR_USERNAME 并根据需要调整路径):
# YOUR_USERNAME ALL=(ALL) NOPASSWD: /home/YOUR_USERNAME/mcpspy/build/mcpspy-linux-amd64, /home/YOUR_USERNAME/mcpspy/.worktrees/*/build/mcpspy-linux-amd64
# 选项 2:单行命令(替换 YOUR_USERNAME 和路径)
echo 'YOUR_USERNAME ALL=(ALL) NOPASSWD: /home/YOUR_USERNAME/mcpspy/build/mcpspy-linux-amd64, /home/YOUR_USERNAME/mcpspy/.worktrees/*/build/mcpspy-linux-amd64' | sudo tee /etc/sudoers.d/mcpspy && sudo chmod 440 /etc/sudoers.d/mcpspy
```
`.worktrees/*` 模式允许从 git worktrees 进行无密码执行。请注意,sudoers 的 `*` 不匹配 `/`,因此需要两种模式。
配置后,验证其是否有效:
```
sudo /path/to/build/mcpspy-linux-amd64 --help # Should not prompt for password
```
这使 AI 助手能够运行需要 sudo 进行 eBPF 操作的 E2E 测试(`make test-e2e`)。
## 贡献
我们欢迎贡献!随时可以提交 issue 或 pull request。
## 许可证
- **用户模式代码**(主要是 Go):Apache 2.0(见 [LICENSE](LICENSE))
- **eBPF C 程序**(`bpf/*`):GPL-2.0-only(见 [LICENSE-BPF](LICENSE-BPF))
███╗ ███╗ ██████╗██████╗ ███████╗██████╗ ██╗ ██╗ ████╗ ████║██╔════╝██╔══██╗██╔════╝██╔══██╗╚██╗ ██╔╝ ██╔████╔██║██║ ██████╔╝███████╗██████╔╝ ╚████╔╝ ██║╚██╔╝██║██║ ██╔═══╝ ╚════██║██╔═══╝ ╚██╔╝ ██║ ╚═╝ ██║╚██████╗██║ ███████║██║ ██║ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚══════╝╚═╝ ╚═╝MCPSpy - 使用 eBPF 对模型上下文协议通信进行实时监控
由 Alex Ilgayev 用 ❤️ 制作
标签:API集成, DNS解析, Docker镜像, Go语言, Hpfeeds, HTTP监控, IP 地址批量处理, JSON-RPC, MCP, Model Context Protocol, SSE, Stdio, 内核级监控, 协议分析, 可观测性, 大模型, 子域名突变, 客户端加密, 客户端加密, 客户端加密, 开源项目, 日志审计, 服务器监控, 权限提升, 监控工具, 程序破解, 系统调用, 网络安全, 网络安全监测, 请求拦截, 隐私保护