mcpField
G
google-drive

google-drive

github.com/acedatacloud文档处理17211 次安装1 天前更新
代码仓库

关于 google-drive

通过 curl、jq 和 Google Drive API 操作用户已选择或共享给应用的文件,适用于需要在命令行处理 Drive 文档的场景。指南包含读取、导出、上传和修改文件的步骤,并强调权限范围与破坏性操作确认。

主要功能

  1. 01检查 OAuth 连接与账户
  2. 02列出指定文件夹内容
  3. 03读取、下载与导出文件
  4. 04上传、重命名和移动文件
  5. 05遵循权限限制与修改确认

适用场景

  1. 01读取指定 Google 文档或表格
  2. 02向 Drive 文件夹上传报告
  3. 03在确认后重命名或移动文件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/acedatacloud/skills --skill google-drive

安装后在 Claude Code 中输入/google-drive确认已加载。

详细介绍

通过 curl + jq 操作 Google Drive。用户的 OAuth bearer token 位于 $GOOGLE_DRIVE_TOKEN;每次调用都需要将其作为 Authorization: Bearer $GOOGLE_DRIVE_TOKEN。该 token 包含 drive.file 以及身份作用域(openid email profile),只能访问用户为此应用选择、打开、创建或共享的文件。

Drive API 返回标准 JSON;失败时会返回 {"error": {"code": 401|403|..., "message": "..."}}——将该错误原样展示给用户。401 表示 token 已过期,用户必须重新安装连接器。403 insufficientPermissions 表示文件未与此应用共享,或该操作需要更广泛的 Drive 作用域,而该作用域在 Google 审核期间暂时被禁用。

不要使用此技能广泛发现 Drive 内容:不要“列出我最近的文件”、不要在整个 Drive 中进行全文搜索、不要扫描与我共享的内容、不要清理根文件夹,也不要根据覆盖整个 Drive 的查询批量移动文件。先让用户选择或粘贴确切的文件/文件夹 ID。

执行任何破坏性写入之前(重命名、移动、移至垃圾桶或批量修改文件),先展示确切的目标列表并请用户确认。切勿猜测 ID 后移至垃圾桶——始终回显即将操作的文件名和路径。

始终先调用 /about?fields=user,以确认连接正常并了解当前操作所用的 Google 账号。

可选:用于上传的 Google Workspace CLI(gws)

gws 是 Google 的官方 CLI(但不受官方支持——由社区在 googleworkspace 组织下维护)。它根据 Google 的 Discovery Document 动态构建命令界面,遇到 API 错误时以非零状态码退出,支持 --page-all 自动分页,并提供封装 multipart 上传协议的 +upload 辅助命令。

上传请使用 gws。 Drive multipart 上传需要手动构造 multipart/related 请求体,其中 JSON 元数据部分和二进制文件部分由边界字符串分隔——使用 curl 时很容易出错。gws drive +upload 能正确处理。其他所有操作 (获取、导出、重命名、移动、移至垃圾桶、删除)都可以使用下方等效且更简短的 curl 配方——请继续使用这些配方。

安装
npm install -g @googleworkspace/cli   # or: brew install googleworkspace-cli
# Pre-built binaries also at https://github.com/googleworkspace/cli/releases
gws --version
认证

gws 从环境变量 GOOGLE_WORKSPACE_CLI_TOKEN 读取 OAuth bearer token。此技能使用的 Drive token 位于 $GOOGLE_DRIVE_TOKEN,因此每个调用 gws 的 shell 代码块开头都要重新导出一次:

export GOOGLE_WORKSPACE_CLI_TOKEN="$GOOGLE_DRIVE_TOKEN"
上传
# Simple upload to My Drive (auto-detects MIME type, sets the file name
# from --name; falls back to the local filename if --name is omitted)
gws drive +upload ./report.pdf --name "Q1 Report"

# Upload into a specific folder, or with explicit metadata, via the
# generic Discovery method + --upload (multipart wire format handled
# for you)
gws drive files create \
  --json '{"name":"report.pdf","parents":["FOLDER_ID"],"description":"Q1"}' \
  --upload ./report.pdf

