MCP Toolbox for Databases 中 cloud-storage-delete-bucket 工具详解:空桶安全删除、参数校验与错误分类机制
【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox
本文围绕 MCP Toolbox for Databases 提供的cloud-storage-delete-bucket工具展开,系统讲解该工具的 YAML 配置方式、调用参数、输出格式与 IAM 权限要求,并结合仓库源码剖析其底层的桶校验、破坏性操作标注以及 GCS 错误分类逻辑,帮助你在生产环境中安全地将"删除 Cloud Storage 空桶"能力暴露给 LLM 客户端使用。
工具定位与功能边界
cloud-storage-delete-bucket是 Cloud Storage 集成下的一组桶管理工具之一,其唯一职责是删除一个空的 Cloud Storage 桶。需要特别注意它的功能边界:
- 该工具不会先清空桶内对象——它不调用任何对象删除逻辑;
- 如果目标桶不为空,Cloud Storage 服务会直接拒绝删除操作,工具将返回错误;
- 调用前必须确保桶内没有任何对象(含归档版本,由 GCS 服务端判断)。
从源码看,工具与数据源之间通过一个极简的接口契约通信(cloudstoragedeletebucket.go):
type compatibleSource interface { DeleteBucket(ctx context.Context, bucket string) (map[string]any, error) }任何实现了DeleteBucket方法的 Source 都被视为该工具的兼容数据源,这也是官方文档中 "Compatible Sources" 一节的代码级定义。
工具配置
在 Toolbox 配置文件中以kind: tool声明该工具。官方文档给出的最小配置示例如下:
kind: tool name: delete_bucket type: cloud-storage-delete-bucket source: my-gcs-source description: Use this tool to delete empty Cloud Storage buckets.其中source指向一个已配置的 Cloud Storage 数据源。对应的数据源配置示例(摘自 Cloud Storage Source 文档):
kind: source name: my-gcs-source type: "cloud-storage" project: "my-project-id" allowedBuckets: - "my-app-bucket" - "my-backup-bucket" allowedLocalRoots: - "/workspace"配置字段参考
对照源码中Config结构体的定义(cloudstoragedeletebucket.go):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | string | 是 | 必须为cloud-storage-delete-bucket |
| source | string | 是 | 要从中删除桶的 Cloud Storage 数据源名称 |
| description | string | 是 | 传递给 LLM 的工具描述;Initialize时若为空会直接报错 |
| authRequired | []string | 否 | 需要的前置认证服务列表,测试用例覆盖了authRequired: [google-auth-service]的解析 |
| annotations | object | 否 | MCP 工具注解;缺省时自动套用破坏性操作默认注解(见下文) |
破坏性操作标注
一个容易忽略但很关键的设计:该工具在初始化时会为 MCP 客户端附加注解(cloudstoragedeletebucket.go):
tools.GetAnnotationsOrDefault(cfg.Annotations, tools.NewDestructiveAnnotations),也就是说,若配置中未显式提供annotations,工具会自动使用NewDestructiveAnnotations生成的注解,向 MCP 客户端声明这是一个破坏性操作(destructive)。客户端可据此决定是否对调用施加确认流程。若业务上希望自定义这一语义,可在 YAML 中显式给出annotations覆盖默认值。
调用参数
工具只接受一个参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| bucket | string | 是 | 要删除的空 Cloud Storage 桶名称 |
从参数构造代码可以看到,Initialize阶段用parameters.NewStringParameter(bucketKey, "Name of the empty Cloud Storage bucket to delete.")注册了该参数,因此 LLM 客户端在tools/list中拿到的就是这条参数 schema 与描述。
Invoke阶段还会做防御性校验(cloudstoragedeletebucket.go):
mapParams := params.AsMap() bucket, ok := mapParams[bucketKey].(string) if !ok || bucket == "" { return nil, util.NewAgentError( fmt.Sprintf("invalid or missing '%s' parameter; expected a non-empty string", bucketKey), nil) }即bucket缺失、为空字符串或类型不是 string 时,返回AgentError(invalid or missing 'bucket' parameter; expected a non-empty string),且不会真正调用数据源。这一行为在单元测试TestInvokeValidation中有明确断言:参数校验失败时mockSource.called必须为false(cloudstoragedeletebucket_test.go)。
输出格式
删除成功后,工具返回如下 JSON 对象:
| 字段 | 类型 | 说明 |
|---|---|---|
| bucket | string | 被删除的 Cloud Storage 桶名 |
| deleted | boolean | 是否已删除(成功时恒为true) |
这个返回结构由数据源层的DeleteBucket方法直接构造(cloudstorage.go):
// DeleteBucket deletes an empty Cloud Storage bucket. func (s *Source) DeleteBucket(ctx context.Context, bucket string) (map[string]any, error) { if err := s.validateBucket(bucket); err != nil { return nil, err } if err := s.client.Bucket(bucket).Delete(ctx); err != nil { return nil, fmt.Errorf("failed to delete bucket %q: %w", bucket, err) } return map[string]any{ "bucket": bucket, "deleted": true, }, nil }单元测试中的 mock 数据源也以相同结构返回map[string]any{"bucket": bucket, "deleted": true},印证了契约的一致性(cloudstoragedeletebucket_test.go)。
数据源侧实现细节:桶白名单校验
cloud-storage数据源在配置层是项目级的,单个数据源即可操作凭证有权限访问的任意桶;而每个桶级操作(包括本工具)都会先经过白名单校验:
func (s *Source) validateBucket(bucket string) error { if len(s.AllowedBuckets) == 0 { return nil } for _, b := range s.AllowedBuckets { if b == bucket { return nil } } return fmt.Errorf("bucket %q is not allowed by source %q configuration", bucket, s.Name) }(cloudstorage.go)
关键结论:
- 省略
allowedBuckets时,项目内所有桶都允许操作——对于删除这种破坏性操作,生产配置建议显式列出白名单,把删除范围收敛到确需管理的桶; - 数据源配置中
project为必填字段(cloudstorage.go),用于初始化 GCS 客户端与确定桶归属项目; - 白名单之外的桶,错误消息形如
bucket "xxx" is not allowed by source "my-gcs-source" configuration,便于在日志中定位越界调用。
错误分类:AgentError 与 ServerError
工具调用出错时,所有来自 GCS 客户端的错误都会经过统一的分类函数ProcessGCSError(errors.go)。该函数把错误分成两类:
- AgentError:LLM 可以通过修正输入自行纠正的问题;
- ServerError:基础设施/权限层面的失败,改输入也没用。
与delete-bucket场景直接相关的映射规则如下:
| 底层情况 | 分类 | 返回语义 |
|---|---|---|
storage.ErrBucketNotExist(GCS 哨兵错误) | AgentError | cloud storage bucket does not exist |
| HTTP 404 Not Found | AgentError | cloud storage resource not found |
| HTTP 401 Unauthorized | ServerError | cloud storage authentication failed |
| HTTP 403 Forbidden | ServerError | cloud storage permission denied |
| 上下文取消/超时 | ServerError | cloud storage request cancelled or timed out(504 语义) |
| HTTP ≥500 | ServerError | cloud storage server error(502 语义) |
| 其他未识别错误 | ServerError | cloud storage request failed(500 语义) |
对删除桶这一动作的实际含义:
- 桶不存在被归类为 AgentError,提示 Agent 停止用同样的桶名重试,改为核对
list_buckets的结果; - 权限不足(凭证没有删除桶的 IAM 权限)会被归类为 ServerError(401/403),明确告知这是凭证问题而非参数问题;
- 桶非空导致的删除失败,由 GCS 服务端返回相应错误码后经上述管道透传,Agent 可据此先调用
list_objects检查桶内容再决定后续动作。
工具层对源兼容性的兜底检查同样位于Invoke入口:若运行时传入的数据源未实现DeleteBucket(配置期ValidateSource应已拦截),则返回 500 ServerErrorsource used is not compatible with the tool(cloudstoragedeletebucket.go)。
IAM 权限要求
要使该工具可用,需要满足两个前提:
- 凭证权限:Toolbox 使用 Application Default Credentials(ADC)与 Cloud Storage 交互;删除桶属于桶管理操作,按照 Cloud Storage 集成文档 与 预构建配置说明,桶生命周期操作(
list_buckets、create_bucket、delete_bucket等)需要Storage Admin(roles/storage.admin)级别的角色。只读角色(roles/storage.bucketViewer、roles/storage.objectViewer)不足以执行删除。 - 桶必须为空:即使拥有足够权限,非空桶的删除请求也会被 Cloud Storage 拒绝。
预构建配置与工具集
若不想手写上述 source + tool 配置,可以直接使用cloud-storage预构建配置启动 Toolbox:
--prebuilt取值:cloud-storage;- 环境变量:
CLOUD_STORAGE_PROJECT(桶所属的 GCP 项目 ID); - 预构建配置内置了
delete_bucket工具,其描述为 "Deletes an empty bucket.",并归入cloud-storage-buckets工具集(桶管理:list、create、inspect metadata/IAM、delete)(详见 cloud-storage.md)。
预构建配置下,删除桶所需权限同样是roles/storage.admin;如需最小权限部署,可按预构建文档中的角色矩阵裁剪暴露的工具集。
测试覆盖情况
仓库中为该工具提供了两层测试(cloudstoragedeletebucket_test.go):
- 配置解析测试(
TestParseFromYamlCloudStorageDeleteBucket):验证基本 YAML(name/type/source/description)以及带authRequired的 YAML 都能被正确反序列化为cloudstoragedeletebucket.Config; - 调用行为测试(
TestInvokeValidation):用实现DeleteBucket的mockSource验证——bucket为空时返回AgentError且数据源未被调用;正常路径下数据源收到正确的桶名并返回{"bucket": ..., "deleted": true}。
这些测试与本文描述的配置字段、参数校验和输出结构一一对应,可作为行为验证依据。
实操注意事项小结
- 删除前先用
list_objects或list_buckets工具确认桶存在且为空,避免把 404/非空错误浪费在一次真实调用上; - 生产环境务必在 source 上配置
allowedBuckets白名单,将delete-bucket的影响面限定在指定桶; - 不要依赖该工具做"级联删除"——清空桶内对象应通过
cloud-storage-delete-object等对象工具完成; - 桶不存在会返回 AgentError(而非静默成功),因此对 Agent 而言该工具天然不具备"幂等成功"语义;
- 由于工具默认携带 destructive 注解,对接的 MCP 客户端可能会要求人工确认,这是预期行为而非配置缺陷。
【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考