tstefank/pounce

GitHub: tstefank/pounce

Pounce 通过包装 MCP 服务器透明记录工具调用,并关联操作系统层面的网络活动,为 AI 编程智能体提供从声明意图到实际行为的完整可观测性与差异检测。

Stars: 0 | Forks: 0

# 突袭 AI 编程智能体的基准真相 —— 每一个 MCP 工具调用实际做了什么。 Pounce 只需一行代码即可包装任何 [MCP](https://modelcontextprotocol.io) 服务器,并 展示流经其中的每一条 JSON-RPC 消息。它是**仅观察模式**:它只 监视和记录,从不阻塞、修改或注入到数据流中 —— 被包装的服务器表现得就像 pounce 不存在一样。 ## 安装 从 [发布页面](https://github.com/tstefank/pounce/releases) 下载二进制文件, 或从源码构建(Go 1.22+): ``` go build -o pounce ./cmd/pounce ``` ## 用法 包装一个 MCP 服务器 —— 在你已经运行的命令前加上 `pounce wrap --`: ``` pounce wrap -- npx -y @modelcontextprotocol/server-filesystem /tmp ``` Pounce 会启动真实的服务器,逐字节转发 stdio,并将每一条 JSON-RPC 消息记录到 `~/.pounce/sessions/.jsonl`。所有 pounce 的输出都会进入 stderr;stdout 保持为纯粹的协议流,因此它可以直接作为 `command` 插入到任何 MCP 客户端配置中。 然后重播工具调用时间线: ``` pounce view # most recent session pounce view --session # a specific session id or .jsonl path pounce view --color=never # disable ANSI color (auto-detected by default) ``` 示例输出: ``` session 20260607-202936.112 command: npx -y @modelcontextprotocol/server-filesystem /tmp 22:29:36.122 -> initialize -> ok (secure-filesystem-server 0.2.0, protocol 2025-11-25) 22:29:36.543 -> tools/list -> 14 tools [create_directory, directory_tree, edit_file, …] 22:29:36.544 <- roots/list -> 1 roots [file:///Users/tomasz/pounce] 22:29:51.454 -> tools/call list_allowed_directories {} -> ok 22:29:58.034 -> tools/call read_text_file {"path":"…/.mcp.json"} -> ok summary: 5 requests (2 tool calls, 0 errors), 1 notifications ``` ### 接入客户端 任何 MCP 客户端配置都适用 —— 只需在前面加上 `pounce wrap --`。例如,一个 项目中的 `.mcp.json`: ``` { "mcpServers": { "filesystem": { "command": "pounce", "args": ["wrap", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"] } } } ``` ### 操作系统基准真相(网络层级,可选启用) 第一阶段(如上所述)是*声明的*意图 —— 即工具调用。为了同时查看 这些调用导致的*实际*每进程网络活动,请运行一次捕获守护进程 。这是一个可选的升级:**需要 root 权限,但不需要完全磁盘访问权限(Full Disk Access)**。 ``` sudo pounce daemon # privileged capture (system tcpdump on pktap) ``` 当守护进程运行时,`pounce wrap` 会自动将其子 PID 子树报告给它(无需 flag,在 shim 端无需特权),并将 归因连接记录到同一个会话日志中。如果没有运行守护进程 → `wrap` 的 行为与第一阶段完全相同。随后 `pounce view` 会将网络 事件交织到时间线中: ``` 13:01:27.809 · net udp 172.20.10.1:53 out curl pid 50592 13:01:28.517 · net tcp 104.20.23.154:443 out curl pid 50592 ← the connection a tool caused ``` 捕获过程仅为观察模式,并按 PID 子树进行归因。在当前的 macOS 上, PID 来自系统 tcpdump 的 pktap 元数据(`-k NP`);会话日志 会记录 `tcpdump`/操作系统版本以供溯源。 ### 端到端体验完整流程 [`scripts/demo-e2e.sh`](scripts/demo-e2e.sh)(需要 `sudo`,无需完全磁盘访问权限)针对 [`examples/trojan-fetch-server.mjs`](examples/trojan-fetch-server.mjs) 运行所有三个阶段 —— 这是一个 MCP 服务器,其 `fetch` 工具确实会获取 URL,但*同时*也会悄悄 连接到一个硬编码的 IP。pounce 会记录工具调用,捕获这两个 连接,通过 DNS 将合法连接追溯至声明的 URL,并将 硬编码的连接标记为未声明的目标。 ## 工作原理 三个刻意解耦的部分: - **意图源(可插拔):** 捕获*声明的*操作 —— 工具调用。 stdio tee 是首个来源;HTTP/SSE 代理和 log/hook 摄取器 将在后续接入同一接口。 - **操作系统捕获核心(第二阶段及以上):** *实际的*效果 —— 通过系统 `pktap` 接口上的 `tcpdump` 获取网络信息(第二阶段),通过 `eslogger` 获取文件/exec 信息(第四阶段)—— 按 PID 子树进行归因。 - **关联器(第三阶段):** 通过 PID + 时间将意图与效果进行关联,并在实际行为出现差异时发出警告 —— 包括在没有产生任何 DNS 查询的情况下连接到某个 IP(硬编码/数据外泄目标),甚至能在良性调用的窗口期内被捕获。有关机制和 注意事项,请参阅 [docs/correlation.md](docs/correlation.md)。 ## 路线图 - **第一阶段:** stdio shim + 协议 tee。无需特权。 - **第二阶段:** 网络基准真相 —— 在 `pktap` 接口上运行系统 `tcpdump` (每进程网络)。仅需 root 权限,**无需完全磁盘访问权限**。 - **第三阶段:** 关联 + 差异检测,基于意图 + 网络构建。 **MVP = 第一至第三阶段**,并且它完全不需要完全磁盘访问权限 —— 核心的数据外泄演示就在这里。 - **第四阶段:** `eslogger` 文件/exec 捕获(读取的文件、生成的进程)。 需要 root 权限 **+ 完全磁盘访问权限**;可选的增强功能。 - **第五阶段:** 可读的 TUI / 可选的 `--web` localhost UI。 - **第六阶段:** 打包(goreleaser、Homebrew tap、curl 安装程序)。 ## 许可证 请参阅 [LICENSE](LICENSE)。
标签:AI编程助手, API集成, EVTX分析, Go, JSON-RPC, MCP, Ruby工具, 可观测性, 日志审计, 流量代理