如果 Google 拒绝请求,两者都会以非零状态码退出,并在 stderr 上输出结构化 JSON 错误——请原样展示该错误。

配方

验证认证(始终先运行)
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  "https://www.googleapis.com/drive/v3/about?fields=user(displayName,emailAddress,photoLink),storageQuota(usage,limit)" \
  | jq '{user, quota: .storageQuota}'
列出所选文件夹的子项

仅在用户明确选择或提供文件夹 ID 后使用。

FOLDER_ID='1A2B3CdEfGhIjKlMn'
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  --get "https://www.googleapis.com/drive/v3/files" \
  --data-urlencode "q='$FOLDER_ID' in parents and trashed = false" \
  --data-urlencode 'fields=files(id,name,mimeType,size,modifiedTime),nextPageToken' \
  | jq '.files'
获取单个文件的元数据
FILE_ID='1A2B3CdEfGhIjKlMn'
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  "https://www.googleapis.com/drive/v3/files/$FILE_ID?fields=id,name,mimeType,size,modifiedTime,parents,owners,webViewLink,description"
下载二进制文件(PDF/图片/zip/…)
FILE_ID='1A2B3CdEfGhIjKlMn'
OUT=/tmp/download.bin
curl -sS -L -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  "https://www.googleapis.com/drive/v3/files/$FILE_ID?alt=media" \
  -o "$OUT"
file "$OUT" && wc -c "$OUT"
将 Google 文档读取为纯 Markdown/文本

Google 原生文件(Docs、Sheets、Slides)没有原始字节数据—— 必须请求 Drive 将其导出为具体的 MIME 类型:

DOC_ID='1A2B3CdEfGhIjKlMn'

# Markdown (best for chat-friendly summaries)
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  "https://www.googleapis.com/drive/v3/files/$DOC_ID/export?mimeType=text/markdown" \
  > /tmp/doc.md
head -40 /tmp/doc.md

# Plain text fallback for older docs
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  "https://www.googleapis.com/drive/v3/files/$DOC_ID/export?mimeType=text/plain" \
  > /tmp/doc.txt

常见的导出 MIME 类型:

原生 MIME导出为
application/vnd.google-apps.documenttext/markdown、text/plain、text/html、application/pdf、application/vnd.openxmlformats-officedocument.wordprocessingml.document
application/vnd.google-apps.spreadsheettext/csv、application/pdf、application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
application/vnd.google-apps.presentationapplication/pdf、text/plain、application/vnd.openxmlformats-officedocument.presentationml.presentation
将 Google 表格读取为 CSV
SHEET_ID='1A2B3CdEfGhIjKlMn'
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  "https://www.googleapis.com/drive/v3/files/$SHEET_ID/export?mimeType=text/csv" \
  > /tmp/sheet.csv
head /tmp/sheet.csv

Drive 的 export 端点仅返回第一个工作表。如需访问多个标签页,用户需要安装独立的 Google Sheets 连接器(目前未收录)——请说明这一点并停止操作。

获取文件权限/共享信息
FILE_ID='1A2B3CdEfGhIjKlMn'
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  "https://www.googleapis.com/drive/v3/files/$FILE_ID/permissions?fields=permissions(id,type,role,emailAddress,domain,deleted)" \
  | jq '.permissions[] | {who: (.emailAddress // .domain // .type), role}'

编写操作示例

这些操作仅适用于通过 drive.file 访问的文件和文件夹。 如果 Google 返回 403 insufficientPermissions,请显示该错误,并 让用户选择目标文件或将其共享给应用。 在将任何内容移至回收站或批量移动之前,务必先向用户 确认目标名称和路径。

重命名文件
FILE_ID='1A2B3CdEfGhIjKlMn'
NEW_NAME='2026 Q2 OKR (final).gdoc'
curl -sS -X PATCH -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  --data "{\"name\":$(jq -nr --arg n "$NEW_NAME" '$n')}" \
  "https://www.googleapis.com/drive/v3/files/$FILE_ID?fields=id,name"
将文件移动到其他文件夹

Drive 的文件夹模型基于父级 ID。移动 = 移除旧父级, 添加新父级:

FILE_ID='1A2B3CdEfGhIjKlMn'
NEW_PARENT='1XYZnewFolderId'

# Read existing parents (so we can pass them in removeParents)
OLD_PARENTS=$(curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  "https://www.googleapis.com/drive/v3/files/$FILE_ID?fields=parents" \
  | jq -r '.parents | join(",")')

curl -sS -X PATCH -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  --data '' \
  "https://www.googleapis.com/drive/v3/files/$FILE_ID?addParents=$NEW_PARENT&removeParents=$OLD_PARENTS&fields=id,name,parents"
创建新文件夹
PARENT_ID='1XYZparentFolderId'  # or 'root' for My Drive root
curl -sS -X POST -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  --data "{\"name\":\"Reports / 2026Q2\",\"mimeType\":\"application/vnd.google-apps.folder\",\"parents\":[\"$PARENT_ID\"]}" \
  "https://www.googleapis.com/drive/v3/files?fields=id,name,webViewLink" \
  | jq
上传文件(使用 multipart,以便在一个请求中发送元数据和字节)
LOCAL=/tmp/report.pdf
NAME='Q2 report.pdf'
PARENT_ID='1XYZparentFolderId'
MIME='application/pdf'

BOUNDARY='aceDataBoundary'
META=$(jq -nc --arg n "$NAME" --arg p "$PARENT_ID" '{name:$n, parents:[$p]}')
{
  printf -- '--%s\r\n' "$BOUNDARY"
  printf 'Content-Type: application/json; charset=UTF-8\r\n\r\n'
  printf '%s\r\n' "$META"
  printf -- '--%s\r\n' "$BOUNDARY"
  printf 'Content-Type: %s\r\n\r\n' "$MIME"
  cat "$LOCAL"
  printf '\r\n--%s--\r\n' "$BOUNDARY"
} > /tmp/_drive_upload.bin

curl -sS -X POST -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  -H "Content-Type: multipart/related; boundary=$BOUNDARY" \
  --data-binary @/tmp/_drive_upload.bin \
  "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,name,webViewLink" \
  | jq

对于仅媒体上传(无元数据),使用 uploadType=media;对于 大于 5 MB 的文件,使用 uploadType=resumable(详见 [Drive 文档] (https://developers.google.com/drive/api/guides/manage-uploads#resumable))。

替换现有文件的内容
FILE_ID='1A2B3CdEfGhIjKlMn'
LOCAL=/tmp/report-v2.pdf
curl -sS -X PATCH -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  -H 'Content-Type: application/pdf' \
  --data-binary @"$LOCAL" \
  "https://www.googleapis.com/upload/drive/v3/files/$FILE_ID?uploadType=media&fields=id,name,modifiedTime"

元数据保持不变(id / parents / name)——仅替换字节,且 Drive 会更新 modifiedTime。

将文件移至回收站(或恢复文件)
FILE_ID='1A2B3CdEfGhIjKlMn'
curl -sS -X PATCH -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"trashed":true}' \
  "https://www.googleapis.com/drive/v3/files/$FILE_ID?fields=id,name,trashed"

# Restore:
curl -sS -X PATCH -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"trashed":false}' \
  "https://www.googleapis.com/drive/v3/files/$FILE_ID?fields=id,name,trashed"

优先使用 trashed:true,而非 DELETE——DELETE 是永久操作,用户无法撤销。仅当用户明确说 “永久删除”时才使用 DELETE。

常见错误代码

HTTP含义告知用户的内容
401 UNAUTHENTICATED令牌已过期 / 已撤销“请在 Connections 页面重新连接 Google Drive 连接器。”
403 insufficientPermissions目标文件未与应用共享 / 已停用更广泛的 Drive 权限范围“在当前 drive.file 权限下,应用无法访问此文件。请在 Google Drive 连接器中选择或共享确切的文件,然后重试。”
403 userRateLimitExceeded配额限制5–10 秒后重试一次;如果问题仍然存在,请告知用户。
404 notFound文件 ID 错误,或应用无法看到该文件仔细检查 ID;让用户在连接器中选择或共享该文件。
400 invalidQueryq 格式错误向用户显示你发送的 q 和错误消息。

切勿记录或回显 $GOOGLE_DRIVE_TOKEN——请将其视为机密。

评论

支持 Markdown