MCP 服务器应使用限定的文件系统挂载、最小权限密钥、显式网络策略、按代理划分的工作空间边界以及日志来运行,这样工具访问不会悄然扩大代理的信任边界。当 MCP 服务器可以读取文件、生成子进程、安装包、调用内部 API 或为长时间运行的代理会话保持状态时,沙箱就很有用。难点不在于决定 MCP 是否需要隔离,而在于决定每个工具周围应设置哪些边界、哪些数据可以跨越该边界,以及哪些操作仍需要人工审核。
为什么 MCP 会改变代理信任边界
模型上下文协议(Model Context Protocol)为 AI 应用程序提供了一种将模型连接到工具、提示和资源的通用方式。这使得集成更简洁,但同时也将每个 MCP 服务器变成了一个策略边界。如果服务器暴露了 read_file、run_command、query_database 或 deploy_preview,那么代理现在可以请求超出模型上下文窗口范围的操作。
MCP 规范描述了几个对沙箱设计很重要的安全期望:用户应理解并同意暴露的工具;主机应在工具调用前要求同意;工具描述除非经过验证,否则不可信;敏感数据应通过适当的访问控制得到保护。这些规则是应用层控制。沙箱在其下方添加了运行时控制,限制了 MCP 服务器进程可以触及的内容,即使代理、工具描述或提示链发出了错误的请求。
可以从三个层面来思考信任边界:
| 层面 | 控制内容 | 常见故障模式 |
|---|---|---|
| 主机或 MCP 客户端 | 连接了哪些服务器,批准了哪些工具调用 | 一个宽泛的工具被批准一次,然后在更敏感的上下文中被重复使用 |
| MCP 服务器 | 工具实现、身份验证、输入验证、资源访问 | 一个工具读取了比预期更多的文件、发送了更多数据、或运行了更多命令 |
| 沙箱运行时 | 文件系统、进程、网络、密钥、生命周期和日志 | 服务器进程因过于接近生产资源运行而继承了主机访问权限 |
目标并非让所有 MCP 服务器都以相同的方式被视为不可信。日历查询工具、本地代码执行工具和部署工具具有不同的风险特征。目标是让每个服务器的运行时访问范围不超过其执行任务所需的范围。
首先隔离什么
从那些可以改变外部状态、触及敏感数据或执行代码的 MCP 服务器开始。这些服务器最有可能将一次普通的提示错误演变成更广泛的事件。
需要沙箱化的高优先级候选对象包括:
- 执行 shell 命令、Python、Node.js、编译器、测试或笔记本的代码执行工具。
- 读取或写入仓库、用户上传文件、挂载数据集、凭证文件或生成工件的文件系统工具。
- 持有 cookies、会话状态、下载文件或截图的浏览器和计算机使用工具。
- 可以查询客户记录、分析导出、工单或私有文档的数据连接器。
- 可以创建分支、发布预览、轮换配置或修改基础设施的部署和 CI 工具。
- 可以从注册表、Git 远程仓库或任意 URL 获取代码的包和依赖管理工具。
风险较低的 MCP 服务器仍然可以拥有控制措施。一个只读的公共文档搜索服务器可能不需要为每个请求提供一个微型虚拟机,但它仍然应该有一个经过允许的网络路径、日志和速率限制。隔离应该遵循工具的实际爆炸半径,而不是“MCP 服务器”这个标签。
MCP 服务器应在何处运行
有三种常见的放置模式,没有一种是普遍正确的。
| 放置方式 | 适用场景 | 注意事项 |
|---|---|---|
| 与代理工作空间置于同一沙箱 | 服务器与代理的当前文件、shell 命令、浏览器会话或生成的工件紧密耦合 | 服务器和代理共享状态,因此如果挂载和密钥的范围未限定,被攻破的工具可能看到相同的工作空间 |
| 每个 MCP 服务器或工具组有独立的沙箱 | 工具需要比代理工作空间更强的隔离、处理不同的凭据或执行更高风险的操作 | 跨沙箱文件传输和延迟成为产品设计的一部分 |
| 在沙箱外,通过限定的 API 访问 | 工具是一个稳定的生产服务,拥有自己的认证、授权、日志和速率限制 | API 必须狭窄;不要仅仅因为位于沙箱外部就暴露宽泛的内部管理面 |
将服务器运行在同一个沙箱中对于编码代理来说很方便。MCP 服务器可以查看仓库、运行测试、检查工件并返回结果,而无需在环境之间移动文件。当工作空间本身已经是可丢弃的,并且只包含代理应该使用的文件时,这种方法效果最佳。
当工具需要不同的策略时,使用独立的沙箱更好。例如,一个包分析 MCP 服务器可能需要访问公共注册表的互联网,而主编码代理则不应该。一个浏览器 MCP 服务器可能需要测试账户的 cookies,而代码执行服务器永远不应该看到这些 cookies。
对于并非真正“运行时工具”的工具,外部服务更合适。账单查询、功能标志读取或问题追踪搜索,作为具有服务器端授权的普通后端 API,比作为代理计算环境内自由形式的服务器更安全。
文件系统挂载和按代理工作空间
文件系统访问通常是 MCP 便利性转变为意外权限的地方。一个只需要读取 ./src 的服务器不应该继承开发者的主目录。一个编写生成图表的工具不应该能覆盖部署配置。
使用显式的工作空间边界:
- 为每次代理运行分配一个独立的工作空间目录。
- 仅挂载任务所需的仓库、上传文件夹、数据集或工件目录。
- 对于源材料,优先使用只读挂载;对于输出,才使用读写挂载。
- 将生成的输出与受信任的源文件分开。
- 避免挂载凭证文件夹,例如
.ssh、云配置目录、浏览器配置文件或本地包管理器认证文件。 - 在不同用户、租户或任务之间重置或快照工作空间。
MCP 根(roots)可以帮助客户端告知服务器应操作的文件系统位置,但根本身并不是一个完整的安全边界。应将其视为客户端和服务器之间的协调机制。运行时仍然需要文件系统级别的限制,并且服务器应验证路径,以确保请求无法通过符号链接、相对路径或归档解压技巧逃逸到预期的工作空间之外。
一个实用的模式是根据角色划分工作空间访问权限:
| 目录 | 访问权限 | 目的 |
|---|---|---|
/workspace/input |
只读 | 用户上传、种子仓库、基准测试夹具或测试数据 |
/workspace/output |
读写 | 生成的文件、报告、补丁、图表或截图 |
/workspace/tmp |
读写,可丢弃 | 构建缓存、包安装缓存、临时文件 |
/workspace/secrets |
尽量避免文件挂载 | 如果无法避免,挂载一个限定的密钥文件,具有严格的生存期和脱敏处理 |
具体的路径不重要,原则才重要。
密钥和环境变量
密钥通常比文件更容易泄露,因为它们会通过环境变量、日志、堆栈跟踪、包脚本、shell 历史、浏览器会话和工具响应传播。当 MCP 服务器需要凭证时,应给予它能够完成工具操作的最狭窄的凭证。
为不同的 MCP 服务器使用不同的凭证。一个 GitHub 问题搜索服务器可能只需要只读的问题访问权限。一个 PR 编写服务器可能需要分支写入权限。部署服务器不应共享任何令牌,除非权限模型确实需要。
MCP 服务器良好的密钥处理方法如下:
- 在沙箱或进程启动时注入密钥,而不是通过提示。
- 当提供商支持时,使用短期或可撤销的令牌。
- 按工具、租户、环境和操作限定凭证范围。
- 在 stdout、stderr、结构化的工具响应和跟踪日志中对密钥进行脱敏处理。
- 不要将原始环境变量返回给模型。
- 不要让代理决定加载哪个密钥。
- 轮换高风险服务器使用的凭证,以及在怀疑发生提示注入后轮换凭证。
避免一个常见的反模式:将一堆通用环境文件挂载到每个代理会话中。这会让本地开发更简单,但让生产审查更困难。如果一个工具不需要密钥,它就不应该能读取到密钥。
网络出口和传输选择
MCP 支持本地和远程传输模式。规范描述了用于本地进程通信的 stdio 和用于服务器到客户端通信的 Streamable HTTP(通过 HTTP)。较旧的 SSE 设计仍在生态系统中出现,但新的集成应在依赖特定传输之前检查当前的 MCP 文档和所选 SDK。
传输选择和沙箱网络策略解决不同的问题:
| 问题 | 传输回答 | 网络策略回答 |
|---|---|---|
| MCP 客户端如何与服务器通信? | stdio、基于 HTTP 的传输或其他受支持的模式 | 不适用 |
| 服务器可以调用哪些外部主机? | 本身不够 | 允许列表、拒绝列表、代理、DNS 策略或禁止出口 |
| 服务器可以获取包或网页吗? | 本身不够 | 注册表允许列表、URL 允许列表、缓存和日志 |
| 其他进程能访问服务器吗? | 绑定和认证细节 | 入站防火墙和沙箱网络边界 |
对于本地 stdio 服务器,风险通常是继承主机访问权限。服务器可能作为主机应用程序的子进程运行,并看到本地文件、环境变量和网络路由。如果该服务器执行代码或读取敏感文件,则将其移入沙箱化进程,或者在可丢弃的工作空间内运行整个主机-工作者对。
对于基于 HTTP 的 MCP 服务器,风险转向认证、网络暴露和跨租户隔离。使用服务器端授权、TLS、适当的来源检查和每客户端凭证。不要将远程 MCP 服务器暴露在宽泛的内部网络上而没有明确的策略来规定谁可以调用哪些工具。
对于网络出口,默认拒绝比默认开放更容易推理。如果工具需要包安装,允许该包注册表或拉取缓存。如果它需要网络研究,则通过一个记录请求域名并阻止内部元数据端点的代理进行路由。如果它需要内部 API,则暴露一个狭窄的 API,而不是整个私有网络。
包安装、子进程和长期运行状态
许多有用的 MCP 工具需要子进程。编码代理运行测试。数据代理安装库。浏览器代理启动浏览器。构建代理调用编译器。子进程支持本身不是问题,但不可见的子进程支持才是。
在允许包安装或 shell 执行之前,定义:
- 哪些命令是允许的、拒绝的或需要审批的。
- 包管理器是否可以访问公共互联网。
- 是否必须锁定依赖版本或使用 lockfile。
- 构建缓存和安装的包存放在哪里。
- 后台进程可以运行多久。
- 清理后保留哪些输出文件。
- 代理是否可以启动网络监听器。
长时间运行的 MCP 服务器引入了第二个问题:状态漂移。一个运行数小时的服务器可能累积文件、凭证、浏览器 cookies、shell 历史、依赖更改和后台作业。该状态对于多步骤工作流可能有用,但它必须属于正确的代理、用户和任务。
使用生命周期控制:
| 控制措施 | 为何重要 |
|---|---|
| 每代理沙箱 ID | 防止一个代理的工具状态成为另一个代理的上下文 |
| 空闲超时 | 清理废弃的工具会话 |
| 暂停和恢复策略 | 支持长时间任务,无需保持不必要的计算活动 |
| 快照或模板策略 | 从已知基线启动可重复的环境 |
| 显式清理 | 在任务结束后删除文件、终止进程并释放凭证 |
如果工具产生持久的工件,则仅将这些工件复制出沙箱。除非产品明确需要完整的会话回放,否则不要保留整个工作空间。
日志、清理和人工审核
MCP 工具日志应回答安全性和调试问题,而不会变成一个新的密钥存储。有用的日志包括工具名称、调用者身份、沙箱 ID、工作空间 ID、命令类别、读取或写入的文件、联系的外部域、安装的包名称、退出状态和工件路径。
默认情况下,不要记录原始提示、原始客户数据、令牌、完整文件内容或完整的命令输出。将敏感跟踪记录放在更严格的访问控制和保留策略之后。
即使是在沙箱内部,某些 MCP 操作也仍需要人工审核:
- 发布或部署到生产环境。
- 发送电子邮件、聊天、工单、发票或面向客户的消息。
- 修改访问控制、计费、用户数据或基础设施配置。
- 泄露大型文件、私有仓库、数据库导出或类似凭证的字符串。
- 在工作空间策略之外运行命令。
- 调用具有写入权限的内部 API。
沙箱应减少爆炸半径,而不应成为从敏感业务操作中移除审核的理由。
Novita Agent Sandbox 如何适配
Novita Agent Sandbox 专为需要隔离运行时进行代码执行、文件、进程、浏览器式工作流和长时间会话的代理工作负载而设计。它适用于 MCP 架构,其中工具服务器需要可丢弃的工作空间,而不是直接访问开发者笔记本电脑、生产主机或共享 CI 机器。
将其用作需要以下功能的服务器的运行时边界:
- 执行生成的代码或命令。
- 处理临时文件和生成的工件。
- 在多步骤任务中保持每代理工作空间状态。
- 运行代理稍后可以检查的后台工作。
- 将代理实验与应用主机分开。
请明确产品边界:MCP 服务器仍然是你的应用代码。你仍然需要设计工具权限、凭证范围、网络策略、审批流程、日志模式和清理行为。沙箱提供了强制执行这些决策的隔离环境。
关于产品特定的设置,请使用当前的 Novita 文档,而不是从较旧教程中复制过时的片段。从概念上讲,结构如下:
对于每个代理任务:
从批准的模板创建沙箱
仅挂载任务工作空间
仅注入工具特定的密钥
在沙箱内启动 MCP 服务器,或连接到沙箱支持的工具 API
通过审批和策略检查路由工具调用
收集日志和批准的工件
根据任务生命周期停止、重置或暂停沙箱
这样保持文章级别的指导稳定,而将确切的 SDK 调用留给最新的文档和你自己的平台代码。
实施检查清单
在将 MCP 服务器连接到自主或半自主代理之前,使用此检查清单:
| 领域 | 需要回答的问题 |
|---|---|
| 工具范围 | 服务器暴露了哪些工具,哪些会改变外部状态? |
| 放置方式 | 服务器应运行在代理沙箱、独立沙箱中,还是在沙箱外通过狭小 API 访问? |
| 文件系统 | 挂载了哪些目录,是只读还是读写,如何阻止路径逃逸? |
| 密钥 | 注入了哪些凭据,如何限定范围,它们可能出现在日志或输出中的哪些地方? |
| 网络 | 出口是默认拒绝、通过代理路由,还是按域名、注册表和内部 API 进行允许列表? |
| 子进程 | 允许哪些命令、包管理器、后台作业和监听器? |
| 状态 | 如何处理每代理工作空间、快照、空闲超时、暂停/恢复行为和清理? |
| 日志 | 能否在不存储密钥的情况下重建工具调用、文件更改、外部域和工件? |
| 人工审核 | 哪些工具调用在执行、导出、部署或面向客户的操作之前需要审批? |
| 测试 | 是否测试了提示注入、符号链接/路径遍历、大量输出、清理失败和拒绝出口路径? |
MCP 使工具集成更简单。沙箱化可以防止这种集成成为模型权限的悄然扩张。正确的设计通常是混合的:一些服务器在同一个代理工作空间,一些在独立的沙箱,还有一些在沙箱外通过具有严格授权的 API 访问。选择与工具的数据、密钥、子进程和网络需求相匹配的放置方式。
常见问题解答
每个 MCP 服务器都应该在沙箱中运行吗?
不。优先考虑那些执行代码、读取或写入文件、使用密钥、调用私有服务、启动浏览器、安装包或改变外部状态的服务器。风险较低的只读服务器可能仍需要认证、日志和网络控制,但可能不需要每个请求都使用专用沙箱。
stdio 比 HTTP 更安全吗?
不自动如此。Stdio 对于本地服务器可能简单,但服务器可能继承本地文件系统、环境和网络访问权限。基于 HTTP 的服务器需要更强的认证和暴露控制。更安全的选择取决于进程在哪里运行以及它获得哪些运行时权限。
MCP 根(roots)可以替代文件系统沙箱化吗?
不能。根有助于在客户端和服务器之间传达预期的工位位置,但它们不是一个完整的运行时边界。使用路径验证和沙箱级文件系统控制,将服务器限制在预期的工作空间内。
沙箱化 MCP 工具的密钥应存储在哪里?
仅注入工具需要的凭据,最好是作为短期环境变量或限定的运行时密钥。不要挂载宽泛的开发者凭证文件夹,也不要通过提示传递密钥。在日志和工具响应中对其进行脱敏处理。
MCP 工具何时需要人工审批?
对于生产部署、面向客户的消息、计费或访问控制更改、大量数据导出、基础设施写入,以及任何超出正常工作空间策略的命令或网络操作,都需要审批。
