简述
本文介绍在 Linux 环境下,如何通过系统级工具 peekfd
来观察 AI Agent 与本地 MCP Server 的流量。
缘起
作为一个焦虑与甲抗状态的待业中年。总会担心自己技术落后,而被资本家无情抛弃。特别是当下打开招聘平台,熟识的岗位不断被加上大模型
前缀,好像不学点 AI 都找不到工作了…… 。现在去学 AI 基础科学显然已经不是中年程序员的能力范围了。不如结合自己老本行,去做点科学家们不乐于做的,暂时还是人工完成的 AI 应用基础架构。在技术变革的洪流中,希望还能找到一艘小船可以顺利渡过。有人说过,同是变化,有人看到是危机,有人看到是的却是机遇。
最近半年,AI Agent 应用架构大趋势是外部集成与协议标准化。而这些方向上,可以看到几个在 Cloud Native 场景上熟识的机会:
- 基础设施提供应用可观察性
- 基础设施提供应用可靠性与安全性
- 基础设施提高应用开发效率
还记得 Cloud Native 大热时,什么技术具有这些 features ? Service Mesh 。对,回到我熟识的 Istio 了。最近我一直研究 AI Agent 应用环境下,什么基础设施可以提供类似 Istio 的特性。还真找到:
它同时支持了:
它背后是 solo.io 公司。 相信了解 Istio/Envoy 的人,都知道这公司的名字。
要研究 MCP 和 agentgateway 。当然得先有个 AI Agent 。我是 self-hosted 主义者。也安装了 ollama ,所以选了 Dive AI 这个本地桌面的 AI Agent 。虽然最后由于我机器太烂,还是用了云端 LLM。
出于对 MCP 协议的好奇,也想知道 Agent 与 MCP Server 是怎么交流的。我要想个方法视察 mcp 实时流量数据。我知道本地 MCP Server 是用 stdio
作为 transport 层。所以问题就回归到熟识的 Linux 进程间 fd 通讯了。
去年,我写过一篇 《Linux: 一切皆文件; peekfd: 偷看一切文件读写》 。所以一切都水到渠成了。
观察 MCP 流量
环境
-
AI Agent 和 MCP Host 与 MCP Client 是 Dive AI
-
MCP Server 是
@modelcontextprotocol/server-filesystem
操作
labile@labile-hp ➜ myset $ ps -e --forest
3538618 pts/8 00:00:05 | | \_ dive
3538624 pts/8 00:00:00 | | \_ dive
3538663 pts/8 00:00:08 | | | \_ dive
3538625 pts/8 00:00:00 | | \_ dive
3538685 pts/8 00:00:14 | | | \_ dive
3538669 pts/8 00:00:00 | | \_ dive
3538786 pts/8 00:00:10 | | \_ python3
3538798 pts/8 00:00:00 | | \_ node
3538800 pts/8 00:00:00 | | \_ npm exec @model
3538884 pts/8 00:00:00 | | | \_ sh
3538885 pts/8 00:00:00 | | | \_ node
3538802 pts/8 00:00:00 | | \_ uv
3538915 pts/8 00:00:00 | | | \_ python
3538804 pts/8 00:00:00 | | \_ uv
3538931 pts/8 00:00:00 | | \_ python
labile@labile-hp ➜ myset $ ps -ef | grep mcp-server-filesystem
labile 3538884 3538800 0 15:38 pts/8 00:00:00 sh -c mcp-server-filesystem /home/labile /home/labile
labile 3538885 3538884 0 15:38 pts/8 00:00:00 node /home/labile/.npm/_npx/a3241bba59c344f5/node_modules/.bin/mcp-server-filesystem /home/labile /home/labile
可见 3538885
是长期运行的 MCP Server 进程。3538786
是 MCP Client 。
labile@labile-hp ➜ cd /procs/3538885/fd
labile@labile-hp ➜ fd $ ll
total 0
lr-x------ 1 labile labile 64 Aug 14 16:54 0 -> 'pipe:[14398976]'
l-wx------ 1 labile labile 64 Aug 14 16:54 1 -> 'pipe:[14398977]'
labile@labile-hp ➜ fd $ peekfd -c 3538885
writing fd 1:
{"result":{"content":[{"type":"text","text":"[DIR] .FBReader\n[FILE] .GA_ClientID\n[DIR] .ICAClient\n[FILE] .ICEauthority\n[FILE] .Xauthority\n[FILE] .Xdefaults\n[DIR] .audacity-data\n[FILE] .bash_history\n[FILE] .bash_logout\n[FILE] .bashrc\n[DIR] .cache\n[DIR] .config\n[DIR] .cursor\n[DIR] .dbus\n[DIR] .dive\n[FILE] .dmrc\n[DIR] .docker\n[DIR] .dotnet\n[DIR] .fltk\n[FILE] .gitconfig\n[DIR] .gk\n[DIR] .gnome\n[DIR] .gnupg\n[FILE] .gorilla-cli-last-update-check\n[FILE] .gorilla-cli-userid\n[DIR] .ipython\n[DIR] ...y1.png\n[FILE] zotero_236248.svg\n[FILE] zotero_64x64x32.png\n[FILE].pdf"}]},"jsonrpc":"2.0","id":26}
{"result":{},"jsonrpc":"2.0","id":27}
{"result":{},"jsonrpc":"2.0","id":28}
{"result":{},"jsonrpc":"2.0","id":29}
{"result":{},"jsonrpc":"2.0","id":30}
{"result":{},"jsonrpc":"2.0","id":31}
# 可见 MCP Server 进程的 fd 0(stdin) 即 kernel全局 的 pipe:[14398976] 是 MCP Server 进程的
# 可见 MCP Server 进程的 fd 1(stdout) 是 MCP Server 的输出
观察 MCP Client 3538786
。 其中应该有上面的 kernel全局 的 pipe:[14398976]
对应的 fd 。
labile@labile-hp ➜ cd /procs/3538786/fd
labile@labile-hp ➜ fd $ ll |grep 14398976
l-wx------ 1 labile labile 64 Aug 14 17:06 32 -> pipe:[14398976]
labile@labile-hp ➜ fd $ peekfd 3538786 32
writing fd 32:
{"method":"ping","jsonrpc":"2.0","id":23}
{"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"mcp","version":"0.1.0"}},"jsonrpc":"2.0","id":24}
{"method":"notifications/initialized","jsonrpc":"2.0"}
{"method":"tools/call","params":{"name":"list_directory","arguments":{"path":"/home/labile"},"_meta":{"progressToken":25}},"jsonrpc":"2.0","id":25}
{"method":"tools/call","params":{"name":"list_directory","arguments":{"path":"/home/labile"},"_meta":{"progressToken":26}},"jsonrpc":"2.0","id":26}
{"method":"ping","jsonrpc":"2.0","id":27}
{"method":"ping","jsonrpc":"2.0","id":28}
后记
AI 应用现在还是需要一定的人工 infra 和 DevOps 的。直到一天 AI 完全自举地统治电脑世界为止。而我们能做的,可能只能是建立一个条例:
The Old Testament tells of Adam and Eve, our progenitors. They lived in paradise in total innocence until the serpent (the devil) enticed them to eat the forbidden fruit from the tree of knowledge. As punishment for their disobedience, God banished them from Paradise.