MCP 处的防护:技术原理与开源工具
一、MCP 防护和"护栏"有什么不同
在讨论具体技术之前,需要先明确一个概念区分。前文讨论的的 Llama Guard、Presidio、Bastion 等,管的是与模型对话------检查 Prompt 有没有被注入、输出有没有泄露隐私、内容有没有违规。这类工具通常叫"护栏"(Guardrail)。
而 MCP 处的防护管的是"Agent 到底做了什么" 。它关心的是工具调用本身:Agent 有没有去删数据库、有没有把敏感数据往外传、有没有调用不该调用的工具。这类工具的定位更接近防火墙,而不是内容审查器。
这个区别在实践中很关键。模型被绕过了,不代表动作就一定会造成破坏------只要在动作真正执行前拦住它就行。这也是 MCP 防护的核心设计哲学:不赌模型不被攻破,而是确保即使模型被攻破,危险动作也无法落地。
所谓MCP,就是 是一套标准化协议,让 Agent 通过 JSON-RPC 消息,跨进程(stdio 或 HTTP)去发现和调用 MCP Server 暴露的 Tools / Resources / Prompts。
#mermaid-svg-anhb9Y8R8zCip9Uk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-anhb9Y8R8zCip9Uk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-anhb9Y8R8zCip9Uk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-anhb9Y8R8zCip9Uk .error-icon{fill:#552222;}#mermaid-svg-anhb9Y8R8zCip9Uk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-anhb9Y8R8zCip9Uk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-anhb9Y8R8zCip9Uk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-anhb9Y8R8zCip9Uk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-anhb9Y8R8zCip9Uk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-anhb9Y8R8zCip9Uk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-anhb9Y8R8zCip9Uk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-anhb9Y8R8zCip9Uk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-anhb9Y8R8zCip9Uk .marker.cross{stroke:#333333;}#mermaid-svg-anhb9Y8R8zCip9Uk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-anhb9Y8R8zCip9Uk p{margin:0;}#mermaid-svg-anhb9Y8R8zCip9Uk .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-anhb9Y8R8zCip9Uk .cluster-label text{fill:#333;}#mermaid-svg-anhb9Y8R8zCip9Uk .cluster-label span{color:#333;}#mermaid-svg-anhb9Y8R8zCip9Uk .cluster-label span p{background-color:transparent;}#mermaid-svg-anhb9Y8R8zCip9Uk .label text,#mermaid-svg-anhb9Y8R8zCip9Uk span{fill:#333;color:#333;}#mermaid-svg-anhb9Y8R8zCip9Uk .node rect,#mermaid-svg-anhb9Y8R8zCip9Uk .node circle,#mermaid-svg-anhb9Y8R8zCip9Uk .node ellipse,#mermaid-svg-anhb9Y8R8zCip9Uk .node polygon,#mermaid-svg-anhb9Y8R8zCip9Uk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-anhb9Y8R8zCip9Uk .rough-node .label text,#mermaid-svg-anhb9Y8R8zCip9Uk .node .label text,#mermaid-svg-anhb9Y8R8zCip9Uk .image-shape .label,#mermaid-svg-anhb9Y8R8zCip9Uk .icon-shape .label{text-anchor:middle;}#mermaid-svg-anhb9Y8R8zCip9Uk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-anhb9Y8R8zCip9Uk .rough-node .label,#mermaid-svg-anhb9Y8R8zCip9Uk .node .label,#mermaid-svg-anhb9Y8R8zCip9Uk .image-shape .label,#mermaid-svg-anhb9Y8R8zCip9Uk .icon-shape .label{text-align:center;}#mermaid-svg-anhb9Y8R8zCip9Uk .node.clickable{cursor:pointer;}#mermaid-svg-anhb9Y8R8zCip9Uk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-anhb9Y8R8zCip9Uk .arrowheadPath{fill:#333333;}#mermaid-svg-anhb9Y8R8zCip9Uk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-anhb9Y8R8zCip9Uk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-anhb9Y8R8zCip9Uk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-anhb9Y8R8zCip9Uk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-anhb9Y8R8zCip9Uk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-anhb9Y8R8zCip9Uk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-anhb9Y8R8zCip9Uk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-anhb9Y8R8zCip9Uk .cluster text{fill:#333;}#mermaid-svg-anhb9Y8R8zCip9Uk .cluster span{color:#333;}#mermaid-svg-anhb9Y8R8zCip9Uk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-anhb9Y8R8zCip9Uk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-anhb9Y8R8zCip9Uk rect.text{fill:none;stroke-width:0;}#mermaid-svg-anhb9Y8R8zCip9Uk .icon-shape,#mermaid-svg-anhb9Y8R8zCip9Uk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-anhb9Y8R8zCip9Uk .icon-shape p,#mermaid-svg-anhb9Y8R8zCip9Uk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-anhb9Y8R8zCip9Uk .icon-shape .label rect,#mermaid-svg-anhb9Y8R8zCip9Uk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-anhb9Y8R8zCip9Uk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-anhb9Y8R8zCip9Uk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-anhb9Y8R8zCip9Uk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} JSON-RPC
tools/call
真正执行
JSON-RPC 响应
Agent / MCP Client
传输层
stdio 或 HTTP+SSE
MCP Server
Tools 工具
Resources 资源
Prompts 提示
框架SDK 提供的是定义能力的接口 + 通信的实现。
| 2处写自己的代码 | 具体 |
|---|---|
| "定义服务的位置" | SDK 提供声明/注册能力的 API(写 Server 端) |
| "客户端调用的位置" | SDK 提供发现/调用能力的 API(写 Client 端) |
但 SDK 做的远不止提供一个"位置",它把底层协议(JSON-RPC、stdio/HTTP 传输、握手、序列化)全封装了。
以 MCP 为例,SDK 分别提供什么
服务端(Server SDK)------"定义服务"
python
from mcp.server import Server
from mcp.types import Tool
server = Server("my-server")
@server.tool() # ← 定义能力的位置
def get_weather(city: str) -> str:
return f"{city} 晴"
# SDK 负责:注册工具、生成 tools/list 响应、解析 tools/call、回写 JSON-RPC
你只写业务函数,SDK 帮你:
- 把函数注册成 MCP Tool
- 自动生成 JSON Schema(参数描述)
- 监听传输层、解析请求、路由到对应函数
- 把返回值打包成 JSON-RPC 响应
客户端(Client SDK)------"调用服务"
python
from mcp import ClientSession, StdioServerParameters
params = StdioServerParameters(command="python", args=["server.py"])
async with ClientSession(...) as session:
await session.initialize() # ← 握手
tools = await session.list_tools() # ← 发现能力
result = await session.call_tool( # ← 调用能力
"get_weather", {"city": "北京"}
)
你只调高层方法,SDK 帮你:
- 启动/连接 Server(stdio 或 HTTP)
- 完成 initialize 握手、能力协商
- 把
call_tool翻译成tools/call的 JSON-RPC 消息 - 发送、等待、解析响应
所以更准确的说:
SDK 提供的是「定义能力的接口」和「调用能力的接口」,并把底层的 JSON-RPC 协议、传输方式、握手协商全部封装掉。
"位置"只是表象,本质是接口 + 协议实现。
一张图看 SDK 的角色
#mermaid-svg-78xLsJU2dDrI0jXK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-78xLsJU2dDrI0jXK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-78xLsJU2dDrI0jXK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-78xLsJU2dDrI0jXK .error-icon{fill:#552222;}#mermaid-svg-78xLsJU2dDrI0jXK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-78xLsJU2dDrI0jXK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-78xLsJU2dDrI0jXK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-78xLsJU2dDrI0jXK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-78xLsJU2dDrI0jXK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-78xLsJU2dDrI0jXK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-78xLsJU2dDrI0jXK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-78xLsJU2dDrI0jXK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-78xLsJU2dDrI0jXK .marker.cross{stroke:#333333;}#mermaid-svg-78xLsJU2dDrI0jXK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-78xLsJU2dDrI0jXK p{margin:0;}#mermaid-svg-78xLsJU2dDrI0jXK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-78xLsJU2dDrI0jXK .cluster-label text{fill:#333;}#mermaid-svg-78xLsJU2dDrI0jXK .cluster-label span{color:#333;}#mermaid-svg-78xLsJU2dDrI0jXK .cluster-label span p{background-color:transparent;}#mermaid-svg-78xLsJU2dDrI0jXK .label text,#mermaid-svg-78xLsJU2dDrI0jXK span{fill:#333;color:#333;}#mermaid-svg-78xLsJU2dDrI0jXK .node rect,#mermaid-svg-78xLsJU2dDrI0jXK .node circle,#mermaid-svg-78xLsJU2dDrI0jXK .node ellipse,#mermaid-svg-78xLsJU2dDrI0jXK .node polygon,#mermaid-svg-78xLsJU2dDrI0jXK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-78xLsJU2dDrI0jXK .rough-node .label text,#mermaid-svg-78xLsJU2dDrI0jXK .node .label text,#mermaid-svg-78xLsJU2dDrI0jXK .image-shape .label,#mermaid-svg-78xLsJU2dDrI0jXK .icon-shape .label{text-anchor:middle;}#mermaid-svg-78xLsJU2dDrI0jXK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-78xLsJU2dDrI0jXK .rough-node .label,#mermaid-svg-78xLsJU2dDrI0jXK .node .label,#mermaid-svg-78xLsJU2dDrI0jXK .image-shape .label,#mermaid-svg-78xLsJU2dDrI0jXK .icon-shape .label{text-align:center;}#mermaid-svg-78xLsJU2dDrI0jXK .node.clickable{cursor:pointer;}#mermaid-svg-78xLsJU2dDrI0jXK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-78xLsJU2dDrI0jXK .arrowheadPath{fill:#333333;}#mermaid-svg-78xLsJU2dDrI0jXK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-78xLsJU2dDrI0jXK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-78xLsJU2dDrI0jXK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-78xLsJU2dDrI0jXK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-78xLsJU2dDrI0jXK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-78xLsJU2dDrI0jXK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-78xLsJU2dDrI0jXK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-78xLsJU2dDrI0jXK .cluster text{fill:#333;}#mermaid-svg-78xLsJU2dDrI0jXK .cluster span{color:#333;}#mermaid-svg-78xLsJU2dDrI0jXK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-78xLsJU2dDrI0jXK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-78xLsJU2dDrI0jXK rect.text{fill:none;stroke-width:0;}#mermaid-svg-78xLsJU2dDrI0jXK .icon-shape,#mermaid-svg-78xLsJU2dDrI0jXK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-78xLsJU2dDrI0jXK .icon-shape p,#mermaid-svg-78xLsJU2dDrI0jXK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-78xLsJU2dDrI0jXK .icon-shape .label rect,#mermaid-svg-78xLsJU2dDrI0jXK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-78xLsJU2dDrI0jXK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-78xLsJU2dDrI0jXK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-78xLsJU2dDrI0jXK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Client 端
Server 端
stdio / HTTP
JSON-RPC 消息
你写的业务函数
def get_weather(...)
SDK 提供的定义接口
@server.tool()
SDK 封装的协议层
JSON-RPC + 传输
你写的调用代码
session.call_tool(...)
SDK 提供的调用接口
list_tools / call_tool
SDK 封装的协议层
JSON-RPC + 传输
关键点:SDK 抹平了什么
| 你本来要自己做的 | 此时用MCP SDK 做了 |
|---|---|
| 拼 JSON-RPC 报文 | ✅ 自动 |
| 处理 stdio/HTTP 传输 | ✅ 自动 |
| initialize 握手 / 能力协商 | ✅ 自动 |
| 参数 → JSON Schema | ✅ 从函数签名生成 |
| 消息路由到对应函数 | ✅ 自动 |
| 错误码 / 异常转换 | ✅ 自动 |
你只写业务逻辑,协议细节全被 SDK 藏起来了 ------ 这才是 SDK 的真正价值。
二、MCP 防护的技术原理
MCP 防护的技术原理可以拆成三个层面来理解:拦截点、检测机制、执行策略。
| 方式 | 改动点 | 拦截时机 | 适用场景 |
|---|---|---|---|
| 透明代理 | 客户端配置 | JSON-RPC 消息层 | 任意第三方 MCP Server,零代码 ✅ |
| 装饰器 | 工具函数代码 | 函数调用层 | 自己写的工具函数 |
| CLI Shim | PATH / 命令 | 终端命令层 | 命令行/二进制工具 |
2.1 拦截点:在哪里拦住工具调用
MCP 工具调用的请求最终是一个 JSON-RPC 消息,通常以 stdio 或 SSE 传输。防护层需要在这个消息到达真正的 MCP Server 之前把它截住。目前主流的拦截方式有三种:
方式一:透明代理(Proxy) 。这是最推荐的零代码改动方案。你只需在 MCP 客户端的配置里,把目标从原来的 Server 命令改成"防护代理 + 原 Server 命令",代理会拦截所有 tools/call 请求,检查通过后再转发给真正的 Server。
AgentSentrix 的 MCP Proxy 和 mcp-gate 都是这个模式。
#mermaid-svg-dwqrhMtZPALFEXt2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dwqrhMtZPALFEXt2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dwqrhMtZPALFEXt2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dwqrhMtZPALFEXt2 .error-icon{fill:#552222;}#mermaid-svg-dwqrhMtZPALFEXt2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dwqrhMtZPALFEXt2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dwqrhMtZPALFEXt2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dwqrhMtZPALFEXt2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dwqrhMtZPALFEXt2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dwqrhMtZPALFEXt2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dwqrhMtZPALFEXt2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dwqrhMtZPALFEXt2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dwqrhMtZPALFEXt2 .marker.cross{stroke:#333333;}#mermaid-svg-dwqrhMtZPALFEXt2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dwqrhMtZPALFEXt2 p{margin:0;}#mermaid-svg-dwqrhMtZPALFEXt2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-dwqrhMtZPALFEXt2 .cluster-label text{fill:#333;}#mermaid-svg-dwqrhMtZPALFEXt2 .cluster-label span{color:#333;}#mermaid-svg-dwqrhMtZPALFEXt2 .cluster-label span p{background-color:transparent;}#mermaid-svg-dwqrhMtZPALFEXt2 .label text,#mermaid-svg-dwqrhMtZPALFEXt2 span{fill:#333;color:#333;}#mermaid-svg-dwqrhMtZPALFEXt2 .node rect,#mermaid-svg-dwqrhMtZPALFEXt2 .node circle,#mermaid-svg-dwqrhMtZPALFEXt2 .node ellipse,#mermaid-svg-dwqrhMtZPALFEXt2 .node polygon,#mermaid-svg-dwqrhMtZPALFEXt2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dwqrhMtZPALFEXt2 .rough-node .label text,#mermaid-svg-dwqrhMtZPALFEXt2 .node .label text,#mermaid-svg-dwqrhMtZPALFEXt2 .image-shape .label,#mermaid-svg-dwqrhMtZPALFEXt2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-dwqrhMtZPALFEXt2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dwqrhMtZPALFEXt2 .rough-node .label,#mermaid-svg-dwqrhMtZPALFEXt2 .node .label,#mermaid-svg-dwqrhMtZPALFEXt2 .image-shape .label,#mermaid-svg-dwqrhMtZPALFEXt2 .icon-shape .label{text-align:center;}#mermaid-svg-dwqrhMtZPALFEXt2 .node.clickable{cursor:pointer;}#mermaid-svg-dwqrhMtZPALFEXt2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dwqrhMtZPALFEXt2 .arrowheadPath{fill:#333333;}#mermaid-svg-dwqrhMtZPALFEXt2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dwqrhMtZPALFEXt2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dwqrhMtZPALFEXt2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dwqrhMtZPALFEXt2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dwqrhMtZPALFEXt2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dwqrhMtZPALFEXt2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dwqrhMtZPALFEXt2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dwqrhMtZPALFEXt2 .cluster text{fill:#333;}#mermaid-svg-dwqrhMtZPALFEXt2 .cluster span{color:#333;}#mermaid-svg-dwqrhMtZPALFEXt2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dwqrhMtZPALFEXt2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dwqrhMtZPALFEXt2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-dwqrhMtZPALFEXt2 .icon-shape,#mermaid-svg-dwqrhMtZPALFEXt2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dwqrhMtZPALFEXt2 .icon-shape p,#mermaid-svg-dwqrhMtZPALFEXt2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dwqrhMtZPALFEXt2 .icon-shape .label rect,#mermaid-svg-dwqrhMtZPALFEXt2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dwqrhMtZPALFEXt2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dwqrhMtZPALFEXt2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dwqrhMtZPALFEXt2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 1.JSON-RPC 消息
(tools/call)
2. 执行检查
❌ 2.1 拦截,返回错误
✅ 2.1 通过
2.2 JSON-RPC 响应
3. 转发响应
客户端配置改动
原来: server = git-mcp
改成: server = proxy + git-mcp
MCP Client / Agent
防护代理 MCP Proxy
(AgentSentrix / mcp-gate)
安全策略检查
参数校验 / 权限 / 敏感操作
真正的 MCP Server
(原 Server 命令)
特点 :零代码改动,只需改客户端配置,把目标命令换成「代理 + 原命令」。代理拦截所有 tools/call,检查通过再转发。✅ 最推荐。
方式二:Python SDK 装饰器(Decorator) 。在你的工具函数上套一个 @guardrail 或 @intercept_tool 装饰器,函数被调用时自动触发安全检查。Aegis Tool Firewall 和 Agent-Airlock 都提供这种方式。
适合你自己写的工具函数。
#mermaid-svg-kcOfuXJ1NMLuT63h{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kcOfuXJ1NMLuT63h .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kcOfuXJ1NMLuT63h .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kcOfuXJ1NMLuT63h .error-icon{fill:#552222;}#mermaid-svg-kcOfuXJ1NMLuT63h .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kcOfuXJ1NMLuT63h .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kcOfuXJ1NMLuT63h .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kcOfuXJ1NMLuT63h .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kcOfuXJ1NMLuT63h .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kcOfuXJ1NMLuT63h .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kcOfuXJ1NMLuT63h .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kcOfuXJ1NMLuT63h .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kcOfuXJ1NMLuT63h .marker.cross{stroke:#333333;}#mermaid-svg-kcOfuXJ1NMLuT63h svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kcOfuXJ1NMLuT63h p{margin:0;}#mermaid-svg-kcOfuXJ1NMLuT63h .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-kcOfuXJ1NMLuT63h .cluster-label text{fill:#333;}#mermaid-svg-kcOfuXJ1NMLuT63h .cluster-label span{color:#333;}#mermaid-svg-kcOfuXJ1NMLuT63h .cluster-label span p{background-color:transparent;}#mermaid-svg-kcOfuXJ1NMLuT63h .label text,#mermaid-svg-kcOfuXJ1NMLuT63h span{fill:#333;color:#333;}#mermaid-svg-kcOfuXJ1NMLuT63h .node rect,#mermaid-svg-kcOfuXJ1NMLuT63h .node circle,#mermaid-svg-kcOfuXJ1NMLuT63h .node ellipse,#mermaid-svg-kcOfuXJ1NMLuT63h .node polygon,#mermaid-svg-kcOfuXJ1NMLuT63h .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kcOfuXJ1NMLuT63h .rough-node .label text,#mermaid-svg-kcOfuXJ1NMLuT63h .node .label text,#mermaid-svg-kcOfuXJ1NMLuT63h .image-shape .label,#mermaid-svg-kcOfuXJ1NMLuT63h .icon-shape .label{text-anchor:middle;}#mermaid-svg-kcOfuXJ1NMLuT63h .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kcOfuXJ1NMLuT63h .rough-node .label,#mermaid-svg-kcOfuXJ1NMLuT63h .node .label,#mermaid-svg-kcOfuXJ1NMLuT63h .image-shape .label,#mermaid-svg-kcOfuXJ1NMLuT63h .icon-shape .label{text-align:center;}#mermaid-svg-kcOfuXJ1NMLuT63h .node.clickable{cursor:pointer;}#mermaid-svg-kcOfuXJ1NMLuT63h .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kcOfuXJ1NMLuT63h .arrowheadPath{fill:#333333;}#mermaid-svg-kcOfuXJ1NMLuT63h .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kcOfuXJ1NMLuT63h .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kcOfuXJ1NMLuT63h .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kcOfuXJ1NMLuT63h .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kcOfuXJ1NMLuT63h .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kcOfuXJ1NMLuT63h .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kcOfuXJ1NMLuT63h .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kcOfuXJ1NMLuT63h .cluster text{fill:#333;}#mermaid-svg-kcOfuXJ1NMLuT63h .cluster span{color:#333;}#mermaid-svg-kcOfuXJ1NMLuT63h div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kcOfuXJ1NMLuT63h .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kcOfuXJ1NMLuT63h rect.text{fill:none;stroke-width:0;}#mermaid-svg-kcOfuXJ1NMLuT63h .icon-shape,#mermaid-svg-kcOfuXJ1NMLuT63h .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kcOfuXJ1NMLuT63h .icon-shape p,#mermaid-svg-kcOfuXJ1NMLuT63h .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kcOfuXJ1NMLuT63h .icon-shape .label rect,#mermaid-svg-kcOfuXJ1NMLuT63h .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kcOfuXJ1NMLuT63h .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kcOfuXJ1NMLuT63h .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kcOfuXJ1NMLuT63h :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 调用工具函数
❌ 不通过,抛异常/返回拒绝
✅ 通过
包装后返回
代码层面
@guardrail
def my_tool(args):
...
MCP Client / Agent
工具函数
@guardrail / @intercept_tool
装饰器包装层
(Aegis Tool Firewall / Agent-Airlock)
安全检查
参数 / 行为 / 策略
原始工具函数体
真正执行逻辑
返回执行结果
特点 :适合你自己写的工具函数。在函数上套装饰器,函数被调用时自动触发安全检查,无需改客户端,但要改工具代码。
方式三:CLI Shim 。用防护层的命令行工具"包裹"真正的终端命令,比如 agentsentrix shim install --binary git,之后所有 git 调用都会先经过安全层。
#mermaid-svg-VoPhzzRf7RMVi9Bv{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VoPhzzRf7RMVi9Bv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VoPhzzRf7RMVi9Bv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VoPhzzRf7RMVi9Bv .error-icon{fill:#552222;}#mermaid-svg-VoPhzzRf7RMVi9Bv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VoPhzzRf7RMVi9Bv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VoPhzzRf7RMVi9Bv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VoPhzzRf7RMVi9Bv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VoPhzzRf7RMVi9Bv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VoPhzzRf7RMVi9Bv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VoPhzzRf7RMVi9Bv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VoPhzzRf7RMVi9Bv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VoPhzzRf7RMVi9Bv .marker.cross{stroke:#333333;}#mermaid-svg-VoPhzzRf7RMVi9Bv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VoPhzzRf7RMVi9Bv p{margin:0;}#mermaid-svg-VoPhzzRf7RMVi9Bv .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-VoPhzzRf7RMVi9Bv .cluster-label text{fill:#333;}#mermaid-svg-VoPhzzRf7RMVi9Bv .cluster-label span{color:#333;}#mermaid-svg-VoPhzzRf7RMVi9Bv .cluster-label span p{background-color:transparent;}#mermaid-svg-VoPhzzRf7RMVi9Bv .label text,#mermaid-svg-VoPhzzRf7RMVi9Bv span{fill:#333;color:#333;}#mermaid-svg-VoPhzzRf7RMVi9Bv .node rect,#mermaid-svg-VoPhzzRf7RMVi9Bv .node circle,#mermaid-svg-VoPhzzRf7RMVi9Bv .node ellipse,#mermaid-svg-VoPhzzRf7RMVi9Bv .node polygon,#mermaid-svg-VoPhzzRf7RMVi9Bv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VoPhzzRf7RMVi9Bv .rough-node .label text,#mermaid-svg-VoPhzzRf7RMVi9Bv .node .label text,#mermaid-svg-VoPhzzRf7RMVi9Bv .image-shape .label,#mermaid-svg-VoPhzzRf7RMVi9Bv .icon-shape .label{text-anchor:middle;}#mermaid-svg-VoPhzzRf7RMVi9Bv .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VoPhzzRf7RMVi9Bv .rough-node .label,#mermaid-svg-VoPhzzRf7RMVi9Bv .node .label,#mermaid-svg-VoPhzzRf7RMVi9Bv .image-shape .label,#mermaid-svg-VoPhzzRf7RMVi9Bv .icon-shape .label{text-align:center;}#mermaid-svg-VoPhzzRf7RMVi9Bv .node.clickable{cursor:pointer;}#mermaid-svg-VoPhzzRf7RMVi9Bv .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VoPhzzRf7RMVi9Bv .arrowheadPath{fill:#333333;}#mermaid-svg-VoPhzzRf7RMVi9Bv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VoPhzzRf7RMVi9Bv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VoPhzzRf7RMVi9Bv .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VoPhzzRf7RMVi9Bv .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VoPhzzRf7RMVi9Bv .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VoPhzzRf7RMVi9Bv .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VoPhzzRf7RMVi9Bv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VoPhzzRf7RMVi9Bv .cluster text{fill:#333;}#mermaid-svg-VoPhzzRf7RMVi9Bv .cluster span{color:#333;}#mermaid-svg-VoPhzzRf7RMVi9Bv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VoPhzzRf7RMVi9Bv .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VoPhzzRf7RMVi9Bv rect.text{fill:none;stroke-width:0;}#mermaid-svg-VoPhzzRf7RMVi9Bv .icon-shape,#mermaid-svg-VoPhzzRf7RMVi9Bv .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VoPhzzRf7RMVi9Bv .icon-shape p,#mermaid-svg-VoPhzzRf7RMVi9Bv .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VoPhzzRf7RMVi9Bv .icon-shape .label rect,#mermaid-svg-VoPhzzRf7RMVi9Bv .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VoPhzzRf7RMVi9Bv .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VoPhzzRf7RMVi9Bv .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VoPhzzRf7RMVi9Bv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} git push / git clone ...
❌ 拦截,返回非零退出码
✅ 通过
透传结果
安装时
PATH 中 shim 优先于原 binary
git → shim → 真正的 git
Agent / 进程
调用 git 命令
Shim 可执行文件
agentsentrix shim install --binary git
安全层检查
命令 / 参数 / 危险操作
真正的二进制
(原 git 命令)
实际执行
返回 stdout/stderr/exit code
特点 :用命令行工具"包裹"真正的终端命令。安装后所有 git 调用都先经过安全层。适合命令行/终端类工具的拦截。
2.2 检测机制:检查什么
拦截到调用后,防护层要判断这个调用是否危险。检测机制通常分层级,从快到慢、从便宜到贵:
第一层:确定性规则。这是最基础也最必要的。
包括:
-
工具名黑名单(禁止调用
delete_*、drop_*) -
参数模式匹配(检测 shell 注入字符
;、|、&&、路径穿越../) -
参数值边界(金额是否超过阈值)
AgentSentrix 的 Tier 0 在约 1ms 内完成 YAML 策略评估和密钥熵检测。
第二层:启发式/行为分析 。检测器不只看单次调用的参数,还看调用序列。比如"先读敏感文件、再调 HTTP 外发"这种多步数据外泄链,单看任何一步都正常,组合起来就是攻击。
mcp-gate 的威胁扫描器会检查参数中的 Prompt 注入、命令注入、密钥外泄迹象。
第三层:模型判断。对于模糊情况,用一个小模型做最终裁决。
AgentSentrix 的 Tier 1 用本地 Ollama 检查 Prompt 注入和意图漂移(约 50ms),Tier 2 用 Groq 上的 LLM 做裁判处理风险评分在 30-70 之间的模糊请求(约 300ms)。SpiderShield 也有类似的运行时防护。
2.3 执行策略:拦住之后怎么办
检测出风险后,防护层可以采取不同的执行动作:
- Allow:放行。
- Deny:直接拒绝,Agent 收到 JSON-RPC 错误,工具永远不会执行。
- Require Approval:挂起调用,等待人工在 Dashboard 上确认或拒绝。AgentSentrix 的 Human-in-the-Loop Quarantine 就是这个模式。
- Redact :对参数做脱敏后放行,比如把信用卡号替换成
[REDACTED]。 - Sandbox:在隔离环境中执行,即使代码有恶意也影响不到宿主系统。Agent-Airlock 用 E2B Firecracker MicroVM,启动约 125ms,预热后延迟低于 200ms。
三、免费/开源工具对比
以下是 MCP 防护领域目前可用的免费或开源工具,按定位分类。
3.1 通用 MCP 安全网关
| 工具 | 定位 | 核心能力 | 接入方式 |
|---|---|---|---|
| AgentSentrix | 实时 Agent 安全网关 | 三层风险管线(规则→Ollama→LLM 裁判),人工隔离,3D 可视化 | MCP Proxy / SDK 装饰器 / Shell Shim |
| mcp-gate | 策略驱动的 MCP 防火墙 | 首匹配规则引擎,四类执行效果,每 Agent 密码学身份,防篡改审计日志 | stdio MCP Proxy |
| mcp-aegis | 生产加固的 MCP 代理 | OAuth 2.1/JWT 认证,RBAC 策略,参数消毒,有状态限流 | CLI Shim / Python 库 |
| MCPVanguard | 分层 MCP 安全网关 | L0-L3 五层检测(预检→规则→伪装检测→语义→行为),支持 stdio 和 HTTP | stdio / SSE / Streamable HTTP |
AgentSentrix 是目前功能最完整的开源选择。
它的三层风险管线设计很务实:
-
第一层 YAML 规则(0-1ms)覆盖大部分已知威胁
-
第二层本地小模型(~50ms)处理意图漂移
-
第三层才调云端 LLM(~300ms)处理模糊情况。
这种分层让它在成本和覆盖率之间取得了平衡。
mcp-gate 的特色是审计日志的防篡改性。
它用 SHA-256 哈希链记录每一条工具调用,verify() 命令可以检测任何编辑、重排或删除。对于需要合规审计的医学场景,这个特性很重要。
3.2 工具调用防火墙(更聚焦于执行拦截)
| 工具 | 定位 | 核心能力 | 接入方式 |
|---|---|---|---|
| Aegis Tool Firewall | 轻量工具调用防火墙 | 拦截破坏性命令,脱敏敏感载荷,审计日志降级容错 | @guardrail 装饰器 |
| Agent-Airlock | MCP Server 的 Pydantic 防火墙 | 剥离幻觉参数、严格类型验证、沙箱执行(Firecracker MicroVM) | @Airlock() 装饰器 |
| Strathon | 开源 Agent 防火墙 | CEL 策略在工具调用边界强制执行,支持 7 种执行动作,10+ 框架集成 | SDK instrument |
| mcp-guard | MCP 调用的输入验证层 | Shell 注入、路径穿越、SSRF 检测,响应异常监控 | Proxy / Python API / CLI |
Agent-Airlock 解决了一个很实际的问题:LLM 会幻觉出不存在的参数。
Claude 可能给你的函数发 force=True,但你的函数签名里根本没有这个参数,结果直接崩溃。
Airlock 会自动剥离这些"幽灵参数",并给 LLM 返回结构化的修复提示,让 Agent 重试。
Strathon 的 CEL(Common Expression Language)策略引擎值得关注。
CEL 是 Google 开源的表达式语言,安全、高效、无副作用。
用它写策略比写 Python 代码更安全,也更容易审计。
3.3 专注特定防护方向
| 工具 | 专注方向 | 核心能力 |
|---|---|---|
| MCPKernel | 数据外泄链检测 | Taint 追踪,DLP 链检测,防止多跳数据泄露(数据库→HTTP 被拦截),4 种沙箱后端 |
| Little Canary | 牺牲模型行为探测 | 用小的"金丝雀"模型(qwen2.5:1.5b)先试输入,检测行为妥协,250ms |
| SpiderShield | MCP Server 扫描+运行时 | 静态安全扫描,工具描述重写,代理模式运行时防护 |
| Fendrix | Prompt 注入检测 | 三层管线:规则(75% 覆盖)→启发式评分→LLM 裁判 |
MCPKernel 的 Taint 追踪是数据外泄防护的核心思路。
它不只是看单次调用,而是追踪数据的"污染标签":
- 如果 Agent 从数据库读到了 PII,这个 PII 就被打上 taint 标签;
- 如果后续任何工具调用试图把这个数据发到 HTTP 端点,DLP 链检测就会拦截。这能防住"分多步慢慢偷数据"的攻击模式。
Little Canary 的"牺牲模型"思路很独特。
传统防护是分类输入文本,Little Canary 是把输入喂给一个故意做得很弱的小模型,观察这个小模型会不会被攻破。
如果小模型都被攻破了,说明攻击强度很高,生产模型也很危险。
它的检测率在 TensorTrust 基准上达到 99%,但代价是每次检查约 250ms。
四、给前文医学 Agent 的选型建议
结合之前讨论的架构(Ollama + Qdrant + LangGraph),MCP 防护可以这样落地:
1. 首选 AgentSentrix 作为 MCP 代理层 。它的分层检测和人工隔离机制,正好匹配医学场景"高风险操作需要人工确认"的需求。你可以把 prescribe_drug、delete_record 这类工具标记为需要审批,其他只读工具自动放行。
2. MCPKernel 的 Taint 追踪作为数据外泄的第二道防线。医学场景对 PII/PHI 保护要求极高,Taint 追踪能防住"先查病历、再通过其他工具外发"的隐蔽攻击。
3. Agent-Airlock 作为你自研工具的保护层 。如果你在 FastMCP 里定义了很多工具函数,用 @Airlock() 装饰器能自动处理参数验证和沙箱执行,减少自己写安全逻辑的工作量。
如果要从零开始,mcp-gate 是最轻量的起点 ------纯 stdio 代理,零运行时依赖,YAML 策略配置,pip install 就能跑起来。验证效果后再叠加更复杂的防护层。