Safety Fence MCP
README.md
# Safety Fence MCP
这是验收版 `SKILL.md` 的本地 MCP Server 最小实现。它通过唯一工具
`guard_payload` 对本地任务或即将外发的精确 payload 做 `ALLOW`、
`REWRITE`、`REFUSE` 判定。
当前策略基线:
```text
sha256:24fdc1b886003e5a76cfc8e8103bbcc5afead5c0f9d3af0167462bf76055e3d7
```
## 安全边界
- Server 使用本地 `stdio`,无网络依赖、无外部模型调用、无遥测。
- `ALLOW` 不复制原始 payload;`REWRITE` 只返回安全 payload;`REFUSE` 不返回原文。
- 日志接口只包含决策、原因代码、目标类型、字节数和脱敏数量。
- MCP 本身是决策面,不是透明代理。OpenClaw 必须在可信外发边界强制调用并执行结果。
- 围栏超时、进程异常或返回无效结构时,调用方必须 fail-closed,禁止本次外发。
## 启动
无需安装第三方依赖:
```powershell
python -m safety_fence
```
也可以安装为本地包后使用命令:
```powershell
python -m pip install -e .
safety-fence-mcp
```
MCP 客户端配置见 `mcp-config.example.json`。`cwd` 必须替换为本项目绝对路径。
## 工具输入
```json
{
"flow": "EGRESS",
"task_context": "用云端模型总结随访重点",
"payload": {
"message": "患者韩珂,手机号 13500006666"
},
"destination": {
"kind": "cloud_model",
"name": "remote-model"
}
}
```
`flow` 必须由可信拦截器填写,不能采用模型自行声明的值。`EGRESS` 必须提供
`destination.kind`。`payload` 支持任意 JSON,默认最大 2 MiB、最大嵌套 32 层。
返回值同时提供 MCP 文本兼容内容和 `structuredContent`:
```json
{
"policy_version": "sha256:...",
"decision": "REWRITE",
"reason_codes": ["PHONE", "ROLE_BOUND_NAME"],
"reason": "敏感信息属于附带上下文,已最小化处理。",
"rewritten_payload": {
"message": "患者<REDACTED>,手机号 <REDACTED>"
},
"user_notice": "为保护隐私与安全,已使用脱敏或最小化后的 payload 继续。",
"redaction_count": 2
}
```
## 强制执行
`safety_fence.interceptor.EgressInterceptor` 是最小参考适配器:
- `ALLOW`:把原始 payload 交给 sender。
- `REWRITE`:只把 `rewritten_payload` 交给 sender。
- `REFUSE`:不调用 sender。
- 引擎或审计异常:不调用 sender,并抛出 `FenceUnavailable`。
生产接入时,应把同样的状态机放到云模型、远程工具、HTTP API、邮件、聊天、
仓库、远程日志和 Telemetry 的共同出口,而不是让 Agent 自主决定是否调用围栏。
## 验证
```powershell
python -m unittest discover -s tests -v
```
测试覆盖验收版锚点、嵌套 JSON 脱敏、改写幂等、MCP 生命周期、真实 stdio
子进程往返、原文不外发以及失败关闭。
## 当前最小版的范围
当前语义层是本地确定性意图/角色分类器,覆盖 `SKILL.md` 中的验收锚点和核心
不变量,不依赖云端 LLM。后续如引入本地模型,应作为保守规则之后的语义补充,
且仍必须通过相同 Golden Tests、脱敏复检和失败关闭机制。
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues