Google Drive Action

Move files in and out of Google Drive as part of your webhook pipelines. Twelve operations — upload, download, list, get, copy, move, delete, share, update, createFolder, export, getPermissions — all using the same auth and the same canvas node. Streams files directly from R2 to Drive (no in-memory buffering); in AI Toolkit mode each operation becomes a separate tool the LLM picks dynamically.

Why this beats n8n: n8n's Drive node fails on uploads over ~10–70 MB and corrupts binary downloads. HostWebhook streams via R2, returns proper _file refs the next pipeline node can chain on (FileTransform → Drive → AI vision is one continuous pipeline), and exposes per-op tools to MCP clients.

Authentication

Three OAuth scope tiers, picked when you connect the credential. Pick the least-privileged that fits the operation.

drive_file       ← default. App only sees files it created or the user explicitly picks.
drive_readonly   ← list / get / search across the whole Drive (no writes).
drive_full       ← move / delete / share on any file the user has access to.

Service Accounts work too, but they have no Drive storage quota — useful only with Shared Drives. The detail page warns when this combo is misconfigured.


Operations

upload

Streams a file from a payload _file ref into Drive. The _file ref typically comes from a multipart webhook ingress, a File Transform output, or a previous Drive download.

{
  "fileName":       "{{payload.name}}",   // optional override
  "sourceField":    "_file",              // payload field path holding the _file ref
  "parentFolderId": "",                   // empty = root
  "mimeType":       ""                    // override; defaults to _file.mimeType
}

download

Downloads a Drive file and returns it as a _file ref in the output payload — downstream nodes (FileTransform, AI vision, HTTP Action with binary body) consume it directly.

{ "fileId": "{{payload.driveFileId}}" }

// output:
{
  "_meta":   { "iterable": false, "count": 1 },
  "_file":   { "id", "key", "originalName", "mimeType", "size", "downloadUrl" },
  "driveFileId": "..."
}

list / search

Paginated search over Drive. Output is iterable — downstream nodes process each file independently.

{
  "query":          "report",                   // matches name contains
  "parentFolderId": "",
  "mimeType":       "application/pdf",
  "pageSize":       50,                          // max 100
  "orderBy":        "modifiedTime desc"
}

// output:
{
  "_meta": { "iterable": true, "iterateField": "files", "count": 12 },
  "files": [{ "id", "name", "mimeType", "size", "modifiedTime", "url", "parents" }]
}

get

Reads metadata for one file. Does NOT download the bytes.

{ "fileId": "..." }

copy

{
  "fileId":         "...",
  "newName":        "",            // optional rename
  "parentFolderId": ""             // optional — destination folder
}

move

{
  "fileId":         "...",
  "parentFolderId": "..."          // required — destination folder
}

delete

Defaults to trash (recoverable for 30 days). Set permanent: true only when the user explicitly confirms — irreversible. The AI Toolkit guardrail blockspermanent: true calls without prior user confirmation.
{ "fileId": "...", "permanent": false }

share

Sharing externally is sensitive. type: "anyone" makes the file public — only use when the user explicitly says so.
{
  "fileId":                "...",
  "type":                  "user",      // user | group | domain | anyone
  "role":                  "reader",    // reader | commenter | writer
  "emailAddress":          "...",       // required when type=user|group
  "domain":                "",          // required when type=domain
  "sendNotificationEmail": false
}

update

Rename, set description, or star/unstar.

{
  "fileId":      "...",
  "name":        "New name",
  "description": "",
  "starred":     true
}

createFolder

{ "name": "Reports", "parentFolderId": "" }

export

Export a Google native doc (Doc, Sheet, Slide, Drawing) to a downloadable format. Returns a _file ref. Common target MIME types:

application/pdf
application/vnd.openxmlformats-officedocument.wordprocessingml.document   // DOCX
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet         // XLSX
text/plain
text/csv

getPermissions

{ "fileId": "..." }

// output:
{
  "_meta": { "iterable": true, "iterateField": "permissions", "count": 3 },
  "fileId": "...",
  "permissions": [{ "id", "type", "role", "emailAddress", "domain", "displayName" }]
}

AI Toolkit Mode

Toggle aiEnabled on the detail page. The node hides from canvas connections and the LLM sees twelve discrete tools: upload_to_drive, download_from_drive, list_drive_files, get_drive_file, copy_drive_file, move_drive_file, delete_drive_file, share_drive_file, update_drive_file, create_drive_folder, export_drive_file, get_drive_permissions.

Each tool carries its own description + parameter schema curated for LLMs. The destructive ones (delete, share) are marked so the per-AI-Node requireConfirmationForDestructive gate can block them until the user confirms.

Pick this node from MCP servers

Settings → MCP Servers → New → pick your aiEnabled Drive Action. The single node becomes 12 entries in the MCP tools/list — Claude Desktop, Cursor, OpenAI Agents SDK see them as first-class tools.


Streaming & file size

Uploads stream from R2 to Drive — no full-file buffering — so size is bounded only by the plan's maxFileSize cap (10 MB free, 50 MB pro, 500 MB enterprise). Downloads currently round-trip through a buffer to R2; multipart streaming lands in a future patch for files > 100 MB. export uses the same path — exports up to the plan cap work today.


Pipeline examples

Save webhook attachments to Drive

Webhook (multipart ingress)
  → Drive Action (operation: upload, sourceField: "_file", parentFolderId: "<reports folder>")
  → Notification (Slack: "New attachment saved to Drive: {{payload.name}}")

Resize images and re-upload

Webhook
  → File Transform (imageResize, width: 800)
  → Drive Action (operation: upload, fileName: "{{payload.name}}-resized")

Convert Google Doc to PDF and email it

Scheduled Workflow (daily 9am)
  → Drive Action (operation: export, fileId: "<doc id>", mimeType: "application/pdf")
  → Email Action (attachment_file_ids: "{{payload._file.id}}")

Troubleshooting

Service Account upload returns 403 storageQuotaExceeded

Service Accounts have no Drive quota of their own. Either move the target folder to a Shared Drive, or switch to OAuth.

OAuth scope insufficient for operation

If the user authorized with drive_file but the operation needs drive_full (e.g. move a file the app didn't create), reconnect the credential with the higher tier from the credential picker.

list returns 0 results with drive_file scope

drive.file only returns files the app created or that the user picked through the file picker — by design. Use drive_readonly or drive_full for whole-Drive search.