MCP 安全与授权
MCP 标准化了能力如何被描述和调用。它不会决定 代理应该接收哪些能力,也不会决定用户已批准哪些副作用。
四个独立的决策
- 连接认证 — 此客户端是否可以连接到此服务器?
- 能力可见性 — 模型可以看到哪些工具和资源?
- 执行授权 — 此身份现在是否可以在此资源上执行这个特定操作?
- 人工批准 — 某个有后果的操作是否需要人工确认其确切输入和影响?
不要把这些决策合并成一个 autoApprove 配置列表。
本地 stdio 服务器
本地子进程会在应用宿主中继承一个强大的位置。
- 使用绝对、经过审查的可执行文件路径。
- 固定包和二进制版本;避免
latest标签。 - 只传递必需的环境变量。
- 不要在命令行参数中放置密钥。
- 限制文件系统根目录和工作目录。
- 当服务器处理不受信任的输入时,应用操作系统沙箱配置文件。
- 将服务器描述、资源和结果视为不受信任的内容。
JSON 加载和运行时添加/更新路径会验证服务器 ID。
McpServerManager 不会对已配置的命令进行沙箱隔离。
远程可流式传输的 HTTP
McpHttpClientBuilder 可以应用:
- 持有者令牌;
- 调用方选择的 API-key 头;
- 任意经过审查的头;
- 固定的 OAuth 2.0 客户端凭据令牌获取;
- 请求超时;以及
- 在收到过期会话响应后进行一次有界的会话重新初始化。
OAuth2Config 不是完整的 MCP 授权流程。它不会执行
受保护资源元数据发现、授权服务器发现、浏览器授权、PKCE,或资源指示器协商。当部署需要该流程时,请使用 rmcp 的授权 APIs 或身份组件。
对令牌请求设置边界,这样缓慢或无法访问的授权服务器就不会使连接建立挂起,并注意客户端绝不会把客户端密钥回显回来——在令牌端点错误正文到达日志之前会被脱敏:
use adk_tool::mcp::OAuth2Config;
use std::time::Duration;
let auth = OAuth2Config::new(client_id, token_url)
.with_secret(client_secret)
.with_scopes(vec!["mcp.read".into(), "mcp.invoke".into()])
.with_timeout(Duration::from_secs(10)); // token request timeout
默认的令牌请求超时时间为 30 秒。
工具暴露与执行
使用 with_tools 或 with_filter 将不必要的能力排除在模型请求之外。然后在执行时应用 ADK-Rust 工具授权和确认。
对于有后果的工具:
- 向人工展示最终解析后的参数;
- 区分一次性允许与持久策略;
- 将批准绑定到精确的函数调用 ID;
- 在可能的情况下让外部写入具有幂等性;
- 将批准决策和工具结果一起存储;并且
- 在未检查返回证据之前,绝不要把成功的协议响应当作业务结果成功的证明。
信息征询
信息征询是服务器对更多信息的请求,而不是应用必须服从的指令。审查消息、URL、请求的字段和元数据。拒绝不受支持或意外的请求。在使用所有被接受的表单值之前先验证它们。
日志与密钥
脱敏环境变量、授权头、API 密钥、信息征询答案以及敏感工具参数。改为记录服务器 ID、工具名称、任务 ID、状态、耗时、批准,以及一个有界的结果摘要。