Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
295 changes: 271 additions & 24 deletions app/en/mcp-servers/productivity/google-drive/page.mdx

Large diffs are not rendered by default.

107 changes: 71 additions & 36 deletions app/en/mcp-servers/productivity/google-drive/reference/page.mdx
Original file line number Diff line number Diff line change
@@ -1,45 +1,80 @@
# GoogleDrive Reference
# Google Drive Reference

Below is a reference of enumerations used by some tools in the GoogleDrive MCP Server:
Below is a reference of enumerations used by some tools in the Google Drive MCP Server:

## OrderBy

- **CREATED_TIME**: `createdTime`
- **CREATED_TIME_DESC**: `createdTime desc`
- **FOLDER**: `folder`
- **FOLDER_DESC**: `folder desc`
- **MODIFIED_BY_ME_TIME**: `modifiedByMeTime`
- **MODIFIED_BY_ME_TIME_DESC**: `modifiedByMeTime desc`
- **MODIFIED_TIME**: `modifiedTime`
- **MODIFIED_TIME_DESC**: `modifiedTime desc`
- **NAME**: `name`
- **NAME_DESC**: `name desc`
- **NAME_NATURAL**: `name_natural`
- **NAME_NATURAL_DESC**: `name_natural desc`
- **QUOTA_BYTES_USED**: `quotaBytesUsed`
- **QUOTA_BYTES_USED_DESC**: `quotaBytesUsed desc`
- **RECENCY**: `recency`
- **RECENCY_DESC**: `recency desc`
- **SHARED_WITH_ME_TIME**: `sharedWithMeTime`
- **SHARED_WITH_ME_TIME_DESC**: `sharedWithMeTime desc`
- **STARRED**: `starred`
- **STARRED_DESC**: `starred desc`
- **VIEWED_BY_ME_TIME**: `viewedByMeTime`
- **VIEWED_BY_ME_TIME_DESC**: `viewedByMeTime desc`
Sort order options for listing and searching files.

- **CREATED_TIME**: `createdTime` - When the file was created (ascending)
- **CREATED_TIME_DESC**: `createdTime desc` - When the file was created (descending)
- **FOLDER**: `folder` - The folder ID, sorted using alphabetical ordering (ascending)
- **FOLDER_DESC**: `folder desc` - The folder ID, sorted using alphabetical ordering (descending)
- **MODIFIED_BY_ME_TIME**: `modifiedByMeTime` - The last time the file was modified by the user (ascending)
- **MODIFIED_BY_ME_TIME_DESC**: `modifiedByMeTime desc` - The last time the file was modified by the user (descending)
- **MODIFIED_TIME**: `modifiedTime` - The last time the file was modified by anyone (ascending)
- **MODIFIED_TIME_DESC**: `modifiedTime desc` - The last time the file was modified by anyone (descending)
- **NAME**: `name` - The name of the file, sorted alphabetically (ascending)
- **NAME_DESC**: `name desc` - The name of the file, sorted alphabetically (descending)
- **NAME_NATURAL**: `name_natural` - The name of the file, sorted using natural sort ordering (ascending)
- **NAME_NATURAL_DESC**: `name_natural desc` - The name of the file, sorted using natural sort ordering (descending)
- **QUOTA_BYTES_USED**: `quotaBytesUsed` - The number of storage quota bytes used by the file (ascending)
- **QUOTA_BYTES_USED_DESC**: `quotaBytesUsed desc` - The number of storage quota bytes used by the file (descending)
- **RECENCY**: `recency` - The most recent timestamp from the file's date-time fields (ascending)
- **RECENCY_DESC**: `recency desc` - The most recent timestamp from the file's date-time fields (descending)
- **SHARED_WITH_ME_TIME**: `sharedWithMeTime` - When the file was shared with the user (ascending)
- **SHARED_WITH_ME_TIME_DESC**: `sharedWithMeTime desc` - When the file was shared with the user (descending)
- **STARRED**: `starred` - Whether the user has starred the file (ascending)
- **STARRED_DESC**: `starred desc` - Whether the user has starred the file (descending)
- **VIEWED_BY_ME_TIME**: `viewedByMeTime` - The last time the file was viewed by the user (ascending)
- **VIEWED_BY_ME_TIME_DESC**: `viewedByMeTime desc` - The last time the file was viewed by the user (descending)

## GoogleDriveFileType

- **SPREADSHEET**: `spreadsheet`
- **SLIDES**: `slides`
- **DOCUMENT**: `document`
- **DRAWING**: `drawing`
- **FORM**: `form`
- **FOLDER**: `folder`
- **IMAGE**: `image`
- **VIDEO**: `video`
- **AUDIO**: `audio`
- **SCRIPT**: `script`
- **SITES**: `sites`
- **PDF**: `pdf`
File type filters for searching files.

