fncreator22/sentinel-mcp

GitHub: fncreator22/sentinel-mcp

一款通过 MCP 协议与 LLM 编程助手集成的三阶段安全护栏代理,在 AI 执行操作前进行分级风险评估与拦截。

Stars: 3 | Forks: 0

# Sentinel ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue?logo=python&logoColor=white) ![License: MIT](https://img.shields.io/badge/license-MIT-green) ![Docker](https://img.shields.io/badge/docker-ready-2496ED?logo=docker&logoColor=white) ![MCP Protocol](https://img.shields.io/badge/protocol-MCP-blueviolet) ![Stage 2 CV Accuracy](https://img.shields.io/badge/Stage%202%20CV%20Accuracy-76.3%25-brightgreen) ![Dataset](https://img.shields.io/badge/dataset-828%20examples-orange) **一个专为 LLM 驱动的编程助手设计的三阶段护栏代理。** Sentinel 部署在 LLM 代理与其执行环境之间,在执行每一个拟议的操作前进行审查。它通过 Model Context Protocol (MCP) 与 Claude Code、Cursor 和 CodeX 等工具集成,充当一个始终在线的安全层,可以拦截破坏性命令、标记范围蔓延,并维护每个决策的完整审计跟踪。 为了实现最大的兼容性,支持 **Stdio(本地进程)和 SSE(Web endpoint)** 两种 MCP 传输方式。 ## 🎬 演示 ![Sentinel MCP 演示 — 运行中的三阶段护栏 pipeline](https://raw.githubusercontent.com/fncreator22/sentinel-landing/main/assets/sentinel-demo.gif) ## 问题所在 自主的 LLM 编程代理可以执行 shell 命令、修改文件、推送到远程仓库以及发起网络请求。这种能力伴随着实际风险:一个范围界定不清的 prompt 或一个幻觉产生的操作就可能导致数据丢失、暴露凭证,或对生产系统造成不可逆的更改。 现有的解决方案都是二元的——要么代理在没有审查的情况下运行所有内容,要么必须由人工手动批准每一个步骤。这两种方式都无法扩展。 ## 解决方案 Sentinel 实现了一个**多阶段决策 pipeline**,使用在每个阶段最快、最合适的工具,处理从明显安全到极度危险的操作的全谱系: **阶段 1 — 规则引擎**:基于可配置的 YAML 规则集进行模式匹配。在微秒级处理明确的案例(递归删除、凭证暴露、根目录写入),且零网络依赖。 **阶段 2 — 训练的分类器**:TF-IDF 向量器和 Logistic Regression 分类器,在标注过的代理操作数据集上训练。完全离线运行,耗时仅几毫秒,并产生具有置信区间的可解释风险评分。 **阶段 3 — LLM 审查器**:对于统计模型无法可靠解决的模糊操作,由大型语言模型结合用户陈述任务的上下文对其进行评估。这是唯一进行网络调用的阶段,且仅在前几个阶段不确定时才会激活。支持 Ollama(本地)、OpenAI、Anthropic 和 Google Gemini。 ## 架构 ``` MCP Client (Claude Code / Cursor / CodeX) | +-- stdio transport (mcp_server/server.py) +-- SSE transport (mcp_server/sse_server.py) | v | HTTP POST /review v api/main.py (FastAPI) <- REST API, audit log, config management | v sentinel_core/orchestrator.py | +-- Stage 1: sentinel_core/rules_engine.py (config/rules.yaml) +-- Stage 2: sentinel_core/classifier.py (model_artifacts/model.pkl) +-- Stage 3: sentinel_core/llm_reviewer.py (sentinel_core/model_manager.py) | v sentinel.db (SQLite) <- append-only audit log ``` ## 分类器性能 | 指标 | 数值 | |---|---| | 训练样本 | 828(人工标注 + 合成生成) | | 类别分布 | 58% 安全 / 42% 风险 | | 5 折交叉验证准确率 | 76.3% ± 3.0% | | 交叉验证 Macro-F1 分数 | 75.9% ± 3.1% | | 留出测试集准确率 | 75.2% | | 风险类别准确率 | 70% | | 安全类别准确率 | 79% | | 高置信度预测(由阶段 2 直接处理) | 占流量的 40% | | 阶段 3 LLM 升级率 | 占流量的 60% | 分类器的置信度阈值设定为 80%。高于此阈值的预测由阶段 2 解决,无需调用阶段 3 LLM,从而降低了平均延迟,并为 40% 的受审查操作省去了 API 成本。 **与风险操作相关的前 5 个特征**:`bash`、`delete`、`iptables`、`exec`、`secret` **与安全操作相关的前 5 个特征**:`version`、`list`、`describe`、`test`、`check` ## 项目结构 ``` sentinel/ ├── api/ │ └── main.py FastAPI application, all HTTP endpoints ├── sentinel_core/ │ ├── orchestrator.py Three-stage pipeline coordinator │ ├── rules_engine.py Stage 1: YAML rule matching │ ├── classifier.py Stage 2: sklearn inference │ ├── llm_reviewer.py Stage 3: LLM reasoning │ ├── model_manager.py Provider abstraction (Ollama / OpenAI / Anthropic / Gemini) │ ├── audit_log.py SQLite decision logger │ └── model_artifacts/ model.pkl + vectorizer.pkl (gitignored) ├── mcp_server/ │ ├── server.py MCP stdio server │ └── sse_server.py MCP SSE server (port 8002) ├── dashboard/ │ ├── index.html Single-page control panel │ ├── app.js Dashboard logic │ └── style.css Dashboard styles ├── config/ │ ├── rules.yaml Stage 1 allow/block patterns │ ├── model_config.yaml Active provider and model selection │ └── model_config.local.yaml API keys (gitignored, never committed) ├── data/ │ └── training_examples.csv Labeled dataset for Stage 2 training ├── train/ │ ├── train_classifier.py Training script (scikit-learn) │ └── generate_training_data.py Synthetic training data generation ├── docs/ │ └── ARCHITECTURE.md Internal design notes and rationale ├── start.bat Windows one-click launcher ├── Dockerfile Container image definition └── requirements.txt ``` ## 设计决策 ### 为什么是三个阶段而不是一个? 设计目标是在处理常见情况时最小化延迟和成本,同时在处理模糊情况时保持高准确性的判断。绝大多数代理操作要么明显安全(`git status`、`npm install`),要么明显具有风险(`rm -rf /`、`git push --force`)。将这两者都通过 LLM 路由会既慢又昂贵。而将两者都仅通过规则引擎路由则会漏掉大量的中间地带。 三阶段级联解决了这个问题: - **阶段 1** 确定性地处理明确的案例,耗时在微秒级,且没有模型参与循环。对已知危险字符串的模式匹配不会产生幻觉。这是防范灾难性命令的最后一道防线。 - **阶段 2** 离线处理统计上的中间地带,耗时在毫秒级,使用基于系数的可解释模型。我们有意选择 TF-IDF + Logistic Regression:该模型在 CPU 上几秒钟即可完成训练,产生可检查的系数,非常适合风险集中在特定关键词和 n-gram 上的短操作文本。神经网络只会增加不透明度,而不能有效地改善这个问题。 - **阶段 3** 处理真正的模糊性——即上下文(用户陈述的任务、会话的范围)比表面级别的 token 更重要的情况。这是 LLM 的推理能力真正增加价值的地方,也是唯一需要支付模型调用的延迟和成本的阶段。 ### 为什么阶段 3 优先本地化? 我们将阶段 3 的默认实现设为 Ollama,以确保除非用户明确配置了云提供商,否则任何操作文本都不会离开用户的机器。这对于可能包含专有逻辑、内部主机名或敏感文件路径的代码库非常重要。`model_manager.py` 中的提供商抽象使得切换到云端 LLM 变得非常简单,且无需更改任何阶段 3 的逻辑。 ### 为什么要有置信度阈值? 阶段 2 并不会将每个预测都传递给阶段 3——仅传递低于 80% 置信度阈值的预测。这将昂贵的网络调用置于统计信号的控制之下。高于阈值的预测由阶段 2 直接解决,在实际应用中约占所有流量的 40%。剩下的 60% 升级到阶段 3,此时 LLM 的推理能提供最大的边际价值。 ## 设置与快速开始 ### 步骤 1:启动 Sentinel 后端与仪表板 **Windows(一键启动)**: 双击项目根目录中的 `start.bat`。该脚本将自动: 1. 如果缺失则创建 Python 虚拟环境 (`venv`) 2. 从 `requirements.txt` 安装所需的包 3. 如果缺失模型 pickle 文件,则训练阶段 2 的 ML 分类器 4. 在 `http://localhost:8000` 启动 FastAPI 后端 5. 在 `http://localhost:8002` 启动 SSE 服务器 6. 在您的默认浏览器中打开 `http://localhost:8080` 启动实时仪表板 **手动 / Linux / macOS 设置**: ``` # 1. 创建并激活 virtual environment python -m venv venv source venv/bin/activate # macOS/Linux (use venv\Scripts\activate on Windows) # 2. 安装依赖 pip install -r requirements.txt # 3. 训练 classifier model(仅首次运行) python train/train_classifier.py # 4. 运行 API Server(终端 1) python -m uvicorn api.main:app --port 8000 --reload # 5. 运行 SSE MCP Server(终端 2) python mcp_server/sse_server.py --port 8002 # 6. 运行 Dashboard UI(终端 3) python -m http.server 8080 --directory dashboard ``` ## 分步客户端集成指南 Sentinel 可无缝连接到任何兼容 MCP 的 AI 助手。请根据您的平台遵循以下详细的分步指南: ### 1. Claude Desktop (Windows / macOS) 1. **启动 Sentinel**:确保 `start.bat` 或后端服务正在运行。 2. **打开配置文件**: - **Windows**:在记事本或 VS Code 中打开 `%APPDATA%\Claude\claude_desktop_config.json`。 - **macOS**:打开 `~/Library/Application Support/Claude/claude_desktop_config.json`。 3. **粘贴配置**: 在 `mcpServers` 下添加 `sentinel`,并附带您的 Python 虚拟环境可执行文件和 `mcp_server/server.py` 的绝对路径: { "mcpServers": { "sentinel": { "command": "C:\\path\\to\\sentinel\\venv\\Scripts\\python.exe", "args": [ "C:\\path\\to\\sentinel\\mcp_server\\server.py" ], "env": { "PYTHONPATH": "C:\\path\\to\\sentinel" } } } } 4. **重启 Claude Desktop**:完全关闭并重新启动 Claude Desktop。 5. **验证连接**: - 在 Claude Desktop 中,点击聊天窗口右下角的 **Hammer 🔨 / 设置** 图标,或前往 **设置 > 开发者**。 - 您会看到一个蓝色的徽章,显示 **`sentinel running`**,并带有活跃工具 `review_action` 和 `get_recent_decisions`。 ### 2. Cursor IDE (Stdio & SSE Transport) 1. **打开 Cursor 设置**:打开 Cursor IDE,点击右上角的 **设置(齿轮图标)** 或按 `Ctrl + ,` / `Cmd + ,`。 2. **导航到 MCP**:从侧边栏选择 **功能**,然后向下滚动到 **MCP 服务器**。 3. **添加新服务器**: - 点击 **+ 添加新的 MCP 服务器**。 - **名称**:`sentinel` - **类型**:选择 `SSE`(推荐,以实现零子进程开销)或 `stdio`。 - **URL / 命令**: - 对于 **SSE**:输入 `http://localhost:8002/sse`。 - 对于 **stdio**:将 `command` 设置为您的 `python.exe`,将 `args` 设置为 `mcp_server/server.py`。 4. **验证**:状态指示器将变为 **绿色(已连接)**。 ### 3. Claude Code CLI 1. **定位配置**:打开 `~/.claude/claude_code_config.json`(或项目级别的 `.claude/config.json`)。 2. **添加 MCP 服务器**: { "mcpServers": { "sentinel": { "command": "python", "args": ["mcp_server/server.py"], "cwd": "/path/to/sentinel" } } } 3. **运行 prompt**:当 Claude Code 提议命令时,它会在执行前自动调用 `review_action`。 ### 4. 基于 Web 的 IDE 和自定义 HTTP 客户端 (SSE) 对于 Web 平台、远程代理或使用 **MCP Inspector** 进行测试: - **SSE Endpoint**:`http://localhost:8002/sse` - **消息 Endpoint**:`http://localhost:8002/messages/` - **使用 Inspector 测试**: npx -y @modelcontextprotocol/inspector sse http://localhost:8002/sse ### 5. 仪表板中的快速连接工具 仪表板提供了一个内置的交互式复制工具: 1. 在浏览器中打开 `http://localhost:8080`。 2. 点击右上角顶部的 **连接** 按钮。 3. 在 **Stdio** 和 **SSE** 标签页之间切换,以生成根据您的本地文件路径自动填充的配置代码片段。 4. 点击 **复制配置到剪贴板**,并直接将其粘贴到您客户端的配置文件中! ## 配置 ### 阶段 3 模型提供商 在 `http://localhost:8080` 打开仪表板并导航到 **模型设置**。 **本地**:选择从您本地 Ollama 安装中检测到的任何模型。无需互联网。在选择之前,请使用 `ollama pull ` 拉取模型。 **API 提供商**:选择 Google Gemini、OpenAI、Anthropic 或自定义的 OpenAI 兼容 endpoint。输入您的 API key 并点击 **保存模型设置**。保存后,仪表板会自动调用提供商实时的 `/models` endpoint,并使用您的 key 有权访问的每个模型填充模型下拉列表。然后您可以从列表中进行选择,或手动输入任何模型名称。如果将模型字段留空,Sentinel 会自动选择该提供商推荐的默认模型。key 存储在磁盘上的 `config/model_config.local.yaml` 中,从不写入审计日志,也从不通过 API 完整返回(仪表板中仅显示最后 4 个字符)。 随时点击模型字段旁边的 **↻ 刷新**,即可重新获取实时模型列表,而无需再次保存。 ### 阶段 1 规则 在仪表板中导航到 **规则** 标签页,以添加、编辑或删除模式匹配规则。规则支持精确的子字符串匹配和正则表达式。更改立即生效,无需重启服务器。 ## MCP 集成与工具初始化 Sentinel 通过 Model Context Protocol (MCP) 向编程助手公开其功能。服务器使用 `FastMCP` 初始化工具并处理传输层(同时支持 `stdio` 和 `sse`)。 ### 工具初始化 当 MCP 服务器启动时,它会初始化以下工具并将其提供给连接的客户端: | 工具 | 初始化与参数 | 描述 | |---|---|---| | `review_action` | `action_text` (str), `user_task` (str) 在执行前审查拟议的代理操作。返回 `ALLOW`、`BLOCK` 或 `REVIEW` 的裁决。 | | `get_recent_decisions` | `limit` (int, 默认为 20) | 从审计日志中返回最近的条目,以向代理提供过去裁决的上下文。 | ## API 参考 FastAPI 后端公开了以下 endpoint。当服务器运行时,可在 `http://localhost:8000/docs` 获取完整的交互式文档。 | 方法 | 路径 | 描述 | |---|---|---| | GET | `/health` | 健康检查,返回暂停状态和项目路径 | | GET | `/status` | 轻量级的暂停/认证状态 | | POST | `/review` | 提交操作以供审查 | | POST | `/pause` | 暂停护栏 pipeline | | POST | `/resume` | 恢复护栏 pipeline | | GET | `/log` | 检索最近的审计日志条目 | | GET | `/rules` | 获取当前阶段 1 规则集 | | POST | `/rules` | 更新阶段 1 规则集 | | GET | `/models/local` | 列出本地可用的 Ollama 模型 | | GET | `/models/config` | 获取当前的模型提供商配置 | | POST | `/models/config` | 更新模型提供商配置 | | POST | `/models/test` | 测试活动的模型提供商连接 | | GET | `/models/available` | 获取已保存 API key 上可用的模型实时列表 | | GET | `/mcp/servers` | 列出已注册的 MCP 服务器 | | POST | `/mcp/servers` | 注册新的 MCP 服务器 | | DELETE | `/mcp/servers/{name}` | 删除已注册的 MCP 服务器 | ### 示例:审查操作 ``` curl -X POST http://localhost:8000/review \ -H "Content-Type: application/json" \ -d '{"action_text": "rm -rf /tmp/build", "user_task": "Clean up build artifacts"}' ``` 响应: ``` { "action_text": "rm -rf /tmp/build", "verdict": "ALLOW", "decided_by_stage": "classifier", "reason": "Classifier predicted 'safe' with 89% confidence.", "log_id": 42 } ``` ## 阶段 2 分类器 — 训练 分类器在 `data/training_examples.csv` 上进行训练,这是一个经过人工筛选和合成增强的数据集,包含被标记为 `safe`(安全)或 `risky`(有风险)的 shell 命令、SQL 语句、git 操作和 API 调用。 要生成额外的合成训练数据: ``` python train/generate_training_data.py ``` 在修改或扩充数据集后重新训练: ``` python train/train_classifier.py ``` 该脚本会输出完整的分类报告以及与风险相关的前 15 个特征,允许对模型学习到的信号进行验证和理解,而不是将其视为一个黑盒。 ## 安全说明 - API key 仅存储在 `config/model_config.local.yaml` 中,该文件默认被 gitignore 忽略。 - 审计日志 (`sentinel.db`) 记录操作文本和审查决策,但从不存储 API key。 - 如果在启动服务器之前将 `SENTINEL_API_KEY` 设置为环境变量,则所有变更型 endpoint(规则更新、模型配置更新、暂停/恢复)都需要通过 `X-Sentinel-Key` 标头提供该 key。 - 护栏可以从仪表板中暂停。在暂停模式下,所有操作均返回 `REVIEW`,需要人工签字确认。这是出于保守考虑的设计。 ## 许可证 MIT 许可证。有关详细信息,请参见 `LICENSE`。
标签:AI风险缓解, 请求拦截, 逆向工具