# MCP 安全

[English](README.md) | 中文

为官方 DSH MCP Client 注册的工具提供 **MCP 安全**设置页和 fail-closed Host 策略。

## 策略

- 仅覆盖公共名称采用 `mcp__<serverName>__<rawName>` 格式的工具。
- 首次观察到的定义集合处于未信任状态。插件绝不会自动创建或更新已接受基线。
- 已接受基线是所有可见 MCP Server 和工具的一份完整快照，包括公共名称、原始名称、描述、输入 Schema 和输出 Schema。
- 基线缺失、格式错误、指纹无效或发生漂移时，所有受覆盖调用都会在 MCP 分派前被拒绝。
- Server 或工具的增删，以及工具描述、输入 Schema 或输出 Schema 的变化，都会使完整基线失效。
- 基线匹配时，每次调用仍需获得一次显式批准。没有可用的批准支持、取消或拒绝都会阻止调用。
- 非 MCP 工具继续经过其余 `tools/pre-execute` 策略。

接受基线只记录用户已经检查并信任当时可见的定义；它不能证明初始 Server 或其定义安全，不能认证 Server 实现，也不会批准任何工具调用。请检查完整的已接受列表，不要只依赖后续的“没有差异”结果：如果用户最初接受了有害定义，该定义在可见内容改变前仍会保持基线匹配。

## 设置界面

设置页显示：

- 安全状态以及当前 Server 和工具数量；
- 已接受定义与当前定义之间的所有字段级差异，包括旧值和新值；
- 完整的已接受基线，包括采集时间、指纹、Server、工具、描述和 Schema；
- 完整的当前工具定义；
- 最近的预执行审计记录和结果审计记录。

已接受列表和当前列表中的每个工具都可以单独展开。“接受当前完整基线”会使用完整的当前快照替换整个已接受快照，不是对单个工具执行接受操作。只有当用户明确接受一个不包含任何可见 MCP 工具的工具代际时，空基线快照才是有效基线。

## 观察与强制执行时机

Bundle 启动时，Host 发布当前 `ToolRuntime` 定义，并且每五秒检查一次注册表以更新界面。在每个受覆盖的 `tools/pre-execute` 执行期间，Host 还会同步重新读取 `tools.schemas()`；这次调用时比较才是授权决定，并且发生在 MCP Client 分派 `tools/call` 之前。

插件观察 DSH MCP Client 当前注册的定义，不直接观察 MCP Server 源码或远端状态。对于 stdio、SSE 和其他受支持的传输方式，只有 MCP Client 刷新已注册工具后，远端定义变化才会变得可检测。可能需要 Server 发送工具列表通知、重新连接、重启 MCP Client 或重启 DSH Host。在同步完成前，本地注册表仍保存旧定义，任何仅检查定义的监控机制都无法报告远端变化。

## 覆盖范围

该策略覆盖当前 DSH `ToolRuntime` 中使用官方公共命名格式注册的官方 MCP 工具。直接调用 MCP SDK、其他进程中的 Client、使用独立 MCP Client 的 subagent，以及其他应用程序发起的调用都不会经过此运行时，因此不受该策略覆盖。

快照用于检测 Server 公布的能力变化。Server 可以保持名称、描述和 Schema 不变，同时改变实现行为、目标地址、数据处理方式或副作用；基线无法发现这类变化。快照还使用配置的 `serverName` 标识 Server，而不是通过密码学方式验证 Server 或二进制文件身份。端点认证、TLS 验证、网络策略、Server 来源验证和行为监控仍需由其他控制措施负责。

## 审计语义

预执行策略写入 `approval-required` 和 `denied` 记录。`executed` 和 `error-or-denied` 汇总最终 ToolRuntime 结果。结果记录仅用作审计证据，无法撤销远端副作用。Settings 命名空间最多保留 200 条审计记录，页面显示最新的 100 条。

## 模型体验

Bundle 不添加工具或提示词。MCP 工具仍然对模型可见。基线缺失、无效或发生漂移时，调用会在分派前失败；基线匹配时，调用通过现有批准界面获得单次授权。