- **SPREADSHEET**: `spreadsheet` - Google Sheets
- **SLIDES**: `slides` - Google Slides presentations
- **DOCUMENT**: `document` - Google Docs
- **DRAWING**: `drawing` - Google Drawings
- **FORM**: `form` - Google Forms
- **FOLDER**: `folder` - Folders
- **IMAGE**: `image` - Image files (JPEG, PNG, GIF, WebP)
- **VIDEO**: `video` - Video files (MP4, MPEG, QuickTime, WebM)
- **AUDIO**: `audio` - Audio files (MP3, M4A, WAV)
- **SCRIPT**: `script` - Google Apps Script
- **SITES**: `sites` - Google Sites
- **PDF**: `pdf` - PDF documents

## PermissionRole

Permission roles for sharing Google Drive files and folders.

- **READER**: `reader` - Can view and download
- **COMMENTER**: `commenter` - Can view, download, and comment
- **WRITER**: `writer` - Can view, download, comment, and edit
- **OWNER**: `owner` - Full control (transfer ownership)

## UploadMimeType

Supported file types for uploading to Google Drive. This tool can only upload regular files - it cannot create Google Workspace files (Google Docs, Sheets, Slides).

### Text-based files

- **PLAIN_TEXT**: `text/plain` - .txt files
- **CSV**: `text/csv` - .csv spreadsheet data
- **JSON**: `application/json` - .json data files
- **HTML**: `text/html` - .html web pages
- **MARKDOWN**: `text/markdown` - .md documentation

### Documents

- **PDF**: `application/pdf` - .pdf documents

### Images

- **PNG**: `image/png` - .png images
- **JPEG**: `image/jpeg` - .jpg/.jpeg images
- **GIF**: `image/gif` - .gif images
- **WEBP**: `image/webp` - .webp images
- **SVG**: `image/svg+xml` - .svg vector graphics
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Arcade } from "@arcadeai/arcadejs";

const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable

const USER_ID = "{arcade_user_id}";
const TOOL_NAME = "GoogleDrive.CreateFolder";

// Start the authorization process
const authResponse = await client.tools.authorize({tool_name: TOOL_NAME, user_id: USER_ID});

if (authResponse.status !== "completed") {
console.log(`Click this link to authorize: ${authResponse.url}`);
}

// Wait for the authorization to complete
await client.auth.waitForCompletion(authResponse);

const toolInput = {
"folder_name": "My New Folder",
"parent_folder_path_or_id": "Projects/2024"
};

const response = await client.tools.execute({
tool_name: TOOL_NAME,
input: toolInput,
user_id: USER_ID,
});

console.log(JSON.stringify(response.output.value, null, 2));

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import json
from arcadepy import Arcade

client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable

USER_ID = "{arcade_user_id}"
TOOL_NAME = "GoogleDrive.CreateFolder"

auth_response = client.tools.authorize(tool_name=TOOL_NAME, user_id=USER_ID)

if auth_response.status != "completed":
print(f"Click this link to authorize: {auth_response.url}")

# Wait for the authorization to complete
client.auth.wait_for_completion(auth_response)

tool_input = {
"folder_name": "My New Folder",
"parent_folder_path_or_id": "Projects/2024"
}

response = client.tools.execute(
tool_name=TOOL_NAME,
input=tool_input,
user_id=USER_ID,
)
print(json.dumps(response.output.value, indent=2))

Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { Arcade } from "@arcadeai/arcadejs";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";

const client = new Arcade(); // Automatically finds the `ARCADE_API_KEY` env variable

const USER_ID = "{arcade_user_id}";
const FILE_ID = "Projects/report.pdf";
const __dirname = path.dirname(fileURLToPath(import.meta.url));

// Authorize for download tools
const authResponse = await client.tools.authorize({
tool_name: "GoogleDrive.DownloadFile",
user_id: USER_ID,
});

if (authResponse.status !== "completed") {
console.log(`Click this link to authorize: ${authResponse.url}`);
}

// Wait for the authorization to complete
await client.auth.waitForCompletion(authResponse);

// Step 1: Call download_file to get file info and possibly content
console.log(`Downloading file: ${FILE_ID}`);
const response = await client.tools.execute({
tool_name: "GoogleDrive.DownloadFile",
input: { file_path_or_id: FILE_ID },
user_id: USER_ID,
});

// Check for errors in the response
if (response.output.error) {
console.error(`Error: ${response.output.error}`);
process.exit(1);
}

const result = response.output.value;
if (!result) {
console.error(`Unexpected response: ${JSON.stringify(response)}`);
process.exit(1);
}

console.log(`File name: ${result.name}`);
console.log(`MIME type: ${result.mimeType}`);
console.log(`Size: ${result.size || "unknown"} bytes`);

