mcp-toolbox 的 Cloud Storage Source 详解:项目级配置、14 个 GCS 工具与 allowedLocalRoots 路径安全机制
【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox
本文为 mcp-toolbox 中cloud-storage数据源(source)的完整技术指南。读完你将掌握:如何在配置文件中声明一个项目级的 Cloud Storage 数据源、该数据源暴露的全部 14 个工具及其分组的 toolsets、各工具所需的 IAM 权限、allowedBuckets与allowedLocalRoots两个安全约束字段的精确语义与源码级实现原理,以及预置配置(prebuilt)的启用方式。
一、Cloud Storage Source 是什么
Cloud Storage 是 Google Cloud 的托管对象存储服务,用于以bucket(桶)为容器存放非结构化数据(blob)。bucket 隶属于一个 GCP 项目,对象通过gs://<bucket>/<object>寻址。
在 mcp-toolbox 中,Cloud Storage source 是一个**项目级(project level)**的数据源:
- source 只配置一个 GCP 项目 ID,不绑定具体 bucket;
- 每个工具都接受
bucket参数,因此一个配置好的 source 可以操作该凭据有权限访问的任意 bucket; - 通过 [IAM][gcs-iam-roles](Identity and Access Management)控制对 bucket 和 object 的访问,toolbox 使用Application Default Credentials(ADC)在与 Cloud Storage 交互时完成授权和认证。因此部署前必须先为服务器进程配置好 ADC,并确保对应 IAM 身份拥有将要暴露的工具所需的角色。
说明:外部文档链接(Cloud Storage 官方文档、quickstart、IAM 角色清单)以本文中的术语名称代替,读者可按名称在 Google 官方文档中检索。
二、Source 配置:字段参考与完整示例
2.1 配置示例
以下是一个可直接放入 toolbox 配置文件的完整 source 声明(继承自官方文档的示例):
kind: source name: my-gcs-source type: "cloud-storage" project: "my-project-id" allowedBuckets: - "my-app-bucket" - "my-backup-bucket" allowedLocalRoots: - "/workspace"2.2 字段参考
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | string | 是 | 必须为"cloud-storage"。 |
project | string | 是 | source 所属 GCP 项目的 ID(例如"my-project-id")。 |
allowedBuckets | []string | 否 | 允许操作的对象存储桶名称列表;省略时表示允许所有桶。 |
allowedLocalRoots | []string | 否 | 允许用于文件上传/下载的绝对本地目录列表;路径在解析符号链接后仍须留在根目录之内;省略时表示允许所有路径。 |
从源码看,该字段表与 Cloud Storage source 配置结构体 一一对应:Name、Type、Project标注了validate:"required",而AllowedBuckets与AllowedLocalRoots均为可省略(omitempty)的字符串切片。source 在初始化时会以该 project 创建 GCS 客户端(Initialize调用initGCSClient),并在init()中向 source 注册表登记cloud-storage类型。
2.3 预置配置(prebuilt)
仓库自带cloud-storage预置配置,预置配置文件 展示了开箱即用的完整声明:
kind: source name: cloud-storage-source type: cloud-storage project: ${CLOUD_STORAGE_PROJECT}--prebuilt取值:cloud-storage- 需要的环境变量:
CLOUD_STORAGE_PROJECT(拥有目标 bucket 的 GCP 项目 ID) - 预置配置一次性声明了全部 14 个工具(见下节)和 2 个 toolset,未设置
allowedBuckets/allowedLocalRoots(即不做额外收敛,安全边界完全依赖 IAM 角色)。
三、可用工具一览与 Toolsets
该 source 提供 14 个工具,按操作对象分为两组(工具文档索引):
桶(Bucket)管理工具(toolset:cloud-storage-buckets)
| 工具类型 | 作用 |
|---|---|
cloud-storage-list-buckets | 列出配置项目下的所有 Cloud Storage 桶 |
cloud-storage-create-bucket | 在配置项目中创建桶 |
cloud-storage-get-bucket-metadata | 获取桶的元数据 |
cloud-storage-get-bucket-iam-policy | 获取桶的 IAM 策略绑定 |
cloud-storage-delete-bucket | 删除空桶 |
对象(Object)管理工具(toolset:cloud-storage-objects)
| 工具类型 | 作用 |
|---|---|
cloud-storage-list-objects | 列出桶中的对象,支持前缀(prefix)与分隔符(delimiter)过滤 |
cloud-storage-get-object-metadata | 获取对象元数据 |
cloud-storage-read-object | 读取 UTF-8 文本对象(或字节范围);上限 8 MiB,拒绝读取二进制对象,二进制请用download-object |
cloud-storage-download-object | 将对象下载到本地文件路径 |
cloud-storage-write-object | 将文本内容直接写入对象 |
cloud-storage-upload-object | 将本地文件上传为对象 |
cloud-storage-copy-object | 将对象复制到目标对象(同桶或跨桶) |
cloud-storage-move-object | 在同一桶内原子重命名对象 |
cloud-storage-delete-object | 删除对象 |
两个 toolset 在 预置配置 中通过kind: group定义,并带有面向 LLM 的用途描述(例如cloud-storage-buckets组注明"当你需要管理桶、创建桶、检查桶元数据与访问控制策略、删除桶时使用"),帮助 Agent 在工具众多时快速选中正确的组。
关于read-object的 8 MiB 上限:从源码看,Cloud Storage source 代码 中定义了defaultMaxReadBytes = 8 << 20(8 MiB)常量,注释明确说明其目的有两个——防止服务端 OOM、以及把 LLM 上下文保持在可管理规模;超出的对象或范围会以ErrReadSizeLimitExceeded拒绝。
四、IAM 权限要求
Cloud Storage 通过 IAM 控制对桶和对象的访问。除配置 ADC 外,还必须确保 IAM 身份拥有与所暴露工具匹配的角色。常用角色:
roles/storage.bucketViewer— 桶元数据的只读访问,足以支撑cloud-storage-list-buckets与cloud-storage-get-bucket-metadata;roles/storage.objectViewer— 对象及对象元数据的只读访问,足以支撑cloud-storage-list-objects、cloud-storage-get-object-metadata、cloud-storage-read-object、cloud-storage-download-object;roles/storage.objectUser— 对象的读写访问,足以支撑cloud-storage-upload-object、cloud-storage-write-object、cloud-storage-copy-object;roles/storage.admin— 完全控制,包括桶管理。
各变更类工具对应的细粒度对象/桶权限:
| 工具 | 所需权限 |
|---|---|
upload-object/write-object/copy-object | 对目标对象的对象创建或更新权限 |
move-object | 同桶内的storage.objects.move与storage.objects.create;若目标对象已存在,还需storage.objects.delete |
delete-object | 对象删除权限 |
create-bucket | 在配置项目中的桶创建权限 |
get-bucket-iam-policy | 读取桶 IAM 策略的权限 |
delete-bucket | 桶删除权限,且目标桶必须为空 |
完整的角色-权限映射参见 Cloud Storage 预置配置文档,其中还给出只读部署的建议组合:Storage Object Viewer(roles/storage.objectViewer)+Storage Legacy Bucket Reader(roles/storage.legacyBucketReader)即可覆盖只读工具子集。
五、allowedLocalRoots:本地文件访问的安全边界
cloud-storage-upload-object与cloud-storage-download-object读写的是Toolbox 服务器进程所在文件系统的本地文件,而不是客户端机器。服务器进程必须具备相应的本地文件权限。
allowedLocalRoots将这两个工具约束在你列出的目录之内。官方文档对语义的表述与源码实现高度一致,这里结合源码逐条展开。
5.1 路径校验:拒绝..与相对路径
ValidateLocalPath 执行三道检查:
- 路径非空;
- 对原始输入逐段检查——出现独立的
..段即拒绝(检查原始输入而非 Clean 后的结果,是为了防止/legit/../../etc/passwd这类经filepath.Clean折叠后看似无害的路径混过检查;而foo..bar这类仅"包含两个点"的合法文件名不受影响); - Clean 后必须是绝对路径。
5.2 双重边界检查:字面路径 + 符号链接解析
Source.validateLocalPath 实现了文档中的核心语义——"路径在书写形式和解析符号链接后都必须留在允许的根内":
- 名称层检查:路径 Clean 后必须位于某个
allowedLocalRoots根目录下(isUnderRoot(clean, root)),否则报错local path %q is not under any allowed local roots; - 解析层检查:调用 ResolveSymlinks 将路径沿每个符号链接解析到最终目标,再将解析后的路径与解析后的根目录比较(
escapes判断相对路径是否以..开头或跨盘符)。这样做的意义在于:种在根目录内的一个符号链接可能指向文件系统任意位置,仅凭名称级检查形同虚设——解析后比较才是让根目录成为真正边界的关键; - 两个方向的解析都做了容错:允许根本身经由符号链接到达(例如 macOS 的
/tmp、符号链接化的工作区)仍然匹配;而无法解析的根不会授权任何东西(跳过该根,而不是回退到已通过的名称级匹配); - 悬空链接(dangling link)会被显式拒绝而非当作"不存在的名字"处理,因为在这样的路径上创建文件会跟随链接,接受它会重新打开这个函数旨在封死的逃逸口。
这些行为均有对应测试覆盖:cloudstorage_test.go 中包含"空allowedLocalRoots放行"、"符号链接指向根外被拒绝"(注释直言:这正是allowedLocalRoots要阻止的场景)、"未设置allowedLocalRoots时链接不受限制"等用例;paths_test.go 则覆盖..段拒绝、符号链接解析等边界。
5.3 文档明示的两项局限(部署时必须了解)
- 硬链接不可区分:硬链接与普通文件在文件系统层面无法区分,因此在允许根内创建的、指向根外文件的硬链接仍然可读;
- TOCTOU 竞争:检查发生在文件打开前的"一瞬间"。能写入允许根目录的进程,原则上可以在检查与打开之间替换该路径上的文件。
因此官方建议把allowedLocalRoots当作叠加在操作系统权限之上的护栏(guardrail),而非替代品:应让 Toolbox 以一个只拥有必要文件访问权限的用户运行。若省略allowedLocalRoots,服务器进程可达的所有绝对路径都会被放行。
六、allowedBuckets:桶级白名单
Source.validateBucket 的逻辑很直接:
AllowedBuckets为空(即未配置该字段)时,任何桶名都通过;- 配置后则做精确字符串匹配,不在列表内的桶名返回
bucket %q is not allowed by source %q configuration错误。
相关测试(cloudstorage_test.go)验证了"空列表放行"与"列表内/列表外"的行为。
值得注意的设计取向:allowedBuckets与allowedLocalRoots都是应用层软约束,真正的访问控制边界仍然是 IAM 角色——source 配置决定"工具能看见/尝试什么",IAM 决定"凭据真正能做什么"。二者叠加使用(IAM 最小权限 + 白名单收敛)是文档与预置配置隐含的最佳实践:预置配置刻意不设置白名单,把收敛权留给使用者按部署环境自行收紧。
七、配置落地清单
- 为服务器进程配置 ADC(service account key、
gcloud auth或 metadata server 均可),并使身份具备上节所需的 IAM 角色; - 在 toolbox 配置中声明
type: "cloud-storage"的 source,必填name与project; - 按最小权限原则决定是否添加
allowedBuckets(收敛可操作桶)与allowedLocalRoots(收敛本地上传/下载目录,须为绝对路径目录列表); - 声明工具与 toolset:可手写
kind: tool条目(工具type为第三节的cloud-storage-*名称),或直接使用--prebuilt cloud-storage获得全部 14 个工具 + 2 个 toolset(需设置CLOUD_STORAGE_PROJECT环境变量); - 让 Toolbox 以受限用户运行,使 OS 权限与
allowedLocalRoots形成双层防护。
相关仓库路径:source 实现 internal/sources/cloudstorage/cloudstorage.go、路径安全公共库 internal/tools/cloudstorage/cloudstoragecommon/paths.go、各工具实现位于 internal/tools/cloudstorage/ 下的独立子包(每个工具一个包并配套测试)、集成测试见 tests/cloudstorage/cloud_storage_integration_test.go。
【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考