🔥 MCP动作防火墙
  
适用于任何MCP兼容代理
     
透明 MCP代理 拦截危险的工具调用,并要求 基于OTP的人工审批 在执行之前。充当您的AI代理和任何MCP服务器之间的断路器。
运作原理
┌──────────┐ stdin/stdout ┌──────────────────┐ stdin/stdout ┌──────────────────┐
│ AI Agent │ ◄────────────────► │ MCP Action │ ◄────────────────► │ Target MCP Server│
│ (Claude) │ │ Firewall │ │ (e.g. Stripe) │
└──────────┘ └──────────────────┘ └──────────────────┘
│
Policy Engine
┌───────────────┐
│ Allow? Block? │
│ Generate OTP │
└───────────────┘MCP服务器不像web服务器那样运行——端口上没有后台进程。相反,你的AI代理(Claude、Cursor等) 将MCP服务器作为子进程生成 并通过stdin/stdout与它进行通信。聊天结束后,进程终止。
防火墙将自己插入到该链中:
Without firewall:
Claude ──spawns──► mcp-server-stripe
With firewall:
Claude ──spawns──► mcp-action-firewall ──spawns──► mcp-server-stripe所以你只是 替换服务器命令 在带有防火墙的MCP客户端配置中,告诉防火墙原始命令是什么:
之前 (直接):
{ "command": "uvx", "args": ["mcp-server-stripe", "--api-key", "sk_test_..."] }之后 (用防火墙包裹):
{ "command": "uv", "args": ["run", "mcp-action-firewall", "--target", "mcp-server-stripe --api-key sk_test_..."] }然后防火墙应用您的安全策略:
- ✅ 安全通话 (例如。
get_balance) → 立即转发 - 🛑 危险电话 (例如。
delete_user) → 已阻止,生成OTP - 🔑 代理向用户询问代码→ 用户回复→ 客服电话
firewall_confirm→ 原始动作执行
安装
pip install mcp-action-firewall
# or
uvx mcp-action-firewall --help快速入门--MCP客户端配置
在客户端配置中添加防火墙作为任何MCP服务器的包装器:
{
"mcpServers": {
"stripe": {
"command": "uv",
"args": ["run", "mcp-action-firewall", "--target", "mcp-server-stripe --api-key sk_test_abc123"]
}
}
}就是这样。之后的一切 --target 是 完整shell命令 启动真正的MCP服务器,包括它自己的标志,如 --api-key防火墙不会触及这些参数,它只是生成目标并位于其前面。
更多示例
Claude Desktop with per-server rules
{
"mcpServers": {
"stripe": {
"command": "uv",
"args": [
"run", "mcp-action-firewall",
"--target", "uvx mcp-server-stripe --api-key sk_test_...",
"--name", "stripe"
]
},
"database": {
"command": "uv",
"args": [
"run", "mcp-action-firewall",
"--target", "uvx mcp-server-postgres --connection-string postgresql://...",
"--name", "database",
"--config", "/path/to/my/firewall_config.json"
]
}
}
}Cursor / Other MCP Clients
{
"mcpServers": {
"github": {
"command": "uvx",
"args": [
"mcp-action-firewall",
"--target", "npx @modelcontextprotocol/server-github"
]
}
}
}OTP流程
当代理尝试调用被阻止的工具时,防火墙会返回结构化响应:
{
"status": "PAUSED_FOR_APPROVAL",
"message": "⚠️ The action 'delete_user' is HIGH RISK and has been locked by the Action Firewall.",
"action": {
"tool": "delete_user",
"arguments": { "id": 42 }
},
"instruction": "To unlock this action, you MUST ask the user for authorization.\n\n1. Show the user the following and ask for approval:\n Tool: **delete_user**\n Arguments:\n{\"id\": 42}\n\n2. Tell the user: 'Please reply with approval code: **9942**' to allow this action, or say no to cancel.\n3. STOP and wait for their reply.\n4. When they reply with '9942', call the 'firewall_confirm' tool with that code.\n5. If they say no or give a different code, do NOT retry."
}参数可见性保证: 向用户显示的参数在拦截时被冻结——它们来自原始被阻止的调用,而不是来自代理传递给的调用 firewall_confirm。颁发OTP后,代理无法更改参数。这 firewall_confirm 工具会自动注入到服务器的工具列表中:
{
"name": "firewall_confirm",
"description": "Call this tool ONLY when the user provides the correct 4-digit approval code to confirm a paused action.",
"inputSchema": {
"type": "object",
"properties": {
"otp": {
"type": "string",
"description": "The 4-digit code provided by the user."
}
},
"required": ["otp"]
}
}配置
防火墙附带了合理的默认设置。覆盖 --config:
{
"global": {
"allow_prefixes": ["get_", "list_", "read_", "fetch_"],
"block_keywords": ["delete", "update", "create", "pay", "send", "transfer", "drop", "remove", "refund"],
"default_action": "block",
"otp_attempt_count": 1
},
"servers": {
"stripe": {
"allow_prefixes": [],
"block_keywords": ["refund", "charge"],
"default_action": "block"
},
"database": {
"allow_prefixes": ["select_"],
"block_keywords": ["drop", "truncate", "alter"],
"default_action": "block"
}
}
}规则评估顺序:
- 工具名称以允许前缀开头→ 允许
- 工具名称包含块关键字→ 块 (需要OTP)
- 不匹配→ 回退到
default_action
otp_attempt_count --在挂起的操作被永久锁定之前,OTP尝试失败的最大次数。默认为 1 (任何错误的代码都会取消请求)。提高用户体验,保持宽容 1 为了最大限度的安全。
按服务器规则 扩展(而不是替换)全局规则。使用 --name stripe 激活服务器特定的覆盖。
CLI参考
--target (必填)
启动真实MCP服务器的完整命令。这是您要保护的服务器:
mcp-action-firewall --target "mcp-server-stripe --api-key sk_test_abc123"
mcp-action-firewall --target "npx @modelcontextprotocol/server-github"
mcp-action-firewall --target "uvx mcp-server-postgres --connection-string postgresql://localhost/mydb"--name (可选)
从配置中激活每台服务器的规则。没有它,只有全局规则适用:
mcp-action-firewall --target "mcp-server-stripe" --name stripe--config (可选)
自定义配置文件路径。没有它,使用 firewall_config.json 在当前目录中,或捆绑的默认值:
mcp-action-firewall --target "mcp-server-stripe" --config /path/to/my_rules.json-v / --verbose (可选)
打开调试日志记录(写入stderr,不会干扰MCP流量):
mcp-action-firewall --target "mcp-server-stripe" -v项目结构
src/mcp_action_firewall/
├── __init__.py # Package version
├── __main__.py # python -m support
├── server.py # CLI entry point
├── proxy.py # JSON-RPC stdio proxy
├── policy.py # Allow/block rule engine
├── state.py # OTP store with TTL
└── default_config.json # Bundled default rules试试看——互动演示
无需任何设置即可查看防火墙的运行情况:
git clone https://github.com/starskrime/mcp-action-firewall.git
cd mcp-action-firewall
uv sync
uv run python demo.py该演示模拟了一个AI代理,并引导您完成完整的OTP流程:
- ✅ 安全通话 (
get_balance) → 瞬间通过 - 🛑 危险电话 (
delete_user) → 已阻止,生成OTP - 🔑 您输入代码 → 批准后执行操作
已知限制
论据检查
防火墙已打开 仅工具名称,而不是参数值。这意味着一个类似的工具 get_data({"sql": "DROP TABLE users"}) 如果 get_ 在您的允许列表中,因为策略引擎只看到 get_data.
解决方法: 在允许/阻止列表中使用明确的工具名称并设置 "default_action": "block" 因此,无法识别的工具需要获得批准。
🚧 路线图: 参数级别检查(扫描参数值 block_keywords)计划在未来发布。发展
# Install dev dependencies
uv sync
# Run tests
uv run pytest tests/ -v
# Run the firewall locally
uv run mcp-action-firewall --target "your-server-command" -v许可证
麻省理工学院