// Get file extension from the original filename
const originalName = result.name;
const ext = path.extname(originalName) || ".bin";
const outputPath = path.join(__dirname, `downloaded_file${ext}`);

let fileContent;

// Step 2: Check if chunked download is required
if (result.requires_chunked_download) {
console.log("\nFile requires chunked download. Downloading in chunks...");
const chunkSize = result.recommended_chunk_size;

// Collect all chunks
const chunks = [];
let startByte = 0;

while (true) {
console.log(`Downloading chunk starting at byte ${startByte}...`);
const chunkResponse = await client.tools.execute({
tool_name: "GoogleDrive.DownloadFileChunk",
input: {
file_path_or_id: FILE_ID,
start_byte: startByte,
chunk_size: chunkSize,
},
user_id: USER_ID,
});

if (chunkResponse.output.error) {
console.error(`Error downloading chunk: ${chunkResponse.output.error}`);
process.exit(1);
}

const chunkResult = chunkResponse.output.value;
if (!chunkResult) {
console.error(`Unexpected chunk response: ${JSON.stringify(chunkResponse)}`);
process.exit(1);
}

const chunkContent = Buffer.from(chunkResult.content, "base64");
chunks.push(chunkContent);

console.log(`Progress: ${chunkResult.progress_percent}%`);

if (chunkResult.is_final_chunk) {
break;
}

startByte = chunkResult.next_start_byte;
}

// Combine all chunks
fileContent = Buffer.concat(chunks);
} else {
// Small file - content is included directly
console.log("\nFile content received directly (small file).");
fileContent = Buffer.from(result.content, "base64");
}

// Save the file
fs.writeFileSync(outputPath, fileContent);

console.log(`\nFile saved to: ${outputPath}`);
console.log(`Total bytes written: ${fileContent.length}`);
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import base64
import os

from arcadepy import Arcade

client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable

USER_ID = "{arcade_user_id}"
FILE_ID = "Projects/report.pdf"
OUTPUT_DIR = os.path.dirname(os.path.abspath(__file__))

# Authorize for download tools
auth_response = client.tools.authorize(tool_name="GoogleDrive.DownloadFile", user_id=USER_ID)

if auth_response.status != "completed":
print(f"Click this link to authorize: {auth_response.url}")

# Wait for the authorization to complete
client.auth.wait_for_completion(auth_response)

# Step 1: Call download_file to get file info and possibly content
print(f"Downloading file: {FILE_ID}")
response = client.tools.execute(
tool_name="GoogleDrive.DownloadFile",
input={"file_path_or_id": FILE_ID},
user_id=USER_ID,
)

# Check for errors in the response
if response.output.error:
print(f"Error: {response.output.error}")
exit(1)

result = response.output.value
if result is None:
print(f"Unexpected response: {response}")
exit(1)

print(f"File name: {result['name']}")
print(f"MIME type: {result['mimeType']}")
print(f"Size: {result.get('size', 'unknown')} bytes")

# Get file extension from the original filename
original_name = result["name"]
_, ext = os.path.splitext(original_name)
if not ext:
ext = ".bin" # Default extension if none found

output_path = os.path.join(OUTPUT_DIR, f"downloaded_file{ext}")

# Step 2: Check if chunked download is required
if result.get("requires_chunked_download"):
print("\nFile requires chunked download. Downloading in chunks...")
total_size = result["total_size_bytes"]
chunk_size = result["recommended_chunk_size"]

# Collect all chunks
chunks = []
start_byte = 0

while True:
print(f"Downloading chunk starting at byte {start_byte}...")
chunk_response = client.tools.execute(
tool_name="GoogleDrive.DownloadFileChunk",
input={
"file_path_or_id": FILE_ID,
"start_byte": start_byte,
"chunk_size": chunk_size,
},
user_id=USER_ID,
)

if chunk_response.output.error:
print(f"Error downloading chunk: {chunk_response.output.error}")
exit(1)

chunk_result = chunk_response.output.value
if chunk_result is None:
print(f"Unexpected chunk response: {chunk_response}")
exit(1)

chunk_content = base64.b64decode(chunk_result["content"])
chunks.append(chunk_content)

print(f"Progress: {chunk_result['progress_percent']}%")

if chunk_result["is_final_chunk"]:
break

start_byte = chunk_result["next_start_byte"]

# Combine all chunks and save
file_content = b"".join(chunks)
else:
# Small file - content is included directly
print("\nFile content received directly (small file).")
file_content = base64.b64decode(result["content"])

# Save the file
with open(output_path, "wb") as f:
f.write(file_content)

print(f"\nFile saved to: {output_path}")
print(f"Total bytes written: {len(file_content)}")
Loading