内容
# 工具使用防火墙
[](https://github.com/reaatech/tool-use-firewall/actions/workflows/ci.yml)
[](LICENSE)
[](https://www.typescriptlang.org/)
[](https://pnpm.io/)
[](https://vitest.dev/)
> **AI 代理与 MCP 服务器之间的策略强制层** — 拦截、验证和保护每个工具调用,防止其到达上游。
---
## 为什么使用工具使用防火墙?
AI 代理功能强大,但也可能带来危险。一次错误的 `DROP TABLE` 或 `rm -rf /` 操作可能会毁掉数小时的工作。该项目位于您的 AI 代理和 MCP 服务器之间,作为每次工具调用的**安全卫士**,实现速率限制、参数验证、成本跟踪、只读强制和人工审批链。
如果您正在部署与数据库、文件系统或任何 MCP 服务器通信的 AI 代理,那么这就是您的安全网。
---
## 架构
```
┌─────────────────┐ ┌──────────────────────┐ ┌─────────────────┐
│ AI 代理 │────▶│ 工具使用防火墙 │────▶│ 上游 MCP 服务器 │
│ (Claude, │ │ (拦截器管道) │ │ (数据库, │
│ GPT, 等) │◀────│ │◀────│ 文件系统, 网络, │
└─────────────────┘ └──────────────────────┘ │ 等) │
└─────────────────┘
```
拦截器管道按严格的顺序强制执行策略:
```
请求 → 速率限制器 → 成本跟踪器 → 机密扫描器 → 参数验证器
→ 模式验证器 → 策略引擎 → 只读检查 → 异常检测器
→ 审批工作流 → 审计日志器 → 上游
```
仅当在策略中启用时,才会注册阶段(例如,机密扫描、模式验证和异常检测是按需开启的)。入站 JSON-RPC 帧可以是单个消息或批次(顶级数组);批次中的每个 `tools/call` 都被独立拦截。
数据流详情和状态管理:[架构文档](./ARCHITECTURE.md)
---
## 功能
### 策略引擎
- **规则评估** — 按工具名称、参数值和自定义条件阻止、允许或要求审批
- **基于优先级的匹配** — 按优先级顺序评估规则;优先匹配获胜
- **通配符模式匹配** — `db.*` 匹配 `db.execute`、`db.query` 等
### 速率限制
- **令牌桶算法** — 全局、每工具和每会话限制
- **有界内存** — 基于 TTL 的驱逐防止内存耗尽
- **突发容量** — 可配置的突发许可用于流量峰值
### 参数验证
- **SQL 注入检测** — 针对已知危险模式的模式匹配
- **Shell 注入防护** — 阻止诸如 `;`、`&&`、`` ` ``、 `$()` 之类的元字符
- **自定义正则表达式模式** — 每个工具/参数的用户定义验证
- **JSON 模式验证** — 验证 `tools/call` 参数是否符合上游公布的 `inputSchema`
- **ReDoS 防护** — 编译前验证所有正则表达式模式的安全性
### 机密扫描
- **出站机密检测** — 阻止参数中包含 API 密钥、令牌或其他机密的工具调用
- **自定义模式** — 为每个部署定义命名模式
### 异常检测
- **行为基准** — 标记偏离会话最近模式的工具调用
- **可配置的灵敏度** — 按策略调整窗口大小和阈值
### 只读模式
- **全局切换** — 启用时阻止所有写操作
- **每工具例外** — 允许列表用于只读安全的工具
- **突破玻璃令牌** — 用于紧急情况的时限安全绕过
### 成本跟踪
- **每会话预算** — 为昂贵的工具调用强制执行成本限制
- **工具级定价** — 按调用次数分配成本
- **可配置操作** — 预算超额时阻止或警告
### 审批工作流
- **多级链** — 需要多个组的审批
- **超时处理** — 过期审批自动拒绝
- **多个接口** — HTTP API、CLI 提示、Webhook、Slack 和 Discord 通知
- **自动审批** — 可选地,在安全调用达到阈值后自动审批受信任的工具
- **速率限制 API** — 审批 HTTP 端点上的每 IP 令牌桶
### 审计日志
- **结构化 JSON** — 每个决策都记录在完整的上下文中
- **敏感数据编辑** — API 密钥、令牌、电子邮件自动编辑
- **级别控制** — `none`、`summary` 或 `full` 详细程度
- **文件和边车输出** — 将事件写入旋转的本地文件(每天/大小旋转,最大文件保留,gzip)并/或通过 HTTP 将它们转发到边车/SIEM 端点(stdout 保留用于 MCP JSON-RPC 流)
### 传输和路由
- **stdio 和 HTTP** — 默认情况下作为 stdio 代理运行或公开 HTTP 传输
- **多上游** — 通过通配符模式将工具路由到不同的上游 MCP 服务器
- **时间窗口** — 使用时区支持限制规则在特定日期/小时内
### 操作
- **策略热重载** — 编辑策略文件后无需重启即可生效
- **干运行/影子模式** — 记录将被阻止的内容而不强制执行
- **Prometheus 指标** — 可选的 `/metrics` 端点(请求、阻止、审批、延迟)
- **`--init` 搭建** — 从上游的 `tools/list` 生成启动策略
- **`--validate` 校验** — 在 CI 中验证策略(模式 + ReDoS)而无需启动代理
---
## 安装
已发布的入口点是 **[`工具使用防火墙`](https://www.npmjs.com/package/tool-use-firewall)**,它提供了 `工具使用防火墙` 二进制文件,并引入了 `@reaatech/工具使用防火墙-*` 包。您可以通过 `npx` 运行它而无需安装:
```bash
npx 工具使用防火墙 \
--config ./policy.yaml \
--upstream node ./my-mcp-server.js
```
或全局安装 CLI:
```bash
npm install -g 工具使用防火墙
工具使用防火墙 --config ./policy.yaml --upstream node ./my-mcp-server.js
```
> 需要 Node.js ≥ 20。
>
> `工具使用防火墙` 是 [`@reaatech/工具使用防火墙-服务器`](https://www.npmjs.com/package/@reaatech/tool-use-firewall-server) 的薄别名 — 使用任一名称皆可。对于较窄的依赖表面,直接导入作用域 `@reaatech/工具使用防火墙-*` 包。
### 快速入门
从上游服务器的工具列表生成启动策略,然后针对它运行防火墙:
```bash
# 1. 从上游的 tools/list 搭建 policy.generated.yaml
工具使用防火墙 --init --upstream node ./my-mcp-server.js
# 2. 验证它(模式 + ReDoS 检查)- 失败时退出非零,适用于 CI
工具使用防火墙 --validate ./policy.generated.yaml
# 3. 运行代理
工具使用防火墙 --config ./policy.generated.yaml --upstream node ./my-mcp-server.js
```
要插入 MCP 客户端(例如 Claude Desktop),请将客户端指向防火墙而不是上游:
```json
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": [
"@reaatech/tool-use-firewall-server",
"--config", "/abs/path/to/policy.yaml",
"--upstream", "node",
"--", "/abs/path/to/my-mcp-server.js"
]
}
}
}
```
启用人工审批 API:
```bash
export APPROVAL_API_TOKEN="$(openssl rand -hex 32)"
工具使用防火墙 \
--config ./policy.yaml \
--upstream node ./my-mcp-server.js \
--approval-port 8080
```
在容器化/脚本环境中使用 `--upstream-args`,其中上游命令及其参数是单个字符串:
```bash
工具使用防火墙 --config ./policy.yaml --upstream node --upstream-args "./my-mcp-server.js --port 9000"
```
### 程序化使用
```ts
import { MCPProxyServer } from '@reaatech/tool-use-firewall-server';
const server = new MCPProxyServer({
policyPath: './policy.yaml',
upstreamCommand: 'node',
upstreamArgs: ['./my-mcp-server.js'],
});
await server.start();
```
### 从源码(贡献者)
```bash
git clone https://github.com/reaatech/tool-use-firewall.git
cd tool-use-firewall
pnpm install
pnpm build
pnpm test
# 在示例上游服务器上运行本地构建
pnpm dev -- --config ./policies/default.yaml --upstream node ./examples/basic-proxy/upstream-server.js
```
---
## CLI 参考
```
工具使用防火墙 --config <path> --upstream <command> [options]
```
| 标志 | 描述 |
| ---- | ----------- |
| `--config, -c <path>` | 策略 YAML 文件的路径(运行代理所需) |
| `--upstream, -u <command>` | 启动上游 MCP 服务器的命令(运行代理所需) |
| `--upstream-args <string>` | 上游的参数,用于脚本环境 |
| `--approval-port <port>` | 人工审批 HTTP API 的端口 |
| `--http-port <port>` | HTTP 传输的端口 |
| `--dry-run` | 影子模式:记录将被阻止的内容而不强制执行 |
| `--init` | 从上游的 `tools/list` 搭建 `policy.generated.yaml` |
| `--validate <path>` | 验证策略(模式 + ReDoS)并在失败时退出非零 |
| `--help, -h` | 显示帮助 |
| `--version, -v` | 显示版本 |
`--` 之后的參數會被傳遞給上游:
```bash
工具使用防火墙 --config p.yaml --upstream node -- ./mcp-server.js --port 9000
```
---
## 软件包
| 软件包 | 描述 | 依赖 |
| ------- | ----------- | ------------ |
| [`core`](./packages/core) | 类型、错误类、日志记录器、编辑器、安全正则表达式 | (无) |
| [`config`](./packages/config) | 策略 YAML 模式(Zod)和加载器 | `core`、`yaml`、`zod` |
| [`policies`](./packages/policies) | 策略引擎、速率限制器、成本跟踪器、验证器 | `core`、`config` |
| [`approvals`](./packages/approvals) | 审批工作流、HTTP API、CLI/Webhook 审批器 | `core`、`config`、`policies`、`express`、`zod` |
| [`audit`](./packages/audit) | 带有编辑的审计日志 | `core`、`config` |
---
## 策略配置
参阅 [`policies/`](./policies/) 获取示例 YAML 文件:
| 策略 | 描述 |
| ------ | ----------- |
| [`default.yaml`](./policies/default.yaml) | 合理的默认值 — 速率限制、SQL 安全、Shell 安全 |
| [`database-safe.yaml`](./policies/database-safe.yaml) | 面向数据库的策略,带有严格的 SQL 验证 |
| [`read-only.yaml`](./policies/read-only.yaml) | 只读模式,带有绕过令牌支持 |
---
## 文档
| 文档 | 内容 |
| -------- | ------- |
| [架构文档](./ARCHITECTURE.md) | 系统设计、管道流、资源管理 |
| [贡献指南](./CONTRIBUTING.md) | 开发设置、约定提交、PR 流程 |
| [代理指南](./AGENTS.md) | AI 代理的编码约定和指南 |
| [安全政策](./SECURITY.md) | 安全政策和漏洞报告 |
---
## 技术栈
| 层 | 技术 |
| ----- | ---------- |
| 语言 | TypeScript 5.8(严格模式) |
| 运行时 | Node.js ≥ 20 |
| 包管理器 | pnpm 10(工作区) |
| 构建 | tsup + Turborepo |
| 校验和格式化 | Biome |
| 测试 | Vitest |
| 验证 | Zod |
| 模式 | YAML |
---
## 贡献
欢迎贡献。请参阅 [CONTRIBUTING.md](./CONTRIBUTING.md) 获取完整的工作流程:
1. 复刻仓库,创建功能分支
2. 编写带有测试(`vitest`)的代码,使用 `biome` 进行校验
3. 在提交前运行 `pnpm lint && pnpm test`
4. 使用 [Conventional Commits](https://www.conventionalcommits.org/)
5. 打开 PR
---
## 许可证
[MIT](./LICENSE) © [Rick Somers](https://reaatech.com)