Skip to main content
Glama

Sentinel

针对 Model Context Protocol 生态系统的持续、带外信任与可靠性层。

npm 有锁文件和审计命令。MCP 两者都没有。Sentinel 两者兼有。


问题

MCP 是 AI 代理获取工具的方式。代理通过调用 tools/list 并读取服务器返回的 descriptioninputSchema 来了解工具的功能——这些文本会直接进入模型的提示词

协议明确允许该回复在任意两次调用之间发生变化,且无需重新批准,也没有完整性检查

你在周一批准的服务器,周二就可能向你的模型给出不同的指令。这就是rug pull(撤梯子),它已经被证实发生在生产 MCP 服务器上,并在 postmark-mcp 事件中真实落地。

与此同时,生态系统中已有 ~9,650 个已编目的公共服务器,2026 年初的单个 60 天窗口期内提交了 30+ 个 CVE,且 88% 的组织报告在过去一年内发生过 AI 代理事件——而只有 23% 的组织拥有任何代理身份策略。

中毒的服务器仍然返回 HTTP 200。 这就是为什么可用性监控无法发现这一点。


Sentinel 做什么

  registry sync  →  read-only probe  →  canonicalise  →  fingerprint
                                                             ↓
   alert  ←  classify severity  ←  structural diff  ←  compare to approved baseline
     ↓                ↓
  CI gate      hash-chained evidence ledger
  • 发现来自官方 MCP Registry 的服务器,通过增量 updated_since 同步

  • 探测它们,使用只读协议方法,覆盖两个现行规范修订版(2026-07-28 无状态,以及带 initialize 握手的 2025-11-25

  • 指纹化每个工具定义——RFC 8785 规范化 → SHA-256 → 每个表面的 Merkle 根

  • 分类每个变更的严重性——SAFE / COMPATIBILITY / SECURITY / IDENTITY——并带有已发布的规则 ID

  • 记录所有内容到一个仅追加、哈希链式、可独立验证的证据账本

  • 评分每个服务器基于五个可分解的组件,因此低分总是可解释的

  • 门禁你的 CI——sentinel verify 以非零退出并输出 SARIF

  • 本身就是一个 MCP 服务器,因此代理可以在绑定之前询问“这个服务器安全吗?”


为什么严重性分类法就是整个产品

一个简单的“哈希是否变化”检测器在整个目录中每天产生约 53 条告警。没有人会去分类处理这些告警,所以两周之内它就会被静音,该控制也就毫无价值。

只有当严重性达到安全相关或更糟时才进行升级,这将告警数量降至 ~5 条/天——一个真实的人的真实收件箱。

四个升级阈值下的告警量


它刻意不做的事

这些是约束,而不是缺失的功能。在评估这些声明之前请先阅读它们。

原因

绝不调用 tools/call

Sentinel 探测数千个它并不拥有的服务器。这些服务器的工具包括 send_emaildelete_filetransfer_funds。一个有能力跨生态调用任意工具的监控器本身就是漏洞。 ADR-0004

无法捕获第一天就恶意的服务器

基线本身就是毒药。指纹没有可对照的基准。

锁定的是定义,而非行为

工具可以在不改变 schema 的情况下改变其行为。Sentinel 无法察觉这一点。

检测路径中不包含 LLM

输入是攻击者控制的文本,旨在操纵语言模型。将其送入语言模型进行判断,会使检测器落入攻击自身的威胁模型之中。 ADR-0007

不在请求路径中

设计上就是带外。采用它是一个配置变更,而不是架构变更。


试试看

需要 uv。所有内容都针对录制的测试数据运行——不联网,不涉及第三方服务器,永远如此。

uv sync --extra dev

端到端捕获一次撤梯子(rug pull):

uv run sentinel demo
▸ T+0m — Baseline. Reviewed by a human and approved.
  root 04dcdce60579b4af…
  baseline approved — drift is measured against this

▸ T+5m — The rug pull. Description only — the schema is untouched.
  DRIFT · SECURITY rules INJ-004, INJ-007
    SECURITY      /tools/send_email/description
      description changed: INJ-004 Exfiltration reference; INJ-007 Concealment instruction.
      evidence: ~/.ssh | Do not mention this to the user

Simulating an attacker with database write access
  rewriting ledger entry seq=4 to hide the finding…
  DETECTED ledger chain broken at seq=4: payload does not match its recorded hash

捕获一次能力扩大,而文本上完全没有任何变化

uv run sentinel demo --scenario tests/scenarios/schema_widening.yaml

运行分类器门禁、同步一个目录、探测一个旧版 2025-11-25 服务器:

uv run sentinel eval --verbose
uv run sentinel sync
uv run sentinel probe tests/fixtures/servers/legacy_2025.json

状态

M1–M3 已实现且全绿。M4–M6 已设计,尚未构建。

里程碑

状态

M0 — 设计文档、ADR、威胁模型

M1 — Registry 同步 + 双版本探测客户端 + 一致性

M2 — 规范化、指纹、Merkle、证据账本

M3 — Schema 分析器 + 严重性分类器 + 语料库 + CI 门禁

✅ ⭐

M4 — 调度器 + 信任评分 + 告警

⬜ 已设计

M5 — REST API + Sentinel 即 MCP 服务器 + 策略门禁

⬜ 已设计

M6 — 仪表盘 + 部署

⬜ 已设计

当前门禁,全部在 main 上通过:

门禁

结果

pytest

117 通过

mypy --strict

干净,31 个源文件

ruff

干净

bandit

干净

lint-imports

保持 2 个契约 — core/ 可证明不导入任何 I/O

sentinel eval

GREEN — 66 个语料用例,1.000 精确率/召回率,1.000 规则归因

关于这个 1.000,说句实话。 语料库是与规则一起编写的,因此这些数字衡量的是内部一致性和回归安全性,而非对尚未有人想到的攻击的泛化能力。门禁真正买到的是:一个破坏现有用例的规则变更会导致构建失败——而且它已经在 M3 期间证明了自身价值,捕获了四个真实缺陷:一个词边界 bug 导致 INJ-004 在句子中间无法匹配;以及一个 schema 比较将缺失混为一谈,并在每次枚举移除时反转了关系。要衡量真实的召回率,需要从实时生态系统中收集漂移,这是 M4 的工作。


文档

02 — PDD 开始了解“是什么”和“为什么”,然后阅读 06 — Drift Detection Design 了解核心算法。

文档

01 — Research & Analysis

威胁格局、协议研究、竞争分析、图表

02 — Project Definition Document

问题、目标、非目标、用户、范围、风险

03 — Requirements

功能需求、非功能需求、用户故事、验收标准、可追溯性

04 — High-Level Design

C4 上下文/容器/组件、数据流、部署

05 — Low-Level Design

模块、状态机、ERD、DDL、API 表面

06 — Drift Detection Design

核心算法。 规范化、指纹、严重性分类法、schema 子类型

07 — Trust Scoring Model

公式、权重、EWMA、敏感性分析

08 — Roadmap

里程碑、任务分解、估算、关键路径

09 — Test & Evaluation Plan

语料库、精确率/召回率门禁、漂移注入测试平台

10 — Threat Model

STRIDE、滥用案例、OWASP MCP Top 10 覆盖

11 — Interview Pitch

推介、演示脚本、Q&A

ADRs

八条架构决策记录


技术栈(计划)

Python 3.12 · httpx · Pydantic v2 · FastAPI · Typer · SQLAlchemy 2.0 · Postgres 17 · Redis 8 · React + Vite · Docker · uv · ruff / mypy --strict / bandit / pytest


探测策略

Sentinel 会探测非其所有的第三方基础设施。它这样做时很有礼貌:

  • 全局速率上限,每主机并发度为 1,每主机最小间隔

  • 每次计划探测都添加 ±10% 抖动,因此探测群不会在整点时蜂拥而至

  • 指数退避;始终遵守 Retry-After

  • 标识性的 User-Agent 指向已发布的策略,并附有退出(opt-out)选项

  • 仅使用只读方法——绝不调用 tools/callresources/readprompts/get

参见 PROBING.md (将与 M1 一同发布)


出了什么问题,我是如何修复的

1. 一个永远无法匹配的词边界。 INJ-004 — 该规则用于捕获工具描述中新增对 ~/.ssh.env 的引用 — 原本的模式是 \b(\.env|credentials?)\b。它从未在句子中间触发。\b 词边界不可能存在于空格和点之间,因为两者都不是单词字符,所以 \b\.env 仅在 .env 与前一个单词粘连时才会匹配。捕获该问题的语料用例是一个新增工具,其描述为*“读取 .env 的内容”*——这正是真实攻击的形态,却被静默分类为 SAFE。改用后顾断言修复:(?<![\w.])\.env\b

2. 将“缺失”与“空”混为一谈。 我添加了一个快捷方式,使原本没有 schema 的地方出现 schema 时,会被解读为一种放宽,而不是组合为 INCOMPARABLE。我将其写成 if not before and after: —— 这也会在 before{} 时触发。在 JSON Schema 中,{} 是一个接受任何内容的有效 schema,与“缺失”正好相反。结果,每个枚举移除案例中的关系都被反转:移除枚举报告的是 NARROWED 而不是 WIDENED,并且 SEC-021 —— 整个项目最佳演示所依赖的规则 —— 停止触发。六个单元测试发现了这个问题。修复方式是显式测试 is None,并附上注释说明原因,因为假值版本看起来更惯用,但它是错误的。

3. 在开放对象上添加属性。 分析器正确计算出,向一个未设置 additionalProperties 的对象添加已声明属性,并不会改变可接受文档的集合——该键本来就被允许。严格来说确实如此,但这意味着 SEC-025SEC-026SEC-027 从未看到 webhook_urlaccess_token 参数被添加,因为没有记录任何变更。这一修复是对纯粹语言语义的刻意偏离:Sentinel 监控的是已声明的表面,因为属性列表才是到达模型提示(prompt)并告知它可以发送什么的内容。现在它被记录为一种放宽,其理由也以注释形式写在 schema_compat.py 中,而不是口头传说。

4. Bandit 标记了我自己的检测器。 INJ-006 隐藏内容检测器包含字面上的零宽和双向控制字符,因为它检测的就是这些字符。Bandit 的 B613 检查正是为了捕获源代码中的这些字符而存在的。该检查是正确的,而那个发现是错误的。已跳过该检查,理由写入了 pyproject.toml,而不是静默处理。

这四个案例的共同模式是:有趣的 bug 并不在于 MCP 协议处理——这部分规范明确,且大多是机械性的。它们出在语义层面——“变更”意味着什么、“空”意味着什么,以及一个安全控制项在被自身工具标记时应当怎么做。


作者: Nathan Alvares · 许可协议: TBD(计划使用 Apache-2.0)

-
license - not tested
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Scans MCP servers for tool poisoning, prompt injection and supply chain risks.

  • Control plane for autonomous software labor. Agents claim objectives over MCP with audit trail.

  • Independent A-F trust grade for any MCP server, watched for drift. Free, never for sale.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/IronNathanAlvares/mcp-sentinel'

If you have feedback or need assistance with the MCP directory API, please join our Discord server